551862d9bfdb1932ec5806813763c41230559f0e
[platform/upstream/libX11.git] / modules / lc / xlocale / lcJis.c
1 /*
2  * Copyright 1992, 1993 by TOSHIBA Corp.
3  *
4  * Permission to use, copy, modify, and distribute this software and its
5  * documentation for any purpose and without fee is hereby granted, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of TOSHIBA not be used in advertising
9  * or publicity pertaining to distribution of the software without specific,
10  * written prior permission. TOSHIBA make no representations about the
11  * suitability of this software for any purpose.  It is provided "as is"
12  * without express or implied warranty.
13  *
14  * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16  * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20  * SOFTWARE.
21  *
22  * Author: Katsuhisa Yano       TOSHIBA Corp.
23  *                              mopi@osa.ilab.toshiba.co.jp
24  */
25
26 /*
27  * A Japanese JIS locale.
28  * Supports: all locales with codeset JIS7.
29  * How: Provides converters for JIS.
30  * Platforms: Only those defining X_LOCALE (only Lynx, Linux-libc5, OS/2).
31  */
32
33 #ifdef X_LOCALE
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38 #include "Xlibint.h"
39 #include "XlcGeneric.h"
40 #include <stdio.h>
41
42 #if !defined(X_LOCALE)
43 #define STDCVT
44 #endif
45
46 typedef struct _StateRec {
47     XLCd lcd;
48     XlcCharSet charset;
49     XlcCharSet GL_charset;
50     XlcCharSet GR_charset;
51 } StateRec, *State;
52
53 static void
54 init_state(
55     XlcConv conv)
56 {
57     State state = (State) conv->state;
58     XLCdGenericPart *gen = XLC_GENERIC_PART(state->lcd);
59     CodeSet codeset;
60
61     codeset = gen->initial_state_GL;
62     if (codeset && codeset->charset_list)
63         state->GL_charset = *codeset->charset_list;
64     codeset = gen->initial_state_GR;
65     if (codeset && codeset->charset_list)
66         state->GR_charset = *codeset->charset_list;
67
68     if (state->GL_charset == NULL)
69         if ((codeset = *gen->codeset_list) != NULL)
70             state->GL_charset = *codeset->charset_list;
71 }
72
73 static int
74 compare(
75     const char *src,
76     const char *encoding,
77     int length)
78 {
79     const char *start = src;
80
81     while (length-- > 0) {
82         if (*src++ != *encoding++)
83             return 0;
84         if (*encoding == '\0')
85             return src - start;
86     }
87
88     return 0;
89 }
90
91 static int
92 mbtocs(
93     XlcConv conv,
94     XPointer *from,
95     int *from_left,
96     XPointer *to,
97     int *to_left,
98     XPointer *args,
99     int num_args)
100 {
101     State state = (State) conv->state;
102     XLCd lcd = state->lcd;
103     const char *src;
104     char *dst;
105     unsigned char *mb_parse_table;
106     ParseInfo *parse_list, parse_info;
107     XlcCharSet charset;
108     int length, number, encoding_len = 0;
109     int i;
110
111     src = *((const char **) from);
112     dst = *((char **) to);
113
114     mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
115     if (mb_parse_table != NULL) {
116         number = mb_parse_table[(unsigned char) *src];
117         if (number > 0) {
118             parse_list = XLC_GENERIC(lcd, mb_parse_list) + number - 1;
119             for ( ; (parse_info = *parse_list) != NULL; parse_list++) {
120                 encoding_len = compare(src, parse_info->encoding, *from_left);
121                 if (encoding_len > 0) {
122                     switch (parse_info->type) {
123                         case E_SS:
124                             src += encoding_len;
125                             charset = *parse_info->codeset->charset_list;
126                             goto found;
127                         case E_LSL:
128                         case E_LSR:
129                             src += encoding_len;
130                             charset = *parse_info->codeset->charset_list;
131                             if (parse_info->type == E_LSL)
132                                 state->GL_charset = charset;
133                             else
134                                 state->GR_charset = charset;
135                             length = 0;
136                             goto end;
137                         case E_GL:
138                             charset = state->GL_charset;
139                             goto found;
140                         case E_GR:
141                             charset = state->GR_charset;
142                             goto found;
143                         default:
144                             break;
145                     }
146                 }
147             }
148         }
149     }
150
151     if ((*src & 0x80) && state->GR_charset)
152         charset = state->GR_charset;
153     else
154         charset = state->GL_charset;
155
156 found:
157     if (charset == NULL ||
158         (num_args == 2 && (XlcCharSet) args[1] != charset))
159         return -1;
160
161     length = charset->char_size;
162     if (length > *from_left - encoding_len)
163         return -1;
164
165     if (dst) {
166         if (length > *to_left)
167             return -1;
168         if (charset->side == XlcGL) {
169             for (i = 0; i < length; i++)
170                 *dst++ = *src++ & 0x7f;
171         } else if (charset->side == XlcGR) {
172             for (i = 0; i < length; i++)
173                 *dst++ = *src++ | 0x80;
174         } else {
175             for (i = 0; i < length; i++)
176                 *dst++ = *src++;
177         }
178         *to = (XPointer) dst;
179         *to_left -= length;
180     }
181 end:
182     *from = (XPointer) src;
183     *from_left -= encoding_len + length;
184     state->charset = charset;
185     if (num_args == 1)
186         *((XlcCharSet *) args[0]) = charset;
187
188     return 0;
189 }
190
191 static int
192 mbstocs(
193     XlcConv conv,
194     XPointer *from,
195     int *from_left,
196     XPointer *to,
197     int *to_left,
198     XPointer *args,
199     int num_args)
200 {
201     XlcCharSet charset = NULL;
202     XPointer tmp_args[2], save_from = *from;
203     int ret, unconv_num = 0, tmp_num = 1;
204
205     tmp_args[0] = (XPointer) &charset;
206
207     while (*from_left > 0 && *to_left > 0) {
208         ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, tmp_num);
209         if (ret < 0)
210             break;
211         unconv_num += ret;
212         if (tmp_num == 1 && charset) {
213             tmp_args[1] = (XPointer) charset;
214             tmp_num = 2;
215         }
216     }
217
218     if (save_from == *from)
219         return -1;
220
221     if (num_args > 0)
222         *((XlcCharSet *) args[0]) = charset;
223
224     return unconv_num;
225 }
226
227 static CodeSet
228 wc_parse_codeset(
229     XLCd lcd,
230     const wchar_t *wcstr)
231 {
232     CodeSet *codeset;
233     unsigned long wc_encoding;
234     int num;
235
236     wc_encoding = *wcstr & XLC_GENERIC(lcd, wc_encode_mask);
237     num = XLC_GENERIC(lcd, codeset_num);
238     codeset = XLC_GENERIC(lcd, codeset_list);
239     while (num-- > 0) {
240         if (wc_encoding == (*codeset)->wc_encoding)
241             return *codeset;
242         codeset++;
243     }
244
245     return NULL;
246 }
247
248 static int
249 wcstocs(
250     XlcConv conv,
251     XPointer *from,
252     int *from_left,
253     XPointer *to,
254     int *to_left,
255     XPointer *args,
256     int num_args)
257 {
258     State state = (State) conv->state;
259     XLCd lcd = state->lcd;
260     const wchar_t *wcptr;
261     char *bufptr;
262     wchar_t wch;
263     char *tmpptr;
264     int length;
265     CodeSet codeset;
266     unsigned long wc_encoding;
267     int wcstr_len, buf_len;
268
269     if (from == NULL || *from == NULL)
270         return 0;
271
272     wcptr = *((const wchar_t **) from);
273     bufptr = *((char **) to);
274     wcstr_len = *from_left;
275     buf_len = *to_left;
276
277     codeset = wc_parse_codeset(lcd, wcptr);
278     if (codeset == NULL)
279         return -1;
280     wc_encoding = codeset->wc_encoding;
281
282     if (wcstr_len < buf_len / codeset->length)
283         buf_len = wcstr_len * codeset->length;
284
285     for ( ; wcstr_len > 0 && buf_len > 0; wcptr++, wcstr_len--) {
286         wch = *wcptr;
287         if ((wch & XLC_GENERIC(lcd, wc_encode_mask)) != wc_encoding)
288             break;
289         length = codeset->length;
290         buf_len -= length;
291         bufptr += length;
292
293         tmpptr = bufptr - 1;
294         if ((*codeset->charset_list)->side == XlcGL) {
295             while (length--) {
296                 *tmpptr-- = (unsigned char) (wch & 0x7f);
297                 wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
298             }
299         } else if ((*codeset->charset_list)->side == XlcGR) {
300             while (length--) {
301                 *tmpptr-- = (unsigned char) (wch | 0x80);
302                 wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
303             }
304         } else {
305             while (length--) {
306                 *tmpptr-- = (unsigned char) wch;
307                 wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
308             }
309         }
310     }
311
312     if (num_args > 0)
313         *((XlcCharSet *) args[0]) = *codeset->charset_list;
314
315     *from_left -= wcptr - *((wchar_t **) from);
316     *from = (XPointer) wcptr;
317
318     *to_left -= bufptr - *((char **) to);
319     *to = bufptr;
320
321     return 0;
322 }
323
324 static CodeSet
325 GetCodeSetFromCharSet(
326     XLCd lcd,
327     XlcCharSet charset)
328 {
329     CodeSet *codeset = XLC_GENERIC(lcd, codeset_list);
330     XlcCharSet *charset_list;
331     int codeset_num, num_charsets;
332
333     codeset_num = XLC_GENERIC(lcd, codeset_num);
334
335     for ( ; codeset_num-- > 0; codeset++) {
336         num_charsets = (*codeset)->num_charsets;
337         charset_list = (*codeset)->charset_list;
338
339         for ( ; num_charsets-- > 0; charset_list++)
340             if (*charset_list == charset)
341                 return *codeset;
342     }
343
344     return (CodeSet) NULL;
345 }
346
347 static int
348 cstombs(
349     XlcConv conv,
350     XPointer *from,
351     int *from_left,
352     XPointer *to,
353     int *to_left,
354     XPointer *args,
355     int num_args)
356 {
357     State state = (State) conv->state;
358     const char *csptr;
359     char *bufptr;
360     int csstr_len;
361     int buf_len;
362     int num, encoding_len = 0;
363     CodeSet codeset;
364     XlcCharSet charset;
365     EncodingType type;
366     int cvt_length;
367
368     csptr = *((const char **) from);
369     bufptr = *((char **) to);
370     csstr_len = *from_left;
371     buf_len = *to_left;
372
373     if (num_args < 1)
374         return -1;
375
376     charset = (XlcCharSet) args[0];
377
378     codeset = GetCodeSetFromCharSet(state->lcd, charset);
379     if (codeset == NULL)
380         return -1;
381
382     cvt_length = 0;
383     if (codeset->parse_info) {
384         switch (type = codeset->parse_info->type) {
385             case E_SS:
386                 encoding_len = strlen(codeset->parse_info->encoding);
387                 break;
388             case E_LSL:
389             case E_LSR:
390                 if (type == E_LSL) {
391                     if (charset == state->GL_charset)
392                         break;
393                 } else {
394                     if (charset == state->GR_charset)
395                         break;
396                 }
397                 encoding_len = strlen(codeset->parse_info->encoding);
398                 if (encoding_len > buf_len)
399                     return -1;
400                 cvt_length += encoding_len;
401                 if (bufptr) {
402                     strcpy(bufptr, codeset->parse_info->encoding);
403                     bufptr += encoding_len;
404                 }
405                 buf_len -= encoding_len;
406                 encoding_len = 0;
407                 if (type == E_LSL)
408                     state->GL_charset = charset;
409                 else
410                     state->GR_charset = charset;
411                 break;
412             default:
413                 break;
414         }
415     }
416
417     csstr_len /= codeset->length;
418     buf_len /= codeset->length + encoding_len;
419     if (csstr_len < buf_len)
420         buf_len = csstr_len;
421
422     cvt_length += buf_len * (encoding_len + codeset->length);
423     if (bufptr) {
424         while (buf_len--) {
425             if (encoding_len) {
426                 strcpy(bufptr, codeset->parse_info->encoding);
427                 bufptr += encoding_len;
428             }
429             num = codeset->length;
430             if (codeset->side == XlcGL) {
431                 while (num--)
432                     *bufptr++ = *csptr++ & 0x7f;
433             } else if (codeset->side == XlcGR) {
434                 while (num--)
435                     *bufptr++ = *csptr++ | 0x80;
436             } else {
437                 while (num--)
438                     *bufptr++ = *csptr++;
439             }
440         }
441     }
442
443     *from_left -= csptr - *((char **) from);
444     *from = (XPointer) csptr;
445
446     if (bufptr)
447         *to = (XPointer) bufptr;
448     *to_left -= cvt_length;
449
450     return 0;
451 }
452
453 static int
454 cstowcs(
455     XlcConv conv,
456     XPointer *from,
457     int *from_left,
458     XPointer *to,
459     int *to_left,
460     XPointer *args,
461     int num_args)
462 {
463     State state = (State) conv->state;
464     XLCd lcd = state->lcd;
465     const char *csptr;
466     wchar_t *bufptr;
467     int csstr_len;
468     int buf_len;
469     wchar_t wch;
470     unsigned long code_mask, wc_encoding;
471     int num, length, wc_shift_bits;
472     CodeSet codeset;
473
474     csptr = *((const char **) from);
475     bufptr = *((wchar_t **) to);
476     csstr_len = *from_left;
477     buf_len = *to_left;
478
479     if (num_args < 1)
480         return -1;
481
482     codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0]);
483     if (codeset == NULL)
484         return -1;
485
486     length = codeset->length;
487     csstr_len /= length;
488     if (csstr_len < buf_len)
489         buf_len = csstr_len;
490
491     code_mask = ~XLC_GENERIC(lcd, wc_encode_mask);
492     wc_encoding = codeset->wc_encoding;
493     wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
494
495     *to_left -= buf_len;
496
497     if (bufptr) {
498         while (buf_len--) {
499             wch = (wchar_t) (*csptr++ & 0x7f);
500             num = length - 1;
501             while (num--)
502                 wch = (wch << wc_shift_bits) | (*csptr++ & 0x7f);
503
504             *bufptr++ = (wch & code_mask) | wc_encoding;
505         }
506     }
507
508     *from_left -= csptr - *((char **) from);
509     *from = (XPointer) csptr;
510
511     if (bufptr)
512         *to = (XPointer) bufptr;
513
514     return 0;
515 }
516
517
518 static void
519 close_converter(
520     XlcConv conv)
521 {
522     if (conv->state) {
523         Xfree((char *) conv->state);
524     }
525
526     Xfree((char *) conv);
527 }
528
529 static XlcConv
530 create_conv(
531     XLCd lcd,
532     XlcConvMethods methods)
533 {
534     XlcConv conv;
535     State state;
536
537     conv = (XlcConv) Xmalloc(sizeof(XlcConvRec));
538     if (conv == NULL)
539         return (XlcConv) NULL;
540
541     conv->methods = (XlcConvMethods) Xmalloc(sizeof(XlcConvMethodsRec));
542     if (conv->methods == NULL)
543         goto err;
544     *conv->methods = *methods;
545     if (XLC_PUBLIC(lcd, is_state_depend))
546         conv->methods->reset = init_state;
547
548     conv->state = Xcalloc(1, sizeof(StateRec));
549     if (conv->state == NULL)
550         goto err;
551
552     state = (State) conv->state;
553     state->lcd = lcd;
554     init_state(conv);
555
556     return conv;
557
558 err:
559     close_converter(conv);
560
561     return (XlcConv) NULL;
562 }
563
564 static XlcConvMethodsRec mbstocs_methods = {
565     close_converter,
566     mbstocs,
567     NULL
568 };
569
570 static XlcConv
571 open_mbstocs(
572     XLCd from_lcd,
573     const char *from_type,
574     XLCd to_lcd,
575     const char *to_type)
576 {
577     return create_conv(from_lcd, &mbstocs_methods);
578 }
579
580 static XlcConvMethodsRec wcstocs_methods = {
581     close_converter,
582     wcstocs,
583     NULL
584 };
585
586 static XlcConv
587 open_wcstocs(
588     XLCd from_lcd,
589     const char *from_type,
590     XLCd to_lcd,
591     const char *to_type)
592 {
593     return create_conv(from_lcd, &wcstocs_methods);
594 }
595
596 static XlcConvMethodsRec mbtocs_methods = {
597     close_converter,
598     mbtocs,
599     NULL
600 };
601
602 static XlcConv
603 open_mbtocs(
604     XLCd from_lcd,
605     const char *from_type,
606     XLCd to_lcd,
607     const char *to_type)
608 {
609     return create_conv(from_lcd, &mbtocs_methods);
610 }
611
612 static XlcConvMethodsRec cstombs_methods = {
613     close_converter,
614     cstombs,
615     NULL
616 };
617
618 static XlcConv
619 open_cstombs(
620     XLCd from_lcd,
621     const char *from_type,
622     XLCd to_lcd,
623     const char *to_type)
624 {
625     return create_conv(from_lcd, &cstombs_methods);
626 }
627
628 static XlcConvMethodsRec cstowcs_methods = {
629     close_converter,
630     cstowcs,
631     NULL
632 };
633
634 static XlcConv
635 open_cstowcs(
636     XLCd from_lcd,
637     const char *from_type,
638     XLCd to_lcd,
639     const char *to_type)
640 {
641     return create_conv(from_lcd, &cstowcs_methods);
642 }
643
644 #ifdef STDCVT
645 static int
646 stdc_mbstowcs(
647     XlcConv conv,
648     XPointer *from,
649     int *from_left,
650     XPointer *to,
651     int *to_left,
652     XPointer *args,
653     int num_args)
654 {
655     const char *src = *((const char **) from);
656     wchar_t *dst = *((wchar_t **) to);
657     int src_left = *from_left;
658     int dst_left = *to_left;
659     int length;
660
661     while (src_left > 0 && dst_left > 0) {
662         length = mbtowc(dst, src, src_left);
663         if (length < 0)
664             break;
665
666         src += length;
667         src_left -= length;
668         if (dst)
669             dst++;
670         dst_left--;
671
672         if (length == 0) {
673             src++;
674             src_left--;
675             break;
676         }
677     }
678
679     if (*from_left == src_left)
680         return -1;
681
682     *from = (XPointer) src;
683     if (dst)
684         *to = (XPointer) dst;
685     *from_left = src_left;
686     *to_left = dst_left;
687
688     return 0;
689 }
690
691 static int
692 stdc_wcstombs(
693     XlcConv conv,
694     XPointer *from,
695     int *from_left,
696     XPointer *to,
697     int *to_left,
698     XPointer *args,
699     int num_args)
700 {
701     const wchar_t *src = *((const wchar_t **) from);
702     char *dst = *((char **) to);
703     int src_left = *from_left;
704     int dst_left = *to_left;
705     int length;
706
707     while (src_left > 0 && dst_left > 0) {
708         length = wctomb(dst, *src);             /* XXX */
709         if (length < 0 || dst_left < length)
710             break;
711
712         src++;
713         src_left--;
714         dst += length;
715         dst_left -= length;
716
717         if (length == 0) {
718             dst++;
719             dst_left--;
720             break;
721         }
722     }
723
724     if (*from_left == src_left)
725         return -1;
726
727     *from = (XPointer) src;
728     *to = (XPointer) dst;
729     *from_left = src_left;
730     *to_left = dst_left;
731
732     return 0;
733 }
734
735 static int
736 stdc_wcstocs(
737     XlcConv conv,
738     XPointer *from,
739     int *from_left,
740     XPointer *to,
741     int *to_left,
742     XPointer *args,
743     int num_args)
744 {
745     const wchar_t *src = *((const wchar_t **) from);
746     wchar_t wch;
747     XlcCharSet charset = NULL;
748     XPointer tmp_args[2], tmp_from, save_from = *from;
749     char tmp[32];
750     int length, ret, src_left = *from_left;
751     int unconv_num = 0, tmp_num = 1;
752
753     tmp_args[0] = (XPointer) &charset;
754
755     while (src_left > 0 && *to_left > 0) {
756         if (wch = *src) {
757             length = wctomb(tmp, wch);
758         } else {
759             length = 1;
760             *tmp = '\0';
761         }
762
763         if (length < 0)
764             break;
765
766         tmp_from = (XPointer) tmp;
767         ret = mbtocs(conv, &tmp_from, &length, to, to_left, tmp_args, tmp_num);
768         if (ret < 0)
769             break;
770         unconv_num += ret;
771         if (tmp_num == 1 && charset) {
772             tmp_args[1] = (XPointer) charset;
773             tmp_num = 2;
774         }
775
776         src++;
777         src_left--;
778     }
779
780     if (save_from == (XPointer) src)
781         return -1;
782
783     *from = (XPointer) src;
784     *from_left = src_left;
785
786     if (num_args > 0)
787         *((XlcCharSet *) args[0]) = charset;
788
789     return unconv_num;
790 }
791
792 #define DefineLocalBuf          char local_buf[BUFSIZ]
793 #define AllocLocalBuf(length)   (length > BUFSIZ ? (char*) Xmalloc(length) : local_buf)
794 #define FreeLocalBuf(ptr)       if (ptr != local_buf) Xfree(ptr)
795
796 static int
797 stdc_cstowcs(
798     XlcConv conv,
799     XPointer *from,
800     int *from_left,
801     XPointer *to,
802     int *to_left,
803     XPointer *args,
804     int num_args)
805 {
806     XLCd lcd = ((State) conv->state)->lcd;
807     DefineLocalBuf;
808     XPointer buf, save_buf;
809     int length, left, ret;
810
811     left = length = *to_left * XLC_PUBLIC(lcd, mb_cur_max);
812     buf = save_buf = (XPointer) AllocLocalBuf(length);
813     if (buf == NULL)
814         return -1;
815
816     ret = cstombs(conv, from, from_left, &buf, &left, args, num_args);
817     if (ret < 0)
818         goto err;
819
820     buf = save_buf;
821     length -= left;
822     if (stdc_mbstowcs(conv, &buf, &length, to, to_left, args, num_args) < 0)
823         ret = -1;
824
825 err:
826     FreeLocalBuf(save_buf);
827
828     return ret;
829 }
830
831 static XlcConvMethodsRec stdc_mbstowcs_methods = {
832     close_converter,
833     stdc_mbstowcs,
834     NULL
835 };
836
837 static XlcConv
838 open_stdc_mbstowcs(
839     XLCd from_lcd,
840     const char *from_type,
841     XLCd to_lcd,
842     const char *to_type)
843 {
844     return create_conv(from_lcd, &stdc_mbstowcs_methods);
845 }
846
847 static XlcConvMethodsRec stdc_wcstombs_methods = {
848     close_converter,
849     stdc_wcstombs,
850     NULL
851 };
852
853 static XlcConv
854 open_stdc_wcstombs(
855     XLCd from_lcd,
856     const char *from_type,
857     XLCd to_lcd,
858     const char *to_type)
859 {
860     return create_conv(from_lcd, &stdc_wcstombs_methods);
861 }
862
863 static XlcConvMethodsRec stdc_wcstocs_methods = {
864     close_converter,
865     stdc_wcstocs,
866     NULL
867 };
868
869 static XlcConv
870 open_stdc_wcstocs(
871     XLCd from_lcd,
872     const char *from_type,
873     XLCd to_lcd,
874     const char *to_type)
875 {
876     return create_conv(from_lcd, &stdc_wcstocs_methods);
877 }
878
879 static XlcConvMethodsRec stdc_cstowcs_methods = {
880     close_converter,
881     stdc_cstowcs,
882     NULL
883 };
884
885 static XlcConv
886 open_stdc_cstowcs(
887     XLCd from_lcd,
888     const char *from_type,
889     XLCd to_lcd,
890     const char *to_type)
891 {
892     return create_conv(from_lcd, &stdc_cstowcs_methods);
893 }
894 #endif /* STDCVT */
895
896 XLCd
897 _XlcJisLoader(
898     const char *name)
899 {
900     XLCd lcd;
901 #ifdef STDCVT
902     XLCdGenericPart *gen;
903 #endif
904
905     lcd = _XlcCreateLC(name, _XlcGenericMethods);
906     if (lcd == NULL)
907         return lcd;
908
909     if (!XLC_PUBLIC_PART(lcd)->codeset ||
910         (_XlcCompareISOLatin1(XLC_PUBLIC_PART(lcd)->codeset, "JIS7"))) {
911         _XlcDestroyLC(lcd);
912         return (XLCd) NULL;
913     }
914
915     _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs);
916     _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs);
917     _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs);
918
919 #ifdef STDCVT
920     gen = XLC_GENERIC_PART(lcd);
921
922     if (gen->use_stdc_env == True) {
923         _XlcSetConverter(lcd,XlcNMultiByte,lcd,XlcNWideChar,open_stdc_mbstowcs);
924         _XlcSetConverter(lcd,XlcNWideChar,lcd,XlcNMultiByte,open_stdc_wcstombs);
925     }
926     if (gen->force_convert_to_mb == True) {
927         _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet,open_stdc_wcstocs);
928         _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar,open_stdc_cstowcs);
929     } else {
930 #endif
931     _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs);
932     _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs);
933 #ifdef STDCVT
934     }
935 #endif
936
937     _XlcAddUtf8Converters(lcd);
938
939     return lcd;
940 }
941
942 #else
943 typedef int dummy;
944 #endif /* X_LOCALE */