home *** CD-ROM | disk | FTP | other *** search
/ Languages Around the World / LanguageWorld.iso / language / japanese / win_prog / win_jwp / jis.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-31  |  29.9 KB  |  1,291 lines

  1. /* Copyright (C) Ken R. Lunde, 1991-1992.  All rights reserved. */
  2.  
  3. /* These routines originally came from Ken R. Lunde's JCONV.C program, */
  4. /* version 2.3, August 12, 1992.  Many thanks to Ken for his donation. */
  5.  
  6. /* The original code was reformatted (to fit the style of the rest     */
  7. /* of the program).  Because EUC is used as the internal representa-   */
  8. /* tion, code corresponding to conversions not involving EUC is        */
  9. /* deleted.  Also, the original file-based character I/O machanism     */
  10. /* is changed.                                                         */
  11.  
  12. /* A modified version of the original documentation follows...         */
  13.  
  14. /*
  15. Program: jconv.c
  16. Version: 2.3
  17. Date:    August 12, 1992
  18. Author:  Ken R. Lunde, Adobe Systems Incorporated
  19.   EMAIL: lunde@mv.us.adobe.com
  20.   MAIL : 1585 Charleston Road, P.O. Box 7900, Mountain View, CA 94039-7900
  21. Type:    A tool for converting the Japanese code of Japanese textfiles.
  22. Code:    ANSI C (portable)
  23.  
  24. PORTABILITY:
  25. This source code was written so that it would be portable on C compilers which
  26. conform to the ANSI C standard. It has been tested on a variety of compilers.
  27.  
  28. I used THINK C and GNU C as my development platforms. I left in the Macintosh-
  29. specific lines of code so that it would be easier to enhance/debug this tool
  30. later. For those of you who wish to use this tool on the Macintosh, simply
  31. add the ANSI library to the THINK C project, and then build the application.
  32. Be sure that THINK_C has been defined, though, as the conditional compilation
  33. depends on it. You then have a double-clickable application, which when
  34. launched, will greet you with a Macintosh-style interface.
  35.  
  36. DISTRIBUTION AND RESTRICTIONS ON USAGE:
  37.  1) Please give this source code away to your friends at no charge.
  38.  2) Please try to compile this source code on various platforms to check for
  39.     portablity, and please report back to me with any results be they good or
  40.     bad. Suggestions are always welcome.
  41.  3) Only use this tool on a copy of a file -- do not use an original. This
  42.     is just common sense.
  43.  4) This source code or a compiled version may be bundled with commercial
  44.     software as long as the author is notified beforehand. The author's name
  45.     should also be mentioned in the credits.
  46.  5) Feel free to use any of the algorithms for your own work. Many of them are
  47.     being used in other tools I have written.
  48.  6) The most current version can be obtained by requesting a copy directly
  49.     from me.
  50.  
  51. DESCRIPTION:
  52.  1) Supports Shift-JIS, EUC, New-JIS, Old-JIS, and NEC-JIS for both input and
  53.     output.
  54.  2) Automatically detects infile's Japanese code (the ability to force an
  55.     input Japanese code is also supported through a command-line option).
  56.  3) The ability to convert Shift-JIS and EUC half-width katakana into full-
  57.     width equivalents. Note that half-width katakana includes other symbols
  58.     such as a Japanese period, Japanese comma, center dot, etc.
  59.  4) Supports conversion between the same code (i.e., EUC -> EUC, Shift-JIS ->
  60.     Shift-JIS, etc.). This is useful as a filter for converting half-width
  61.     katakana to their full-width equivalents.
  62.  5) If the infile does not contain any Japanese, then its contents are
  63.     echoed to the outfile. It will also try to repair the file as though
  64.     it had stripped escape characters (see #6 below).
  65.  6) The functionality of my other tool called repair-jis.c is included in
  66.     this tool by using the "-r[CODE]" option. This will recover stripped
  67.     escape characters, then convert the file to be in CODE format.
  68. */
  69.  
  70. #include "jwp.h"
  71.  
  72. #include <ctype.h>
  73. #include <errno.h>
  74.  
  75.  
  76. #define TOFULLSIZE        TRUE
  77. #define UNGETBUFSIZ     10
  78.  
  79. #define ReadChar()      ((stackp > 0) ? UngetBuf[--stackp] : f_charin())
  80. #define WriteChar(x)    f_charout(x)
  81. #define UnreadChar(x)   UngetBuf[stackp++] = (x)
  82.  
  83.  
  84.  
  85. #define FF_EUCSJIS  (FF_NEC + 1)
  86.  
  87. #define NUL         0
  88. #define NL          10
  89. #define FF          12
  90. #define CR          13
  91. #define ESC         27
  92.  
  93. #define SJIS1(A)    ((A >= 129 && A <= 159) || (A >= 224 && A <= 239))
  94. #define SJIS2(A)    (A >= 64 && A <= 252)
  95. #define HANKATA(A)  (A >= 161 && A <= 223)
  96. #define ISEUC(A)    (A >= 161 && A <= 254)
  97. #define ISMARU(A)   (A >= 202 && A <= 206)
  98. #define ISNIGORI(A) ((A >= 182 && A <= 196) || (A >= 202 && A <= 206))
  99.  
  100. void StraightEcho (void);
  101. void HanToZen(int *p1, int *p2, FILEFORMAT incode);
  102. void SJisToJis(int *p1, int *p2);
  103. void JisToSJis(int *p1, int *p2);
  104. void ShiftToEuc(FILEFORMAT incode);
  105. void EucToSeven(FILEFORMAT incode, char *ki, char *ko);
  106. void EucToEuc(FILEFORMAT incode);
  107. void EucToShift(FILEFORMAT incode);
  108. void SevenToEuc(void);
  109. void JisRepair(FILEFORMAT outcode, char *ki, char *ko);
  110. BOOL SkipESCSeq(int ch, int *TwoBytes);
  111. FILEFORMAT DetectCodeType(void);
  112.  
  113.  
  114.  
  115. /* The I/O Routines */
  116.  
  117. static int (* f_charin)(void);
  118. static void (* f_charout)(int);
  119.  
  120. static int UngetBuf[UNGETBUFSIZ];
  121. static int stackp;
  122.  
  123.  
  124.  
  125.  
  126. void SetupIO (int (* in)(void), void (* out)(int))
  127. {
  128.     f_charin = in;
  129.     f_charout = out;
  130.     stackp = 0;
  131. }
  132.  
  133.  
  134. static void OutPuts (char *buf)
  135. {
  136.     for (; *buf; buf++) WriteChar(*buf);
  137. }
  138.  
  139.  
  140.  
  141. /* Convert input file ==> EUC */
  142.  
  143. void FileImport (FILEFORMAT incode)
  144. {
  145.     switch (incode) {
  146.         case FF_UNKNOWN:    StraightEcho(); break;
  147.  
  148.         case FF_OLDJIS:
  149.         case FF_NEWJIS:
  150.         case FF_NEC:        SevenToEuc(); break;
  151.  
  152.         case FF_EUC:        EucToEuc(incode); break;
  153.  
  154.         case FF_SJIS:       ShiftToEuc(incode); break;
  155.     }
  156. }
  157.  
  158.  
  159. /* Convert internal EUC ==> Output format */
  160.  
  161. void FileExport (FILEFORMAT outcode)
  162. {
  163.     switch (outcode) {
  164.         case FF_NEWJIS:     EucToSeven(FF_EUC, "$B", "(J"); break;
  165.         case FF_OLDJIS:     EucToSeven(FF_EUC, "$@", "(J"); break;
  166.         case FF_NEC:        EucToSeven(FF_EUC, "K", "H"); break;
  167.  
  168.         case FF_UNKNOWN:
  169.         case FF_EUC:        /*EucToEuc(FF_EUC); */ StraightEcho(); break;
  170.  
  171.         case FF_SJIS:       EucToShift(FF_EUC); break;
  172.     }
  173. }
  174.  
  175.  
  176. #ifdef FOOBAR
  177. void main(int argc,char **argv)
  178. {
  179.   *out;
  180. #ifndef THINK_C
  181.   int rc;
  182. #endif
  183.   int tempincode,incode,doing = FALSE,forcedelesc = FALSE;
  184.   int makeoutfile = TRUE,outcode = FF_UNKNOWN,delesc = FALSE;
  185.   int repairjis = FALSE,TOFULLSIZE = FALSE,setincode = FALSE,docheck = FALSE;
  186.   char infilename[100],outfilename[100],extension[10],ki[10],ko[10],toolname[20];
  187.  
  188. #ifdef THINK_C
  189.   argc = ccommand(&argv);
  190. #endif
  191.  
  192.   strcpy(toolname,*argv);
  193.   while (--argc > 0 && (*++argv)[0] == '-')
  194.     switch (ToUpperCase(*++argv[0])) {
  195.       case 'C' :
  196.         docheck = TRUE;
  197.         break;
  198.       case 'F' :
  199.         TOFULLSIZE = TRUE;
  200.         break;
  201.       case 'H' :
  202.         dohelp(toolname);
  203.         break;
  204.       case 'I' :
  205.         setincode = TRUE;
  206.         doing = INPUT;
  207.         incode = getcode(extension,ToUpperCase(*++argv[0]),ki,ko,doing);
  208.         break;
  209.       case 'O' :
  210.         doing = OUTPUT;
  211.         outcode = getcode(extension,ToUpperCase(*++argv[0]),ki,ko,doing);
  212.         break;
  213.       case 'R' :
  214.         repairjis = TRUE;
  215.         doing = REPAIR;
  216.         outcode = getcode(extension,ToUpperCase(*++argv[0]),ki,ko,doing);
  217.         break;
  218.       case 'S' :
  219.         delesc = TRUE;
  220.         strcpy(extension,".rem");
  221.         if (ToUpperCase(*++argv[0]) == 'F')
  222.           forcedelesc = TRUE;
  223.         break;
  224.       case 'T' :
  225.         switch (ToUpperCase(*++argv[0])) {
  226.           case 'E' :
  227.             doeuctable();
  228.             break;
  229.           case 'J' :
  230.           case 'N' :
  231.           case 'O' :
  232.             dojistable();
  233.             break;
  234.           case 'S' :
  235.             dosjistable();
  236.             break;
  237.           default :
  238.             dojistable();
  239.             dosjistable();
  240.             doeuctable();
  241.             break;
  242.         }
  243.         exit(0);
  244.         break;
  245.       case 'V' :
  246.         break;
  247.       default :
  248.         fprintf(stderr,"Illegal option \"-%c\"! Try using the \"-h\" option for help.\n",*argv[0]);
  249.         fprintf(stderr,"Usage: %s [-options] [infile] [outfile]\nExiting...\n",toolname);
  250.         exit(1);
  251.         break;
  252.     }
  253.   if (repairjis && delesc) {
  254.     fprintf(stderr,"Error! Both \"-r\" and \"-s\" options cannot be selected! Exiting...\n");
  255.     exit(1);
  256.   }
  257.   if (outcode == FF_UNKNOWN && !repairjis && !delesc) {
  258.     strcpy(ki,DEFAULT_OKI);
  259.     strcpy(ko,DEFAULT_OKO);
  260.     strcpy(extension,DEFAULT_OS);
  261.     outcode = DEFAULT_O;
  262.   }
  263.   if (argc == 0) {
  264.     in = stdin;
  265.     out = stdout;
  266.   }
  267.   else if (argc > 0) {
  268.     if (argc == 1) {
  269.       strcpy(infilename,*argv);
  270.       if (strchr(*argv,PERIOD) != NULL)
  271.         *strrchr(*argv,PERIOD) = '\0';
  272.       strcpy(outfilename,*argv);
  273.       strcat(outfilename,extension);
  274.       if (!strcmp(infilename,outfilename)) {
  275.         if (strchr(outfilename,PERIOD) != NULL)
  276.           *strrchr(outfilename,PERIOD) = '\0';
  277.         strcat(outfilename,"-");
  278.         strcat(outfilename,extension);
  279.       }
  280.     }
  281.     else if (argc > 1) {
  282.       strcpy(infilename,*argv++);
  283.       if (*argv[0] == '-') {
  284.         out = stdout;
  285.         makeoutfile = FALSE;
  286.       }
  287.       else {
  288.         strcpy(outfilename,*argv);
  289.         if (!strcmp(infilename,outfilename)) {
  290.           if (strchr(outfilename,PERIOD) != NULL)
  291.             *strrchr(outfilename,PERIOD) = '\0';
  292.           strcat(outfilename,"-");
  293.           strcat(outfilename,extension);
  294.         }
  295.       }
  296.     }
  297.     if ((in = fopen(infilename,"r")) == NULL) {
  298.       fprintf(stderr,"Cannot open %s! Exiting...\n",infilename);
  299.       exit(1);
  300.     }
  301.     if (!docheck && makeoutfile)
  302.       if ((out = fopen(outfilename,"w")) == NULL) {
  303.         fprintf(stderr,"Cannot open %s! Exiting...\n",outfilename);
  304.         exit(1);
  305.       }
  306.   }
  307.   if (repairjis) {
  308.     JisRepair(in,out,outcode,ki,ko);
  309.     exit(0);
  310.   }
  311.   if (delesc) {
  312.     RemoveEscape(in,out,forcedelesc);
  313.     exit(0);
  314.   }
  315.   tempincode = incode;
  316.   if (!setincode || docheck) {
  317.     incode = DetectCodeType(in);
  318.     if (docheck) {
  319.       if (setincode && docheck)
  320.         fprintf(stderr,"NOTE: The selected \"-iCODE\" option was ignored\n");
  321.       fprintf(stderr,"Detected input code: ");
  322.       printcode(incode);
  323.       if (docheck)
  324.         exit(0);
  325.     }
  326.     rewind(in);
  327.   }
  328.   if (setincode)
  329.     incode = tempincode;
  330.   switch (incode) {
  331.     case FF_UNKNOWN :
  332.       fprintf(stderr,"Unknown input code! Exiting...\n");
  333.       exit(1);
  334.       break;
  335.     case FF_EUCSJIS :
  336.       fprintf(stderr,"Ambiguous (Shift-JIS or EUC) input code!\n");
  337.       fprintf(stderr,"Try using the \"-iCODE\" option to specify either Shift-JIS or EUC.\n");
  338.       fprintf(stderr,"Exiting...\n");
  339.       exit(1);
  340.       break;
  341.     case ASCII :
  342.       fprintf(stderr,"Since detected input code is ASCII, it may be damaged New- or Old-JIS\n");
  343.       fprintf(stderr,"Trying to repair...\n");
  344.       JisRepair(in,out,outcode,ki,ko);
  345.       break;
  346.     case FF_NEWJIS :
  347.     case FF_OLDJIS :
  348.     case FF_NEC :
  349.       switch (outcode) {
  350.         case FF_NEWJIS :
  351.         case FF_OLDJIS :
  352.         case FF_NEC :
  353.           seven2seven(in,out,ki,ko);
  354.           break;
  355.         case FF_EUC :
  356.           SevenToEuc(in,out);
  357.           break;
  358.         case FF_SJIS :
  359.           seven2shift(in,out);
  360.           break;
  361.       }
  362.       break;
  363.     case FF_EUC :
  364.       switch (outcode) {
  365.         case FF_NEWJIS :
  366.         case FF_OLDJIS :
  367.         case FF_NEC :
  368.           EucToSeven(in,out,incode,ki,ko);
  369.           break;
  370.         case FF_EUC :
  371.           EucToEuc(in,out,incode,TOFULLSIZE);
  372.           break;
  373.         case FF_SJIS :
  374.           EucToShift(in,out,incode,TOFULLSIZE);
  375.           break;
  376.       }
  377.       break;
  378.     case FF_SJIS :
  379.       switch (outcode) {
  380.         case FF_NEWJIS :
  381.         case FF_OLDJIS :
  382.         case FF_NEC :
  383.           shift2seven(in,out,incode,ki,ko);
  384.           break;
  385.         case FF_EUC :
  386.           ShiftToEuc(in,out,incode,TOFULLSIZE);
  387.           break;
  388.         case FF_SJIS :
  389.           shift2shift(in,out,incode,TOFULLSIZE);
  390.           break;
  391.       }
  392.       break;
  393.   }
  394.   exit(0);
  395. }
  396. #endif
  397.  
  398.  
  399. static void StraightEcho (void)
  400. {
  401.   int p1;
  402.  
  403.   while ((p1 = ReadChar()) != EOF) WriteChar(p1);
  404. }
  405.  
  406.  
  407. static BOOL SkipESCSeq (int ch, int *TwoBytes)
  408. {
  409.   BOOL temp;
  410.  
  411.   temp = *TwoBytes;
  412.   if (ch == '$' || ch == '(') ReadChar();
  413.  
  414.   if (ch == 'K' || ch == '$') *TwoBytes = TRUE;
  415.   else *TwoBytes = FALSE;
  416.  
  417.   return (temp == *TwoBytes);
  418. }
  419.  
  420.  
  421. static void JisRepair (FILEFORMAT outcode, char *ki, char *ko)
  422. {
  423.   int p1, p2, p3;
  424.   BOOL TwoBytes = FALSE;
  425.   unsigned long count = 0;
  426.  
  427.   while ((p1 = ReadChar()) != EOF) {
  428.     if (TwoBytes) {
  429.       if (p1 == ESC) {
  430.         p2 = ReadChar();
  431.         if (p2 == '(') {
  432.           p3 = ReadChar();
  433.           switch (p3) {
  434.             case 'J' :
  435.             case 'B' :
  436.             case 'H' :
  437.               TwoBytes = FALSE;
  438.               switch (outcode) {
  439.                 case FF_NEWJIS :
  440.                 case FF_NEC :
  441.                 case FF_OLDJIS :
  442.                   WriteChar(ESC);
  443.                   OutPuts(ko);
  444.                   break;
  445.                 default :
  446.                   break;
  447.               }
  448.               break;
  449.             default :
  450.               WriteChar(p1);
  451.               WriteChar(p2);
  452.               WriteChar(p3);
  453.               break;
  454.           }
  455.         }
  456.         else if (p2 == 'H') {
  457.           TwoBytes = FALSE;
  458.           switch (outcode) {
  459.             case FF_NEWJIS :
  460.             case FF_NEC :
  461.             case FF_OLDJIS :
  462.               WriteChar(ESC);
  463.               OutPuts(ko);
  464.               break;
  465.             default :
  466.               break;
  467.           }
  468.         }
  469.         else {
  470.           WriteChar(p1);
  471.           WriteChar(p2);
  472.         }
  473.       }
  474.       else if (p1 == '(') {
  475.         p2 = ReadChar();
  476.         switch (p2) {
  477.           case 'J' :
  478.           case 'B' :
  479.           case 'H' :
  480.             TwoBytes = FALSE;
  481.             switch (outcode) {
  482.               case FF_NEWJIS :
  483.               case FF_NEC :
  484.               case FF_OLDJIS :
  485.                 WriteChar(ESC);
  486.                 OutPuts(ko);
  487.                 break;
  488.               default :
  489.                 break;
  490.             }
  491.             count++;
  492.             break;
  493.           default :
  494.             switch (outcode) {
  495.               case FF_NEWJIS :
  496.               case FF_NEC :
  497.               case FF_OLDJIS :
  498.                 WriteChar(p1);
  499.                 WriteChar(p2);
  500.                 break;
  501.               case FF_EUC :
  502.                 p1 += 128;
  503.                 p2 += 128;
  504.                 WriteChar(p1);
  505.                 WriteChar(p2);
  506.                 break;
  507.               case FF_SJIS :
  508.                 JisToSJis(&p1,&p2);
  509.                 WriteChar(p1);
  510.                 WriteChar(p2);
  511.                 break;
  512.             }
  513.             break;
  514.         }
  515.       }
  516.       else if (p1 == NL) {
  517.         switch (outcode) {
  518.           case FF_NEWJIS :
  519.           case FF_NEC :
  520.           case FF_OLDJIS :
  521.             WriteChar(ESC);
  522.             OutPuts(ko);
  523.             WriteChar(p1);
  524.             break;
  525.           default :
  526.             WriteChar(p1);
  527.             break;
  528.         }
  529.         count++;
  530.         TwoBytes = FALSE;
  531.       }
  532.       else if (p1 == FF)
  533.         ;
  534.       else {
  535.         p2 = ReadChar();
  536.         switch (outcode) {
  537.           case FF_NEWJIS :
  538.           case FF_NEC :
  539.           case FF_OLDJIS :
  540.             WriteChar(p1);
  541.             WriteChar(p2);
  542.             break;
  543.           case FF_EUC :
  544.             p1 += 128;
  545.             p2 += 128;
  546.             WriteChar(p1);
  547.             WriteChar(p2);
  548.             break;
  549.           case FF_SJIS :
  550.             JisToSJis(&p1,&p2);
  551.             WriteChar(p1);
  552.             WriteChar(p2);
  553.             break;
  554.         }
  555.       }
  556.     }
  557.     else {
  558.       if (p1 == ESC) {
  559.         p2 = ReadChar();
  560.         if (p2 == '$') {
  561.           p3 = ReadChar();
  562.           switch (p3) {
  563.             case 'B' :
  564.             case '@' :
  565.               TwoBytes = TRUE;
  566.               switch (outcode) {
  567.                 case FF_NEWJIS :
  568.                 case FF_NEC :
  569.                 case FF_OLDJIS :
  570.                   WriteChar(ESC);
  571.                   OutPuts(ki);
  572.                   break;
  573.                 default :
  574.                   break;
  575.               }
  576.               break;
  577.             default :
  578.               WriteChar(p1);
  579.               WriteChar(p2);
  580.               WriteChar(p3);
  581.               break;
  582.           }
  583.         }
  584.         else if (p2 == 'K') {
  585.           TwoBytes = TRUE;
  586.           switch (outcode) {
  587.             case FF_NEWJIS :
  588.             case FF_NEC :
  589.             case FF_OLDJIS :
  590.               WriteChar(ESC);
  591.               OutPuts(ki);
  592.               break;
  593.             default :
  594.               break;
  595.           }
  596.         }
  597.         else {
  598.           WriteChar(p1);
  599.           WriteChar(p2);
  600.         }
  601.       }
  602.       else if (p1 == '$') {
  603.         p2 = ReadChar();
  604.         switch (p2) {
  605.           case 'B' :
  606.           case '@' :
  607.             TwoBytes = TRUE;
  608.             switch (outcode) {
  609.               case FF_NEWJIS :
  610.               case FF_NEC :
  611.               case FF_OLDJIS :
  612.                 WriteChar(ESC);
  613.                 OutPuts(ki);
  614.                 break;
  615.               default :
  616.                 break;
  617.             }
  618.             count++;
  619.             break;
  620.           default :
  621.             switch (outcode) {
  622.               case FF_NEWJIS :
  623.               case FF_NEC :
  624.               case FF_OLDJIS :
  625.                 WriteChar(p1);
  626.                 WriteChar(p2);
  627.                 break;
  628.               case FF_EUC :
  629.                 WriteChar(p1);
  630.                 WriteChar(p2);
  631.                 break;
  632.               case FF_SJIS :
  633.                 WriteChar(p1);
  634.                 WriteChar(p2);
  635.                 break;
  636.             }
  637.             break;
  638.         }
  639.       }
  640.       else if (p1 == FF)
  641.         ;
  642.       else
  643.         WriteChar(p1);
  644.     }
  645.   }
  646.   if (TwoBytes) {
  647.     switch (outcode) {
  648.       case FF_NEWJIS :
  649.       case FF_NEC :
  650.       case FF_OLDJIS :
  651.         WriteChar(ESC);
  652.         OutPuts(ko);
  653.         count++;
  654.         break;
  655.       default :
  656.         break;
  657.     }
  658.   }
  659. }
  660.  
  661. static void SJisToJis (int *p1, int *p2)
  662. {
  663.     register unsigned char c1 = *p1;
  664.     register unsigned char c2 = *p2;
  665.     register int adjust = c2 < 159;
  666.     register int RowOffset = c1 < 160 ? 112 : 176;
  667.     register int CellOffset = adjust ? (31 + (c2 > 127)) : 126;
  668.  
  669.     *p1 = ((c1 - RowOffset) << 1) - adjust;
  670.     *p2 -= CellOffset;
  671. }
  672.  
  673. static void JisToSJis (int *p1, int *p2)
  674. {
  675.     register unsigned char c1 = *p1;
  676.     register unsigned char c2 = *p2;
  677.     register int RowOffset = c1 < 95 ? 112 : 176;
  678.     register int CellOffset = c1 % 2 ? 31 + (c2 > 95) : 126;
  679.  
  680.     *p1 = ((c1 + 1) >> 1) + RowOffset;
  681.     *p2 = c2 + CellOffset;
  682. }
  683.  
  684.  
  685. static void ShiftToEuc (FILEFORMAT incode)
  686. {
  687.   int p1, p2;
  688.   
  689.   while ((p1 = ReadChar()) != EOF) {
  690.     switch (p1) {
  691.       case CR :
  692.         WriteChar(CR);
  693.         break;
  694.       case NL :
  695.         WriteChar(NL);
  696.         break;
  697.       case NUL :
  698.       case FF :
  699.         break;
  700.       default :
  701.         if SJIS1(p1) {
  702.           p2 = ReadChar();
  703.           if SJIS2(p2) {
  704.             SJisToJis(&p1,&p2);
  705.             p1 += 128;
  706.             p2 += 128;
  707.           }
  708.           WriteChar(p1);
  709.           WriteChar(p2);
  710.         }
  711.         else if HANKATA(p1) {
  712.           if (TOFULLSIZE) {
  713.             HanToZen(&p1,&p2,incode);
  714.             SJisToJis(&p1,&p2);
  715.             p1 += 128;
  716.             p2 += 128;
  717.           }
  718.           else {
  719.             p2 = p1;
  720.             p1 = 142;
  721.           }
  722.           WriteChar(p1);
  723.           WriteChar(p2);
  724.         }
  725.         else
  726.           WriteChar(p1);
  727.         break;
  728.     }
  729.   }
  730. }
  731.  
  732. static void EucToSeven (FILEFORMAT incode, char *ki, char *ko)
  733. {
  734.   int p1, p2;
  735.   BOOL TwoBytes = FALSE;
  736.  
  737.   while ((p1 = ReadChar()) != EOF) {
  738.     switch (p1) {
  739.       case NL :
  740.         if (TwoBytes) {
  741.           TwoBytes = FALSE;
  742.           WriteChar(ESC);
  743.           OutPuts(ko);
  744.         }
  745.         WriteChar(p1);
  746.         break;
  747.       case FF :
  748.         break;
  749.       default :
  750.         if ISEUC(p1) {
  751.           p2 = ReadChar();
  752.           if ISEUC(p2) {
  753.             p1 -= 128;
  754.             p2 -= 128;
  755.             if (!TwoBytes) {
  756.               TwoBytes = TRUE;
  757.               WriteChar(ESC);
  758.               OutPuts(ki);
  759.             }
  760.           }
  761.           WriteChar(p1);
  762.           WriteChar(p2);
  763.         }
  764.         else if (p1 == 142) {
  765.           p2 = ReadChar();
  766.           if HANKATA(p2) {
  767.             p1 = p2;
  768.             HanToZen(&p1,&p2,incode);
  769.             SJisToJis(&p1,&p2);
  770.             if (!TwoBytes) {
  771.               TwoBytes = TRUE;
  772.               WriteChar(ESC);
  773.               OutPuts(ki);
  774.             }
  775.           }
  776.           WriteChar(p1);
  777.           WriteChar(p2);
  778.         }
  779.         else {
  780.           if (TwoBytes) {
  781.             TwoBytes = FALSE;
  782.             WriteChar(ESC);
  783.             OutPuts(ko);
  784.           }
  785.           WriteChar(p1);
  786.         }
  787.         break;
  788.     }
  789.   }
  790.   if (TwoBytes) {
  791.     WriteChar(ESC);
  792.     OutPuts(ko);
  793.   }
  794. }
  795.  
  796. static void EucToShift (FILEFORMAT incode)
  797. {
  798.   int p1, p2;
  799.  
  800.   while ((p1 = ReadChar()) != EOF) {
  801.     switch (p1) {
  802.       case FF :
  803.         break;
  804.       default :
  805.         if ISEUC(p1) {
  806.           p2 = ReadChar();
  807.           if ISEUC(p2) {
  808.             p1 -= 128;
  809.             p2 -= 128;
  810.             JisToSJis(&p1,&p2);
  811.           }
  812.           WriteChar(p1);
  813.           WriteChar(p2);
  814.         }
  815.         else if (p1 == 142) {
  816.           p2 = ReadChar();
  817.           if HANKATA(p2) {
  818.             if (TOFULLSIZE) {
  819.               p1 = p2;
  820.               HanToZen(&p1,&p2,incode);
  821.               WriteChar(p1);
  822.               WriteChar(p2);
  823.             }
  824.             else {
  825.               p1 = p2;
  826.               WriteChar(p1);
  827.             }
  828.           }
  829.           else {
  830.             WriteChar(p1);
  831.             WriteChar(p2);
  832.           }
  833.         }
  834.         else
  835.           WriteChar(p1);
  836.         break;
  837.     }
  838.   }
  839. }
  840.  
  841. static void EucToEuc (FILEFORMAT incode)
  842. {
  843.   int p1, p2;
  844.  
  845.   while ((p1 = ReadChar()) != EOF) {
  846.     switch (p1) {
  847.       case FF :
  848.         break;
  849.       default :
  850.         if ISEUC(p1) {
  851.           p2 = ReadChar();
  852.           if ISEUC(p2) {
  853.             WriteChar(p1);
  854.             WriteChar(p2);
  855.           }
  856.         }
  857.         else if (p1 == 142) {
  858.           p2 = ReadChar();
  859.           if (HANKATA(p2) && TOFULLSIZE) {
  860.             p1 = p2;
  861.             HanToZen(&p1,&p2,incode);
  862.             SJisToJis(&p1,&p2);
  863.             p1 += 128;
  864.             p2 += 128;
  865.           }
  866.           WriteChar(p1);
  867.           WriteChar(p2);
  868.         }
  869.         else
  870.           WriteChar(p1);
  871.         break;
  872.     }
  873.   }
  874. }
  875.  
  876.   
  877. static void SevenToEuc (void)
  878. {
  879.   int temp,p1, p2,TwoBytes = FALSE;
  880.  
  881.   while ((p1 = ReadChar()) != EOF) {
  882.     switch (p1) {
  883.       case ESC :
  884.         temp = ReadChar();
  885.         SkipESCSeq(temp,&TwoBytes);
  886.         break;
  887.       case NL :
  888.         TwoBytes = FALSE;
  889.         WriteChar(p1);
  890.         break;
  891.       case FF :
  892.         break;
  893.       default :
  894.         if (TwoBytes) {
  895.           p2 = ReadChar();
  896.           p1 += 128;
  897.           p2 += 128;
  898.           WriteChar(p1);
  899.           WriteChar(p2);
  900.         }
  901.         else
  902.           WriteChar(p1);
  903.         break;
  904.     }
  905.   }
  906. }
  907.  
  908.  
  909. FILEFORMAT DetectCodeType (void)
  910. {
  911.   int c = 0;
  912.   FILEFORMAT whatcode = FF_UNKNOWN;
  913.  
  914.   while ((whatcode == FF_EUCSJIS || whatcode == FF_UNKNOWN) && c != EOF) {
  915.     if ((c = ReadChar()) != EOF) {
  916.       if (c == ESC) {
  917.         c = ReadChar();
  918.         if (c == '$') {
  919.           c = ReadChar();
  920.           if (c == 'B')
  921.             whatcode = FF_NEWJIS;
  922.           else if (c == '@')
  923.             whatcode = FF_OLDJIS;
  924.         }
  925.         else if (c == 'K')
  926.           whatcode = FF_NEC;
  927.       }
  928.       else if ((c >= 129 && c <= 141) || (c >= 143 && c <= 159))
  929.         whatcode = FF_SJIS;
  930.       else if (c == 142) {
  931.         c = ReadChar();
  932.         if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160) || (c >= 224 && c <= 252))
  933.           whatcode = FF_SJIS;
  934.         else if (c >= 161 && c <= 223)
  935.           whatcode = FF_EUCSJIS;
  936.       }
  937.       else if (c >= 161 && c <= 223) {
  938.         c = ReadChar();
  939.         if (c >= 240 && c <= 254)
  940.           whatcode = FF_EUC;
  941.         else if (c >= 161 && c <= 223)
  942.           whatcode = FF_EUCSJIS;
  943.         else if (c >= 224 && c <= 239) {
  944.           whatcode = FF_EUCSJIS;
  945.           while (c >= 64 && c != EOF && whatcode == FF_EUCSJIS) {
  946.             if (c >= 129) {
  947.               if (c <= 141 || (c >= 143 && c <= 159))
  948.                 whatcode = FF_SJIS;
  949.               else if (c >= 253 && c <= 254)
  950.                 whatcode = FF_EUC;
  951.             }
  952.             c = ReadChar();
  953.           }
  954.         }
  955.         else if (c <= 159)
  956.           whatcode = FF_SJIS;
  957.       }
  958.       else if (c >= 240 && c <= 254)
  959.         whatcode = FF_EUC;
  960.       else if (c >= 224 && c <= 239) {
  961.         c = ReadChar();
  962.         if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160))
  963.           whatcode = FF_SJIS;
  964.         else if (c >= 253 && c <= 254)
  965.           whatcode = FF_EUC;
  966.         else if (c >= 161 && c <= 252)
  967.           whatcode = FF_EUCSJIS;
  968.       }
  969.     }
  970.   }
  971.  
  972.   if (whatcode == FF_EUCSJIS) whatcode = FF_EUC;
  973.  
  974.   return (whatcode);
  975. }
  976.  
  977. static void HanToZen (int *p1, int *p2, FILEFORMAT incode)
  978. {
  979.   int junk, maru, nigori;
  980.  
  981.   maru = nigori = FALSE;
  982.   if (incode == FF_SJIS) {
  983.     *p2 = ReadChar();
  984.     if (*p2 == 222) {
  985.       if (ISNIGORI(*p1) || *p1 == 179)
  986.         nigori = TRUE;
  987.       else
  988.         UnreadChar(*p2);
  989.     }
  990.     else if (*p2 == 223) {
  991.       if ISMARU(*p1)
  992.         maru = TRUE;
  993.       else
  994.         UnreadChar(*p2);
  995.     }
  996.     else
  997.       UnreadChar(*p2);
  998.   }
  999.   else if (incode == FF_EUC) {
  1000.     junk = ReadChar();
  1001.     if (junk == 142) {
  1002.       *p2 = ReadChar();
  1003.       if (*p2 == 222) {
  1004.         if (ISNIGORI(*p1) || *p1 == 179)
  1005.           nigori = TRUE;
  1006.         else {
  1007.           UnreadChar(*p2);
  1008.           UnreadChar(junk);
  1009.         }
  1010.       }
  1011.       else if (*p2 == 223) {
  1012.         if ISMARU(*p1)
  1013.           maru = TRUE;
  1014.         else {
  1015.           UnreadChar(*p2);
  1016.           UnreadChar(junk);
  1017.         }
  1018.       }
  1019.       else {
  1020.         UnreadChar(*p2);
  1021.         UnreadChar(junk);
  1022.       }
  1023.     }
  1024.     else
  1025.       UnreadChar(junk);
  1026.   }
  1027.   switch (*p1) {
  1028.     case 161 :
  1029.       *p1 = 129;
  1030.       *p2 = 66;
  1031.       break;
  1032.     case 162 :
  1033.       *p1 = 129;
  1034.       *p2 = 117;
  1035.       break;
  1036.     case 163 :
  1037.       *p1 = 129;
  1038.       *p2 = 118;
  1039.       break;
  1040.     case 164 :
  1041.       *p1 = 129;
  1042.       *p2 = 65;
  1043.       break;
  1044.     case 165 :
  1045.       *p1 = 129;
  1046.       *p2 = 69;
  1047.       break;
  1048.     case 166 :
  1049.       *p1 = 131;
  1050.       *p2 = 146;
  1051.       break;
  1052.     case 167 :
  1053.       *p1 = 131;
  1054.       *p2 = 64;
  1055.       break;
  1056.     case 168 :
  1057.       *p1 = 131;
  1058.       *p2 = 66;
  1059.       break;
  1060.     case 169 :
  1061.       *p1 = 131;
  1062.       *p2 = 68;
  1063.       break;
  1064.     case 170 :
  1065.       *p1 = 131;
  1066.       *p2 = 70;
  1067.       break;
  1068.     case 171 :
  1069.       *p1 = 131;
  1070.       *p2 = 72;
  1071.       break;
  1072.     case 172 :
  1073.       *p1 = 131;
  1074.       *p2 = 131;
  1075.       break;
  1076.     case 173 :
  1077.       *p1 = 131;
  1078.       *p2 = 133;
  1079.       break;
  1080.     case 174 :
  1081.       *p1 = 131;
  1082.       *p2 = 135;
  1083.       break;
  1084.     case 175 :
  1085.       *p1 = 131;
  1086.       *p2 = 98;
  1087.       break;
  1088.     case 176 :
  1089.       *p1 = 129;
  1090.       *p2 = 91;
  1091.       break;
  1092.     case 177 :
  1093.       *p1 = 131;
  1094.       *p2 = 65;
  1095.       break;
  1096.     case 178 :
  1097.       *p1 = 131;
  1098.       *p2 = 67;
  1099.       break;
  1100.     case 179 :
  1101.       *p1 = 131;
  1102.       *p2 = 69;
  1103.       break;
  1104.     case 180 :
  1105.       *p1 = 131;
  1106.       *p2 = 71;
  1107.       break;
  1108.     case 181 :
  1109.       *p1 = 131;
  1110.       *p2 = 73;
  1111.       break;
  1112.     case 182 :
  1113.       *p1 = 131;
  1114.       *p2 = 74;
  1115.       break;
  1116.     case 183 :
  1117.       *p1 = 131;
  1118.       *p2 = 76;
  1119.       break;
  1120.     case 184 :
  1121.       *p1 = 131;
  1122.       *p2 = 78;
  1123.       break;
  1124.     case 185 :
  1125.       *p1 = 131;
  1126.       *p2 = 80;
  1127.       break;
  1128.     case 186 :
  1129.       *p1 = 131;
  1130.       *p2 = 82;
  1131.       break;
  1132.     case 187 :
  1133.       *p1 = 131;
  1134.       *p2 = 84;
  1135.       break;
  1136.     case 188 :
  1137.       *p1 = 131;
  1138.       *p2 = 86;
  1139.       break;
  1140.     case 189 :
  1141.       *p1 = 131;
  1142.       *p2 = 88;
  1143.       break;
  1144.     case 190 :
  1145.       *p1 = 131;
  1146.       *p2 = 90;
  1147.       break;
  1148.     case 191 :
  1149.       *p1 = 131;
  1150.       *p2 = 92;
  1151.       break;
  1152.     case 192 :
  1153.       *p1 = 131;
  1154.       *p2 = 94;
  1155.       break;
  1156.     case 193 :
  1157.       *p1 = 131;
  1158.       *p2 = 96;
  1159.       break;
  1160.     case 194 :
  1161.       *p1 = 131;
  1162.       *p2 = 99;
  1163.       break;
  1164.     case 195 :
  1165.       *p1 = 131;
  1166.       *p2 = 101;
  1167.       break;
  1168.     case 196 :
  1169.       *p1 = 131;
  1170.       *p2 = 103;
  1171.       break;
  1172.     case 197 :
  1173.       *p1 = 131;
  1174.       *p2 = 105;
  1175.       break;
  1176.     case 198 :
  1177.       *p1 = 131;
  1178.       *p2 = 106;
  1179.       break;
  1180.     case 199 :
  1181.       *p1 = 131;
  1182.       *p2 = 107;
  1183.       break;
  1184.     case 200 :
  1185.       *p1 = 131;
  1186.       *p2 = 108;
  1187.       break;
  1188.     case 201 :
  1189.       *p1 = 131;
  1190.       *p2 = 109;
  1191.       break;
  1192.     case 202 :
  1193.       *p1 = 131;
  1194.       *p2 = 110;
  1195.       break;
  1196.     case 203 :
  1197.       *p1 = 131;
  1198.       *p2 = 113;
  1199.       break;
  1200.     case 204 :
  1201.       *p1 = 131;
  1202.       *p2 = 116;
  1203.       break;
  1204.     case 205 :
  1205.       *p1 = 131;
  1206.       *p2 = 119;
  1207.       break;
  1208.     case 206 :
  1209.       *p1 = 131;
  1210.       *p2 = 122;
  1211.       break;
  1212.     case 207 :
  1213.       *p1 = 131;
  1214.       *p2 = 125;
  1215.       break;
  1216.     case 208 :
  1217.       *p1 = 131;
  1218.       *p2 = 126;
  1219.       break;
  1220.     case 209 :
  1221.       *p1 = 131;
  1222.       *p2 = 128;
  1223.       break;
  1224.     case 210 :
  1225.       *p1 = 131;
  1226.       *p2 = 129;
  1227.       break;
  1228.     case 211 :
  1229.       *p1 = 131;
  1230.       *p2 = 130;
  1231.       break;
  1232.     case 212 :
  1233.       *p1 = 131;
  1234.       *p2 = 132;
  1235.       break;
  1236.     case 213 :
  1237.       *p1 = 131;
  1238.       *p2 = 134;
  1239.       break;
  1240.     case 214 :
  1241.       *p1 = 131;
  1242.       *p2 = 136;
  1243.       break;
  1244.     case 215 :
  1245.       *p1 = 131;
  1246.       *p2 = 137;
  1247.       break;
  1248.     case 216 :
  1249.       *p1 = 131;
  1250.       *p2 = 138;
  1251.       break;
  1252.     case 217 :
  1253.       *p1 = 131;
  1254.       *p2 = 139;
  1255.       break;
  1256.     case 218 :
  1257.       *p1 = 131;
  1258.       *p2 = 140;
  1259.       break;
  1260.     case 219 :
  1261.       *p1 = 131;
  1262.       *p2 = 141;
  1263.       break;
  1264.     case 220 :
  1265.       *p1 = 131;
  1266.       *p2 = 143;
  1267.       break;
  1268.     case 221 :
  1269.       *p1 = 131;
  1270.       *p2 = 147;
  1271.       break;
  1272.     case 222 :
  1273.       *p1 = 129;
  1274.       *p2 = 74;
  1275.       break;
  1276.     case 223 :
  1277.       *p1 = 129;
  1278.       *p2 = 75;
  1279.       break;
  1280.   }
  1281.   if (nigori) {
  1282.     if ((*p2 >= 74 && *p2 <= 103) || (*p2 >= 110 && *p2 <= 122))
  1283.       (*p2)++;
  1284.     else if (*p1 == 131 && *p2 == 69)
  1285.       *p2 = 148;
  1286.   }
  1287.   else if (maru && *p2 >= 110 && *p2 <= 122)
  1288.     *p2 += 2;
  1289. }
  1290.  
  1291.