1 /*
2  *    qkcconv.c
3  *
4  *    Copyright (C) 1992 by K.Sato
5  *    All rights reserved.
6  */
7 
8 #include <stdio.h>
9 #include "qkc.h"
10 
11 unsigned char kanji2nd;
12 
13 extern int _7bitmode, rotencoding;
14 extern unsigned char esc_k[], esc_a[];
15 extern unsigned char *inbufptr, *outbufptr;
16 extern unsigned char *inbufend, *outbufend;
17 extern unsigned char rot13tbl[], rot47tbl[];
18 
19 extern int readbuf();
20 extern void writebuf();
21 
22 #define get() (inbufptr >= inbufend && readbuf() ? EOF : *inbufptr++)
23 #define put(c) (outbufptr >= outbufend ?\
24                (writebuf(), *outbufptr++ = (c)) : (*outbufptr++ = (c)))
25 
26 /* function version of get() */
getf()27 int getf()
28 {
29     return get();
30 }
31 
32 /* function version of put() */
putf(c)33 void putf(c)
34 int c;
35 {
36     put(c);
37 }
38 
39 /* convert JIS code to Shift-JIS code */
jistojms(c1,c2)40 unsigned char jistojms(c1, c2)
41 register unsigned char c1, c2;
42 {
43     if (c1 & 1) {
44         c1 = (c1 >> 1) + 0x71;
45         c2 += 0x1f;
46         if (c2 >= 0x7f)
47             c2++;
48     }
49     else {
50         c1 = (c1 >> 1) + 0x70;
51         c2 += 0x7e;
52     }
53     if (c1 > 0x9f)
54         c1 += 0x40;
55     kanji2nd = c2;
56     return c1;
57 }
58 
59 /* convert Shift-JIS code to JIS code */
jmstojis(c1,c2)60 unsigned char jmstojis(c1, c2)
61 register unsigned char c1, c2;
62 {
63     c1 -= (c1 <= 0x9f) ? 0x70 : 0xb0;
64     c1 <<= 1;
65     if (c2 < 0x9f) {
66         c2 -= (c2 < 0x7f) ? 0x1f : 0x20;
67         c1--;
68     }
69     else
70         c2 -= 0x7e;
71     kanji2nd = c2;
72     return c1;
73 }
74 
75 /* output escape sequence for 1 byte character */
set1byte()76 void set1byte()
77 {
78     putf(ESC);
79     putf(esc_a[0]);
80     if (esc_a[1])
81         putf(esc_a[1]);
82 }
83 
84 /* output escape sequence for 2 byte character */
set2byte()85 void set2byte()
86 {
87     putf(ESC);
88     putf(esc_k[0]);
89     if (esc_k[1])
90         putf(esc_k[1]);
91 }
92 
93 /* at the end of JIS file, output escape sequence for 1 byte character */
jisend(s,k)94 void jisend(s, k)
95 char s, k;
96 {
97     if (k)
98         putf(SI);
99     else if (s)
100         set1byte();
101 }
102 
103 /* copy */
copy()104 void copy()
105 {
106     register int c;
107 
108     while ((c = get()) != EOF)
109         put(c);
110 }
111 
112 /* Shift-JIS to EUC */
sjistoeuc()113 void sjistoeuc()
114 {
115     register int c, c2;
116     register char rot;
117 
118     rot = rotencoding;
119     if ((c = getf()) == EOF)
120         return;
121     while (1) {
122         if (c < 0x80) {
123             if (rot)
124                 c = rot13tbl[c];
125             putf(c);
126         }
127         else if (iskanji1st(c)) {
128             if ((c2 = get()) == EOF) {
129                 putf(c);
130                 return;
131             }
132             if (iskanji2nd(c2)) {
133                 c = jmstojis(c, c2);
134                 if (rot) {
135                     c = rot47tbl[c];
136                     kanji2nd = rot47tbl[kanji2nd];
137                 }
138                 put(c | 0x80);
139                 put(kanji2nd | 0x80);
140             }
141             else {
142                 putf(c);
143                 putf(c2);
144             }
145         }
146         else if (iskana(c)) {
147             putf(0x8e);
148             putf(c);
149         }
150         else
151             putf(c);
152         if ((c = get()) == EOF)
153             return;
154     }
155 }
156 
157 /* EUC to Shift-JIS */
euctosjis()158 void euctosjis()
159 {
160     register int c, c2;
161     register char rot;
162 
163     rot = rotencoding;
164     if ((c = getf()) == EOF)
165         return;
166     while (1) {
167         if (c < 0x80) {
168             if (rot)
169                 c = rot13tbl[c];
170             put(c);
171         }
172         else if (iseuc(c)) {
173             if ((c2 = get()) == EOF) {
174                 putf(c);
175                 return;
176             }
177             if (iseuc(c2)) {
178                 if (rot) {
179                     c = rot47tbl[c & 0x7f];
180                     c2 = rot47tbl[c2 & 0x7f];
181                 }
182                 c = jistojms(c & 0x7f, c2 & 0x7f);
183                 put(c);
184                 put(kanji2nd);
185             }
186             else {
187                 putf(c);
188                 putf(c2);
189             }
190         }
191         else if (c == 0x8e) {
192             if ((c = getf()) == EOF)
193                 return;
194             putf(c);
195         }
196         else if (c == 0x8f) {
197             if ((c = getf()) == EOF)
198                 return;
199             putf(c);
200             if ((c = getf()) == EOF)
201                 return;
202             putf(c);
203         }
204         else
205             putf(c);
206         if ((c = get()) == EOF)
207             return;
208     }
209 }
210 
211 /* Shift-JIS to JIS */
sjistojis()212 void sjistojis()
213 {
214     register int c, c2;
215     register char rot, state, kana;
216     char _7bit;
217 
218     rot = rotencoding;
219     _7bit = _7bitmode;
220     state = kana = 0;
221     if ((c = getf()) == EOF)
222         return;
223     while (1) {
224         if (c < 0x80) {
225             if (state) {
226                 set1byte();
227                 state = 0;
228             }
229             else if (kana) {
230                 putf(SI);
231                 kana = 0;
232             }
233             if (rot)
234                 c = rot13tbl[c];
235             put(c);
236         }
237         else if (iskanji1st(c)) {
238             if ((c2 = get()) == EOF) {
239                 jisend(state, kana);
240                 putf(c);
241                 return;
242             }
243             if (!state) {
244                 if (kana) {
245                     putf(SI);
246                     kana = 0;
247                 }
248                 set2byte();
249                 state = 1;
250             }
251             if (iskanji2nd(c2)) {
252                 c = jmstojis(c, c2);
253                 if (rot) {
254                     c = rot47tbl[c];
255                     kanji2nd = rot47tbl[kanji2nd];
256                 }
257                 put(c);
258                 put(kanji2nd);
259             }
260             else {
261                 putf(c);
262                 putf(c2);
263             }
264         }
265         else if (iskana(c)) {
266             if (state) {
267                 set1byte();
268                 state = 0;
269             }
270             if (_7bit) {
271                 if (!kana) {
272                     putf(SO);
273                     kana = 1;
274                 }
275                 c &= 0x7f;
276             }
277             putf(c);
278         }
279         else {
280             if (state) {
281                 set1byte();
282                 state = 0;
283             }
284             else if (kana) {
285                 putf(SI);
286                 kana = 0;
287             }
288             putf(c);
289         }
290         if ((c = get()) == EOF) {
291             jisend(state, kana);
292             return;
293         }
294     }
295 }
296 
297 /* JIS to Shift-JIS */
jistosjis()298 void jistosjis()
299 {
300     register int c, c2;
301     register char rot, state, kana;
302     char _7bit;
303 
304     rot = rotencoding;
305     _7bit = _7bitmode;
306     state = kana = 0;
307     if ((c = getf()) == EOF)
308         return;
309     while (1) {
310         if (c == ESC) {
311             if ((c = getf()) == EOF) {
312                 putf(ESC);
313                 return;
314             }
315             switch (c) {
316             case '$':
317                 if ((c2 = getf()) == EOF) {
318                     putf(ESC);
319                     putf(c);
320                     return;
321                 }
322                 if (c2 == 'B' || c2 == '@')
323                     state = 1;
324                 else {
325                     putf(ESC);
326                     putf(c);
327                     c = c2;
328                     continue;
329                 }
330                 break;
331             case '(':
332                 if ((c2 = getf()) == EOF) {
333                     putf(ESC);
334                     putf(c);
335                     return;
336                 }
337                 if (c2 == 'J' || c2 == 'B' || c2 == 'H')
338                     state = 0;
339                 else {
340                     putf(ESC);
341                     putf(c);
342                     c = c2;
343                     continue;
344                 }
345                 break;
346             case 'K':
347                 state = 1;
348                 break;
349             case 'H':
350                 state = 0;
351                 break;
352             default:
353                 putf(ESC);
354                 continue;
355             }
356         }
357         else if (c <= 0x20 || c == 0x7f) {
358             if (_7bit && (c == SO || c == SI))
359                 kana = c == SO;
360             else
361                 putf(c);
362         }
363         else if (state) {
364             if ((c2 = get()) == EOF) {
365                 putf(c);
366                 return;
367             }
368             if (c2 <= 0x20) {
369                 putf(c);
370                 c = c2;
371                 continue;
372             }
373             if (c < 0x80 && isjis(c2)) {
374                 if (rot) {
375                     c = rot47tbl[c];
376                     c2 = rot47tbl[c2];
377                 }
378                 c = jistojms(c, c2);
379                 put(c);
380                 put(kanji2nd);
381             }
382             else {
383                 putf(c);
384                 putf(c2);
385             }
386         }
387         else {
388             if (_7bit && kana)
389                 c |= 0x80;
390             else if (rot)
391                 c = rot13tbl[c];
392             put(c);
393         }
394         if ((c = get()) == EOF)
395             return;
396     }
397 }
398 
399 /* EUC to JIS */
euctojis()400 void euctojis()
401 {
402     register int c, c2;
403     register char rot, state, kana;
404     char _7bit;
405 
406     rot = rotencoding;
407     _7bit = _7bitmode;
408     state = kana = 0;
409     if ((c = getf()) == EOF)
410         return;
411     while (1) {
412         if (c < 0x80) {
413             if (state) {
414                 set1byte();
415                 state = 0;
416             }
417             else if (kana) {
418                 putf(SI);
419                 kana = 0;
420             }
421             if (rot)
422                 c = rot13tbl[c];
423             put(c);
424         }
425         else if (iseuc(c)) {
426             if ((c2 = get()) == EOF) {
427                 jisend(state, kana);
428                 putf(c);
429                 return;
430             }
431             if (!state) {
432                 if (kana) {
433                     putf(SI);
434                     kana = 0;
435                 }
436                 set2byte();
437                 state = 1;
438             }
439             if (iseuc(c2)) {
440                 if (rot) {
441                     c = rot47tbl[c & 0x7f];
442                     c2 = rot47tbl[c2 & 0x7f];
443                 }
444                 put(c & 0x7f);
445                 put(c2 & 0x7f);
446             }
447             else {
448                 putf(c);
449                 putf(c2);
450             }
451         }
452         else if (c == 0x8e) {
453             if ((c = getf()) == EOF) {
454                 jisend(state, kana);
455                 return;
456             }
457             if (state) {
458                 set1byte();
459                 state = 0;
460             }
461             if (_7bit) {
462                 if (!kana) {
463                     putf(SO);
464                     kana = 1;
465                 }
466                 c &= 0x7f;
467             }
468             putf(c);
469         }
470         else if (c == 0x8f) {
471             if ((c = getf()) == EOF) {
472                 jisend(state, kana);
473                 return;
474             }
475             if ((c2 = getf()) == EOF) {
476                 jisend(state, kana);
477                 putf(c);
478                 return;
479             }
480             if (!state) {
481                 if (kana) {
482                     putf(SI);
483                     kana = 0;
484                 }
485                 set2byte();
486                 state = 1;
487             }
488             putf(c);
489             putf(c2);
490         }
491         else {
492             if (state) {
493                 set1byte();
494                 state = 0;
495             }
496             else if (kana) {
497                 putf(SI);
498                 kana = 0;
499             }
500             putf(c);
501         }
502         if ((c = get()) == EOF) {
503             jisend(state, kana);
504             return;
505         }
506     }
507 }
508 
509 /* JIS to EUC */
jistoeuc()510 void jistoeuc()
511 {
512     register int c, c2;
513     register char rot, state, kana;
514     char _7bit;
515 
516     rot = rotencoding;
517     _7bit = _7bitmode;
518     state = kana = 0;
519     if ((c = getf()) == EOF)
520         return;
521     while (1) {
522         if (c == ESC) {
523             if ((c = getf()) == EOF) {
524                 putf(ESC);
525                 return;
526             }
527             switch (c) {
528             case '$':
529                 if ((c2 = getf()) == EOF) {
530                     putf(ESC);
531                     putf(c);
532                     return;
533                 }
534                 if (c2 == 'B' || c2 == '@')
535                     state = 1;
536                 else {
537                     putf(ESC);
538                     putf(c);
539                     c = c2;
540                     continue;
541                 }
542                 break;
543             case '(':
544                 if ((c2 = getf()) == EOF) {
545                     putf(ESC);
546                     putf(c);
547                     return;
548                 }
549                 if (c2 == 'J' || c2 == 'B' || c2 == 'H')
550                     state = 0;
551                 else {
552                     putf(ESC);
553                     putf(c);
554                     c = c2;
555                     continue;
556                 }
557                 break;
558             case 'K':
559                 state = 1;
560                 break;
561             case 'H':
562                 state = 0;
563                 break;
564             default:
565                 putf(ESC);
566                 continue;
567             }
568         }
569         else if (c <= 0x20 || c == 0x7f) {
570             if (_7bit && (c == SO || c == SI))
571                 kana = c == SO;
572             else
573                 putf(c);
574         }
575         else if (state) {
576             if ((c2 = get()) == EOF) {
577                 putf(c);
578                 return;
579             }
580             if (c2 <= 0x20 || c2 == 0x7f) {
581                 putf(c);
582                 c = c2;
583                 continue;
584             }
585             if (c < 0x80 && isjis(c2) && rot) {
586                 c = rot47tbl[c];
587                 c2 = rot47tbl[c2];
588             }
589             put(c | 0x80);
590             put(c2 | 0x80);
591         }
592         else {
593             if (_7bit && kana)
594                 c |= 0x80;
595             else if (rot)
596                 c = rot13tbl[c];
597             if (iskana(c))
598                 putf(0x8e);
599             put(c);
600         }
601         if ((c = get()) == EOF)
602             return;
603     }
604 }
605 
606 /* Shift-JIS to Shift-JIS */
sjistosjis()607 void sjistosjis()
608 {
609     register int c, c2;
610 
611     if (!rotencoding) {
612         copy();
613         return;
614     }
615     if ((c = getf()) == EOF)
616         return;
617     while (1) {
618         if (iskanji1st(c)) {
619             if ((c2 = get()) == EOF) {
620                 putf(c);
621                 return;
622             }
623             if (iskanji2nd(c2)) {
624                 c = jmstojis(c, c2);
625                 c = jistojms(rot47tbl[c], rot47tbl[kanji2nd]);
626                 put(c);
627                 put(kanji2nd);
628             }
629             else {
630                 putf(c);
631                 putf(c2);
632             }
633         }
634         else {
635             c = rot13tbl[c];
636             put(c);
637         }
638         if ((c = get()) == EOF)
639             return;
640     }
641 }
642 
643 /* EUC to EUC */
euctoeuc()644 void euctoeuc()
645 {
646     register int c, c2;
647 
648     if (!rotencoding) {
649         copy();
650         return;
651     }
652     if ((c = getf()) == EOF)
653         return;
654     while (1) {
655         if (c < 0x80) {
656             c = rot13tbl[c];
657             put(c);
658         }
659         else if (iseuc(c)) {
660             if ((c2 = get()) == EOF) {
661                 putf(c);
662                 return;
663             }
664             if (iseuc(c2)) {
665                 c = rot47tbl[c & 0x7f] | 0x80;
666                 c2 = rot47tbl[c2 & 0x7f] | 0x80;
667             }
668             put(c);
669             put(c2);
670         }
671         else if (c == 0x8e || c == 0x8f) {
672             putf(c);
673             c2 = c;
674             if ((c = getf()) == EOF)
675                 return;
676             putf(c);
677             if ((c = getf()) == EOF)
678                 return;
679             if (c2 == 0x8e)
680                 continue;
681             putf(c);
682         }
683         else
684             putf(c);
685         if ((c = get()) == EOF)
686             return;
687     }
688 }
689 
690 /* JIS to JIS */
jistojis()691 void jistojis()
692 {
693     register int c, c2;
694     register char i_state, o_state;
695     char rot, _7bit, i_kana, o_kana;
696 
697     rot = rotencoding;
698     _7bit = _7bitmode;
699     i_state = o_state = i_kana = o_kana = 0;
700     if ((c = getf()) == EOF)
701         return;
702     while (1) {
703         if (c == ESC) {
704             if ((c = getf()) == EOF) {
705                 jisend(o_state, o_kana);
706                 putf(ESC);
707                 return;
708             }
709             switch (c) {
710             case '$':
711                 if ((c2 = getf()) == EOF) {
712                     jisend(o_state, o_kana);
713                     putf(ESC);
714                     putf(c);
715                     return;
716                 }
717                 if (c2 == 'B' || c2 == '@')
718                     i_state = 1;
719                 else {
720                     if (o_state) {
721                         set1byte();
722                         o_state = 0;
723                     }
724                     putf(ESC);
725                     putf(c);
726                     c = c2;
727                     continue;
728                 }
729                 break;
730             case '(':
731                 if ((c2 = getf()) == EOF) {
732                     jisend(o_state, o_kana);
733                     putf(ESC);
734                     putf(c);
735                     return;
736                 }
737                 if (c2 == 'J' || c2 == 'B' || c2 == 'H')
738                     i_state = 0;
739                 else {
740                     if (o_state) {
741                         set1byte();
742                         o_state = 0;
743                     }
744                     putf(ESC);
745                     putf(c);
746                     c = c2;
747                     continue;
748                 }
749                 break;
750             case 'K':
751                 i_state = 1;
752                 break;
753             case 'H':
754                 i_state = 0;
755                 break;
756             default:
757                 if (o_state) {
758                     set1byte();
759                     o_state = 0;
760                 }
761                 putf(ESC);
762                 continue;
763             }
764         }
765         else if (c <= 0x20 || c == 0x7f)
766             switch (c) {
767             case SO:
768                 i_kana = 1;
769                 break;
770             case SI:
771                 i_kana = 0;
772                 break;
773             default:
774                 if (o_state) {
775                     set1byte();
776                     o_state = 0;
777                 }
778                 else if (o_kana) {
779                     putf(SI);
780                     o_kana = 0;
781                 }
782                 putf(c);
783             }
784         else if (i_state) {
785             if ((c2 = get()) == EOF) {
786                 jisend(o_state, o_kana);
787                 putf(c);
788                 return;
789             }
790             if (c2 <= 0x20 || c2 == 0x7f) {
791                 if (o_state) {
792                     set1byte();
793                     o_state = 0;
794                 }
795                 putf(c);
796                 c = c2;
797                 continue;
798             }
799             if (!o_state) {
800                 if (o_kana) {
801                     putf(SI);
802                     o_kana = 0;
803                 }
804                 set2byte();
805                 o_state = 1;
806             }
807             if (c < 0x80 && isjis(c2) && rot) {
808                 c = rot47tbl[c];
809                 c2 = rot47tbl[c2];
810             }
811             put(c);
812             put(c2);
813         }
814         else {
815             if (i_kana)
816                 c |= 0x80;
817             if (o_state) {
818                 set1byte();
819                 o_state = 0;
820             }
821             if (iskana(c) && _7bit) {
822                 if (!o_kana) {
823                     putf(SO);
824                     o_kana = 1;
825                 }
826                 c &= 0x7f;
827             }
828             else {
829                 if (o_kana) {
830                     putf(SI);
831                     o_kana = 0;
832                 }
833                 if (rot)
834                     c = rot13tbl[c];
835             }
836             put(c);
837         }
838         if ((c = get()) == EOF)
839             return;
840     }
841 }
842