kanji.c: Patch from Anders Blomdell <anders.blomdell@control.lth.se>
[samba.git] / source / lib / kanji.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Kanji Extensions
5    Copyright (C) Andrew Tridgell 1992-1997
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21    Adding for Japanese language by <fujita@ainix.isac.co.jp> 1994.9.5
22      and extend coding system to EUC/SJIS/JIS/HEX at 1994.10.11
23      and add all jis codes sequence type at 1995.8.16
24      Notes: Hexadecimal code by <ohki@gssm.otuka.tsukuba.ac.jp>
25 */
26
27 #define _KANJI_C_
28 #include "includes.h"
29
30 /* jis si/so sequence */
31 static char jis_kso = JIS_KSO;
32 static char jis_ksi = JIS_KSI;
33 static char hex_tag = HEXTAG;
34
35 /*******************************************************************
36   SHIFT JIS functions
37 ********************************************************************/
38 /*******************************************************************
39  search token from S1 separated any char of S2
40  S1 contain SHIFT JIS chars.
41 ********************************************************************/
42 char *sj_strtok(char *s1, char *s2)
43 {
44   if (lp_client_code_page() != KANJI_CODEPAGE) {
45    return strtok(s1, s2);
46   } else {
47     static char *s = NULL;
48     char *q;
49     if (!s1) {
50         if (!s) {
51             return NULL;
52         }
53         s1 = s;
54     }
55     for (q = s1; *s1; ) {
56         if (is_shift_jis (*s1)) {
57             s1 += 2;
58         } else if (is_kana (*s1)) {
59             s1++;
60         } else {
61             char *p = strchr (s2, *s1);
62             if (p) {
63                 if (s1 != q) {
64                     s = s1 + 1;
65                     *s1 = '\0';
66                     return q;
67                 }
68                 q = s1 + 1;
69             }
70             s1++;
71         }
72     }
73     s = NULL;
74     if (*q) {
75         return q;
76     }
77     return NULL;
78   }
79 }
80
81 /*******************************************************************
82  search string S2 from S1
83  S1 contain SHIFT JIS chars.
84 ********************************************************************/
85 char *sj_strstr(char *s1, char *s2)
86 {
87   if (lp_client_code_page() != KANJI_CODEPAGE) {
88     return strstr(s1, s2);
89   } else {
90     int len = strlen ((char *) s2);
91     if (!*s2) 
92         return (char *) s1;
93     for (;*s1;) {
94         if (*s1 == *s2) {
95             if (strncmp (s1, s2, len) == 0)
96                 return (char *) s1;
97         }
98         if (is_shift_jis (*s1)) {
99             s1 += 2;
100         } else {
101             s1++;
102         }
103     }
104     return 0;
105   }
106 }
107
108 /*******************************************************************
109  Search char C from beginning of S.
110  S contain SHIFT JIS chars.
111 ********************************************************************/
112 char *sj_strchr (char *s, int c)
113 {
114   if (lp_client_code_page() != KANJI_CODEPAGE) {
115     return strchr(s, c);
116   } else {
117     for (; *s; ) {
118         if (*s == c)
119             return (char *) s;
120         if (is_shift_jis (*s)) {
121             s += 2;
122         } else {
123             s++;
124         }
125     }
126     return 0;
127   }
128 }
129
130 /*******************************************************************
131  Search char C end of S.
132  S contain SHIFT JIS chars.
133 ********************************************************************/
134 char *sj_strrchr(char *s, int c)
135 {
136   if (lp_client_code_page() != KANJI_CODEPAGE) {
137     return strrchr(s, c);
138   } else {
139     char *q;
140
141     for (q = 0; *s; ) {
142         if (*s == c) {
143             q = (char *) s;
144         }
145         if (is_shift_jis (*s)) {
146             s += 2;
147         } else {
148             s++;
149         }
150     }
151     return q;
152   }
153 }
154
155 /*******************************************************************
156   Code conversion
157 ********************************************************************/
158 /* convesion buffer */
159 static char cvtbuf[1024];
160
161 /*******************************************************************
162   EUC <-> SJIS
163 ********************************************************************/
164 static int euc2sjis (int hi, int lo)
165 {
166     if (hi & 1)
167         return ((hi / 2 + (hi < 0xdf ? 0x31 : 0x71)) << 8) |
168             (lo - (lo >= 0xe0 ? 0x60 : 0x61));
169     else
170         return ((hi / 2 + (hi < 0xdf ? 0x30 : 0x70)) << 8) | (lo - 2);
171 }
172
173 static int sjis2euc (int hi, int lo)
174 {
175     if (lo >= 0x9f)
176         return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2);
177     else
178         return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) |
179             (lo + (lo >= 0x7f ? 0x60 : 0x61));
180 }
181
182 /*******************************************************************
183  Convert FROM contain SHIFT JIS codes to EUC codes
184  return converted buffer
185 ********************************************************************/
186 static char *sj_to_euc(char *from, BOOL overwrite)
187 {
188     char *out;
189     char *save;
190
191     save = (char *) from;
192     for (out = cvtbuf; *from;) {
193         if (is_shift_jis (*from)) {
194             int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff);
195             *out++ = (code >> 8) & 0xff;
196             *out++ = code;
197             from += 2;
198         } else if (is_kana (*from)) {
199             *out++ = euc_kana;
200             *out++ = *from++;
201         } else {
202             *out++ = *from++;
203         }
204     }
205     *out = 0;
206     if (overwrite) {
207         strcpy((char *) save, (char *) cvtbuf);
208         return (char *) save;
209     } else {
210         return cvtbuf;
211     }
212 }
213
214 /*******************************************************************
215  Convert FROM contain EUC codes to SHIFT JIS codes
216  return converted buffer
217 ********************************************************************/
218 static char *euc_to_sj(char *from, BOOL overwrite)
219 {
220     char *out;
221     char *save;
222
223     save = (char *) from;
224     for (out = cvtbuf; *from; ) {
225         if (is_euc (*from)) {
226             int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
227             *out++ = (code >> 8) & 0xff;
228             *out++ = code;
229             from += 2;
230         } else if (is_euc_kana (*from)) {
231             *out++ = from[1];
232             from += 2;
233         } else {
234             *out++ = *from++;
235         }
236     }
237     *out = 0;
238     if (overwrite) {
239         strcpy(save, (char *) cvtbuf);
240         return save;
241     } else {
242         return cvtbuf;
243     }
244 }
245
246 /*******************************************************************
247   JIS7,JIS8,JUNET <-> SJIS
248 ********************************************************************/
249 static int sjis2jis(int hi, int lo)
250 {
251     if (lo >= 0x9f)
252         return ((hi * 2 - (hi >= 0xe0 ? 0x160 : 0xe0)) << 8) | (lo - 0x7e);
253     else
254         return ((hi * 2 - (hi >= 0xe0 ? 0x161 : 0xe1)) << 8) |
255             (lo - (lo >= 0x7f ? 0x20 : 0x1f));
256 }
257
258 static int jis2sjis(int hi, int lo)
259 {
260     if (hi & 1)
261         return ((hi / 2 + (hi < 0x5f ? 0x71 : 0xb1)) << 8) |
262             (lo + (lo >= 0x60 ? 0x20 : 0x1f));
263     else
264         return ((hi / 2 + (hi < 0x5f ? 0x70 : 0xb0)) << 8) | (lo + 0x7e);
265 }
266
267 /*******************************************************************
268  Convert FROM contain JIS codes to SHIFT JIS codes
269  return converted buffer
270 ********************************************************************/
271 static char *jis8_to_sj(char *from, BOOL overwrite)
272 {
273     char *out;
274     int shifted;
275     char *save;
276
277     shifted = _KJ_ROMAN;
278     save = (char *) from;
279     for (out = cvtbuf; *from;) {
280         if (is_esc (*from)) {
281             if (is_so1 (from[1]) && is_so2 (from[2])) {
282                 shifted = _KJ_KANJI;
283                 from += 3;
284             } else if (is_si1 (from[1]) && is_si2 (from[2])) {
285                 shifted = _KJ_ROMAN;
286                 from += 3;
287             } else {                    /* sequence error */
288                 goto normal;
289             }
290         } else {
291         normal:
292             switch (shifted) {
293             default:
294             case _KJ_ROMAN:
295                 *out++ = *from++;
296                 break;
297             case _KJ_KANJI:
298                 {
299                     int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
300                     *out++ = (code >> 8) & 0xff;
301                     *out++ = code;
302                     from += 2;
303                 }
304                 break;
305             }
306         }
307     }
308     *out = 0;
309     if (overwrite) {
310         strcpy (save, (char *) cvtbuf);
311         return save;
312     } else {
313         return cvtbuf;
314     }
315 }
316
317 /*******************************************************************
318  Convert FROM contain SHIFT JIS codes to JIS codes
319  return converted buffer
320 ********************************************************************/
321 static char *sj_to_jis8(char *from, BOOL overwrite)
322 {
323     char *out;
324     int shifted;
325     char *save;
326
327     shifted = _KJ_ROMAN;
328     save = (char *) from;
329     for (out = cvtbuf; *from; ) {
330         if (is_shift_jis (*from)) {
331             int code;
332             switch (shifted) {
333             case _KJ_ROMAN:             /* to KANJI */
334                 *out++ = jis_esc;
335                 *out++ = jis_so1;
336                 *out++ = jis_kso;
337                 shifted = _KJ_KANJI;
338                 break;
339             }
340             code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
341             *out++ = (code >> 8) & 0xff;
342             *out++ = code;
343             from += 2;
344         } else {
345             switch (shifted) {
346             case _KJ_KANJI:             /* to ROMAN/KANA */
347                 *out++ = jis_esc;
348                 *out++ = jis_si1;
349                 *out++ = jis_ksi;
350                 shifted = _KJ_ROMAN;
351                 break;
352             }
353             *out++ = *from++;
354         }
355     }
356     switch (shifted) {
357     case _KJ_KANJI:                     /* to ROMAN/KANA */
358         *out++ = jis_esc;
359         *out++ = jis_si1;
360         *out++ = jis_ksi;
361         shifted = _KJ_ROMAN;
362         break;
363     }
364     *out = 0;
365     if (overwrite) {
366         strcpy (save, (char *) cvtbuf);
367         return save;
368     } else {
369         return cvtbuf;
370     }
371 }
372
373 /*******************************************************************
374  Convert FROM contain 7 bits JIS codes to SHIFT JIS codes
375  return converted buffer
376 ********************************************************************/
377 static char *jis7_to_sj(char *from, BOOL overwrite)
378 {
379     char *out;
380     int shifted;
381     char *save;
382
383     shifted = _KJ_ROMAN;
384     save = (char *) from;
385     for (out = cvtbuf; *from;) {
386         if (is_esc (*from)) {
387             if (is_so1 (from[1]) && is_so2 (from[2])) {
388                 shifted = _KJ_KANJI;
389                 from += 3;
390             } else if (is_si1 (from[1]) && is_si2 (from[2])) {
391                 shifted = _KJ_ROMAN;
392                 from += 3;
393             } else {                    /* sequence error */
394                 goto normal;
395             }
396         } else if (is_so (*from)) {
397             shifted = _KJ_KANA;         /* to KANA */
398             from++;
399         } else if (is_si (*from)) {
400             shifted = _KJ_ROMAN;        /* to ROMAN */
401             from++;
402         } else {
403         normal:
404             switch (shifted) {
405             default:
406             case _KJ_ROMAN:
407                 *out++ = *from++;
408                 break;
409             case _KJ_KANJI:
410                 {
411                     int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
412                     *out++ = (code >> 8) & 0xff;
413                     *out++ = code;
414                     from += 2;
415                 }
416                 break;
417             case _KJ_KANA:
418                 *out++ = ((int) from[0]) + 0x80;
419                 break;
420             }
421         }
422     }
423     *out = 0;
424     if (overwrite) {
425         strcpy (save, (char *) cvtbuf);
426         return save;
427     } else {
428         return cvtbuf;
429     }
430 }
431
432 /*******************************************************************
433  Convert FROM contain SHIFT JIS codes to 7 bits JIS codes
434  return converted buffer
435 ********************************************************************/
436 static char *sj_to_jis7(char *from, BOOL overwrite)
437 {
438     char *out;
439     int shifted;
440     char *save;
441
442     shifted = _KJ_ROMAN;
443     save = (char *) from;
444     for (out = cvtbuf; *from; ) {
445         if (is_shift_jis (*from)) {
446             int code;
447             switch (shifted) {
448             case _KJ_KANA:
449                 *out++ = jis_si;        /* to ROMAN and through down */
450             case _KJ_ROMAN:             /* to KANJI */
451                 *out++ = jis_esc;
452                 *out++ = jis_so1;
453                 *out++ = jis_kso;
454                 shifted = _KJ_KANJI;
455                 break;
456             }
457             code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
458             *out++ = (code >> 8) & 0xff;
459             *out++ = code;
460             from += 2;
461         } else if (is_kana (from[0])) {
462             switch (shifted) {
463             case _KJ_KANJI:             /* to ROMAN */
464                 *out++ = jis_esc;
465                 *out++ = jis_si1;
466                 *out++ = jis_ksi;
467             case _KJ_ROMAN:             /* to KANA */
468                 *out++ = jis_so;
469                 shifted = _KJ_KANA;
470                 break;
471             }
472             *out++ = ((int) *from++) - 0x80;
473         } else {
474             switch (shifted) {
475             case _KJ_KANA:
476                 *out++ = jis_si;        /* to ROMAN */
477                 shifted = _KJ_ROMAN;
478                 break;
479             case _KJ_KANJI:             /* to ROMAN */
480                 *out++ = jis_esc;
481                 *out++ = jis_si1;
482                 *out++ = jis_ksi;
483                 shifted = _KJ_ROMAN;
484                 break;
485             }
486             *out++ = *from++;
487         }
488     }
489     switch (shifted) {
490     case _KJ_KANA:
491         *out++ = jis_si;                /* to ROMAN */
492         break;
493     case _KJ_KANJI:                     /* to ROMAN */
494         *out++ = jis_esc;
495         *out++ = jis_si1;
496         *out++ = jis_ksi;
497         break;
498     }
499     *out = 0;
500     if (overwrite) {
501         strcpy (save, (char *) cvtbuf);
502         return save;
503     } else {
504         return cvtbuf;
505     }
506 }
507
508 /*******************************************************************
509  Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes
510  return converted buffer
511 ********************************************************************/
512 static char *junet_to_sj(char *from, BOOL overwrite)
513 {
514     char *out;
515     int shifted;
516     char *save;
517
518     shifted = _KJ_ROMAN;
519     save = (char *) from;
520     for (out = cvtbuf; *from;) {
521         if (is_esc (*from)) {
522             if (is_so1 (from[1]) && is_so2 (from[2])) {
523                 shifted = _KJ_KANJI;
524                 from += 3;
525             } else if (is_si1 (from[1]) && is_si2 (from[2])) {
526                 shifted = _KJ_ROMAN;
527                 from += 3;
528             } else if (is_juk1(from[1]) && is_juk2 (from[2])) {
529                 shifted = _KJ_KANA;
530                 from += 3;
531             } else {                    /* sequence error */
532                 goto normal;
533             }
534         } else {
535         normal:
536             switch (shifted) {
537             default:
538             case _KJ_ROMAN:
539                 *out++ = *from++;
540                 break;
541             case _KJ_KANJI:
542                 {
543                     int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
544                     *out++ = (code >> 8) & 0xff;
545                     *out++ = code;
546                     from += 2;
547                 }
548                 break;
549             case _KJ_KANA:
550                 *out++ = ((int) from[0]) + 0x80;
551                 break;
552             }
553         }
554     }
555     *out = 0;
556     if (overwrite) {
557         strcpy (save, (char *) cvtbuf);
558         return save;
559     } else {
560         return cvtbuf;
561     }
562 }
563
564 /*******************************************************************
565  Convert FROM contain SHIFT JIS codes to 7 bits JIS(junet) codes
566  return converted buffer
567 ********************************************************************/
568 static char *sj_to_junet(char *from, BOOL overwrite)
569 {
570     char *out;
571     int shifted;
572     char *save;
573
574     shifted = _KJ_ROMAN;
575     save = (char *) from;
576     for (out = cvtbuf; *from; ) {
577         if (is_shift_jis (*from)) {
578             int code;
579             switch (shifted) {
580             case _KJ_KANA:
581             case _KJ_ROMAN:             /* to KANJI */
582                 *out++ = jis_esc;
583                 *out++ = jis_so1;
584                 *out++ = jis_so2;
585                 shifted = _KJ_KANJI;
586                 break;
587             }
588             code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
589             *out++ = (code >> 8) & 0xff;
590             *out++ = code;
591             from += 2;
592         } else if (is_kana (from[0])) {
593             switch (shifted) {
594             case _KJ_KANJI:             /* to ROMAN */
595             case _KJ_ROMAN:             /* to KANA */
596                 *out++ = jis_esc;
597                 *out++ = junet_kana1;
598                 *out++ = junet_kana2;
599                 shifted = _KJ_KANA;
600                 break;
601             }
602             *out++ = ((int) *from++) - 0x80;
603         } else {
604             switch (shifted) {
605             case _KJ_KANA:
606             case _KJ_KANJI:             /* to ROMAN */
607                 *out++ = jis_esc;
608                 *out++ = jis_si1;
609                 *out++ = jis_si2;
610                 shifted = _KJ_ROMAN;
611                 break;
612             }
613             *out++ = *from++;
614         }
615     }
616     switch (shifted) {
617     case _KJ_KANA:
618     case _KJ_KANJI:                     /* to ROMAN */
619         *out++ = jis_esc;
620         *out++ = jis_si1;
621         *out++ = jis_si2;
622         break;
623     }
624     *out = 0;
625     if (overwrite) {
626         strcpy (save, (char *) cvtbuf);
627         return save;
628     } else {
629         return cvtbuf;
630     }
631 }
632
633 /*******************************************************************
634   HEX <-> SJIS
635 ********************************************************************/
636 /* ":xx" -> a byte */
637 static char *hex_to_sj(char *from, BOOL overwrite)
638 {
639     char *sp, *dp;
640     
641     sp = (char *) from;
642     dp = cvtbuf;
643     while (*sp) {
644         if (*sp == hex_tag && isxdigit (sp[1]) && isxdigit (sp[2])) {
645             *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
646             sp += 3;
647         } else
648             *dp++ = *sp++;
649     }
650     *dp = '\0';
651     if (overwrite) {
652         strcpy ((char *) from, (char *) cvtbuf);
653         return (char *) from;
654     } else {
655         return cvtbuf;
656     }
657 }
658  
659 /*******************************************************************
660   kanji/kana -> ":xx" 
661 ********************************************************************/
662 static char *sj_to_hex(char *from, BOOL overwrite)
663 {
664     unsigned char *sp, *dp;
665     
666     sp = (unsigned char*) from;
667     dp = (unsigned char*) cvtbuf;
668     while (*sp) {
669         if (is_kana(*sp)) {
670             *dp++ = hex_tag;
671             *dp++ = bin2hex (((*sp)>>4)&0x0f);
672             *dp++ = bin2hex ((*sp)&0x0f);
673             sp++;
674         } else if (is_shift_jis (*sp) && is_shift_jis2 (sp[1])) {
675             *dp++ = hex_tag;
676             *dp++ = bin2hex (((*sp)>>4)&0x0f);
677             *dp++ = bin2hex ((*sp)&0x0f);
678             sp++;
679             *dp++ = hex_tag;
680             *dp++ = bin2hex (((*sp)>>4)&0x0f);
681             *dp++ = bin2hex ((*sp)&0x0f);
682             sp++;
683         } else
684             *dp++ = *sp++;
685     }
686     *dp = '\0';
687     if (overwrite) {
688         strcpy ((char *) from, (char *) cvtbuf);
689         return (char *) from;
690     } else {
691         return cvtbuf;
692     }
693 }
694
695 /*******************************************************************
696   kanji/kana -> ":xx" 
697 ********************************************************************/
698 static char *sj_to_cap(char *from, BOOL overwrite)
699 {
700     unsigned char *sp, *dp;
701
702     sp = (unsigned char*) from;
703     dp = (unsigned char*) cvtbuf;
704     while (*sp) {
705         if (*sp >= 0x80) {
706             *dp++ = hex_tag;
707             *dp++ = bin2hex (((*sp)>>4)&0x0f);
708             *dp++ = bin2hex ((*sp)&0x0f);
709             sp++;
710         } else {
711             *dp++ = *sp++;
712         }
713     }
714     *dp = '\0';
715     if (overwrite) {
716         strcpy ((char *) from, (char *) cvtbuf);
717         return (char *) from;
718     } else {
719         return cvtbuf;
720     }
721 }
722
723 /*******************************************************************
724  sj to sj
725 ********************************************************************/
726 static char *sj_to_sj(char *from, BOOL overwrite)
727 {
728     if (!overwrite) {
729         strcpy (cvtbuf, (char *) from);
730         return cvtbuf;
731     } else {
732         return (char *) from;
733     }
734 }
735
736 /************************************************************************
737  conversion:
738  _dos_to_unix           _unix_to_dos
739 ************************************************************************/
740
741 char *(*_dos_to_unix)(char *str, BOOL overwrite) = sj_to_sj;
742 char *(*_unix_to_dos)(char *str, BOOL overwrite) = sj_to_sj;
743
744 static int setup_string_function(int codes)
745 {
746     switch (codes) {
747     default:
748     case SJIS_CODE:
749         _dos_to_unix = sj_to_sj;
750         _unix_to_dos = sj_to_sj;
751
752         break;
753         
754     case EUC_CODE:
755         _dos_to_unix = sj_to_euc;
756         _unix_to_dos = euc_to_sj;
757         break;
758         
759     case JIS7_CODE:
760         _dos_to_unix = sj_to_jis7;
761         _unix_to_dos = jis7_to_sj;
762         break;
763
764     case JIS8_CODE:
765         _dos_to_unix = sj_to_jis8;
766         _unix_to_dos = jis8_to_sj;
767         break;
768
769     case JUNET_CODE:
770         _dos_to_unix = sj_to_junet;
771         _unix_to_dos = junet_to_sj;
772         break;
773
774     case HEX_CODE:
775         _dos_to_unix = sj_to_hex;
776         _unix_to_dos = hex_to_sj;
777         break;
778
779     case CAP_CODE:
780         _dos_to_unix = sj_to_cap;
781         _unix_to_dos = hex_to_sj;
782         break;
783     }
784     return codes;
785 }
786
787 /*
788  * Interpret coding system.
789  */
790 int interpret_coding_system(char *str)
791 {
792     int codes = UNKNOWN_CODE;
793     
794     if (strequal (str, "sjis")) {
795         codes = SJIS_CODE;
796     } else if (strequal (str, "euc")) {
797         codes = EUC_CODE;
798     } else if (strequal (str, "cap")) {
799         codes = CAP_CODE;
800         hex_tag = HEXTAG;
801     } else if (strequal (str, "hex")) {
802         codes = HEX_CODE;
803         hex_tag = HEXTAG;
804     } else if (strncasecmp (str, "hex", 3)) {
805         codes = HEX_CODE;
806         hex_tag = (str[3] ? str[3] : HEXTAG);
807     } else if (strequal (str, "j8bb")) {
808         codes = JIS8_CODE;
809         jis_kso = 'B';
810         jis_ksi = 'B';
811     } else if (strequal (str, "j8bj") || strequal (str, "jis8")) {
812         codes = JIS8_CODE;
813         jis_kso = 'B';
814         jis_ksi = 'J';
815     } else if (strequal (str, "j8bh")) {
816         codes = JIS8_CODE;
817         jis_kso = 'B';
818         jis_ksi = 'H';
819     } else if (strequal (str, "j8@b")) {
820         codes = JIS8_CODE;
821         jis_kso = '@';
822         jis_ksi = 'B';
823     } else if (strequal (str, "j8@j")) {
824         codes = JIS8_CODE;
825         jis_kso = '@';
826         jis_ksi = 'J';
827     } else if (strequal (str, "j8@h")) {
828         codes = JIS8_CODE;
829         jis_kso = '@';
830         jis_ksi = 'H';
831     } else if (strequal (str, "j7bb")) {
832         codes = JIS7_CODE;
833         jis_kso = 'B';
834         jis_ksi = 'B';
835     } else if (strequal (str, "j7bj") || strequal (str, "jis7")) {
836         codes = JIS7_CODE;
837         jis_kso = 'B';
838         jis_ksi = 'J';
839     } else if (strequal (str, "j7bh")) {
840         codes = JIS7_CODE;
841         jis_kso = 'B';
842         jis_ksi = 'H';
843     } else if (strequal (str, "j7@b")) {
844         codes = JIS7_CODE;
845         jis_kso = '@';
846         jis_ksi = 'B';
847     } else if (strequal (str, "j7@j")) {
848         codes = JIS7_CODE;
849         jis_kso = '@';
850         jis_ksi = 'J';
851     } else if (strequal (str, "j7@h")) {
852         codes = JIS7_CODE;
853         jis_kso = '@';
854         jis_ksi = 'H';
855     } else if (strequal (str, "jubb")) {
856         codes = JUNET_CODE;
857         jis_kso = 'B';
858         jis_ksi = 'B';
859     } else if (strequal (str, "jubj") || strequal (str, "junet")) {
860         codes = JUNET_CODE;
861         jis_kso = 'B';
862         jis_ksi = 'J';
863     } else if (strequal (str, "jubh")) {
864         codes = JUNET_CODE;
865         jis_kso = 'B';
866         jis_ksi = 'H';
867     } else if (strequal (str, "ju@b")) {
868         codes = JUNET_CODE;
869         jis_kso = '@';
870         jis_ksi = 'B';
871     } else if (strequal (str, "ju@j")) {
872         codes = JUNET_CODE;
873         jis_kso = '@';
874         jis_ksi = 'J';
875     } else if (strequal (str, "ju@h")) {
876         codes = JUNET_CODE;
877         jis_kso = '@';
878         jis_ksi = 'H';
879     }   
880     return setup_string_function (codes);
881 }