Home | History | Annotate | Line # | Download | only in gen
      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 (at) osa.ilab.toshiba.co.jp
     24  */
     25 /*
     26  *  (c) Copyright 1995 FUJITSU LIMITED
     27  *  This is source code modified by FUJITSU LIMITED under the Joint
     28  *  Development Agreement for the CDE/Motif PST.
     29  *
     30  *   Modifier: Masayoshi Shimamura      FUJITSU LIMITED
     31  *
     32  */
     33 /*
     34  *  2000
     35  *  Modifier: Ivan Pascal      The XFree86 Project
     36  */
     37 
     38 /*
     39  * A generic locale loader for all kinds of ISO-2022 based codesets.
     40  * Supports: all locales.
     41  * How: Provides generic converters for ISO-2022 based codesets. Extensible as
     42  *      far as ISO-2022 is extensible: codesets can be given by name in the
     43  *      stream. Overall distinction between GL (0x00..0x7f) and GR (0x80..0xff).
     44  *      In every chunk between escape sequences, the number of bytes per
     45  *      character (char_size) is constant.
     46  * Platforms: all systems.
     47  */
     48 
     49 #ifdef HAVE_CONFIG_H
     50 #include <config.h>
     51 #endif
     52 #include "Xlibint.h"
     53 #include "XlcGeneric.h"
     54 #include <stdio.h>
     55 
     56 #ifndef X_LOCALE
     57 #define STDCVT
     58 #endif
     59 
     60 typedef struct _CTDataRec {
     61     const char *name;
     62     const char *encoding; /* Compound Text encoding */
     63 } CTDataRec, *CTData;
     64 
     65 static CTDataRec directionality_data[] =
     66 {
     67     { "BEGIN_LEFT-TO-RIGHT_TEXT", "\2331]" },
     68     { "BEGIN_RIGHT-TO-LEFT_TEXT", "\2332]" },
     69     { "END_OF_STRING", "\233]" },
     70 };
     71 
     72 typedef struct _StateRec {
     73     XLCd lcd;
     74     /* CT state */
     75     XlcCharSet charset;		/* charset of current state */
     76     XlcCharSet GL_charset;	/* charset of initial state in GL */
     77     XlcCharSet GR_charset;	/* charset of initial state in GR */
     78     /* MB shift state */
     79     CodeSet  GL_codeset;
     80     CodeSet  GR_codeset;
     81 } StateRec, *State;
     82 
     83 #define GR      0x80    /* begins right-side (non-ascii) region */
     84 #define GL      0x7f    /* ends left-side (ascii) region        */
     85 #define ESC	0x1b
     86 #define CSI	0x9b
     87 #define STX	0x02
     88 
     89 #define isrightside(c)   ((c) & GR)
     90 #define isleftside(c)  (!isrightside(c))
     91 
     92 /* Forward declarations for local routines. */
     93 static int mbstocts (XlcConv conv, XPointer *from, int *from_left,
     94 		     XPointer *to, int *to_left, XPointer *args, int num_args);
     95 static int ctstombs (XlcConv conv, XPointer *from, int *from_left,
     96 		     XPointer *to, int *to_left, XPointer *args, int num_args);
     97 static int cstombs (XlcConv conv, XPointer *from, int *from_left,
     98 		    XPointer *to, int *to_left, XPointer *args, int num_args);
     99 
    100 /* ------------------------------------------------------------------------- */
    101 /*				Misc                                         */
    102 /* ------------------------------------------------------------------------- */
    103 
    104 static int
    105 compare(
    106     const char *src,
    107     const char *encoding,
    108     int length)
    109 {
    110     const char *start = src;
    111 
    112     while (length-- > 0) {
    113 	if (*src++ != *encoding++)
    114 	    return 0;
    115 	if (*encoding == '\0')
    116 	    return src - start;
    117     }
    118 
    119     return 0;
    120 }
    121 
    122 static unsigned long
    123 conv_to_dest(
    124     Conversion conv,
    125     unsigned long code)
    126 {
    127     int i;
    128     int conv_num = conv->conv_num;
    129     FontScope convlist = conv->convlist;
    130 
    131     for (i = 0; i < conv_num; i++) {
    132   	if (convlist[i].start <= code && code <= convlist[i].end) {
    133 	    switch (convlist[i].shift_direction) {
    134 	    case '+':
    135 	        return(code + convlist[i].shift);
    136 	    case '-':
    137 		return(code - convlist[i].shift);
    138             default:
    139 		return(code);
    140 	    }
    141 	}
    142     }
    143 
    144     return(code);
    145 }
    146 
    147 static unsigned long
    148 conv_to_source(
    149     Conversion conv,
    150     unsigned long code)
    151 {
    152     int i;
    153     int conv_num;
    154     FontScope convlist;
    155     unsigned long start_p;
    156     unsigned long start_m;
    157     unsigned long end_p;
    158     unsigned long end_m;
    159 
    160     if (!conv)
    161 	return(code);
    162 
    163     conv_num = conv->conv_num;
    164     convlist = conv->convlist;
    165 
    166     for (i = 0; i < conv_num; i++) {
    167         switch (convlist[i].shift_direction) {
    168 	case '+':
    169             start_p = convlist[i].start + convlist[i].shift;
    170             end_p = convlist[i].end + convlist[i].shift;
    171 	    if (start_p <= code && code <= end_p)
    172 		return(code - convlist[i].shift);
    173             break;
    174 	case '-':
    175             start_m = convlist[i].start - convlist[i].shift;
    176             end_m = convlist[i].end - convlist[i].shift;
    177 	    if (start_m <= code && code <= end_m)
    178 		return(code + convlist[i].shift);
    179             break;
    180         default:
    181 	    continue;
    182 	}
    183     }
    184 
    185     return(code);
    186 }
    187 
    188 static unsigned long
    189 mb_to_gi(
    190     unsigned long mb,
    191     CodeSet codeset)
    192 {
    193     int i;
    194     unsigned long mb_tmp, mask = 0;
    195 
    196     if (codeset->mbconv) {
    197 	mb_tmp = conv_to_dest(codeset->mbconv, mb);
    198 	if (mb_tmp != mb)
    199 	    return(mb_tmp);
    200     }
    201 
    202     if (codeset->side == XlcC0 || codeset->side == XlcGL ||
    203 	codeset->side == XlcC1 || codeset->side == XlcGR) {
    204 
    205         for (i = 0; i < codeset->length; i++)
    206 	    mask = (mask << 8) | GL;
    207 	mb = mb & mask;
    208     }
    209 
    210     return(mb);
    211 }
    212 
    213 static unsigned long
    214 gi_to_mb(
    215     unsigned long glyph_index,
    216     CodeSet codeset)
    217 {
    218     int i;
    219     unsigned long mask = 0;
    220 
    221     if (codeset->side == XlcC1 || codeset->side == XlcGR) {
    222         for (i = 0; i < codeset->length; i++)
    223 	    mask = (mask << 8) | GR;
    224 	glyph_index = glyph_index | mask;
    225     }
    226 
    227     if (codeset->mbconv)
    228         return( conv_to_source(codeset->mbconv, glyph_index) );
    229 
    230     return(glyph_index);
    231 }
    232 
    233 static Bool
    234 gi_to_wc(
    235     XLCd lcd,
    236     unsigned long glyph_index,
    237     CodeSet codeset,
    238     wchar_t *wc)
    239 {
    240     unsigned char mask = 0;
    241     unsigned long wc_encoding = codeset->wc_encoding;
    242     int length = codeset->length;
    243     unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
    244 
    245     mask = (1 << wc_shift_bits) - 1 ;
    246 
    247     for (*wc = 0, length--; length >= 0; length--)
    248 	*wc = (*wc << wc_shift_bits) | ((glyph_index >> (length * 8 )) & mask);
    249 
    250     *wc = *wc | wc_encoding;
    251 
    252     return(True);
    253 }
    254 
    255 static Bool
    256 wc_to_gi(
    257     XLCd lcd,
    258     wchar_t wc,
    259     unsigned long *glyph_index,
    260     CodeSet *codeset)
    261 {
    262     int i;
    263     unsigned char mask = 0;
    264     unsigned long wc_encoding;
    265     unsigned long wc_encode_mask = XLC_GENERIC(lcd, wc_encode_mask);
    266     unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
    267     int codeset_num = XLC_GENERIC(lcd, codeset_num);
    268     CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
    269 
    270     wc_encoding = wc & wc_encode_mask;
    271     for (*codeset = NULL, i = 0; i < codeset_num; i++) {
    272 	if (wc_encoding == codeset_list[i]->wc_encoding) {
    273 	    *codeset = codeset_list[i];
    274 	    break;
    275         }
    276     }
    277     if (*codeset == NULL)
    278 	return(False);
    279 
    280     mask = (1 << wc_shift_bits) - 1 ;
    281 
    282     wc = wc & ~wc_encode_mask;
    283     for (*glyph_index = 0, i = (*codeset)->length - 1; i >= 0; i--)
    284 	*glyph_index = (*glyph_index << 8) |
    285 		      ( ((unsigned long)wc >> (i * wc_shift_bits)) & mask );
    286 
    287     return(True);
    288 }
    289 
    290 static CodeSet
    291 mb_parse_codeset(
    292     State state,
    293     int num,
    294     const char **inbufptr,
    295     int *from_left)
    296 {
    297     int len;
    298     int from_len = (*from_left) + 1;
    299     const char *src = (*inbufptr) - 1;
    300     ParseInfo *mb_parse_list = XLC_GENERIC(state->lcd, mb_parse_list);
    301     ParseInfo parse_info;
    302     CodeSet codeset;
    303 
    304     for (--num ; (parse_info = mb_parse_list[num]) != NULL; num++) {
    305        len = compare(src, parse_info->encoding, from_len);
    306        if (len > 0) {
    307            codeset = parse_info->codeset;
    308            if (parse_info->type == E_LSL)
    309                state->GL_codeset = codeset;
    310            else if (parse_info->type == E_LSR)
    311                state->GR_codeset = codeset;
    312            --len;
    313            *inbufptr += len;
    314            *from_left -= len;
    315            return codeset;
    316        }
    317     }
    318     return (CodeSet) NULL;
    319 }
    320 
    321 static CodeSet
    322 byteM_parse_codeset(
    323     XLCd lcd,
    324     const char *inbufptr,
    325     int remaining_bytes)
    326 {
    327     unsigned char ch;
    328     CodeSet codeset;
    329     ByteInfoList byteM;
    330     ByteInfoListRec byteM_rec;
    331     ByteInfo byteinfo;
    332     ByteInfoRec byteinfo_rec;
    333     Bool hit = False;
    334     int i, j, k;
    335 
    336     int codeset_num               = XLC_GENERIC(lcd, codeset_num);
    337     CodeSet *codeset_list         = XLC_GENERIC(lcd, codeset_list);
    338 
    339     for (i = 0; i < codeset_num; i++) {
    340         codeset = codeset_list[i];
    341         byteM = codeset->byteM;
    342         if (codeset->side != XlcNONE || byteM == NULL)
    343 	    continue;
    344         if (codeset->length > remaining_bytes)
    345 	    continue;
    346 
    347         for (j = 0; j < codeset->length; j++) {
    348 	    ch = *((const unsigned char *)(inbufptr + j));
    349 	    byteM_rec = byteM[j];
    350 	    byteinfo = byteM_rec.byteinfo;
    351 
    352 	    for (hit = False, k = 0; k < byteM_rec.byteinfo_num; k++) {
    353 	        byteinfo_rec = byteinfo[k];
    354 	        if (byteinfo_rec.start <= ch && ch <= byteinfo_rec.end) {
    355 	            hit = True;
    356 		    break;
    357                 }
    358             }
    359 
    360             if (!hit)
    361 		break;
    362         }
    363 
    364         if (hit)
    365 	    return(codeset);
    366     }
    367 
    368     return(NULL);
    369 }
    370 
    371 #define GLGR_parse_codeset(ch) \
    372      (isrightside(ch) ? (state->GR_codeset) : \
    373                         (state->GL_codeset) )
    374 
    375 static XlcCharSet
    376 gi_parse_charset(
    377     unsigned long glyph_index,
    378     CodeSet codeset)
    379 {
    380     int i;
    381     XlcCharSet *charset_list = codeset->charset_list;
    382     int num_charsets = codeset->num_charsets;
    383     ExtdSegment ctextseg = codeset->ctextseg;
    384     XlcCharSet charset = NULL;
    385     int area_num;
    386     FontScope area;
    387 
    388     /* lockup ct sequence */
    389     for (i = 0; i < num_charsets; i++) {
    390 	charset = charset_list[i];
    391         if (*charset->ct_sequence != '\0')
    392 	    break;
    393     }
    394     if (i >= num_charsets)
    395 	return(NULL);
    396 
    397     if (charset->source != CSsrcStd)
    398         return (charset);
    399 
    400     if (!ctextseg)
    401         return(charset);
    402 
    403     area = ctextseg->area;
    404     area_num = ctextseg->area_num;
    405 
    406     for (i = 0; i < area_num; i++) {
    407 
    408         if (area[i].start <= glyph_index && glyph_index <= area[i].end) {
    409 
    410 	    charset = ctextseg->charset;
    411 
    412             if (*charset->ct_sequence == '\0')
    413                 return(NULL);
    414 
    415 	    break;
    416 	}
    417     }
    418 
    419     return(charset);
    420 }
    421 
    422 static Bool
    423 ct_parse_csi(
    424     const char *inbufptr,
    425     int *ctr_seq_len)
    426 {
    427     int i;
    428     int num = sizeof(directionality_data) / sizeof(directionality_data[0]);
    429 
    430     for (i = 0; i < num; i++) {
    431 	if ( !(*ctr_seq_len = strlen(directionality_data[i].encoding)) )
    432 	    continue;
    433 
    434 	if ( strncmp(inbufptr, directionality_data[i].encoding,
    435 						*ctr_seq_len) == 0)
    436             return(True);
    437     }
    438 
    439     return(False);
    440 }
    441 
    442 static int
    443 cmp_esc_sequence(
    444     const char *inbufptr,
    445     XlcCharSet charset)
    446 {
    447     int seq_len, name_len, total_len;
    448     unsigned char byte_m, byte_l;
    449     const char *ct_sequence =  charset->ct_sequence;
    450     const char *encoding_name = charset->encoding_name;
    451 
    452     /* check esc sequence */
    453     if ( !(seq_len = strlen(ct_sequence) ) )
    454 	return(0);
    455     if ( strncmp(inbufptr, ct_sequence, seq_len) != 0)
    456 	return(0);
    457 
    458     /* Standard Character Set Encoding ? */
    459     if (charset->source == CSsrcStd)
    460         return(seq_len);
    461 
    462     /*
    463      *   Non-Standard Character Set Encoding
    464      *
    465      * +--- ---+-----+-----+-----+----   ----+-----+-----+-------   ------+
    466      * | ctseq |  M  |  L  |     encoding name     | STX |     contents   |
    467      * +--- ---+-----+-----+-----+----   ----+-----+-----+-------   ------+
    468      *  4bytes  1byte 1byte     variable length     1byte  variable length
    469      * 	                   |                                              |
    470      * 	                   +----------------------------------------------+
    471      * 	                     rest length  = ((M - 128) * 128) + (L - 128)
    472      */
    473 
    474     /* get length of encoding name */
    475     inbufptr += seq_len;
    476     byte_m = *inbufptr++;
    477     byte_l = *inbufptr++;
    478     name_len = strlen(encoding_name);
    479 
    480     if (((byte_m - 128) * 128 + (byte_l - 128) - 1) < name_len)
    481 	return(0);
    482 
    483     if ( _XlcNCompareISOLatin1(inbufptr, encoding_name, name_len) != 0 )
    484 	return(0);
    485 
    486     /* check STX (Start of Text) */
    487     inbufptr = inbufptr + name_len;
    488     if ( *inbufptr != STX )
    489 	return(0);
    490 
    491     total_len = seq_len + name_len + 3;
    492     return(total_len);
    493 }
    494 
    495 static Bool
    496 ct_parse_charset(
    497     XLCd lcd,
    498     const char *inbufptr,
    499     XlcCharSet *charset,
    500     int *ctr_seq_len)
    501 {
    502     int i, j;
    503     ExtdSegment ctextseg;
    504     int num_charsets;
    505     XlcCharSet *charset_list;
    506     CodeSet codeset;
    507     int codeset_num       = XLC_GENERIC(lcd, codeset_num);
    508     CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
    509     int segment_conv_num  = XLC_GENERIC(lcd, segment_conv_num);
    510     SegConv segment_conv  = XLC_GENERIC(lcd, segment_conv);
    511 
    512     /* get charset from XLC_XLOCALE by escape sequence */
    513 
    514     for (i = 0; i < codeset_num; i++) {
    515 	codeset = codeset_list[i];
    516 
    517 	num_charsets = codeset->num_charsets;
    518 	charset_list = codeset->charset_list;
    519 	ctextseg     = codeset->ctextseg;
    520 
    521 	for (j = 0; j < num_charsets; j++) {
    522 	    *charset = charset_list[j];
    523             if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
    524 		return(True);
    525 	}
    526 
    527 	if (ctextseg) {
    528 	    *charset = ctextseg->charset;
    529             if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
    530 		return(True);
    531 	}
    532     }
    533 
    534     /* get charset from XLC_SEGMENTCONVERSION by escape sequence */
    535 
    536     if (!segment_conv)
    537 	return(False);
    538 
    539     for (i = 0; i < segment_conv_num; i++) {
    540 	*charset = segment_conv[i].source;
    541         if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
    542 	    return(True);
    543 	*charset = segment_conv[i].dest;
    544         if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
    545 	    return(True);
    546     }
    547 
    548     return(False);
    549 }
    550 
    551 static Bool
    552 segment_conversion(
    553     XLCd lcd,
    554     XlcCharSet *charset,
    555     unsigned long *glyph_index)
    556 {
    557     int i;
    558     int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num);
    559     SegConv segment_conv = XLC_GENERIC(lcd, segment_conv);
    560     FontScopeRec range;
    561     ConversionRec conv_rec;
    562 
    563     if (!segment_conv)
    564 	return(True);
    565 
    566     for (i = 0; i < segment_conv_num; i++) {
    567 	if (segment_conv[i].source == *charset)
    568 	    break;
    569     }
    570 
    571     if (i >= segment_conv_num)
    572 	return(True);
    573 
    574     range = segment_conv[i].range;
    575     if (*glyph_index < range.start || range.end < *glyph_index)
    576 	return(True);
    577 
    578     *charset = segment_conv[i].dest;
    579     conv_rec.conv_num = segment_conv[i].conv_num;
    580     conv_rec.convlist = segment_conv[i].conv;
    581     *glyph_index = conv_to_dest(&conv_rec, *glyph_index);
    582 
    583     return(True);
    584 }
    585 
    586 static CodeSet
    587 _XlcGetCodeSetFromName(
    588     XLCd lcd,
    589     const char *name)
    590 {
    591     int i, j;
    592     XlcCharSet charset;
    593     int num_charsets;
    594     XlcCharSet *charset_list;
    595     CodeSet codeset;
    596 
    597     int codeset_num       = XLC_GENERIC(lcd, codeset_num);
    598     CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
    599 
    600     for (i = 0; i < codeset_num; i++) {
    601         codeset = codeset_list[i];
    602 
    603         num_charsets = codeset->num_charsets;
    604         charset_list = codeset->charset_list;
    605 
    606         for (j = 0; j < num_charsets; j++) {
    607             charset = charset_list[j];
    608 
    609             if (!strlen(charset->name))
    610                 continue;
    611             if ( strcmp(charset->name, name) == 0)
    612                 return(codeset);
    613         }
    614     }
    615 
    616     return(NULL);
    617 }
    618 
    619 static Bool
    620 _XlcGetCodeSetFromCharSet(
    621     XLCd lcd,
    622     XlcCharSet charset,
    623     CodeSet *codeset,
    624     unsigned long *glyph_index)
    625 {
    626     int j, num;
    627     CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
    628     XlcCharSet *charset_list;
    629     int codeset_num, num_charsets;
    630     Conversion ctconv;
    631     unsigned long glyph_index_tmp = 0;
    632     ExtdSegment ctextseg;
    633 
    634     codeset_num = XLC_GENERIC(lcd, codeset_num);
    635 
    636     for (num = 0 ; num < codeset_num; num++) {
    637         *codeset = codeset_list[num];
    638         ctconv = (*codeset)->ctconv;
    639 	ctextseg = (*codeset)->ctextseg;
    640 
    641         num_charsets = (*codeset)->num_charsets;
    642         charset_list = (*codeset)->charset_list;
    643 
    644         glyph_index_tmp = conv_to_source(ctconv, *glyph_index);
    645 
    646         if (charset->source == CSsrcStd) {
    647 
    648             /* Standard Character Set Encoding */
    649 	    if (glyph_index_tmp == *glyph_index) {
    650                 for (j = 0; j < num_charsets; j++) {
    651                     if (charset_list[j] == charset) {
    652                         goto end_loop;
    653                     }
    654                 }
    655             }
    656 
    657 	} else {
    658 
    659             /* Non-Standard Character Set Encoding */
    660             for (j = 0; j < num_charsets; j++) {
    661                 if (charset_list[j] == charset) {
    662                     goto end_loop;
    663                 }
    664             }
    665 
    666             if (glyph_index_tmp != *glyph_index) {
    667 		if (ctextseg && ctextseg->charset == charset) {
    668 		    goto end_loop;
    669                 }
    670             }
    671 
    672 	}
    673 
    674     }
    675 
    676 end_loop:
    677     if (num < codeset_num) {
    678 	*glyph_index = glyph_index_tmp;
    679 	return(True);
    680     }
    681 
    682     return(False);
    683 }
    684 
    685 #define check_string_encoding(codeset)	(codeset->string_encoding)
    686 
    687 static void
    688 output_ulong_value(
    689     char *outbufptr,
    690     unsigned long code,
    691     int length,
    692     XlcSide side)
    693 {
    694     int i;
    695 
    696     for (i = (length - 1) * 8; i >= 0; i -= 8) {
    697 	*outbufptr = ( code >> i) & 0xff;
    698 
    699 	if (side == XlcC0 || side == XlcGL) {
    700 	    *outbufptr = *outbufptr & GL;
    701 	} else if (side == XlcC1 || side == XlcGR) {
    702 	    *outbufptr = *outbufptr | GR;
    703 	}
    704 
    705 	outbufptr++;
    706     }
    707 }
    708 
    709 /* -------------------------------------------------------------------------- */
    710 /*				Init                                          */
    711 /* -------------------------------------------------------------------------- */
    712 
    713 static XlcCharSet default_GL_charset = 0;
    714 static XlcCharSet default_GR_charset = 0;
    715 
    716 static void
    717 init_state(
    718     XlcConv conv)
    719 {
    720     State state = (State) conv->state;
    721 
    722     /* for CT */
    723     state->charset = NULL;
    724     state->GL_charset = default_GL_charset;
    725     state->GR_charset = default_GR_charset;
    726 
    727     /* for MB shift state */
    728     state->GL_codeset = XLC_GENERIC(state->lcd, initial_state_GL);
    729     state->GR_codeset = XLC_GENERIC(state->lcd, initial_state_GR);
    730 }
    731 
    732 /* -------------------------------------------------------------------------- */
    733 /*				Convert                                       */
    734 /* -------------------------------------------------------------------------- */
    735 
    736 static int
    737 mbstowcs_org(
    738     XlcConv conv,
    739     XPointer *from,
    740     int *from_left,
    741     XPointer *to,
    742     int *to_left,
    743     XPointer *args,
    744     int num_args)
    745 {
    746     State state = (State) conv->state;
    747     XLCd lcd = state->lcd;
    748 
    749     unsigned char ch;
    750     unsigned long mb = 0;
    751     wchar_t wc;
    752 
    753     int length = 0, len_left = 0;
    754     int unconv_num = 0;
    755     int num;
    756 
    757     CodeSet codeset = NULL;
    758 
    759     const char *inbufptr;
    760     wchar_t *outbufptr = (wchar_t *) *to;
    761     int from_size = *from_left;
    762 
    763     unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
    764 
    765     if (from == NULL || *from == NULL) {
    766 	_XlcResetConverter(conv);
    767         return( 0 );
    768     }
    769 
    770     inbufptr = *from;
    771 
    772     while (*from_left && *to_left) {
    773 
    774 	ch = *inbufptr++;
    775 	(*from_left)--;
    776 
    777 	/* null ? */
    778 	if (!ch) {
    779             if (outbufptr) {*outbufptr++ = L'\0';}
    780 	    (*to_left)--;
    781 
    782 	    /* error check */
    783             if (len_left) {
    784 	        unconv_num += (length - len_left);
    785 		len_left = 0;
    786             }
    787 
    788 	    continue;
    789 	}
    790 
    791 	/* same mb char data */
    792         if (len_left)
    793 	    goto output_one_wc;
    794 
    795         /* next mb char data for single shift ? */
    796 	if (mb_parse_table && (num = mb_parse_table[ch]) ) {
    797 	    codeset = mb_parse_codeset(state, num, &inbufptr, from_left);
    798             if (codeset != NULL) {
    799 		length = len_left = codeset->length;
    800 		mb = 0;
    801 		continue;
    802 	    }
    803         }
    804 
    805 	/* next mb char data for byteM ? */
    806 	if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1), (*from_left) + 1)))
    807 	    goto next_mb_char;
    808 
    809 	/* next mb char data for GL or GR side ? */
    810 	if ((codeset = GLGR_parse_codeset(ch)))
    811 	    goto next_mb_char;
    812 
    813         /* can't find codeset for the ch */
    814         unconv_num++;
    815         continue;
    816 
    817 next_mb_char:
    818         length = len_left = codeset->length;
    819 	mb = 0;
    820 
    821 output_one_wc:
    822 	mb = (mb << 8) | ch;  /* 1 byte left shift */
    823 	len_left--;
    824 
    825         /* last of one mb char data */
    826         if (!len_left) {
    827             gi_to_wc(lcd, mb_to_gi(mb, codeset), codeset, &wc);
    828             if (outbufptr) {*outbufptr++ = wc;}
    829 	    (*to_left)--;
    830         }
    831 
    832     } /* end of while */
    833 
    834     /* error check on last char */
    835     if (len_left) {
    836 	inbufptr -= (length - len_left);
    837 	(*from_left) += (length - len_left);
    838 	unconv_num += (length - len_left);
    839     }
    840 
    841     *from = (XPointer) ((const char *) *from + from_size);
    842     *from_left = 0;
    843     *to = (XPointer) outbufptr;
    844 
    845     return unconv_num;
    846 }
    847 
    848 static int
    849 stdc_mbstowcs(
    850     XlcConv conv,
    851     XPointer *from,
    852     int *from_left,
    853     XPointer *to,
    854     int *to_left,
    855     XPointer *args,
    856     int num_args)
    857 {
    858     const char *src = *((const char **) from);
    859     wchar_t *dst = *((wchar_t **) to);
    860     int src_left = *from_left;
    861     int dst_left = *to_left;
    862     int length, unconv_num = 0;
    863 
    864     while (src_left > 0 && dst_left > 0) {
    865 	length = mbtowc(dst, src, src_left);
    866 
    867 	if (length > 0) {
    868 	    src += length;
    869 	    src_left -= length;
    870 	    if (dst)
    871 	        dst++;
    872 	    dst_left--;
    873 	} else if (length < 0) {
    874 	    src++;
    875 	    src_left--;
    876 	    unconv_num++;
    877         } else {
    878             /* null ? */
    879             src++;
    880             src_left--;
    881             if (dst)
    882                 *dst++ = L'\0';
    883             dst_left--;
    884         }
    885     }
    886 
    887     *from = (XPointer) src;
    888     if (dst)
    889 	*to = (XPointer) dst;
    890     *from_left = src_left;
    891     *to_left = dst_left;
    892 
    893     return unconv_num;
    894 }
    895 
    896 static int
    897 wcstombs_org(
    898     XlcConv conv,
    899     XPointer *from,
    900     int *from_left,
    901     XPointer *to,
    902     int *to_left,
    903     XPointer *args,
    904     int num_args)
    905 {
    906     State state = (State) conv->state;
    907     XLCd lcd = state->lcd;
    908 
    909     char *encoding;
    910     unsigned long mb, glyph_index;
    911     wchar_t wc;
    912 
    913     int length;
    914     int unconv_num = 0;
    915 
    916     CodeSet codeset;
    917 
    918     const wchar_t *inbufptr = (const wchar_t *) *from;
    919     char *outbufptr = *to;
    920     int from_size = *from_left;
    921 
    922     const char *default_string = XLC_PUBLIC(lcd, default_string);
    923     int defstr_len = strlen(default_string);
    924 
    925 
    926     while (*from_left && *to_left) {
    927 
    928         wc = *inbufptr++;
    929         (*from_left)--;
    930 
    931         /* null ? */
    932         if (!wc) {
    933             if (outbufptr) {*outbufptr++ = '\0';}
    934             (*to_left)--;
    935 
    936             continue;
    937         }
    938 
    939         /* convert */
    940 	if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
    941 
    942 	    /* output default_string of XDefaultString() */
    943             if (*to_left < defstr_len)
    944 		break;
    945 	    if (outbufptr) {
    946                 memcpy(outbufptr, default_string, defstr_len);
    947                 outbufptr += defstr_len;
    948             }
    949 	    (*to_left) -= defstr_len;
    950 
    951             unconv_num++;
    952 
    953         } else {
    954             mb = gi_to_mb(glyph_index, codeset);
    955 	    if (codeset->parse_info) {
    956                 Bool need_shift = False;
    957                 switch (codeset->parse_info->type) {
    958                     case E_LSL :
    959                         if (codeset != state->GL_codeset) {
    960                             need_shift = True;
    961                             state->GL_codeset = codeset;
    962                         }
    963                         break;
    964                     case E_LSR :
    965                         if (codeset != state->GR_codeset) {
    966                             need_shift = True;
    967                             state->GR_codeset = codeset;
    968                         }
    969                         break;
    970                     /* case E_SS */
    971                     default:
    972                         need_shift = True;
    973                 }
    974 
    975 		/* output shift sequence */
    976                 if (need_shift) {
    977 		    encoding = codeset->parse_info->encoding;
    978                     length = strlen(encoding);
    979                     if (*to_left < length)
    980 		        break;
    981 	            if (outbufptr) {
    982 			memcpy(outbufptr, encoding, length);
    983 	                outbufptr += length;
    984                     }
    985 	            (*to_left) -= length;
    986                 }
    987             }
    988 
    989             /* output characters */
    990 	    length = codeset->length;
    991             if (*to_left < length)
    992 		break;
    993 
    994 	    if (outbufptr) {
    995 		output_ulong_value(outbufptr, mb, length, XlcNONE);
    996 	        outbufptr += length;
    997 	    }
    998 
    999 	    (*to_left) -= length;
   1000         }
   1001 
   1002     } /* end of while */
   1003 
   1004     *from = (XPointer) ((const wchar_t *) *from + from_size);
   1005     *from_left = 0;
   1006     *to = (XPointer) outbufptr;
   1007 
   1008     return unconv_num;
   1009 }
   1010 
   1011 static int
   1012 stdc_wcstombs(
   1013     XlcConv conv,
   1014     XPointer *from,
   1015     int *from_left,
   1016     XPointer *to,
   1017     int *to_left,
   1018     XPointer *args,
   1019     int num_args)
   1020 {
   1021     const wchar_t *src = *((const wchar_t **) from);
   1022     char *dst = *((char **) to);
   1023     int src_left = *from_left;
   1024     int dst_left = *to_left;
   1025     int length, unconv_num = 0;
   1026 
   1027     while (src_left > 0 && dst_left >= MB_CUR_MAX) {
   1028 	length = wctomb(dst, *src);		/* XXX */
   1029 
   1030         if (length > 0) {
   1031 	    src++;
   1032 	    src_left--;
   1033 	    if (dst)
   1034 		dst += length;
   1035 	    dst_left -= length;
   1036 	} else if (length < 0) {
   1037 	    src++;
   1038 	    src_left--;
   1039 	    unconv_num++;
   1040 	}
   1041     }
   1042 
   1043     *from = (XPointer) src;
   1044     if (dst)
   1045       *to = (XPointer) dst;
   1046     *from_left = src_left;
   1047     *to_left = dst_left;
   1048 
   1049     return unconv_num;
   1050 }
   1051 
   1052 static int
   1053 wcstocts(
   1054     XlcConv conv,
   1055     XPointer *from,
   1056     int *from_left,
   1057     XPointer *to,
   1058     int *to_left,
   1059     XPointer *args,
   1060     int num_args)
   1061 {
   1062     State state = (State) conv->state;
   1063     XLCd lcd = state->lcd;
   1064 
   1065     unsigned long glyph_index;
   1066     wchar_t wc;
   1067 
   1068     int total_len, seq_len, name_len;
   1069     int unconv_num = 0;
   1070     Bool first_flag = True, standard_flag;
   1071     XlcSide side;
   1072 
   1073     CodeSet codeset;
   1074     XlcCharSet charset, old_charset = NULL;
   1075     const char *ct_sequence;
   1076 
   1077     const wchar_t *inbufptr = (const wchar_t *) *from;
   1078     char *outbufptr = *to;
   1079     int from_size = *from_left;
   1080     char *ext_seg_len = NULL;
   1081 
   1082     while (*from_left && *to_left) {
   1083 
   1084         wc = *inbufptr++;
   1085         (*from_left)--;
   1086 
   1087         /* null ? */
   1088         if (!wc) {
   1089             if (outbufptr) {*outbufptr++ = '\0';}
   1090             (*to_left)--;
   1091 
   1092             continue;
   1093         }
   1094 
   1095         /* convert */
   1096 	if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
   1097             unconv_num++;
   1098 	    continue;
   1099         }
   1100 
   1101         /* parse charset */
   1102         if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) {
   1103             unconv_num++;
   1104 	    continue;
   1105         }
   1106 
   1107         /* Standard Character Set Encoding ? */
   1108 	standard_flag = charset->source == CSsrcStd ? True : False;
   1109 
   1110         /*
   1111          *   Non-Standard Character Set Encoding
   1112          *
   1113          * +-----+-----+-----+-----+-----+-----+-----+----   ----+-----+-----+
   1114          * |     esc sequence      |  M  |  L  |     encoding name     | STX |
   1115          * +-----+-----+-----+-----+-----+-----+-----+----   ----+-----+-----+
   1116          *           4bytes         1byte 1byte     variable length     1byte
   1117          * 	                   |                                         |
   1118          * 	                   +-----------------------------------------+
   1119          * 	                     name length  = ((M - 128) * 128) + (L - 128)
   1120          */
   1121 
   1122         /* make encoding data */
   1123 	ct_sequence = charset->ct_sequence;
   1124 	side = charset->side;
   1125         seq_len = strlen(ct_sequence);
   1126 	if (standard_flag) {
   1127             name_len = 0;
   1128 	    total_len = seq_len;
   1129 	} else {
   1130             name_len = strlen(charset->encoding_name) + 1;
   1131 	    total_len = seq_len + name_len + 2;
   1132 	}
   1133 
   1134         /* output escape sequence of CT */
   1135 	if ( (charset != old_charset) &&
   1136 	    !(first_flag && charset->string_encoding) ){
   1137 
   1138             if ( (ext_seg_len != NULL) && outbufptr) {
   1139                 int i = (outbufptr - ext_seg_len) - 2;
   1140                 *ext_seg_len++ = i / 128 + 128;
   1141                 *ext_seg_len   = i % 128 + 128;
   1142                 ext_seg_len = NULL;
   1143             }
   1144 
   1145 	    if (*to_left < total_len + 1) {
   1146                 unconv_num++;
   1147 	        break;
   1148 	    }
   1149 
   1150 	    if (outbufptr) {
   1151 	        strcpy((char *)outbufptr, ct_sequence);
   1152 		outbufptr += seq_len;
   1153 
   1154                 if (!standard_flag) {
   1155                     const char *i = charset->encoding_name;
   1156                     ext_seg_len = outbufptr;
   1157                     outbufptr += 2;
   1158 	            for (; *i ; i++)
   1159                         *outbufptr++ = ((*i >= 'A') && (*i <= 'Z')) ?
   1160                                        *i - 'A' + 'a' : *i;
   1161 		    *outbufptr++ = STX;
   1162                 }
   1163 	    }
   1164 
   1165 	    (*to_left) -= total_len;
   1166 
   1167 	    first_flag = False;
   1168 	    old_charset = charset;
   1169 	}
   1170 
   1171         /* output glyph index */
   1172 	if (codeset->ctconv)
   1173             glyph_index = conv_to_dest(codeset->ctconv, glyph_index);
   1174         if (*to_left < charset->char_size) {
   1175             unconv_num++;
   1176 	    break;
   1177         }
   1178 
   1179 	if (outbufptr) {
   1180 	   output_ulong_value(outbufptr, glyph_index, charset->char_size, side);
   1181 	   outbufptr += charset->char_size;
   1182 	}
   1183 
   1184 	(*to_left) -= charset->char_size;
   1185 
   1186     } /* end of while */
   1187 
   1188     if ( (ext_seg_len != NULL) && outbufptr) {
   1189         int i = (outbufptr - ext_seg_len) - 2;
   1190         *ext_seg_len++ = i / 128 + 128;
   1191         *ext_seg_len   = i % 128 + 128;
   1192     }
   1193 
   1194     *from = (XPointer) ((const wchar_t *) *from + from_size);
   1195     *from_left = 0;
   1196     *to = (XPointer) outbufptr;
   1197 
   1198     return unconv_num;
   1199 }
   1200 
   1201 static int
   1202 stdc_wcstocts(
   1203     XlcConv conv,
   1204     XPointer *from,
   1205     int *from_left,
   1206     XPointer *to,
   1207     int *to_left,
   1208     XPointer *args,
   1209     int num_args)
   1210 {
   1211     XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
   1212     char *buf_ptr1 = buf;
   1213     int buf_left1 = (*from_left) * MB_CUR_MAX;
   1214     char *buf_ptr2 = buf_ptr1;
   1215     int buf_left2;
   1216     int unconv_num1 = 0, unconv_num2 = 0;
   1217 
   1218     unconv_num1 = stdc_wcstombs(conv,
   1219 		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
   1220     if (unconv_num1 < 0)
   1221         goto ret;
   1222 
   1223     buf_left2 = buf_ptr1 - buf_ptr2;
   1224 
   1225     unconv_num2 = mbstocts(conv,
   1226 		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
   1227     if (unconv_num2 < 0)
   1228         goto ret;
   1229 
   1230 ret:
   1231     Xfree(buf);
   1232 
   1233     return (unconv_num1 + unconv_num2);
   1234 }
   1235 
   1236 static int
   1237 ctstowcs(
   1238     XlcConv conv,
   1239     XPointer *from,
   1240     int *from_left,
   1241     XPointer *to,
   1242     int *to_left,
   1243     XPointer *args,
   1244     int num_args)
   1245 {
   1246     State state = (State) conv->state;
   1247     XLCd lcd = state->lcd;
   1248 
   1249     unsigned char ch;
   1250     unsigned long glyph_index = 0;
   1251     wchar_t wc;
   1252 
   1253     int ctr_seq_len = 0, gi_len_left = 0, gi_len = 0;
   1254     int unconv_num = 0;
   1255 
   1256     CodeSet codeset = NULL;
   1257     XlcCharSet charset_tmp;
   1258 
   1259     const char *inbufptr;
   1260     wchar_t *outbufptr = (wchar_t *) *to;
   1261     int from_size = *from_left;
   1262 
   1263     _XlcResetConverter(conv); /* ??? */
   1264 
   1265     if (from == NULL || *from == NULL) {
   1266 	_XlcResetConverter(conv);
   1267         return( 0 );
   1268     }
   1269     inbufptr = *from;
   1270 
   1271     while (*from_left && *to_left) {
   1272 
   1273 	ch = *inbufptr++;
   1274 	(*from_left)--;
   1275 
   1276 	/* null ? */
   1277 	if (!ch) {
   1278             if (outbufptr) {*outbufptr++ = L'\0';}
   1279 	    (*to_left)--;
   1280 
   1281 	    /* error check */
   1282             if (gi_len_left) {
   1283 	        unconv_num += (gi_len - gi_len_left);
   1284 		gi_len_left = 0;
   1285             }
   1286 
   1287 	    continue;
   1288 	}
   1289 
   1290 	/* same glyph_index data */
   1291         if (gi_len_left)
   1292 	    goto output_one_wc;
   1293 
   1294         /* control sequence ? */
   1295         if (ch == CSI) {
   1296             if ( !ct_parse_csi(inbufptr - 1, &ctr_seq_len) )
   1297 	        goto skip_the_seg;
   1298 
   1299 	    if (*from_left + 1 < ctr_seq_len) {
   1300 		inbufptr--;
   1301 		(*from_left)++;
   1302 		unconv_num += *from_left;
   1303 		break;
   1304 	    }
   1305 
   1306             /* skip the control sequence */
   1307 	    inbufptr += (ctr_seq_len - 1);
   1308 	    *from_left -= (ctr_seq_len - 1);
   1309 
   1310             continue;
   1311 	}
   1312 
   1313         /* escape sequence ? */
   1314         if (ch == ESC) {
   1315 	    if ( !ct_parse_charset(lcd,
   1316 			inbufptr - 1, &state->charset, &ctr_seq_len) )
   1317 		goto skip_the_seg;
   1318 
   1319 	    if (state->charset->side == XlcC0 ||
   1320 		state->charset->side == XlcGL)
   1321 	      {
   1322 		state->GL_charset = state->charset;
   1323 	      }
   1324 	    else if (state->charset->side == XlcC1 ||
   1325 		     state->charset->side == XlcGR)
   1326 	      {
   1327 		state->GR_charset = state->charset;
   1328 	      }
   1329 	    else if (state->charset->side == XlcGLGR)
   1330 	      {
   1331 		state->GL_charset = state->charset;
   1332 		state->GR_charset = state->charset;
   1333 	      }
   1334 
   1335 	    if (*from_left + 1 < ctr_seq_len) {
   1336 		inbufptr--;
   1337 		(*from_left)++;
   1338 		unconv_num += *from_left;
   1339 		break;
   1340 	    }
   1341 
   1342             /* skip the escape sequence */
   1343 	    inbufptr += (ctr_seq_len - 1);
   1344 	    *from_left -= (ctr_seq_len - 1);
   1345 
   1346             continue;
   1347         }
   1348 
   1349  	/* check current state */
   1350 	if (isleftside(ch))
   1351 	  state->charset = state->GL_charset;
   1352 	else
   1353 	  state->charset = state->GR_charset;
   1354 
   1355 	gi_len = gi_len_left = state->charset->char_size;
   1356 	glyph_index = 0;
   1357 
   1358 output_one_wc:
   1359         if (state->charset->side == XlcC1 || state->charset->side == XlcGR)
   1360             glyph_index = (glyph_index << 8) | (ch & GL);
   1361         else
   1362             glyph_index = (glyph_index << 8) | ch;
   1363 
   1364 	gi_len_left--;
   1365 
   1366         /* last of one glyph_index data */
   1367         if (!gi_len_left) {
   1368 
   1369 	    /* segment conversion */
   1370 	    charset_tmp = state->charset;
   1371 	    segment_conversion(lcd, &charset_tmp, &glyph_index);
   1372 
   1373             /* get codeset */
   1374             if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp,
   1375 						&codeset, &glyph_index) ) {
   1376 		unconv_num += gi_len;
   1377 		continue;
   1378             }
   1379 
   1380             /* convert glyph index to wicd char */
   1381             gi_to_wc(lcd, glyph_index, codeset, &wc);
   1382             if (outbufptr) {*outbufptr++ = wc;}
   1383 	    (*to_left)--;
   1384         }
   1385 
   1386         continue;
   1387 
   1388 skip_the_seg:
   1389 	/* skip until next escape or control sequence */
   1390         while ( *from_left ) {
   1391 	    ch = *inbufptr++;
   1392 	    (*from_left)--;
   1393 	    unconv_num++;
   1394 
   1395             if (ch == ESC || ch == CSI) {
   1396 		inbufptr--;
   1397 		(*from_left)++;
   1398 		unconv_num--;
   1399 		break;
   1400 	    }
   1401         }
   1402 
   1403         if ( !(*from_left) )
   1404 	    break;
   1405 
   1406     } /* end of while */
   1407 
   1408     /* error check on last char */
   1409     if (gi_len_left) {
   1410 	inbufptr -= (gi_len - gi_len_left);
   1411 	(*from_left) += (gi_len - gi_len_left);
   1412 	unconv_num += (gi_len - gi_len_left);
   1413     }
   1414 
   1415     *from = (XPointer) ((const char *) *from + from_size);
   1416     *from_left = 0;
   1417     *to = (XPointer) outbufptr;
   1418 
   1419     return unconv_num;
   1420 }
   1421 
   1422 static int
   1423 cstowcs(
   1424     XlcConv conv,
   1425     XPointer *from,
   1426     int *from_left,
   1427     XPointer *to,
   1428     int *to_left,
   1429     XPointer *args,
   1430     int num_args)
   1431 {
   1432     State state = (State) conv->state;
   1433     XLCd lcd = state->lcd;
   1434 
   1435     unsigned char ch;
   1436     unsigned long glyph_index = 0;
   1437     wchar_t wc;
   1438     int gi_len_left = 0, gi_len = 0;
   1439 
   1440     int unconv_num = 0;
   1441 
   1442     CodeSet codeset = NULL;
   1443     XlcCharSet charset, charset_tmp;
   1444 
   1445     const char *inbufptr;
   1446     wchar_t *outbufptr = (wchar_t *) *to;
   1447     int from_size = *from_left;
   1448 
   1449     if (from == NULL || *from == NULL) {
   1450         return( 0 );
   1451     }
   1452 
   1453     inbufptr = *from;
   1454 
   1455     charset = (XlcCharSet) args[0];
   1456 
   1457     while (*from_left && *to_left) {
   1458 
   1459         if (!gi_len_left) {
   1460             gi_len_left = gi_len = charset->char_size;
   1461             glyph_index = 0;
   1462         }
   1463 
   1464 	ch = *inbufptr++;
   1465 	(*from_left)--;
   1466 
   1467 	/* null ? */
   1468 	if (!ch) {
   1469             if (outbufptr) {*outbufptr++ = L'\0';}
   1470 	    (*to_left)--;
   1471 
   1472 	    /* error check */
   1473             if (gi_len_left) {
   1474 	        unconv_num += (gi_len - gi_len_left);
   1475 		gi_len_left = 0;
   1476             }
   1477 	    continue;
   1478 	}
   1479 
   1480         if (charset->side == XlcC1 || charset->side == XlcGR)
   1481             glyph_index = (glyph_index << 8) | (ch & GL);
   1482         else
   1483             glyph_index = (glyph_index << 8) | ch;
   1484 
   1485 	gi_len_left--;
   1486 
   1487         /* last of one glyph_index data */
   1488         if (!gi_len_left) {
   1489 
   1490 	    /* segment conversion */
   1491 	    charset_tmp = charset;
   1492 	    segment_conversion(lcd, &charset_tmp, &glyph_index);
   1493 
   1494             /* get codeset */
   1495             if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp,
   1496 						&codeset, &glyph_index) ) {
   1497 		unconv_num += gi_len;
   1498 		continue;
   1499             }
   1500 
   1501             /* convert glyph index to wicd char */
   1502             gi_to_wc(lcd, glyph_index, codeset, &wc);
   1503             if (outbufptr) {*outbufptr++ = wc;}
   1504 	    (*to_left)--;
   1505         }
   1506 
   1507     } /* end of while */
   1508 
   1509     /* error check on last char */
   1510     if (gi_len_left) {
   1511 	inbufptr -= (gi_len - gi_len_left);
   1512 	(*from_left) += (gi_len - gi_len_left);
   1513 	unconv_num += (gi_len - gi_len_left);
   1514     }
   1515 
   1516     *from = (XPointer) ((const char *) *from + from_size);
   1517     *from_left = 0;
   1518     *to = (XPointer) outbufptr;
   1519 
   1520     return unconv_num;
   1521 }
   1522 
   1523 static int
   1524 stdc_ctstowcs(
   1525     XlcConv conv,
   1526     XPointer *from,
   1527     int *from_left,
   1528     XPointer *to,
   1529     int *to_left,
   1530     XPointer *args,
   1531     int num_args)
   1532 {
   1533     XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
   1534     char *buf_ptr1 = buf;
   1535     int buf_left1 = (*from_left) * MB_CUR_MAX;
   1536     char *buf_ptr2 = buf_ptr1;
   1537     int buf_left2;
   1538     int unconv_num1 = 0, unconv_num2 = 0;
   1539 
   1540     unconv_num1 = ctstombs(conv,
   1541 		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
   1542     if (unconv_num1 < 0)
   1543         goto ret;
   1544 
   1545     buf_left2 = buf_ptr1 - buf_ptr2;
   1546 
   1547     unconv_num2 = stdc_mbstowcs(conv,
   1548 		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
   1549     if (unconv_num2 < 0)
   1550         goto ret;
   1551 
   1552 ret:
   1553     Xfree(buf);
   1554 
   1555     return (unconv_num1 + unconv_num2);
   1556 }
   1557 
   1558 static int
   1559 stdc_cstowcs(
   1560     XlcConv conv,
   1561     XPointer *from,
   1562     int *from_left,
   1563     XPointer *to,
   1564     int *to_left,
   1565     XPointer *args,
   1566     int num_args)
   1567 {
   1568     XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
   1569     char *buf_ptr1 = buf;
   1570     int buf_left1 = (*from_left) * MB_CUR_MAX;
   1571     char *buf_ptr2 = buf_ptr1;
   1572     int buf_left2;
   1573     int unconv_num1 = 0, unconv_num2 = 0;
   1574 
   1575     unconv_num1 = cstombs(conv,
   1576 		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
   1577     if (unconv_num1 < 0)
   1578         goto ret;
   1579 
   1580     buf_left2 = buf_ptr1 - buf_ptr2;
   1581 
   1582     unconv_num2 = stdc_mbstowcs(conv,
   1583 		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
   1584     if (unconv_num2 < 0)
   1585         goto ret;
   1586 
   1587 ret:
   1588     Xfree(buf);
   1589 
   1590     return (unconv_num1 + unconv_num2);
   1591 }
   1592 
   1593 static int
   1594 mbstocts(
   1595     XlcConv conv,
   1596     XPointer *from,
   1597     int *from_left,
   1598     XPointer *to,
   1599     int *to_left,
   1600     XPointer *args,
   1601     int num_args)
   1602 {
   1603     XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t));
   1604     char *buf_ptr1 = buf;
   1605     int buf_left1 = (*from_left);
   1606     char *buf_ptr2 = buf_ptr1;
   1607     int buf_left2;
   1608     int unconv_num1 = 0, unconv_num2 = 0;
   1609 
   1610     unconv_num1 = mbstowcs_org(conv,
   1611 		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
   1612     if (unconv_num1 < 0)
   1613         goto ret;
   1614 
   1615     buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t);
   1616 
   1617     unconv_num2 += wcstocts(conv,
   1618 		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
   1619     if (unconv_num2 < 0)
   1620         goto ret;
   1621 
   1622 ret:
   1623     Xfree(buf);
   1624 
   1625     return (unconv_num1 + unconv_num2);
   1626 }
   1627 
   1628 static int
   1629 mbstostr(
   1630     XlcConv conv,
   1631     XPointer *from,
   1632     int *from_left,
   1633     XPointer *to,
   1634     int *to_left,
   1635     XPointer *args,
   1636     int num_args)
   1637 {
   1638     State state = (State) conv->state;
   1639     XLCd lcd = state->lcd;
   1640 
   1641     unsigned char ch;
   1642     unsigned long mb = 0;
   1643 
   1644     int length = 0, len_left = 0;
   1645     int unconv_num = 0;
   1646     int num;
   1647 
   1648     CodeSet codeset = NULL;
   1649 
   1650     const char *inbufptr;
   1651     char *outbufptr = *to;
   1652     int from_size = *from_left;
   1653 
   1654     unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
   1655 
   1656     if (from == NULL || *from == NULL) {
   1657 	_XlcResetConverter(conv);
   1658         return( 0 );
   1659     }
   1660 
   1661     inbufptr = *from;
   1662 
   1663     while (*from_left && *to_left) {
   1664 
   1665 	ch = *inbufptr++;
   1666 	(*from_left)--;
   1667 
   1668 	/* null ? */
   1669 	if (!ch) {
   1670             if (outbufptr) {*outbufptr++ = '\0';}
   1671 	    (*to_left)--;
   1672 
   1673             /* error check */
   1674             if (len_left) {
   1675                 unconv_num += (length - len_left);
   1676                 len_left = 0;
   1677             }
   1678 
   1679 	    continue;
   1680 	}
   1681 
   1682         /* same mb char data */
   1683         if (len_left)
   1684             goto output_one_mb;
   1685 
   1686         /* next mb char data for single shift ? */
   1687 	if (mb_parse_table && (num = mb_parse_table[ch]) ) {
   1688 	    codeset = mb_parse_codeset(state, num, &inbufptr, from_left);
   1689             if (codeset != NULL) {
   1690 		length = len_left = codeset->length;
   1691 		mb = 0;
   1692 		continue;
   1693 	    }
   1694         }
   1695 
   1696 	/* next char data : byteM ? */
   1697 	if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1), (*from_left) + 1)))
   1698 	    goto next_mb_char;
   1699 
   1700 	/* next char data : GL or GR side ? */
   1701 	if ((codeset = GLGR_parse_codeset(ch)))
   1702 	    goto next_mb_char;
   1703 
   1704         /* can't find codeset for the ch */
   1705         unconv_num++;
   1706         continue;
   1707 
   1708 next_mb_char:
   1709         length = len_left = codeset->length;
   1710         mb = 0;
   1711 
   1712 output_one_mb:
   1713         mb = (mb << 8) | ch;  /* 1 byte left shift */
   1714         len_left--;
   1715 
   1716         /* last of one mb char data */
   1717         if (!len_left) {
   1718             if (check_string_encoding(codeset)) {
   1719                 if (outbufptr) {*outbufptr++ = mb & 0xff;}
   1720 		(*to_left)--;
   1721             } else {
   1722 	        unconv_num++;
   1723             }
   1724         }
   1725 
   1726     } /* end of while */
   1727 
   1728     /* error check on last char */
   1729     if (len_left) {
   1730         inbufptr -= (length - len_left);
   1731         (*from_left) += (length - len_left);
   1732         unconv_num += (length - len_left);
   1733     }
   1734 
   1735     *from = (XPointer) ((const char *) *from + from_size);
   1736     *from_left = 0;
   1737     *to = (XPointer) outbufptr;
   1738 
   1739     return unconv_num;
   1740 }
   1741 
   1742 static int
   1743 mbtocs(
   1744     XlcConv conv,
   1745     XPointer *from,
   1746     int *from_left,
   1747     XPointer *to,
   1748     int *to_left,
   1749     XPointer *args,
   1750     int num_args)
   1751 {
   1752     State state = (State) conv->state;
   1753     XLCd lcd = state->lcd;
   1754 
   1755     unsigned char ch;
   1756     unsigned long mb = 0;
   1757     unsigned long glyph_index;
   1758 
   1759     int length = 0, len_left = 0, char_len;
   1760     int unconv_num = 0;
   1761     int num;
   1762     XlcSide side;
   1763 
   1764     CodeSet codeset = NULL;
   1765     XlcCharSet charset = NULL;
   1766 
   1767     const char *inbufptr;
   1768     char *outbufptr = *to;
   1769     int from_size = *from_left;
   1770 
   1771     unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
   1772 
   1773     if (from == NULL || *from == NULL) {
   1774 	_XlcResetConverter(conv);
   1775         return( 0 );
   1776     }
   1777 
   1778     inbufptr = *from;
   1779 
   1780     while (*from_left && *to_left) {
   1781 
   1782 	ch = *inbufptr++;
   1783 	(*from_left)--;
   1784 
   1785 	/* null ? */
   1786 	if (!ch) {
   1787             unconv_num = 1;
   1788             if (len_left)
   1789 	        unconv_num += (length - len_left);
   1790 	    break;
   1791 	}
   1792 
   1793 	/* same mb char data */
   1794         if (len_left)
   1795 	    goto output;
   1796 
   1797         /* next mb char data for single shift ? */
   1798 	if (mb_parse_table && (num = mb_parse_table[ch]) ) {
   1799 	    codeset = mb_parse_codeset(state, num, &inbufptr, from_left);
   1800             if (codeset != NULL) {
   1801 		length = len_left = codeset->length;
   1802 		mb = 0;
   1803 		continue;
   1804 	    }
   1805         }
   1806 
   1807 	/* next mb char data for byteM ? */
   1808 	if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1), (*from_left) + 1)))
   1809 	    goto next_mb_char;
   1810 
   1811 	/* next mb char data for GL or GR side ? */
   1812 	if ((codeset = GLGR_parse_codeset(ch)))
   1813 	    goto next_mb_char;
   1814 
   1815         /* can't find codeset for the ch */
   1816         unconv_num = 1;
   1817         break;
   1818 
   1819 next_mb_char:
   1820         length = len_left = codeset->length;
   1821 	mb = 0;
   1822 
   1823 output:
   1824 	mb = (mb << 8) | ch;  /* 1 byte left shift */
   1825 	len_left--;
   1826 
   1827         /* last of one mb char data */
   1828         if (!len_left) {
   1829             glyph_index = mb_to_gi(mb, codeset);
   1830             if (!(charset = gi_parse_charset(glyph_index, codeset))) {
   1831                 unconv_num = length;
   1832                 break;
   1833             }
   1834             char_len = charset->char_size;
   1835 	    side = charset->side;
   1836 
   1837             /* output glyph index */
   1838             if (codeset->ctconv)
   1839                 glyph_index = conv_to_dest(codeset->ctconv, glyph_index);
   1840             if (*to_left < char_len) {
   1841                 unconv_num = length;
   1842                 break;
   1843             }
   1844 
   1845 	    if (outbufptr) {
   1846 	        output_ulong_value(outbufptr, glyph_index, char_len, side);
   1847 	        outbufptr += char_len;
   1848 	    }
   1849 
   1850             (*to_left) -= char_len;
   1851 
   1852             break;
   1853         }
   1854 
   1855     } /* end of while */
   1856 
   1857     /* error end */
   1858     if (unconv_num) {
   1859         *from = (XPointer) ((const char *) *from + from_size);
   1860         *from_left = 0;
   1861         *to = (XPointer) outbufptr;
   1862 	return -1;
   1863     }
   1864 
   1865     /* normal end */
   1866     *from = (XPointer) inbufptr;
   1867     *to = (XPointer) outbufptr;
   1868 
   1869     if (num_args > 0)
   1870         *((XlcCharSet *) args[0]) = charset;
   1871 
   1872     return 0;
   1873 }
   1874 
   1875 static int
   1876 mbstocs(
   1877     XlcConv conv,
   1878     XPointer *from,
   1879     int *from_left,
   1880     XPointer *to,
   1881     int *to_left,
   1882     XPointer *args,
   1883     int num_args)
   1884 {
   1885     int ret;
   1886     XlcCharSet charset_old, charset = NULL;
   1887     XPointer tmp_args[1];
   1888 
   1889     const char *inbufptr;
   1890     int	in_left;
   1891     char *outbufptr;
   1892     int	out_left;
   1893     tmp_args[0] = (XPointer) &charset;
   1894 
   1895     ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1);
   1896     charset_old = charset;
   1897 
   1898     while ( ret == 0 && *from_left && *to_left) {
   1899 	inbufptr = *from;
   1900 	in_left = *from_left;
   1901 	outbufptr = *to;
   1902 	out_left = *to_left;
   1903         ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1);
   1904         if (charset_old != charset) {
   1905            *from = (XPointer) inbufptr;
   1906            *from_left = in_left;
   1907            *to = (XPointer) outbufptr;
   1908            *to_left = out_left;
   1909            break;
   1910         }
   1911     }
   1912 
   1913     if (num_args > 0)
   1914         *((XlcCharSet *) args[0]) = charset_old;
   1915 
   1916     /* error end */
   1917     if (ret != 0)
   1918 	return( -1 );
   1919 
   1920     return(0);
   1921 }
   1922 
   1923 static int
   1924 wcstostr(
   1925     XlcConv conv,
   1926     XPointer *from,
   1927     int *from_left,
   1928     XPointer *to,
   1929     int *to_left,
   1930     XPointer *args,
   1931     int num_args)
   1932 {
   1933     State state = (State) conv->state;
   1934     XLCd lcd = state->lcd;
   1935 
   1936     char *encoding;
   1937     unsigned long mb, glyph_index;
   1938     wchar_t wc;
   1939 
   1940     int length;
   1941     int unconv_num = 0;
   1942 
   1943     CodeSet codeset;
   1944 
   1945     const wchar_t *inbufptr = (const wchar_t *) *from;
   1946     char *outbufptr = *to;
   1947     int from_size = *from_left;
   1948 
   1949     const char *default_string = XLC_PUBLIC(lcd, default_string);
   1950     int defstr_len = strlen(default_string);
   1951 
   1952     while (*from_left && *to_left) {
   1953 
   1954         wc = *inbufptr++;
   1955         (*from_left)--;
   1956 
   1957         /* null ? */
   1958         if (!wc) {
   1959             if (outbufptr) {*outbufptr++ = '\0';}
   1960             (*to_left)--;
   1961 
   1962             continue;
   1963         }
   1964 
   1965         /* convert */
   1966 	if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
   1967 
   1968 	    /* output default_string of XDefaultString() */
   1969             if (*to_left < defstr_len)
   1970 		break;
   1971 	    if (outbufptr) {
   1972 		memcpy(outbufptr, default_string, defstr_len);
   1973 	        outbufptr += defstr_len;
   1974             }
   1975 	    (*to_left) -= defstr_len;
   1976 
   1977             unconv_num++;
   1978 
   1979         } else {
   1980             mb = gi_to_mb(glyph_index, codeset);
   1981 
   1982 	    if (check_string_encoding(codeset)) {
   1983 	        if (codeset->parse_info) {
   1984                     Bool need_shift = False;
   1985                     switch (codeset->parse_info->type) {
   1986                         case E_LSL :
   1987                             if (codeset != state->GL_codeset) {
   1988                                 need_shift = True;
   1989                                 state->GL_codeset = codeset;
   1990                             }
   1991                             break;
   1992                         case E_LSR :
   1993                             if (codeset != state->GR_codeset) {
   1994                                 need_shift = True;
   1995                                 state->GR_codeset = codeset;
   1996                             }
   1997                             break;
   1998                         /* case E_SS */
   1999                         default:
   2000                             need_shift = True;
   2001                     }
   2002 
   2003 		    /* output shift sequence */
   2004                     if (need_shift) {
   2005 		        encoding = codeset->parse_info->encoding;
   2006                         length = strlen(encoding);
   2007                         if (*to_left < length)
   2008 		            break;
   2009 
   2010 	                if (outbufptr) {
   2011 			    memcpy(outbufptr, encoding, length);
   2012 	                    outbufptr += length;
   2013                         }
   2014 	                (*to_left) -= length;
   2015                     }
   2016                 }
   2017 
   2018                 /* output characters */
   2019 	        length = codeset->length;
   2020                 if (*to_left < length)
   2021 		    break;
   2022 
   2023 	        if (outbufptr) {
   2024 	            output_ulong_value(outbufptr, mb, length, XlcNONE);
   2025 	            outbufptr += length;
   2026 	        }
   2027 
   2028 	        (*to_left) -= length;
   2029             } else {
   2030 		unconv_num++;
   2031             }
   2032         }
   2033 
   2034     } /* end of while */
   2035 
   2036     *from = (XPointer) ((const wchar_t *) *from + from_size);
   2037     *from_left = 0;
   2038     *to = (XPointer) outbufptr;
   2039 
   2040     return unconv_num;
   2041 }
   2042 
   2043 static int
   2044 stdc_wcstostr(
   2045     XlcConv conv,
   2046     XPointer *from,
   2047     int *from_left,
   2048     XPointer *to,
   2049     int *to_left,
   2050     XPointer *args,
   2051     int num_args)
   2052 {
   2053     XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
   2054     char *buf_ptr1 = buf;
   2055     int buf_left1 = (*from_left) * MB_CUR_MAX;
   2056     char *buf_ptr2 = buf_ptr1;
   2057     int buf_left2;
   2058     int unconv_num1 = 0, unconv_num2 = 0;
   2059 
   2060     unconv_num1 = stdc_wcstombs(conv,
   2061 		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
   2062     if (unconv_num1 < 0)
   2063         goto ret;
   2064 
   2065     buf_left2 = buf_ptr1 - buf_ptr2;
   2066 
   2067     unconv_num2 = mbstostr(conv,
   2068 		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
   2069     if (unconv_num2 < 0)
   2070         goto ret;
   2071 
   2072 ret:
   2073     Xfree(buf);
   2074 
   2075     return (unconv_num1 + unconv_num2);
   2076 }
   2077 
   2078 static int
   2079 wctocs(
   2080     XlcConv conv,
   2081     XPointer *from,
   2082     int *from_left,
   2083     XPointer *to,
   2084     int *to_left,
   2085     XPointer *args,
   2086     int num_args)
   2087 {
   2088     State state = (State) conv->state;
   2089     XLCd lcd = state->lcd;
   2090 
   2091     wchar_t wc;
   2092     unsigned long glyph_index;
   2093 
   2094     int char_len;
   2095     int unconv_num = 0;
   2096     XlcSide side;
   2097 
   2098     CodeSet codeset;
   2099     XlcCharSet charset = NULL;
   2100 
   2101     const wchar_t *inbufptr = (const wchar_t *) *from;
   2102     char *outbufptr = *to;
   2103     int from_size = *from_left;
   2104 
   2105     if (*from_left && *to_left) {
   2106 
   2107         wc = *inbufptr++;
   2108         (*from_left)--;
   2109 
   2110         /* null ? */
   2111         if (!wc) {
   2112             unconv_num = 1;
   2113             goto end;
   2114         }
   2115 
   2116         /* convert */
   2117 	if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
   2118             unconv_num = 1;
   2119 	    goto end;
   2120         }
   2121 
   2122         if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) {
   2123             unconv_num = 1;
   2124 	    goto end;
   2125         }
   2126 	char_len = charset->char_size;
   2127 	side = charset->side;
   2128 
   2129         /* output glyph index */
   2130 	if (codeset->ctconv)
   2131             glyph_index = conv_to_dest(codeset->ctconv, glyph_index);
   2132         if (*to_left < char_len) {
   2133             unconv_num++;
   2134 	    goto end;
   2135         }
   2136 
   2137         if (outbufptr) {
   2138             output_ulong_value(outbufptr, glyph_index, char_len, side);
   2139             outbufptr += char_len;
   2140         }
   2141 
   2142 	(*to_left) -= char_len;
   2143 
   2144     }
   2145 
   2146 end:
   2147 
   2148      /* error end */
   2149     if (unconv_num) {
   2150         *from = (XPointer) ((const wchar_t *) *from + from_size);
   2151         *from_left = 0;
   2152         *to = (XPointer) outbufptr;
   2153         return -1;
   2154     }
   2155 
   2156     /* normal end */
   2157     *from = (XPointer) inbufptr;
   2158     *to = (XPointer) outbufptr;
   2159 
   2160     if (num_args > 0)
   2161         *((XlcCharSet *) args[0]) = charset;
   2162 
   2163     return 0;
   2164 }
   2165 
   2166 static int
   2167 stdc_wctocs(
   2168     XlcConv conv,
   2169     XPointer *from,
   2170     int *from_left,
   2171     XPointer *to,
   2172     int *to_left,
   2173     XPointer *args,
   2174     int num_args)
   2175 {
   2176     const wchar_t *src = *((const wchar_t **) from);
   2177     wchar_t wch;
   2178     XPointer tmp_from, save_from = *from;
   2179     char tmp[32];
   2180     int length, ret, src_left = *from_left;
   2181     int from_size = *from_left;
   2182 
   2183     if (src_left > 0 && *to_left > 0) {
   2184 	if ((wch = *src)) {
   2185 	    length = wctomb(tmp, wch);
   2186 	} else {
   2187 	    goto end;
   2188 	}
   2189 
   2190 	if (length < 0)
   2191 	    goto end;
   2192 
   2193 	tmp_from = (XPointer) tmp;
   2194 	ret = mbtocs(conv, &tmp_from, &length, to, to_left, args, num_args);
   2195 	if (ret < 0)
   2196 	    goto end;
   2197 
   2198 	src++;
   2199 	src_left--;
   2200     }
   2201 
   2202 end:
   2203      /* error end */
   2204     if (save_from == (XPointer) src) {
   2205         *from = (XPointer) ((const wchar_t *) *from + from_size);
   2206         *from_left = 0;
   2207 	return -1;
   2208     }
   2209 
   2210     /* normal end */
   2211     *from = (XPointer) src;
   2212     *from_left = src_left;
   2213 
   2214     return 0;
   2215 }
   2216 
   2217 static int
   2218 wcstocs(
   2219     XlcConv conv,
   2220     XPointer *from,
   2221     int *from_left,
   2222     XPointer *to,
   2223     int *to_left,
   2224     XPointer *args,
   2225     int num_args)
   2226 {
   2227     int ret;
   2228     XlcCharSet charset_old, charset = NULL;
   2229     XPointer tmp_args[1];
   2230 
   2231     const wchar_t *inbufptr;
   2232     int	in_left;
   2233     XPointer outbufptr;
   2234     int	out_left;
   2235     tmp_args[0] = (XPointer) &charset;
   2236 
   2237     ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
   2238     charset_old = charset;
   2239 
   2240     while ( ret == 0 && *from_left && *to_left) {
   2241 	inbufptr = (const wchar_t *) *from;
   2242 	in_left = *from_left;
   2243 	outbufptr = *to;
   2244 	out_left = *to_left;
   2245         ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
   2246         if (charset_old != charset) {
   2247            *from = (XPointer) inbufptr;
   2248            *from_left = in_left;
   2249            *to = (XPointer) outbufptr;
   2250            *to_left = out_left;
   2251            break;
   2252         }
   2253     }
   2254 
   2255     if (num_args > 0)
   2256         *((XlcCharSet *) args[0]) = charset_old;
   2257 
   2258     /* error end */
   2259     if (ret != 0)
   2260 	return( -1 );
   2261 
   2262     return(0);
   2263 }
   2264 
   2265 #ifdef STDCVT
   2266 
   2267 static int
   2268 stdc_wcstocs(
   2269     XlcConv conv,
   2270     XPointer *from,
   2271     int *from_left,
   2272     XPointer *to,
   2273     int *to_left,
   2274     XPointer *args,
   2275     int num_args)
   2276 {
   2277     int ret;
   2278     XlcCharSet charset_old, charset = NULL;
   2279     XPointer tmp_args[1];
   2280 
   2281     const wchar_t *inbufptr;
   2282     int	in_left;
   2283     XPointer outbufptr;
   2284     int	out_left;
   2285     tmp_args[0] = (XPointer) &charset;
   2286 
   2287     ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
   2288     charset_old = charset;
   2289 
   2290     while ( ret == 0 && *from_left && *to_left ) {
   2291 	inbufptr = (const wchar_t *) *from;
   2292 	in_left = *from_left;
   2293 	outbufptr = *to;
   2294 	out_left = *to_left;
   2295         ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
   2296         if (charset_old != charset) {
   2297            *from = (XPointer) inbufptr;
   2298            *from_left = in_left;
   2299            *to = (XPointer) outbufptr;
   2300            *to_left = out_left;
   2301            break;
   2302         }
   2303     }
   2304 
   2305     if (num_args > 0)
   2306         *((XlcCharSet *) args[0]) = charset_old;
   2307 
   2308     /* error end */
   2309     if (ret != 0)
   2310 	return( -1 );
   2311 
   2312     return(0);
   2313 }
   2314 
   2315 #endif
   2316 
   2317 static int
   2318 ctstombs(
   2319     XlcConv conv,
   2320     XPointer *from,
   2321     int *from_left,
   2322     XPointer *to,
   2323     int *to_left,
   2324     XPointer *args,
   2325     int num_args)
   2326 {
   2327     XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t));
   2328     char *buf_ptr1 = buf;
   2329     int buf_left1 = (*from_left);
   2330     char *buf_ptr2 = buf_ptr1;
   2331     int buf_left2;
   2332     int unconv_num1 = 0, unconv_num2 = 0;
   2333 
   2334     unconv_num1 = ctstowcs(conv,
   2335 		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
   2336     if (unconv_num1 < 0)
   2337         goto ret;
   2338 
   2339     buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t);
   2340 
   2341     unconv_num2 += wcstombs_org(conv,
   2342 		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
   2343     if (unconv_num2 < 0)
   2344         goto ret;
   2345 
   2346 ret:
   2347     Xfree(buf);
   2348 
   2349     return (unconv_num1 + unconv_num2);
   2350 }
   2351 
   2352 static int
   2353 cstombs(
   2354     XlcConv conv,
   2355     XPointer *from,
   2356     int *from_left,
   2357     XPointer *to,
   2358     int *to_left,
   2359     XPointer *args,
   2360     int num_args)
   2361 {
   2362     XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t));
   2363     char *buf_ptr1 = buf;
   2364     int buf_left1 = (*from_left);
   2365     char *buf_ptr2 = buf_ptr1;
   2366     int buf_left2;
   2367     int unconv_num1 = 0, unconv_num2 = 0;
   2368 
   2369     unconv_num1 = cstowcs(conv,
   2370 		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
   2371     if (unconv_num1 < 0)
   2372         goto ret;
   2373 
   2374     buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t);
   2375 
   2376     unconv_num2 += wcstombs_org(conv,
   2377 		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
   2378     if (unconv_num2 < 0)
   2379         goto ret;
   2380 
   2381 ret:
   2382     Xfree(buf);
   2383 
   2384     return (unconv_num1 + unconv_num2);
   2385 }
   2386 
   2387 static int
   2388 strtombs(
   2389     XlcConv conv,
   2390     XPointer *from,
   2391     int *from_left,
   2392     XPointer *to,
   2393     int *to_left,
   2394     XPointer *args,
   2395     int num_args)
   2396 {
   2397     State state = (State) conv->state;
   2398     XLCd lcd = state->lcd;
   2399 
   2400     char *encoding;
   2401     unsigned long mb, glyph_index;
   2402     unsigned char ch;
   2403 
   2404     int length;
   2405     int unconv_num = 0;
   2406 
   2407     CodeSet codeset;
   2408 
   2409     const char *inbufptr = *from;
   2410     char *outbufptr = *to;
   2411     int from_size = *from_left;
   2412 
   2413     while (*from_left && *to_left) {
   2414 
   2415         ch = *inbufptr++;
   2416         (*from_left)--;
   2417 
   2418         /* null ? */
   2419         if (!ch) {
   2420             if (outbufptr) {*outbufptr++ = '\0';}
   2421             (*to_left)--;
   2422 
   2423             continue;
   2424         }
   2425 
   2426         /* convert */
   2427         if (isleftside(ch)) {
   2428 	    glyph_index = ch;
   2429 	    codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL");
   2430 	} else {
   2431 	    glyph_index = ch & GL;
   2432 	    codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR");
   2433 	}
   2434 
   2435         if (!codeset) {
   2436 	    unconv_num++;
   2437 	    continue;
   2438         }
   2439 
   2440         mb = gi_to_mb(glyph_index, codeset);
   2441 	if (codeset->parse_info) {
   2442             Bool need_shift = False;
   2443             switch (codeset->parse_info->type) {
   2444                 case E_LSL :
   2445                     if (codeset != state->GL_codeset) {
   2446                         need_shift = True;
   2447                         state->GL_codeset = codeset;
   2448                     }
   2449                     break;
   2450                 case E_LSR :
   2451                     if (codeset != state->GR_codeset) {
   2452                         need_shift = True;
   2453                         state->GR_codeset = codeset;
   2454                     }
   2455                     break;
   2456                 /* case E_SS */
   2457                 default:
   2458                     need_shift = True;
   2459             }
   2460 
   2461 	    /* output shift sequence */
   2462             if (need_shift) {
   2463                 encoding = codeset->parse_info->encoding;
   2464                 length = strlen(encoding);
   2465                 if (*to_left < length)
   2466 		    break;
   2467 	        if (outbufptr) {
   2468 		    memcpy(outbufptr, encoding, length);
   2469 	            outbufptr += length;
   2470                 }
   2471 	        (*to_left) -= length;
   2472 	    }
   2473         }
   2474 
   2475         /* output characters */
   2476 	length = codeset->length;
   2477         if (*to_left < length)
   2478 	    break;
   2479 
   2480         if (outbufptr) {
   2481             output_ulong_value(outbufptr, mb, length, XlcNONE);
   2482             outbufptr += length;
   2483         }
   2484 
   2485 	(*to_left) -= length;
   2486 
   2487     } /* end of while */
   2488 
   2489     *from = (XPointer) ((const char *) *from + from_size);
   2490     *from_left = 0;
   2491     *to = (XPointer) outbufptr;
   2492 
   2493     return unconv_num;
   2494 }
   2495 
   2496 static int
   2497 strtowcs(
   2498     XlcConv conv,
   2499     XPointer *from,
   2500     int *from_left,
   2501     XPointer *to,
   2502     int *to_left,
   2503     XPointer *args,
   2504     int num_args)
   2505 {
   2506     State state = (State) conv->state;
   2507     XLCd lcd = state->lcd;
   2508 
   2509     unsigned char ch;
   2510     unsigned long glyph_index;
   2511     wchar_t wc;
   2512 
   2513     int unconv_num = 0;
   2514     CodeSet codeset;
   2515 
   2516     const char *inbufptr = *from;
   2517     wchar_t *outbufptr = (wchar_t *)*to;
   2518     int from_size = *from_left;
   2519 
   2520     while (*from_left && *to_left) {
   2521 
   2522         ch = *inbufptr++;
   2523         (*from_left)--;
   2524 
   2525         /* null ? */
   2526         if (!ch) {
   2527             if (outbufptr) {*outbufptr++ = L'\0';}
   2528             (*to_left)--;
   2529 
   2530             continue;
   2531         }
   2532 
   2533         /* convert */
   2534         if (isleftside(ch)) {
   2535 	    glyph_index = ch;
   2536 	    codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL");
   2537 	} else {
   2538 	    glyph_index = ch & GL;
   2539 	    codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR");
   2540 	}
   2541 
   2542         if (!codeset) {
   2543 	    unconv_num++;
   2544 	    continue;
   2545         }
   2546 
   2547         gi_to_wc(lcd, glyph_index, codeset, &wc);
   2548 	if (outbufptr) {*outbufptr++ = wc;}
   2549 	(*to_left)--;
   2550 
   2551     } /* end of while */
   2552 
   2553     *from = (XPointer) ((const char *) *from + from_size);
   2554     *from_left = 0;
   2555     *to = (XPointer) outbufptr;
   2556 
   2557     return unconv_num;
   2558 }
   2559 
   2560 static int
   2561 stdc_strtowcs(
   2562     XlcConv conv,
   2563     XPointer *from,
   2564     int *from_left,
   2565     XPointer *to,
   2566     int *to_left,
   2567     XPointer *args,
   2568     int num_args)
   2569 {
   2570     XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
   2571     char *buf_ptr1 = buf;
   2572     int buf_left1 = (*from_left) * MB_CUR_MAX;
   2573     char *buf_ptr2 = buf_ptr1;
   2574     int buf_left2;
   2575     int unconv_num1 = 0, unconv_num2 = 0;
   2576 
   2577     unconv_num1 = strtombs(conv,
   2578 		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
   2579     if (unconv_num1 < 0)
   2580         goto ret;
   2581 
   2582     buf_left2 = buf_ptr1 - buf_ptr2;
   2583 
   2584     unconv_num2 = stdc_mbstowcs(conv,
   2585 		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
   2586     if (unconv_num2 < 0)
   2587         goto ret;
   2588 
   2589 ret:
   2590     Xfree(buf);
   2591 
   2592     return (unconv_num1 + unconv_num2);
   2593 }
   2594 
   2595 /* -------------------------------------------------------------------------- */
   2596 /*				Close                                         */
   2597 /* -------------------------------------------------------------------------- */
   2598 
   2599 static void
   2600 close_converter(
   2601     XlcConv conv)
   2602 {
   2603     Xfree(conv->state);
   2604     Xfree(conv->methods);
   2605     Xfree(conv);
   2606 }
   2607 
   2608 /* -------------------------------------------------------------------------- */
   2609 /*				Open                                          */
   2610 /* -------------------------------------------------------------------------- */
   2611 
   2612 static XlcConv
   2613 create_conv(
   2614     XLCd lcd,
   2615     XlcConvMethods methods)
   2616 {
   2617     XlcConv conv;
   2618     State state;
   2619 
   2620     conv = Xcalloc(1, sizeof(XlcConvRec));
   2621     if (conv == NULL)
   2622 	return (XlcConv) NULL;
   2623 
   2624     conv->methods = Xmalloc(sizeof(XlcConvMethodsRec));
   2625     if (conv->methods == NULL)
   2626 	goto err;
   2627     *conv->methods = *methods;
   2628     conv->methods->reset = init_state;
   2629 
   2630     conv->state = Xcalloc(1, sizeof(StateRec));
   2631     if (conv->state == NULL)
   2632 	goto err;
   2633 
   2634     state = (State) conv->state;
   2635     state->lcd = lcd;
   2636 
   2637     _XlcResetConverter(conv);
   2638 
   2639     return conv;
   2640 
   2641 err:
   2642     close_converter(conv);
   2643 
   2644     return (XlcConv) NULL;
   2645 }
   2646 
   2647 static XlcConvMethodsRec mbstocts_methods = {
   2648     close_converter,
   2649     mbstocts,
   2650     NULL
   2651 };
   2652 
   2653 static XlcConv
   2654 open_mbstocts(
   2655     XLCd from_lcd,
   2656     const char *from_type,
   2657     XLCd to_lcd,
   2658     const char *to_type)
   2659 {
   2660     return create_conv(from_lcd, &mbstocts_methods);
   2661 }
   2662 
   2663 static XlcConvMethodsRec mbstostr_methods = {
   2664     close_converter,
   2665     mbstostr,
   2666     NULL
   2667 };
   2668 
   2669 static XlcConv
   2670 open_mbstostr(
   2671     XLCd from_lcd,
   2672     const char *from_type,
   2673     XLCd to_lcd,
   2674     const char *to_type)
   2675 {
   2676     return create_conv(from_lcd, &mbstostr_methods);
   2677 }
   2678 
   2679 static XlcConvMethodsRec mbstocs_methods = {
   2680     close_converter,
   2681     mbstocs,
   2682     NULL
   2683 };
   2684 
   2685 static XlcConv
   2686 open_mbstocs(
   2687     XLCd from_lcd,
   2688     const char *from_type,
   2689     XLCd to_lcd,
   2690     const char *to_type)
   2691 {
   2692     return create_conv(from_lcd, &mbstocs_methods);
   2693 }
   2694 
   2695 static XlcConvMethodsRec mbtocs_methods = {
   2696     close_converter,
   2697     mbtocs,
   2698     NULL
   2699 };
   2700 
   2701 static XlcConv
   2702 open_mbtocs(
   2703     XLCd from_lcd,
   2704     const char *from_type,
   2705     XLCd to_lcd,
   2706     const char *to_type)
   2707 {
   2708     return create_conv(from_lcd, &mbtocs_methods);
   2709 }
   2710 
   2711 static XlcConvMethodsRec ctstombs_methods = {
   2712     close_converter,
   2713     ctstombs,
   2714     NULL
   2715 };
   2716 
   2717 static XlcConv
   2718 open_ctstombs(
   2719     XLCd from_lcd,
   2720     const char *from_type,
   2721     XLCd to_lcd,
   2722     const char *to_type)
   2723 {
   2724     return create_conv(from_lcd, &ctstombs_methods);
   2725 }
   2726 
   2727 static XlcConvMethodsRec cstombs_methods = {
   2728     close_converter,
   2729     cstombs,
   2730     NULL
   2731 };
   2732 
   2733 static XlcConv
   2734 open_cstombs(
   2735     XLCd from_lcd,
   2736     const char *from_type,
   2737     XLCd to_lcd,
   2738     const char *to_type)
   2739 {
   2740     return create_conv(from_lcd, &cstombs_methods);
   2741 }
   2742 
   2743 static XlcConvMethodsRec strtombs_methods = {
   2744     close_converter,
   2745     strtombs,
   2746     NULL
   2747 };
   2748 
   2749 static XlcConv
   2750 open_strtombs(
   2751     XLCd from_lcd,
   2752     const char *from_type,
   2753     XLCd to_lcd,
   2754     const char *to_type)
   2755 {
   2756     return create_conv(from_lcd, &strtombs_methods);
   2757 }
   2758 
   2759 #ifdef STDCVT
   2760 
   2761 static XlcConvMethodsRec stdc_mbstowcs_methods = {
   2762     close_converter,
   2763     stdc_mbstowcs,
   2764     NULL
   2765 };
   2766 
   2767 static XlcConv
   2768 open_stdc_mbstowcs(
   2769     XLCd from_lcd,
   2770     const char *from_type,
   2771     XLCd to_lcd,
   2772     const char *to_type)
   2773 {
   2774     return create_conv(from_lcd, &stdc_mbstowcs_methods);
   2775 }
   2776 
   2777 static XlcConvMethodsRec stdc_wcstombs_methods = {
   2778     close_converter,
   2779     stdc_wcstombs,
   2780     NULL
   2781 };
   2782 
   2783 static XlcConv
   2784 open_stdc_wcstombs(
   2785     XLCd from_lcd,
   2786     const char *from_type,
   2787     XLCd to_lcd,
   2788     const char *to_type)
   2789 {
   2790     return create_conv(from_lcd, &stdc_wcstombs_methods);
   2791 }
   2792 
   2793 static XlcConvMethodsRec stdc_wcstocts_methods = {
   2794     close_converter,
   2795     stdc_wcstocts,
   2796     NULL
   2797 };
   2798 
   2799 static XlcConv
   2800 open_stdc_wcstocts(
   2801     XLCd from_lcd,
   2802     const char *from_type,
   2803     XLCd to_lcd,
   2804     const char *to_type)
   2805 {
   2806     return create_conv(from_lcd, &stdc_wcstocts_methods);
   2807 }
   2808 
   2809 static XlcConvMethodsRec stdc_wcstostr_methods = {
   2810     close_converter,
   2811     stdc_wcstostr,
   2812     NULL
   2813 };
   2814 
   2815 static XlcConv
   2816 open_stdc_wcstostr(
   2817     XLCd from_lcd,
   2818     const char *from_type,
   2819     XLCd to_lcd,
   2820     const char *to_type)
   2821 {
   2822     return create_conv(from_lcd, &stdc_wcstostr_methods);
   2823 }
   2824 
   2825 static XlcConvMethodsRec stdc_wcstocs_methods = {
   2826     close_converter,
   2827     stdc_wcstocs,
   2828     NULL
   2829 };
   2830 
   2831 static XlcConv
   2832 open_stdc_wcstocs(
   2833     XLCd from_lcd,
   2834     const char *from_type,
   2835     XLCd to_lcd,
   2836     const char *to_type)
   2837 {
   2838     return create_conv(from_lcd, &stdc_wcstocs_methods);
   2839 }
   2840 
   2841 static XlcConvMethodsRec stdc_wctocs_methods = {
   2842     close_converter,
   2843     stdc_wctocs,
   2844     NULL
   2845 };
   2846 
   2847 static XlcConv
   2848 open_stdc_wctocs(
   2849     XLCd from_lcd,
   2850     const char *from_type,
   2851     XLCd to_lcd,
   2852     const char *to_type)
   2853 {
   2854     return create_conv(from_lcd, &stdc_wctocs_methods);
   2855 }
   2856 
   2857 static XlcConvMethodsRec stdc_ctstowcs_methods = {
   2858     close_converter,
   2859     stdc_ctstowcs,
   2860     NULL
   2861 };
   2862 
   2863 static XlcConv
   2864 open_stdc_ctstowcs(
   2865     XLCd from_lcd,
   2866     const char *from_type,
   2867     XLCd to_lcd,
   2868     const char *to_type)
   2869 {
   2870     return create_conv(from_lcd, &stdc_ctstowcs_methods);
   2871 }
   2872 
   2873 static XlcConvMethodsRec stdc_cstowcs_methods = {
   2874     close_converter,
   2875     stdc_cstowcs,
   2876     NULL
   2877 };
   2878 
   2879 static XlcConv
   2880 open_stdc_cstowcs(
   2881     XLCd from_lcd,
   2882     const char *from_type,
   2883     XLCd to_lcd,
   2884     const char *to_type)
   2885 {
   2886     return create_conv(from_lcd, &stdc_cstowcs_methods);
   2887 }
   2888 
   2889 static XlcConvMethodsRec stdc_strtowcs_methods = {
   2890     close_converter,
   2891     stdc_strtowcs,
   2892     NULL
   2893 };
   2894 
   2895 static XlcConv
   2896 open_stdc_strtowcs(
   2897     XLCd from_lcd,
   2898     const char *from_type,
   2899     XLCd to_lcd,
   2900     const char *to_type)
   2901 {
   2902     return create_conv(from_lcd, &stdc_strtowcs_methods);
   2903 }
   2904 
   2905 #endif /* STDCVT */
   2906 
   2907 static XlcConvMethodsRec mbstowcs_methods = {
   2908     close_converter,
   2909     mbstowcs_org,
   2910     NULL
   2911 };
   2912 
   2913 static XlcConv
   2914 open_mbstowcs(
   2915     XLCd from_lcd,
   2916     const char *from_type,
   2917     XLCd to_lcd,
   2918     const char *to_type)
   2919 {
   2920     return create_conv(from_lcd, &mbstowcs_methods);
   2921 }
   2922 
   2923 static XlcConvMethodsRec wcstombs_methods = {
   2924     close_converter,
   2925     wcstombs_org,
   2926     NULL
   2927 };
   2928 
   2929 static XlcConv
   2930 open_wcstombs(
   2931     XLCd from_lcd,
   2932     const char *from_type,
   2933     XLCd to_lcd,
   2934     const char *to_type)
   2935 {
   2936     return create_conv(from_lcd, &wcstombs_methods);
   2937 }
   2938 
   2939 static XlcConvMethodsRec wcstocts_methods = {
   2940     close_converter,
   2941     wcstocts,
   2942     NULL
   2943 };
   2944 
   2945 static XlcConv
   2946 open_wcstocts(
   2947     XLCd from_lcd,
   2948     const char *from_type,
   2949     XLCd to_lcd,
   2950     const char *to_type)
   2951 {
   2952     return create_conv(from_lcd, &wcstocts_methods);
   2953 }
   2954 
   2955 static XlcConvMethodsRec wcstostr_methods = {
   2956     close_converter,
   2957     wcstostr,
   2958     NULL
   2959 };
   2960 
   2961 static XlcConv
   2962 open_wcstostr(
   2963     XLCd from_lcd,
   2964     const char *from_type,
   2965     XLCd to_lcd,
   2966     const char *to_type)
   2967 {
   2968     return create_conv(from_lcd, &wcstostr_methods);
   2969 }
   2970 
   2971 static XlcConvMethodsRec wcstocs_methods = {
   2972     close_converter,
   2973     wcstocs,
   2974     NULL
   2975 };
   2976 
   2977 static XlcConv
   2978 open_wcstocs(
   2979     XLCd from_lcd,
   2980     const char *from_type,
   2981     XLCd to_lcd,
   2982     const char *to_type)
   2983 {
   2984     return create_conv(from_lcd, &wcstocs_methods);
   2985 }
   2986 
   2987 static XlcConvMethodsRec wctocs_methods = {
   2988     close_converter,
   2989     wctocs,
   2990     NULL
   2991 };
   2992 
   2993 static XlcConv
   2994 open_wctocs(
   2995     XLCd from_lcd,
   2996     const char *from_type,
   2997     XLCd to_lcd,
   2998     const char *to_type)
   2999 {
   3000     return create_conv(from_lcd, &wctocs_methods);
   3001 }
   3002 
   3003 static XlcConvMethodsRec ctstowcs_methods = {
   3004     close_converter,
   3005     ctstowcs,
   3006     NULL
   3007 };
   3008 
   3009 static XlcConv
   3010 open_ctstowcs(
   3011     XLCd from_lcd,
   3012     const char *from_type,
   3013     XLCd to_lcd,
   3014     const char *to_type)
   3015 {
   3016     return create_conv(from_lcd, &ctstowcs_methods);
   3017 }
   3018 
   3019 static XlcConvMethodsRec cstowcs_methods = {
   3020     close_converter,
   3021     cstowcs,
   3022     NULL
   3023 };
   3024 
   3025 static XlcConv
   3026 open_cstowcs(
   3027     XLCd from_lcd,
   3028     const char *from_type,
   3029     XLCd to_lcd,
   3030     const char *to_type)
   3031 {
   3032     return create_conv(from_lcd, &cstowcs_methods);
   3033 }
   3034 
   3035 static XlcConvMethodsRec strtowcs_methods = {
   3036     close_converter,
   3037     strtowcs,
   3038     NULL
   3039 };
   3040 
   3041 static XlcConv
   3042 open_strtowcs(
   3043     XLCd from_lcd,
   3044     const char *from_type,
   3045     XLCd to_lcd,
   3046     const char *to_type)
   3047 {
   3048     return create_conv(from_lcd, &strtowcs_methods);
   3049 }
   3050 
   3051 /* -------------------------------------------------------------------------- */
   3052 /*				Loader                                        */
   3053 /* -------------------------------------------------------------------------- */
   3054 
   3055 XLCd
   3056 _XlcGenericLoader(
   3057     const char *name)
   3058 {
   3059     XLCd lcd;
   3060 #ifdef STDCVT
   3061     XLCdGenericPart *gen;
   3062 #endif
   3063 
   3064     lcd = _XlcCreateLC(name, _XlcGenericMethods);
   3065 
   3066     if (lcd == NULL)
   3067 	return lcd;
   3068 
   3069     default_GL_charset = _XlcGetCharSet("ISO8859-1:GL");
   3070     default_GR_charset = _XlcGetCharSet("ISO8859-1:GR");
   3071 
   3072     _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCompoundText, open_mbstocts);
   3073     _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNString,       open_mbstostr);
   3074     _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet,      open_mbstocs);
   3075     _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar,         open_mbtocs);
   3076     _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte, open_ctstombs);
   3077     _XlcSetConverter(lcd, XlcNString,    lcd, XlcNMultiByte,    open_strtombs);
   3078     _XlcSetConverter(lcd, XlcNCharSet,   lcd, XlcNMultiByte,    open_cstombs);
   3079 
   3080 #ifdef STDCVT
   3081      gen = XLC_GENERIC_PART(lcd);
   3082 
   3083      if (gen->use_stdc_env != True) {
   3084 #endif
   3085         _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar,     open_mbstowcs);
   3086         _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNMultiByte,    open_wcstombs);
   3087         _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNCompoundText, open_wcstocts);
   3088         _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNString,       open_wcstostr);
   3089         _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNCharSet,      open_wcstocs);
   3090         _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNChar,         open_wctocs);
   3091         _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar,  open_ctstowcs);
   3092         _XlcSetConverter(lcd, XlcNString,    lcd, XlcNWideChar,     open_strtowcs);
   3093         _XlcSetConverter(lcd, XlcNCharSet,   lcd, XlcNWideChar,     open_cstowcs);
   3094 #ifdef STDCVT
   3095     }
   3096 #endif
   3097 
   3098 #ifdef STDCVT
   3099     if (gen->use_stdc_env == True) {
   3100         _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar,     open_stdc_mbstowcs);
   3101         _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNMultiByte,    open_stdc_wcstombs);
   3102         _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNCompoundText, open_stdc_wcstocts);
   3103         _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNString,       open_stdc_wcstostr);
   3104         _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNCharSet,      open_stdc_wcstocs);
   3105         _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNChar,         open_stdc_wctocs);
   3106         _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar,  open_stdc_ctstowcs);
   3107         _XlcSetConverter(lcd, XlcNString,    lcd, XlcNWideChar,     open_stdc_strtowcs);
   3108         _XlcSetConverter(lcd, XlcNCharSet,   lcd, XlcNWideChar,     open_stdc_cstowcs);
   3109     }
   3110 #endif
   3111 
   3112     _XlcAddUtf8Converters(lcd);
   3113 
   3114     return lcd;
   3115 }
   3116