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