home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1957 < prev    next >
Encoding:
Text File  |  1990-12-28  |  11.3 KB  |  396 lines

  1. Newsgroups: alt.sources
  2. From: KLUNDE@VMS.MACC.WISC.EDU ("Ken R. Lunde")
  3. Subject: [sci.lang.japan] Latest version of VALUES.C (with automatic KANJI code detection)
  4. Message-ID: <1990Oct15.221427.1411@math.lsa.umich.edu>
  5. Date: Mon, 15 Oct 90 22:14:27 GMT
  6.  
  7. Archive-name: kanji-values/13-Oct-90
  8. Original-posting-by: KLUNDE@VMS.MACC.WISC.EDU ("Ken R. Lunde")
  9. Original-subject: Latest version of VALUES.C (with automatic KANJI code detection)
  10. Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)
  11.  
  12. [Reposted from sci.lang.japan.
  13. Comments on this service to emv@math.lsa.umich.edu (Edward Vielmetti).]
  14.  
  15. /* VALUES.C version of 14 October 1990 */
  16. /* A utility for displaying the values of Japanese characters. */
  17. /* Written by Ken R. Lunde, University of Wisconsin-Madison */
  18. /* EMAIL: klunde@vms.macc.wisc.edu */
  19. /* Available at the ucdavis.edu (128.120.2.1) FTP archive in pub/JIS/C. */
  20.  
  21. /* I do not consider myself to be a very advanced programmer, but perhaps one */
  22. /* other person may have a use for this program. Please feel free to use this */
  23. /* source code anyway you wish. The conversion algorithms for the major codes */
  24. /* for Japanese are used, and are very reusable.  The algorithm which detects */
  25. /* the input file's Japanese code automatically is also quite useful. */
  26.  
  27. /* This program was written as a tool for determining the values for Japanese */
  28. /* and ASCII characters.  It is written in ANSI C, so should be compilable on */
  29. /* almost any platform, but I do not offer any guarantees. :-) */
  30.  
  31. /* This version accepts SHIFT-JIS, EUC, or the 7-bit JIS codes as valid input */
  32. /* for the file it reads. This program automatically detects which KANJI code */
  33. /* is used in the input file. The output file will use the same code that the */
  34. /* input file used. */
  35.  
  36. /* This program creates a file containing the contents of the input file, and */
  37. /* displays each character's SHIFT-JIS,  EUC,  and JIS values in one of three */
  38. /* different styles:   octal, decimal, or hexdecimal -- the user must specify */
  39. /* which one to use. ASCII and KUTEN values are also given.   A tab separates */
  40. /* the fields in the output file. I find that a tab width of 14 characters is */
  41. /* best when printing.  The SJIS, EUC, and JIS columns are padded with zero's */
  42. /* for octal and decimal output. This makes the output more "readable." */
  43.  
  44. /* For SHIFT-JIS input files only, half-size KATAKANA are treated. Only their */
  45. /* ASCII value is displayed since they are single-byte characters.  Printable */
  46. /* ASCII characters are handled with all the Japanese codes. */
  47.  
  48. /* Please send comments and suggestions! ENJOY! */
  49.  
  50. #include <stdio.h>
  51.  
  52. int DetectCodeType(FILE *in);
  53. int fclose(FILE *fp);
  54. int isodd(int number);
  55. void exit(int data);
  56. void Introduction(FILE *out,int choice,int code);
  57. void print1byte(FILE *out,int choice,int one);
  58. void print2byte(FILE *out,int code,int choice,int one,int two,int data[8]);
  59. void seven2shift(int *ptr1,int *ptr2);
  60. void shift2seven(int *ptr1,int *ptr2);
  61. void Skip_ESC_Seq(FILE *in,int data,int *ptr);
  62. void TreatEUC(FILE *in,FILE *out,int code,int choice);
  63. void TreatJIS(FILE *in,FILE *out,int code,int choice);
  64. void TreatSJIS(FILE *in,FILE *out,int code,int choice);
  65.  
  66. #define NOT_SET       0
  67. #define NEW           1
  68. #define OLD           2
  69. #define NEC           3
  70. #define EUC           4
  71. #define SJIS          5
  72. #define TRUE          1
  73. #define FALSE         0
  74. #define ESC          27
  75. #define SJIS1         0
  76. #define SJIS2         1
  77. #define EUC1          2
  78. #define EUC2          3
  79. #define JIS1          4
  80. #define JIS2          5
  81. #define KT1           6
  82. #define KT2           7
  83. #define OCT           8
  84. #define DEC          10
  85. #define HEX          16
  86. #define KI_NEW     "$B"
  87. #define KO_NEW     "(J"
  88. #define KI_OLD     "$@"
  89. #define KO_OLD     "(J"
  90. #define KI_NEC      "K"
  91. #define KO_NEC      "H"
  92.  
  93. main()
  94. {
  95.   FILE *in,*out;
  96.   int code,choice;
  97.   char infilename[80],outfilename[80];
  98.  
  99.   printf("\nInfile name  -> ");
  100.   gets(infilename);
  101.   if ((in = fopen(infilename,"r")) == NULL) {
  102.     printf("\nCannot open %s",infilename);
  103.     exit(1);
  104.   }
  105.   if ((code = DetectCodeType(in)) == NOT_SET) {
  106.     printf("\nNo KANJI code detected in %s",infilename);
  107.     exit(1);
  108.   }
  109.   if ((in = fopen(infilename,"r"))==NULL) {
  110.     printf("\nCannot open %s",infilename);
  111.     exit(1);
  112.   }
  113.   printf("Outfile name -> ");
  114.   gets(outfilename);
  115.   if ((out = fopen(outfilename,"w"))==NULL) {
  116.     printf("\nCannot open %s",outfilename);
  117.     exit(1);
  118.   }
  119.   printf("Output (8 = octal, 10 = decimal, 16 = hexadecimal) -> ");
  120.   scanf("%d",&choice);
  121.   if ((choice != OCT) && (choice != DEC) && (choice != HEX)) {
  122.     printf("\nInvalid choice! Bye!");
  123.     exit(1);
  124.   }
  125.   Introduction(out,choice,code);
  126.   switch (code) {
  127.     case SJIS :
  128.       TreatSJIS(in,out,code,choice);
  129.       break;
  130.     case EUC :
  131.       TreatEUC(in,out,code,choice);
  132.       break;
  133.     case NEW :
  134.     case OLD :
  135.     case NEC :
  136.       TreatJIS(in,out,code,choice);
  137.       break;
  138.   }
  139.   fclose(out);
  140.   fclose(in);
  141.   return 0;
  142. }
  143.  
  144. int DetectCodeType(FILE *in)
  145. {
  146.   int p1,p2,p3,whatcode;
  147.  
  148.   whatcode = NOT_SET;
  149.   while (((p1 = getc(in)) != EOF) && (whatcode == NOT_SET)) {
  150.     if (p1 == ESC) {
  151.       p2 = getc(in);
  152.       if (p2 == '$') {
  153.         p3 = getc(in);
  154.         if (p3 == 'B')
  155.           whatcode = NEW;
  156.         else if (p3 == '@')
  157.           whatcode = OLD;
  158.       }
  159.       else if (p2 == 'K')
  160.         whatcode = NEC;
  161.     }
  162.     else if ((p1 >= 129) && (p1 <= 254)) {
  163.       p2 = getc(in);
  164.       if (((p1 >= 129) && (p1 <= 159)) && ((p2 >= 64) && (p2 <= 160)))
  165.         whatcode = SJIS;
  166.       else if (((p1 >= 161) && (p1 <= 254)) && ((p2 >= 161) && (p2 <= 254)))
  167.         whatcode = EUC;
  168.     }
  169.   }
  170.   fclose(in);
  171.   return whatcode;
  172. }
  173.  
  174. int isodd(int number)
  175. {
  176.   return ((number % 2) ? 1 : 0);
  177. }
  178.  
  179. void Introduction(FILE *out,int choice,int code)
  180. {
  181.   switch (choice) {
  182.     case OCT :
  183.       fprintf(out,"Character values (in octal):\n\n");
  184.       break;
  185.     case DEC :
  186.       fprintf(out,"Character values (in decimal):\n\n");
  187.       break;
  188.     case HEX :
  189.       fprintf(out,"Character values (in hexadecimal):\n\n");
  190.       break;
  191.   }
  192.   switch (code) {
  193.     case SJIS :
  194.       fprintf(out,"Output KANJI code will be SHIFT-JIS\n\n");
  195.       break;
  196.     case EUC :
  197.       fprintf(out,"Output KANJI code will be EUC\n\n");
  198.       break;
  199.     case NEW :
  200.       fprintf(out,"Output KANJI code will be JIS 7-bit (NEW-JIS)\n\n");
  201.       break;
  202.     case OLD :
  203.       fprintf(out,"Output KANJI code will be JIS 7-bit (OLD-JIS)\n\n");
  204.       break;
  205.     case NEC :
  206.       fprintf(out,"Output KANJI code will be JIS 7-bit (NEC-JIS)\n\n");
  207.       break;
  208.   }
  209.   fprintf(out,"CHARACTER\tSHIFT-JIS or\tEUC\tJIS\tASCII\tKUTEN\n");
  210.   fprintf(out,"\tsingle-byte\n\n");
  211. }
  212.  
  213. void print1byte(FILE *out,int choice,int one)
  214. {
  215.   switch (choice) {
  216.     case OCT :
  217.       fprintf(out,"%c\t%03o\n",one,one);
  218.       break;
  219.     case DEC :
  220.       fprintf(out,"%c\t%03d\n",one,one);
  221.       break;
  222.     case HEX :
  223.       fprintf(out,"%c\t%X\n",one,one);
  224.       break;
  225.   }
  226. }
  227.  
  228. void print2byte(FILE *out,int code,int choice,int one,int two,int data[8])
  229. {
  230.   switch (code) {
  231.     case NEW :
  232.       fprintf(out,"%c%s%c%c%c%s\t",ESC,KI_NEW,one,two,ESC,KO_NEW);
  233.       break;
  234.     case OLD :
  235.       fprintf(out,"%c%s%c%c%c%s\t",ESC,KI_OLD,one,two,ESC,KO_OLD);
  236.       break;
  237.     case NEC :
  238.       fprintf(out,"%c%s%c%c%c%s\t",ESC,KI_NEC,one,two,ESC,KO_NEC);
  239.       break;
  240.     default :
  241.       fprintf(out,"%c%c\t",one,two);
  242.       break;
  243.   }
  244.   switch (choice) {
  245.     case OCT :
  246.       fprintf(out,"%03o-%03o\t",data[SJIS1],data[SJIS2]);
  247.       fprintf(out,"%03o-%03o\t",data[EUC1],data[EUC2]);
  248.       fprintf(out,"%03o-%03o\t",data[JIS1],data[JIS2]);
  249.       break;
  250.     case DEC :
  251.       fprintf(out,"%03d-%03d\t",data[SJIS1],data[SJIS2]);
  252.       fprintf(out,"%03d-%03d\t",data[EUC1],data[EUC2]);
  253.       fprintf(out,"%03d-%03d\t",data[JIS1],data[JIS2]);
  254.       break;
  255.     case HEX :
  256.       fprintf(out,"%X-%X\t",data[SJIS1],data[SJIS2]);
  257.       fprintf(out,"%X-%X\t",data[EUC1],data[EUC2]);
  258.       fprintf(out,"%X-%X\t",data[JIS1],data[JIS2]);
  259.       break;
  260.   }
  261.   fprintf(out,"%c%c\t",data[JIS1],data[JIS2]);
  262.   fprintf(out,"%02d-%02d\n",data[KT1],data[KT2]);
  263. }
  264.  
  265. void seven2shift (int *p1,int *p2)
  266. {
  267.   if (isodd(*p1))
  268.     *p2 += 31;
  269.   else
  270.     *p2 += 126;
  271.   if ((*p2 >= 127) && (*p2 < 158))
  272.     (*p2)++;
  273.   if ((*p1 >= 33) && (*p1 <= 94)) {
  274.     if (isodd(*p1))
  275.       *p1 = ((*p1 - 1) / 2) + 113;
  276.     else if (!isodd(*p1))
  277.       *p1 = (*p1 / 2) + 112;
  278.   }
  279.   else if ((*p1 >= 95) && (*p1 <= 126)) {
  280.     if (isodd(*p1))
  281.       *p1 = ((*p1 - 1) / 2) + 177;
  282.     else if (!isodd(*p1))
  283.       *p1 = (*p1 / 2) + 176;
  284.   }
  285. }
  286.  
  287. void shift2seven(int *p1,int *p2)
  288. {
  289.   int temp;
  290.  
  291.   temp = *p2;
  292.   if ((*p2 >= 64) && (*p2 <= 158))
  293.     *p2 -= 31;
  294.   else if ((*p2 >= 159) && (*p2 <= 252))
  295.     *p2 -= 126;
  296.   if ((temp > 127) && (temp <= 158))
  297.     (*p2)--;
  298.   if ((*p1 >= 129) && (*p1 <= 159) && (temp >= 64) && (temp <= 158))
  299.     *p1 = ((*p1 - 113) * 2) + 1;
  300.   else if ((*p1 >= 129) && (*p1 <= 159) && (temp >= 159) && (temp <= 252))
  301.     *p1 = (*p1 - 112) * 2;
  302.   else if ((*p1 >= 224) && (*p1 <= 239) && (temp >= 64) && (temp <= 158))
  303.     *p1 = ((*p1 - 177) * 2) + 1;
  304.   else if ((*p1 >= 224) && (*p1 <= 239) && (temp >= 159) && (temp <= 252))
  305.     *p1 = (*p1 - 176) * 2;
  306. }
  307.  
  308. void Skip_ESC_Seq(FILE *in,int temp,int *shifted_in)
  309. {
  310.   int junk;
  311.  
  312.   if ((temp == '$') || (temp == '('))
  313.     junk = getc(in);
  314.   if ((temp == 'K') || (temp == '$'))
  315.     *shifted_in = TRUE;
  316.   else
  317.     *shifted_in = FALSE;
  318. }
  319.  
  320. void TreatEUC(FILE *in,FILE *out,int code,int choice)
  321. {
  322.   int one,two;
  323.   int data[8];
  324.  
  325.   while ((one = getc(in)) != EOF) {
  326.     if ((one >= 161) && (one <= 254)) {
  327.       two = getc(in);
  328.       data[SJIS1] = data[EUC1] = data[JIS1] = data[KT1] = one;
  329.       data[SJIS2] = data[EUC2] = data[JIS2] = data[KT2] = two;
  330.       data[SJIS1] -= 128;
  331.       data[SJIS2] -= 128;
  332.       seven2shift(&data[SJIS1],&data[SJIS2]);
  333.       data[JIS1] -= 128;
  334.       data[JIS2] -= 128;
  335.       data[KT1] -= 160;
  336.       data[KT2] -= 160;
  337.       print2byte(out,code,choice,one,two,data);
  338.     }
  339.     else if ((one >= 33) && (one <= 126))
  340.       print1byte(out,choice,one);
  341.   }
  342. }
  343.  
  344. void TreatJIS(FILE *in,FILE *out,int code,int choice)
  345. {
  346.   int shifted_in,temp,one,two;
  347.   int data[8];
  348.  
  349.   shifted_in = FALSE;
  350.   while ((one = getc(in)) != EOF) {
  351.     if (one == ESC) {
  352.       temp = getc(in);
  353.       Skip_ESC_Seq(in,temp,&shifted_in);
  354.       if ((one = getc(in)) == EOF)
  355.         exit(1);
  356.     }
  357.     if (shifted_in) {
  358.       two = getc(in);
  359.       data[SJIS1] = data[EUC1] = data[JIS1] = data[KT1] = one;
  360.       data[SJIS2] = data[EUC2] = data[JIS2] = data[KT2] = two;
  361.       seven2shift(&data[SJIS1],&data[SJIS2]);
  362.       data[EUC1] += 128;
  363.       data[EUC2] += 128;
  364.       data[KT1] -= 32;
  365.       data[KT2] -= 32;
  366.       print2byte(out,code,choice,one,two,data);
  367.     }
  368.     else if ((!shifted_in) && ((one >= 33) && (one <= 126)))
  369.       print1byte(out,choice,one);
  370.   }
  371. }
  372.  
  373. void TreatSJIS(FILE *in,FILE *out,int code,int choice)
  374. {
  375.   int one,two;
  376.   int data[8];
  377.  
  378.   while ((one = getc(in)) != EOF) {
  379.     if (((one >= 129) && (one <= 159)) || ((one >= 224) && (one <= 239))) {
  380.       two = getc(in);
  381.       data[SJIS1] = data[EUC1] = data[JIS1] = data[KT1] = one;
  382.       data[SJIS2] = data[EUC2] = data[JIS2] = data[KT2] = two;
  383.       shift2seven(&data[EUC1],&data[EUC2]);
  384.       data[EUC1] += 128;
  385.       data[EUC2] += 128;
  386.       shift2seven(&data[JIS1],&data[JIS2]);
  387.       shift2seven(&data[KT1],&data[KT2]);
  388.       data[KT1] -= 32;
  389.       data[KT2] -= 32;
  390.       print2byte(out,code,choice,one,two,data);
  391.     }
  392.     else if (((one >= 33) && (one <= 126)) || ((one >= 161) && (one <= 223)))
  393.       print1byte(out,choice,one);
  394.   }
  395. }
  396.