lcGenConv.c revision cf2acdde
11ab64890Smrg/*
21ab64890Smrg * Copyright 1992, 1993 by TOSHIBA Corp.
31ab64890Smrg *
41ab64890Smrg * Permission to use, copy, modify, and distribute this software and its
51ab64890Smrg * documentation for any purpose and without fee is hereby granted, provided
61ab64890Smrg * that the above copyright notice appear in all copies and that both that
71ab64890Smrg * copyright notice and this permission notice appear in supporting
81ab64890Smrg * documentation, and that the name of TOSHIBA not be used in advertising
91ab64890Smrg * or publicity pertaining to distribution of the software without specific,
101ab64890Smrg * written prior permission. TOSHIBA make no representations about the
111ab64890Smrg * suitability of this software for any purpose.  It is provided "as is"
121ab64890Smrg * without express or implied warranty.
131ab64890Smrg *
141ab64890Smrg * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
151ab64890Smrg * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
161ab64890Smrg * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
171ab64890Smrg * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
181ab64890Smrg * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
191ab64890Smrg * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
201ab64890Smrg * SOFTWARE.
211ab64890Smrg *
221ab64890Smrg * Author: Katsuhisa Yano	TOSHIBA Corp.
231ab64890Smrg *			   	mopi@osa.ilab.toshiba.co.jp
241ab64890Smrg */
251ab64890Smrg/*
261ab64890Smrg *  (c) Copyright 1995 FUJITSU LIMITED
271ab64890Smrg *  This is source code modified by FUJITSU LIMITED under the Joint
281ab64890Smrg *  Development Agreement for the CDE/Motif PST.
291ab64890Smrg *
301ab64890Smrg *   Modifier: Masayoshi Shimamura      FUJITSU LIMITED
311ab64890Smrg *
321ab64890Smrg */
331ab64890Smrg/*
3461b2299dSmrg *  2000
351ab64890Smrg *  Modifier: Ivan Pascal      The XFree86 Project
361ab64890Smrg */
371ab64890Smrg
381ab64890Smrg/*
391ab64890Smrg * A generic locale loader for all kinds of ISO-2022 based codesets.
401ab64890Smrg * Supports: all locales.
411ab64890Smrg * How: Provides generic converters for ISO-2022 based codesets. Extensible as
421ab64890Smrg *      far as ISO-2022 is extensible: codesets can be given by name in the
431ab64890Smrg *      stream. Overall distinction between GL (0x00..0x7f) and GR (0x80..0xff).
441ab64890Smrg *      In every chunk between escape sequences, the number of bytes per
451ab64890Smrg *      character (char_size) is constant.
461ab64890Smrg * Platforms: all systems.
471ab64890Smrg */
481ab64890Smrg
491ab64890Smrg#ifdef HAVE_CONFIG_H
501ab64890Smrg#include <config.h>
511ab64890Smrg#endif
521ab64890Smrg#include "Xlibint.h"
531ab64890Smrg#include "XlcGeneric.h"
541ab64890Smrg#include <stdio.h>
551ab64890Smrg
562e9c7c8cSmrg#if !defined(Lynx_22) && !defined(X_LOCALE)
571ab64890Smrg#define STDCVT
581ab64890Smrg#endif
591ab64890Smrg
601ab64890Smrgtypedef struct _CTDataRec {
611ab64890Smrg    const char *name;
621ab64890Smrg    const char *encoding; /* Compound Text encoding */
631ab64890Smrg} CTDataRec, *CTData;
641ab64890Smrg
651ab64890Smrgstatic CTDataRec directionality_data[] =
661ab64890Smrg{
671ab64890Smrg    { "BEGIN_LEFT-TO-RIGHT_TEXT", "\2331]" },
681ab64890Smrg    { "BEGIN_RIGHT-TO-LEFT_TEXT", "\2332]" },
691ab64890Smrg    { "END_OF_STRING", "\233]" },
701ab64890Smrg};
711ab64890Smrg
721ab64890Smrgtypedef struct _StateRec {
731ab64890Smrg    XLCd lcd;
741ab64890Smrg    /* CT state */
751ab64890Smrg    XlcCharSet charset;		/* charset of current state */
761ab64890Smrg    XlcCharSet GL_charset;	/* charset of initial state in GL */
771ab64890Smrg    XlcCharSet GR_charset;	/* charset of initial state in GR */
781ab64890Smrg    /* MB shift state */
791ab64890Smrg    CodeSet  GL_codeset;
801ab64890Smrg    CodeSet  GR_codeset;
811ab64890Smrg} StateRec, *State;
821ab64890Smrg
831ab64890Smrg#define GR      0x80    /* begins right-side (non-ascii) region */
841ab64890Smrg#define GL      0x7f    /* ends left-side (ascii) region        */
851ab64890Smrg#define ESC	0x1b
861ab64890Smrg#define CSI	0x9b
871ab64890Smrg#define STX	0x02
881ab64890Smrg
891ab64890Smrg#define isrightside(c)   ((c) & GR)
901ab64890Smrg#define isleftside(c)  (!isrightside(c))
911ab64890Smrg
921ab64890Smrg/* Forward declarations for local routines. */
931ab64890Smrgstatic int mbstocts (XlcConv conv, XPointer *from, int *from_left,
941ab64890Smrg		     XPointer *to, int *to_left, XPointer *args, int num_args);
951ab64890Smrgstatic int ctstombs (XlcConv conv, XPointer *from, int *from_left,
961ab64890Smrg		     XPointer *to, int *to_left, XPointer *args, int num_args);
971ab64890Smrgstatic int cstombs (XlcConv conv, XPointer *from, int *from_left,
981ab64890Smrg		    XPointer *to, int *to_left, XPointer *args, int num_args);
991ab64890Smrg
1001ab64890Smrg/* ------------------------------------------------------------------------- */
1011ab64890Smrg/*				Misc                                         */
1021ab64890Smrg/* ------------------------------------------------------------------------- */
1031ab64890Smrg
1041ab64890Smrgstatic int
1051ab64890Smrgcompare(
1061ab64890Smrg    const char *src,
1071ab64890Smrg    const char *encoding,
1081ab64890Smrg    int length)
1091ab64890Smrg{
1101ab64890Smrg    const char *start = src;
1111ab64890Smrg
1121ab64890Smrg    while (length-- > 0) {
1131ab64890Smrg	if (*src++ != *encoding++)
1141ab64890Smrg	    return 0;
1151ab64890Smrg	if (*encoding == '\0')
1161ab64890Smrg	    return src - start;
1171ab64890Smrg    }
1181ab64890Smrg
1191ab64890Smrg    return 0;
1201ab64890Smrg}
1211ab64890Smrg
1221ab64890Smrgstatic unsigned long
1231ab64890Smrgconv_to_dest(
1241ab64890Smrg    Conversion conv,
1251ab64890Smrg    unsigned long code)
1261ab64890Smrg{
1271ab64890Smrg    int i;
1281ab64890Smrg    int conv_num = conv->conv_num;
1291ab64890Smrg    FontScope convlist = conv->convlist;
1301ab64890Smrg
1311ab64890Smrg    for (i = 0; i < conv_num; i++) {
1321ab64890Smrg  	if (convlist[i].start <= code && code <= convlist[i].end) {
1331ab64890Smrg	    switch (convlist[i].shift_direction) {
1341ab64890Smrg	    case '+':
1351ab64890Smrg	        return(code + convlist[i].shift);
1361ab64890Smrg	    case '-':
1371ab64890Smrg		return(code - convlist[i].shift);
1381ab64890Smrg            default:
1391ab64890Smrg		return(code);
1401ab64890Smrg	    }
1411ab64890Smrg	}
1421ab64890Smrg    }
1431ab64890Smrg
1441ab64890Smrg    return(code);
1451ab64890Smrg}
1461ab64890Smrg
1471ab64890Smrgstatic unsigned long
1481ab64890Smrgconv_to_source(
1491ab64890Smrg    Conversion conv,
1501ab64890Smrg    unsigned long code)
1511ab64890Smrg{
1521ab64890Smrg    int i;
1531ab64890Smrg    int conv_num;
1541ab64890Smrg    FontScope convlist;
1551ab64890Smrg    unsigned long start_p;
1561ab64890Smrg    unsigned long start_m;
1571ab64890Smrg    unsigned long end_p;
1581ab64890Smrg    unsigned long end_m;
1591ab64890Smrg
1601ab64890Smrg    if (!conv)
1611ab64890Smrg	return(code);
1621ab64890Smrg
1631ab64890Smrg    conv_num = conv->conv_num;
1641ab64890Smrg    convlist = conv->convlist;
1651ab64890Smrg
1661ab64890Smrg    for (i = 0; i < conv_num; i++) {
1671ab64890Smrg        switch (convlist[i].shift_direction) {
1681ab64890Smrg	case '+':
1691ab64890Smrg            start_p = convlist[i].start + convlist[i].shift;
1701ab64890Smrg            end_p = convlist[i].end + convlist[i].shift;
1711ab64890Smrg	    if (start_p <= code && code <= end_p)
1721ab64890Smrg		return(code - convlist[i].shift);
1731ab64890Smrg            break;
1741ab64890Smrg	case '-':
1751ab64890Smrg            start_m = convlist[i].start - convlist[i].shift;
1761ab64890Smrg            end_m = convlist[i].end - convlist[i].shift;
1771ab64890Smrg	    if (start_m <= code && code <= end_m)
1781ab64890Smrg		return(code + convlist[i].shift);
1791ab64890Smrg            break;
1801ab64890Smrg        default:
1811ab64890Smrg	    continue;
1821ab64890Smrg	}
1831ab64890Smrg    }
1841ab64890Smrg
1851ab64890Smrg    return(code);
1861ab64890Smrg}
1871ab64890Smrg
1881ab64890Smrgstatic unsigned long
1891ab64890Smrgmb_to_gi(
1901ab64890Smrg    unsigned long mb,
1911ab64890Smrg    CodeSet codeset)
1921ab64890Smrg{
1931ab64890Smrg    int i;
1941ab64890Smrg    unsigned long mb_tmp, mask = 0;
1951ab64890Smrg
1961ab64890Smrg    if (codeset->mbconv) {
1971ab64890Smrg	mb_tmp = conv_to_dest(codeset->mbconv, mb);
1981ab64890Smrg	if (mb_tmp != mb)
1991ab64890Smrg	    return(mb_tmp);
2001ab64890Smrg    }
2011ab64890Smrg
20261b2299dSmrg    if (codeset->side == XlcC0 || codeset->side == XlcGL ||
2031ab64890Smrg	codeset->side == XlcC1 || codeset->side == XlcGR) {
2041ab64890Smrg
2051ab64890Smrg        for (i = 0; i < codeset->length; i++)
2061ab64890Smrg	    mask = (mask << 8) | GL;
2071ab64890Smrg	mb = mb & mask;
2081ab64890Smrg    }
2091ab64890Smrg
2101ab64890Smrg    return(mb);
2111ab64890Smrg}
2121ab64890Smrg
2131ab64890Smrgstatic unsigned long
2141ab64890Smrggi_to_mb(
2151ab64890Smrg    unsigned long glyph_index,
2161ab64890Smrg    CodeSet codeset)
2171ab64890Smrg{
2181ab64890Smrg    int i;
2191ab64890Smrg    unsigned long mask = 0;
2201ab64890Smrg
2211ab64890Smrg    if (codeset->side == XlcC1 || codeset->side == XlcGR) {
2221ab64890Smrg        for (i = 0; i < codeset->length; i++)
2231ab64890Smrg	    mask = (mask << 8) | GR;
2241ab64890Smrg	glyph_index = glyph_index | mask;
2251ab64890Smrg    }
2261ab64890Smrg
2271ab64890Smrg    if (codeset->mbconv)
2281ab64890Smrg        return( conv_to_source(codeset->mbconv, glyph_index) );
2291ab64890Smrg
2301ab64890Smrg    return(glyph_index);
2311ab64890Smrg}
2321ab64890Smrg
2331ab64890Smrgstatic Bool
2341ab64890Smrggi_to_wc(
2351ab64890Smrg    XLCd lcd,
2361ab64890Smrg    unsigned long glyph_index,
2371ab64890Smrg    CodeSet codeset,
2381ab64890Smrg    wchar_t *wc)
2391ab64890Smrg{
2401ab64890Smrg    unsigned char mask = 0;
2411ab64890Smrg    unsigned long wc_encoding = codeset->wc_encoding;
2421ab64890Smrg    int length = codeset->length;
2431ab64890Smrg    unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
2441ab64890Smrg
2451ab64890Smrg    mask = (1 << wc_shift_bits) - 1 ;
2461ab64890Smrg
2471ab64890Smrg    for (*wc = 0, length--; length >= 0; length--)
2481ab64890Smrg	*wc = (*wc << wc_shift_bits) | ((glyph_index >> (length * 8 )) & mask);
2491ab64890Smrg
2501ab64890Smrg    *wc = *wc | wc_encoding;
2511ab64890Smrg
2521ab64890Smrg    return(True);
2531ab64890Smrg}
2541ab64890Smrg
2551ab64890Smrgstatic Bool
2561ab64890Smrgwc_to_gi(
2571ab64890Smrg    XLCd lcd,
2581ab64890Smrg    wchar_t wc,
2591ab64890Smrg    unsigned long *glyph_index,
2601ab64890Smrg    CodeSet *codeset)
2611ab64890Smrg{
2621ab64890Smrg    int i;
2631ab64890Smrg    unsigned char mask = 0;
2641ab64890Smrg    unsigned long wc_encoding;
2651ab64890Smrg    unsigned long wc_encode_mask = XLC_GENERIC(lcd, wc_encode_mask);
2661ab64890Smrg    unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
2671ab64890Smrg    int codeset_num = XLC_GENERIC(lcd, codeset_num);
2681ab64890Smrg    CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
2691ab64890Smrg
2701ab64890Smrg    wc_encoding = wc & wc_encode_mask;
2711ab64890Smrg    for (*codeset = NULL, i = 0; i < codeset_num; i++) {
2721ab64890Smrg	if (wc_encoding == codeset_list[i]->wc_encoding) {
2731ab64890Smrg	    *codeset = codeset_list[i];
2741ab64890Smrg	    break;
2751ab64890Smrg        }
2761ab64890Smrg    }
2771ab64890Smrg    if (*codeset == NULL)
2781ab64890Smrg	return(False);
2791ab64890Smrg
2801ab64890Smrg    mask = (1 << wc_shift_bits) - 1 ;
2811ab64890Smrg
2821ab64890Smrg    wc = wc & ~wc_encode_mask;
2831ab64890Smrg    for (*glyph_index = 0, i = (*codeset)->length - 1; i >= 0; i--)
28461b2299dSmrg	*glyph_index = (*glyph_index << 8) |
2851ab64890Smrg		      ( ((unsigned long)wc >> (i * wc_shift_bits)) & mask );
2861ab64890Smrg
2871ab64890Smrg    return(True);
2881ab64890Smrg}
2891ab64890Smrg
2901ab64890Smrgstatic CodeSet
2911ab64890Smrgmb_parse_codeset(
2921ab64890Smrg    State state,
2931ab64890Smrg    int num,
2941ab64890Smrg    const char **inbufptr,
2951ab64890Smrg    int *from_left)
2961ab64890Smrg{
2971ab64890Smrg    int len;
2981ab64890Smrg    int from_len = (*from_left) + 1;
2991ab64890Smrg    const char *src = (*inbufptr) - 1;
3001ab64890Smrg    ParseInfo *mb_parse_list = XLC_GENERIC(state->lcd, mb_parse_list);
3011ab64890Smrg    ParseInfo parse_info;
3021ab64890Smrg    CodeSet codeset;
30361b2299dSmrg
3041ab64890Smrg    for (--num ; (parse_info = mb_parse_list[num]) != NULL; num++) {
3051ab64890Smrg       len = compare(src, parse_info->encoding, from_len);
3061ab64890Smrg       if (len > 0) {
3071ab64890Smrg           codeset = parse_info->codeset;
3081ab64890Smrg           if (parse_info->type == E_LSL)
3091ab64890Smrg               state->GL_codeset = codeset;
3101ab64890Smrg           else if (parse_info->type == E_LSR)
3111ab64890Smrg               state->GR_codeset = codeset;
3121ab64890Smrg           --len;
3131ab64890Smrg           *inbufptr += len;
3141ab64890Smrg           *from_left -= len;
3151ab64890Smrg           return codeset;
3161ab64890Smrg       }
3171ab64890Smrg    }
3181ab64890Smrg    return (CodeSet) NULL;
3191ab64890Smrg}
3201ab64890Smrg
3211ab64890Smrgstatic CodeSet
3221ab64890SmrgbyteM_parse_codeset(
3231ab64890Smrg    XLCd lcd,
3241ab64890Smrg    const char *inbufptr)
3251ab64890Smrg{
3261ab64890Smrg    unsigned char ch;
3271ab64890Smrg    CodeSet codeset;
3281ab64890Smrg    ByteInfoList byteM;
3291ab64890Smrg    ByteInfoListRec byteM_rec;
3301ab64890Smrg    ByteInfo byteinfo;
3311ab64890Smrg    ByteInfoRec byteinfo_rec;
3321ab64890Smrg    Bool hit = False;
3331ab64890Smrg    int i, j, k;
3341ab64890Smrg
3351ab64890Smrg    int codeset_num               = XLC_GENERIC(lcd, codeset_num);
3361ab64890Smrg    CodeSet *codeset_list         = XLC_GENERIC(lcd, codeset_list);
3371ab64890Smrg
3381ab64890Smrg    for (i = 0; i < codeset_num; i++) {
3391ab64890Smrg        codeset = codeset_list[i];
3401ab64890Smrg        byteM = codeset->byteM;
3411ab64890Smrg        if (codeset->side != XlcNONE || byteM == NULL)
3421ab64890Smrg	    continue;
3431ab64890Smrg
3441ab64890Smrg        for (j = 0; j < codeset->length; j++) {
345c555af55Smrg	    ch = *((const unsigned char *)(inbufptr + j));
3461ab64890Smrg	    byteM_rec = byteM[j];
3471ab64890Smrg	    byteinfo = byteM_rec.byteinfo;
3481ab64890Smrg
3491ab64890Smrg	    for (hit = False, k = 0; k < byteM_rec.byteinfo_num; k++) {
3501ab64890Smrg	        byteinfo_rec = byteinfo[k];
3511ab64890Smrg	        if (byteinfo_rec.start <= ch && ch <= byteinfo_rec.end) {
3521ab64890Smrg	            hit = True;
3531ab64890Smrg		    break;
3541ab64890Smrg                }
3551ab64890Smrg            }
3561ab64890Smrg
3571ab64890Smrg            if (!hit)
3581ab64890Smrg		break;
3591ab64890Smrg        }
3601ab64890Smrg
3611ab64890Smrg        if (hit)
3621ab64890Smrg	    return(codeset);
3631ab64890Smrg    }
3641ab64890Smrg
3651ab64890Smrg    return(NULL);
36661b2299dSmrg}
3671ab64890Smrg
3681ab64890Smrg#define GLGR_parse_codeset(ch) \
3691ab64890Smrg     (isrightside(ch) ? (state->GR_codeset) : \
3701ab64890Smrg                        (state->GL_codeset) )
3711ab64890Smrg
3721ab64890Smrgstatic XlcCharSet
3731ab64890Smrggi_parse_charset(
3741ab64890Smrg    unsigned long glyph_index,
3751ab64890Smrg    CodeSet codeset)
3761ab64890Smrg{
3771ab64890Smrg    int i;
3781ab64890Smrg    XlcCharSet *charset_list = codeset->charset_list;
3791ab64890Smrg    int num_charsets = codeset->num_charsets;
3801ab64890Smrg    ExtdSegment ctextseg = codeset->ctextseg;
3811ab64890Smrg    XlcCharSet charset = NULL;
3821ab64890Smrg    int area_num;
3831ab64890Smrg    FontScope area;
3841ab64890Smrg
3851ab64890Smrg    /* lockup ct sequence */
3861ab64890Smrg    for (i = 0; i < num_charsets; i++) {
3871ab64890Smrg	charset = charset_list[i];
3881ab64890Smrg        if (*charset->ct_sequence != '\0')
3891ab64890Smrg	    break;
3901ab64890Smrg    }
3911ab64890Smrg    if (i >= num_charsets)
3921ab64890Smrg	return(NULL);
3931ab64890Smrg
3941ab64890Smrg    if (charset->source != CSsrcStd)
3951ab64890Smrg        return (charset);
3961ab64890Smrg
3971ab64890Smrg    if (!ctextseg)
3981ab64890Smrg        return(charset);
3991ab64890Smrg
4001ab64890Smrg    area = ctextseg->area;
4011ab64890Smrg    area_num = ctextseg->area_num;
4021ab64890Smrg
4031ab64890Smrg    for (i = 0; i < area_num; i++) {
4041ab64890Smrg
4051ab64890Smrg        if (area[i].start <= glyph_index && glyph_index <= area[i].end) {
4061ab64890Smrg
4071ab64890Smrg	    charset = ctextseg->charset;
4081ab64890Smrg
4091ab64890Smrg            if (*charset->ct_sequence == '\0')
4101ab64890Smrg                return(NULL);
4111ab64890Smrg
4121ab64890Smrg	    break;
4131ab64890Smrg	}
4141ab64890Smrg    }
4151ab64890Smrg
4161ab64890Smrg    return(charset);
4171ab64890Smrg}
4181ab64890Smrg
4191ab64890Smrgstatic Bool
4201ab64890Smrgct_parse_csi(
4211ab64890Smrg    const char *inbufptr,
4221ab64890Smrg    int *ctr_seq_len)
4231ab64890Smrg{
4241ab64890Smrg    int i;
4251ab64890Smrg    int num = sizeof(directionality_data) / sizeof(directionality_data[0]);
4261ab64890Smrg
4271ab64890Smrg    for (i = 0; i < num; i++) {
4281ab64890Smrg	if ( !(*ctr_seq_len = strlen(directionality_data[i].encoding)) )
4291ab64890Smrg	    continue;
4301ab64890Smrg
43161b2299dSmrg	if ( strncmp(inbufptr, directionality_data[i].encoding,
4321ab64890Smrg						*ctr_seq_len) == 0)
4331ab64890Smrg            return(True);
4341ab64890Smrg    }
4351ab64890Smrg
4361ab64890Smrg    return(False);
4371ab64890Smrg}
4381ab64890Smrg
4391ab64890Smrgstatic int
4401ab64890Smrgcmp_esc_sequence(
4411ab64890Smrg    const char *inbufptr,
4421ab64890Smrg    XlcCharSet charset)
4431ab64890Smrg{
4441ab64890Smrg    int seq_len, name_len, total_len;
4451ab64890Smrg    unsigned char byte_m, byte_l;
4461ab64890Smrg    const char *ct_sequence =  charset->ct_sequence;
4471ab64890Smrg    const char *encoding_name = charset->encoding_name;
4481ab64890Smrg
4491ab64890Smrg    /* check esc sequence */
4501ab64890Smrg    if ( !(seq_len = strlen(ct_sequence) ) )
4511ab64890Smrg	return(0);
4521ab64890Smrg    if ( strncmp(inbufptr, ct_sequence, seq_len) != 0)
4531ab64890Smrg	return(0);
4541ab64890Smrg
4551ab64890Smrg    /* Standard Character Set Encoding ? */
4561ab64890Smrg    if (charset->source == CSsrcStd)
4571ab64890Smrg        return(seq_len);
4581ab64890Smrg
4591ab64890Smrg    /*
4601ab64890Smrg     *   Non-Standard Character Set Encoding
4611ab64890Smrg     *
4621ab64890Smrg     * +--- ---+-----+-----+-----+----   ----+-----+-----+-------   ------+
4631ab64890Smrg     * | ctseq |  M  |  L  |     encoding name     | STX |     contents   |
4641ab64890Smrg     * +--- ---+-----+-----+-----+----   ----+-----+-----+-------   ------+
4651ab64890Smrg     *  4bytes  1byte 1byte     variable length     1byte  variable length
4661ab64890Smrg     * 	                   |                                              |
4671ab64890Smrg     * 	                   +----------------------------------------------+
4681ab64890Smrg     * 	                     rest length  = ((M - 128) * 128) + (L - 128)
4691ab64890Smrg     */
4701ab64890Smrg
4711ab64890Smrg    /* get length of encoding name */
4721ab64890Smrg    inbufptr += seq_len;
4731ab64890Smrg    byte_m = *inbufptr++;
4741ab64890Smrg    byte_l = *inbufptr++;
4751ab64890Smrg    name_len = strlen(encoding_name);
4761ab64890Smrg
4771ab64890Smrg    if (((byte_m - 128) * 128 + (byte_l - 128) - 1) < name_len)
4781ab64890Smrg	return(0);
4791ab64890Smrg
4801ab64890Smrg    if ( _XlcNCompareISOLatin1(inbufptr, encoding_name, name_len) != 0 )
4811ab64890Smrg	return(0);
4821ab64890Smrg
4831ab64890Smrg    /* check STX (Start of Text) */
4841ab64890Smrg    inbufptr = inbufptr + name_len;
4851ab64890Smrg    if ( *inbufptr != STX )
4861ab64890Smrg	return(0);
4871ab64890Smrg
4881ab64890Smrg    total_len = seq_len + name_len + 3;
4891ab64890Smrg    return(total_len);
4901ab64890Smrg}
4911ab64890Smrg
4921ab64890Smrgstatic Bool
4931ab64890Smrgct_parse_charset(
4941ab64890Smrg    XLCd lcd,
4951ab64890Smrg    const char *inbufptr,
4961ab64890Smrg    XlcCharSet *charset,
4971ab64890Smrg    int *ctr_seq_len)
4981ab64890Smrg{
4991ab64890Smrg    int i, j;
5001ab64890Smrg    ExtdSegment ctextseg;
5011ab64890Smrg    int num_charsets;
5021ab64890Smrg    XlcCharSet *charset_list;
5031ab64890Smrg    CodeSet codeset;
5041ab64890Smrg    int codeset_num       = XLC_GENERIC(lcd, codeset_num);
5051ab64890Smrg    CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
5061ab64890Smrg    int segment_conv_num  = XLC_GENERIC(lcd, segment_conv_num);
5071ab64890Smrg    SegConv segment_conv  = XLC_GENERIC(lcd, segment_conv);
5081ab64890Smrg
5091ab64890Smrg    /* get charset from XLC_XLOCALE by escape sequence */
5101ab64890Smrg
5111ab64890Smrg    for (i = 0; i < codeset_num; i++) {
5121ab64890Smrg	codeset = codeset_list[i];
5131ab64890Smrg
5141ab64890Smrg	num_charsets = codeset->num_charsets;
5151ab64890Smrg	charset_list = codeset->charset_list;
5161ab64890Smrg	ctextseg     = codeset->ctextseg;
5171ab64890Smrg
5181ab64890Smrg	for (j = 0; j < num_charsets; j++) {
5191ab64890Smrg	    *charset = charset_list[j];
5201ab64890Smrg            if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
5211ab64890Smrg		return(True);
5221ab64890Smrg	}
5231ab64890Smrg
5241ab64890Smrg	if (ctextseg) {
5251ab64890Smrg	    *charset = ctextseg->charset;
5261ab64890Smrg            if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
5271ab64890Smrg		return(True);
5281ab64890Smrg	}
5291ab64890Smrg    }
5301ab64890Smrg
5311ab64890Smrg    /* get charset from XLC_SEGMENTCONVERSION by escape sequence */
5321ab64890Smrg
5331ab64890Smrg    if (!segment_conv)
5341ab64890Smrg	return(False);
5351ab64890Smrg
5361ab64890Smrg    for (i = 0; i < segment_conv_num; i++) {
5371ab64890Smrg	*charset = segment_conv[i].source;
5381ab64890Smrg        if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
5391ab64890Smrg	    return(True);
5401ab64890Smrg	*charset = segment_conv[i].dest;
5411ab64890Smrg        if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset)))
5421ab64890Smrg	    return(True);
5431ab64890Smrg    }
5441ab64890Smrg
5451ab64890Smrg    return(False);
5461ab64890Smrg}
5471ab64890Smrg
5481ab64890Smrgstatic Bool
5491ab64890Smrgsegment_conversion(
5501ab64890Smrg    XLCd lcd,
5511ab64890Smrg    XlcCharSet *charset,
5521ab64890Smrg    unsigned long *glyph_index)
5531ab64890Smrg{
5541ab64890Smrg    int i;
5551ab64890Smrg    int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num);
5561ab64890Smrg    SegConv segment_conv = XLC_GENERIC(lcd, segment_conv);
5571ab64890Smrg    FontScopeRec range;
5581ab64890Smrg    ConversionRec conv_rec;
5591ab64890Smrg
5601ab64890Smrg    if (!segment_conv)
5611ab64890Smrg	return(True);
5621ab64890Smrg
5631ab64890Smrg    for (i = 0; i < segment_conv_num; i++) {
5641ab64890Smrg	if (segment_conv[i].source == *charset)
5651ab64890Smrg	    break;
5661ab64890Smrg    }
5671ab64890Smrg
5681ab64890Smrg    if (i >= segment_conv_num)
5691ab64890Smrg	return(True);
5701ab64890Smrg
5711ab64890Smrg    range = segment_conv[i].range;
5721ab64890Smrg    if (*glyph_index < range.start || range.end < *glyph_index)
5731ab64890Smrg	return(True);
57461b2299dSmrg
5751ab64890Smrg    *charset = segment_conv[i].dest;
5761ab64890Smrg    conv_rec.conv_num = segment_conv[i].conv_num;
5771ab64890Smrg    conv_rec.convlist = segment_conv[i].conv;
5781ab64890Smrg    *glyph_index = conv_to_dest(&conv_rec, *glyph_index);
5791ab64890Smrg
5801ab64890Smrg    return(True);
5811ab64890Smrg}
5821ab64890Smrg
5831ab64890Smrgstatic CodeSet
5841ab64890Smrg_XlcGetCodeSetFromName(
5851ab64890Smrg    XLCd lcd,
5861ab64890Smrg    const char *name)
5871ab64890Smrg{
5881ab64890Smrg    int i, j;
5891ab64890Smrg    XlcCharSet charset;
5901ab64890Smrg    int num_charsets;
5911ab64890Smrg    XlcCharSet *charset_list;
5921ab64890Smrg    CodeSet codeset;
5931ab64890Smrg
5941ab64890Smrg    int codeset_num       = XLC_GENERIC(lcd, codeset_num);
5951ab64890Smrg    CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
5961ab64890Smrg
5971ab64890Smrg    for (i = 0; i < codeset_num; i++) {
5981ab64890Smrg        codeset = codeset_list[i];
5991ab64890Smrg
6001ab64890Smrg        num_charsets = codeset->num_charsets;
6011ab64890Smrg        charset_list = codeset->charset_list;
6021ab64890Smrg
6031ab64890Smrg        for (j = 0; j < num_charsets; j++) {
6041ab64890Smrg            charset = charset_list[j];
6051ab64890Smrg
6061ab64890Smrg            if (!strlen(charset->name))
6071ab64890Smrg                continue;
6081ab64890Smrg            if ( strcmp(charset->name, name) == 0)
6091ab64890Smrg                return(codeset);
6101ab64890Smrg        }
6111ab64890Smrg    }
6121ab64890Smrg
6131ab64890Smrg    return(NULL);
6141ab64890Smrg}
6151ab64890Smrg
6161ab64890Smrgstatic Bool
6171ab64890Smrg_XlcGetCodeSetFromCharSet(
6181ab64890Smrg    XLCd lcd,
6191ab64890Smrg    XlcCharSet charset,
6201ab64890Smrg    CodeSet *codeset,
6211ab64890Smrg    unsigned long *glyph_index)
6221ab64890Smrg{
6231ab64890Smrg    int j, num;
6241ab64890Smrg    CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
6251ab64890Smrg    XlcCharSet *charset_list;
6261ab64890Smrg    int codeset_num, num_charsets;
6271ab64890Smrg    Conversion ctconv;
6281ab64890Smrg    unsigned long glyph_index_tmp = 0;
6291ab64890Smrg    ExtdSegment ctextseg;
6301ab64890Smrg
6311ab64890Smrg    codeset_num = XLC_GENERIC(lcd, codeset_num);
6321ab64890Smrg
6331ab64890Smrg    for (num = 0 ; num < codeset_num; num++) {
6341ab64890Smrg        *codeset = codeset_list[num];
6351ab64890Smrg        ctconv = (*codeset)->ctconv;
6361ab64890Smrg	ctextseg = (*codeset)->ctextseg;
6371ab64890Smrg
6381ab64890Smrg        num_charsets = (*codeset)->num_charsets;
6391ab64890Smrg        charset_list = (*codeset)->charset_list;
6401ab64890Smrg
6411ab64890Smrg        glyph_index_tmp = conv_to_source(ctconv, *glyph_index);
6421ab64890Smrg
6431ab64890Smrg        if (charset->source == CSsrcStd) {
6441ab64890Smrg
6451ab64890Smrg            /* Standard Character Set Encoding */
6461ab64890Smrg	    if (glyph_index_tmp == *glyph_index) {
6471ab64890Smrg                for (j = 0; j < num_charsets; j++) {
6481ab64890Smrg                    if (charset_list[j] == charset) {
6491ab64890Smrg                        goto end_loop;
6501ab64890Smrg                    }
6511ab64890Smrg                }
6521ab64890Smrg            }
6531ab64890Smrg
6541ab64890Smrg	} else {
6551ab64890Smrg
6561ab64890Smrg            /* Non-Standard Character Set Encoding */
6571ab64890Smrg            for (j = 0; j < num_charsets; j++) {
6581ab64890Smrg                if (charset_list[j] == charset) {
6591ab64890Smrg                    goto end_loop;
6601ab64890Smrg                }
6611ab64890Smrg            }
6621ab64890Smrg
6631ab64890Smrg            if (glyph_index_tmp != *glyph_index) {
6641ab64890Smrg		if (ctextseg && ctextseg->charset == charset) {
6651ab64890Smrg		    goto end_loop;
6661ab64890Smrg                }
6671ab64890Smrg            }
6681ab64890Smrg
6691ab64890Smrg	}
6701ab64890Smrg
6711ab64890Smrg    }
6721ab64890Smrg
6731ab64890Smrgend_loop:
6741ab64890Smrg    if (num < codeset_num) {
6751ab64890Smrg	*glyph_index = glyph_index_tmp;
6761ab64890Smrg	return(True);
6771ab64890Smrg    }
6781ab64890Smrg
6791ab64890Smrg    return(False);
6801ab64890Smrg}
6811ab64890Smrg
6821ab64890Smrg#define check_string_encoding(codeset)	(codeset->string_encoding)
6831ab64890Smrg
6841ab64890Smrgstatic void
6851ab64890Smrgoutput_ulong_value(
6861ab64890Smrg    char *outbufptr,
6871ab64890Smrg    unsigned long code,
6881ab64890Smrg    int length,
6891ab64890Smrg    XlcSide side)
6901ab64890Smrg{
6911ab64890Smrg    int i;
6921ab64890Smrg
6931ab64890Smrg    for (i = (length - 1) * 8; i >= 0; i -= 8) {
6941ab64890Smrg	*outbufptr = ( code >> i) & 0xff;
6951ab64890Smrg
6961ab64890Smrg	if (side == XlcC0 || side == XlcGL) {
6971ab64890Smrg	    *outbufptr = *outbufptr & GL;
6981ab64890Smrg	} else if (side == XlcC1 || side == XlcGR) {
6991ab64890Smrg	    *outbufptr = *outbufptr | GR;
7001ab64890Smrg	}
7011ab64890Smrg
7021ab64890Smrg	outbufptr++;
7031ab64890Smrg    }
7041ab64890Smrg}
7051ab64890Smrg
7061ab64890Smrg/* -------------------------------------------------------------------------- */
7071ab64890Smrg/*				Init                                          */
7081ab64890Smrg/* -------------------------------------------------------------------------- */
7091ab64890Smrg
7101ab64890Smrgstatic XlcCharSet default_GL_charset = 0;
7111ab64890Smrgstatic XlcCharSet default_GR_charset = 0;
7121ab64890Smrg
7131ab64890Smrgstatic void
7141ab64890Smrginit_state(
7151ab64890Smrg    XlcConv conv)
7161ab64890Smrg{
7171ab64890Smrg    State state = (State) conv->state;
7181ab64890Smrg
7191ab64890Smrg    /* for CT */
7201ab64890Smrg    state->charset = NULL;
7211ab64890Smrg    state->GL_charset = default_GL_charset;
7221ab64890Smrg    state->GR_charset = default_GR_charset;
7231ab64890Smrg
7241ab64890Smrg    /* for MB shift state */
7251ab64890Smrg    state->GL_codeset = XLC_GENERIC(state->lcd, initial_state_GL);
7261ab64890Smrg    state->GR_codeset = XLC_GENERIC(state->lcd, initial_state_GR);
7271ab64890Smrg}
7281ab64890Smrg
7291ab64890Smrg/* -------------------------------------------------------------------------- */
7301ab64890Smrg/*				Convert                                       */
7311ab64890Smrg/* -------------------------------------------------------------------------- */
7321ab64890Smrg
7331ab64890Smrgstatic int
7341ab64890Smrgmbstowcs_org(
7351ab64890Smrg    XlcConv conv,
7361ab64890Smrg    XPointer *from,
7371ab64890Smrg    int *from_left,
7381ab64890Smrg    XPointer *to,
7391ab64890Smrg    int *to_left,
7401ab64890Smrg    XPointer *args,
7411ab64890Smrg    int num_args)
7421ab64890Smrg{
7431ab64890Smrg    State state = (State) conv->state;
7441ab64890Smrg    XLCd lcd = state->lcd;
7451ab64890Smrg
7461ab64890Smrg    unsigned char ch;
7471ab64890Smrg    unsigned long mb = 0;
7481ab64890Smrg    wchar_t wc;
7491ab64890Smrg
7501ab64890Smrg    int length = 0, len_left = 0;
7511ab64890Smrg    int unconv_num = 0;
7521ab64890Smrg    int num;
7531ab64890Smrg
7541ab64890Smrg    CodeSet codeset = NULL;
7551ab64890Smrg
756cf2acddeSmrg    const char *inbufptr;
7571ab64890Smrg    wchar_t *outbufptr = (wchar_t *) *to;
7581ab64890Smrg    int from_size = *from_left;
7591ab64890Smrg
7601ab64890Smrg    unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
7611ab64890Smrg
7621ab64890Smrg    if (from == NULL || *from == NULL) {
7631ab64890Smrg	_XlcResetConverter(conv);
7641ab64890Smrg        return( 0 );
7651ab64890Smrg    }
7661ab64890Smrg
767cf2acddeSmrg    inbufptr = *from;
768cf2acddeSmrg
7691ab64890Smrg    while (*from_left && *to_left) {
7701ab64890Smrg
7711ab64890Smrg	ch = *inbufptr++;
7721ab64890Smrg	(*from_left)--;
7731ab64890Smrg
7741ab64890Smrg	/* null ? */
7751ab64890Smrg	if (!ch) {
7761ab64890Smrg            if (outbufptr) {*outbufptr++ = L'\0';}
7771ab64890Smrg	    (*to_left)--;
7781ab64890Smrg
7791ab64890Smrg	    /* error check */
7801ab64890Smrg            if (len_left) {
7811ab64890Smrg	        unconv_num += (length - len_left);
7821ab64890Smrg		len_left = 0;
7831ab64890Smrg            }
7841ab64890Smrg
7851ab64890Smrg	    continue;
7861ab64890Smrg	}
7871ab64890Smrg
7881ab64890Smrg	/* same mb char data */
7891ab64890Smrg        if (len_left)
7901ab64890Smrg	    goto output_one_wc;
7911ab64890Smrg
7921ab64890Smrg        /* next mb char data for single shift ? */
7931ab64890Smrg	if (mb_parse_table && (num = mb_parse_table[ch]) ) {
7941ab64890Smrg	    codeset = mb_parse_codeset(state, num, &inbufptr, from_left);
7951ab64890Smrg            if (codeset != NULL) {
7961ab64890Smrg		length = len_left = codeset->length;
7971ab64890Smrg		mb = 0;
7981ab64890Smrg		continue;
7991ab64890Smrg	    }
8001ab64890Smrg        }
80161b2299dSmrg
8021ab64890Smrg	/* next mb char data for byteM ? */
8031ab64890Smrg	if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1))))
8041ab64890Smrg	    goto next_mb_char;
8051ab64890Smrg
8061ab64890Smrg	/* next mb char data for GL or GR side ? */
8071ab64890Smrg	if ((codeset = GLGR_parse_codeset(ch)))
8081ab64890Smrg	    goto next_mb_char;
80961b2299dSmrg
8101ab64890Smrg        /* can't find codeset for the ch */
8111ab64890Smrg        unconv_num++;
8121ab64890Smrg        continue;
8131ab64890Smrg
8141ab64890Smrgnext_mb_char:
8151ab64890Smrg        length = len_left = codeset->length;
8161ab64890Smrg	mb = 0;
8171ab64890Smrg
8181ab64890Smrgoutput_one_wc:
8191ab64890Smrg	mb = (mb << 8) | ch;  /* 1 byte left shift */
8201ab64890Smrg	len_left--;
8211ab64890Smrg
8221ab64890Smrg        /* last of one mb char data */
8231ab64890Smrg        if (!len_left) {
8241ab64890Smrg            gi_to_wc(lcd, mb_to_gi(mb, codeset), codeset, &wc);
8251ab64890Smrg            if (outbufptr) {*outbufptr++ = wc;}
8261ab64890Smrg	    (*to_left)--;
8271ab64890Smrg        }
8281ab64890Smrg
8291ab64890Smrg    } /* end of while */
8301ab64890Smrg
8311ab64890Smrg    /* error check on last char */
8321ab64890Smrg    if (len_left) {
8331ab64890Smrg	inbufptr -= (length - len_left);
8341ab64890Smrg	(*from_left) += (length - len_left);
8351ab64890Smrg	unconv_num += (length - len_left);
8361ab64890Smrg    }
8371ab64890Smrg
8381ab64890Smrg    *from = (XPointer) ((const char *) *from + from_size);
8391ab64890Smrg    *from_left = 0;
8401ab64890Smrg    *to = (XPointer) outbufptr;
8411ab64890Smrg
8421ab64890Smrg    return unconv_num;
8431ab64890Smrg}
8441ab64890Smrg
8451ab64890Smrgstatic int
8461ab64890Smrgstdc_mbstowcs(
8471ab64890Smrg    XlcConv conv,
8481ab64890Smrg    XPointer *from,
8491ab64890Smrg    int *from_left,
8501ab64890Smrg    XPointer *to,
8511ab64890Smrg    int *to_left,
8521ab64890Smrg    XPointer *args,
8531ab64890Smrg    int num_args)
8541ab64890Smrg{
8551ab64890Smrg    const char *src = *((const char **) from);
8561ab64890Smrg    wchar_t *dst = *((wchar_t **) to);
8571ab64890Smrg    int src_left = *from_left;
8581ab64890Smrg    int dst_left = *to_left;
8591ab64890Smrg    int length, unconv_num = 0;
8601ab64890Smrg
8611ab64890Smrg    while (src_left > 0 && dst_left > 0) {
8621ab64890Smrg	length = mbtowc(dst, src, src_left);
8631ab64890Smrg
8641ab64890Smrg	if (length > 0) {
8651ab64890Smrg	    src += length;
8661ab64890Smrg	    src_left -= length;
8671ab64890Smrg	    if (dst)
8681ab64890Smrg	        dst++;
8691ab64890Smrg	    dst_left--;
8701ab64890Smrg	} else if (length < 0) {
8711ab64890Smrg	    src++;
8721ab64890Smrg	    src_left--;
8731ab64890Smrg	    unconv_num++;
8741ab64890Smrg        } else {
8751ab64890Smrg            /* null ? */
8761ab64890Smrg            src++;
8771ab64890Smrg            src_left--;
87861b2299dSmrg            if (dst)
8791ab64890Smrg                *dst++ = L'\0';
8801ab64890Smrg            dst_left--;
8811ab64890Smrg        }
8821ab64890Smrg    }
8831ab64890Smrg
8841ab64890Smrg    *from = (XPointer) src;
8851ab64890Smrg    if (dst)
8861ab64890Smrg	*to = (XPointer) dst;
8871ab64890Smrg    *from_left = src_left;
8881ab64890Smrg    *to_left = dst_left;
8891ab64890Smrg
8901ab64890Smrg    return unconv_num;
8911ab64890Smrg}
8921ab64890Smrg
8931ab64890Smrgstatic int
8941ab64890Smrgwcstombs_org(
8951ab64890Smrg    XlcConv conv,
8961ab64890Smrg    XPointer *from,
8971ab64890Smrg    int *from_left,
8981ab64890Smrg    XPointer *to,
8991ab64890Smrg    int *to_left,
9001ab64890Smrg    XPointer *args,
9011ab64890Smrg    int num_args)
9021ab64890Smrg{
9031ab64890Smrg    State state = (State) conv->state;
9041ab64890Smrg    XLCd lcd = state->lcd;
9051ab64890Smrg
9061ab64890Smrg    char *encoding;
9071ab64890Smrg    unsigned long mb, glyph_index;
9081ab64890Smrg    wchar_t wc;
9091ab64890Smrg
9101ab64890Smrg    int length;
9111ab64890Smrg    int unconv_num = 0;
9121ab64890Smrg
9131ab64890Smrg    CodeSet codeset;
9141ab64890Smrg
9151ab64890Smrg    const wchar_t *inbufptr = (const wchar_t *) *from;
9161ab64890Smrg    char *outbufptr = *to;
9171ab64890Smrg    int from_size = *from_left;
91861b2299dSmrg
9191ab64890Smrg    const char *default_string = XLC_PUBLIC(lcd, default_string);
9201ab64890Smrg    int defstr_len = strlen(default_string);
9211ab64890Smrg
9221ab64890Smrg
9231ab64890Smrg    while (*from_left && *to_left) {
9241ab64890Smrg
9251ab64890Smrg        wc = *inbufptr++;
9261ab64890Smrg        (*from_left)--;
9271ab64890Smrg
9281ab64890Smrg        /* null ? */
9291ab64890Smrg        if (!wc) {
9301ab64890Smrg            if (outbufptr) {*outbufptr++ = '\0';}
9311ab64890Smrg            (*to_left)--;
9321ab64890Smrg
9331ab64890Smrg            continue;
9341ab64890Smrg        }
9351ab64890Smrg
9361ab64890Smrg        /* convert */
9371ab64890Smrg	if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
9381ab64890Smrg
9391ab64890Smrg	    /* output default_string of XDefaultString() */
9401ab64890Smrg            if (*to_left < defstr_len)
9411ab64890Smrg		break;
9421ab64890Smrg	    if (outbufptr) {
9431ab64890Smrg                strncpy((char *)outbufptr, default_string, defstr_len);
9441ab64890Smrg                outbufptr += defstr_len;
9451ab64890Smrg            }
9461ab64890Smrg	    (*to_left) -= defstr_len;
9471ab64890Smrg
9481ab64890Smrg            unconv_num++;
9491ab64890Smrg
9501ab64890Smrg        } else {
9511ab64890Smrg            mb = gi_to_mb(glyph_index, codeset);
9521ab64890Smrg	    if (codeset->parse_info) {
9531ab64890Smrg                Bool need_shift = False;
9541ab64890Smrg                switch (codeset->parse_info->type) {
9551ab64890Smrg                    case E_LSL :
9561ab64890Smrg                        if (codeset != state->GL_codeset) {
9571ab64890Smrg                            need_shift = True;
9581ab64890Smrg                            state->GL_codeset = codeset;
9591ab64890Smrg                        }
9601ab64890Smrg                        break;
9611ab64890Smrg                    case E_LSR :
9621ab64890Smrg                        if (codeset != state->GR_codeset) {
9631ab64890Smrg                            need_shift = True;
9641ab64890Smrg                            state->GR_codeset = codeset;
9651ab64890Smrg                        }
9661ab64890Smrg                        break;
9671ab64890Smrg                    /* case E_SS */
9681ab64890Smrg                    default:
9691ab64890Smrg                        need_shift = True;
9701ab64890Smrg                }
9711ab64890Smrg
9721ab64890Smrg		/* output shift sequence */
9731ab64890Smrg                if (need_shift) {
9741ab64890Smrg		    encoding = codeset->parse_info->encoding;
9751ab64890Smrg                    length = strlen(encoding);
9761ab64890Smrg                    if (*to_left < length)
9771ab64890Smrg		        break;
9781ab64890Smrg	            if (outbufptr) {
9791ab64890Smrg                        strncpy((char *)outbufptr, encoding, length);
9801ab64890Smrg	                outbufptr += length;
9811ab64890Smrg                    }
9821ab64890Smrg	            (*to_left) -= length;
9831ab64890Smrg                }
9841ab64890Smrg            }
9851ab64890Smrg
9861ab64890Smrg            /* output characters */
9871ab64890Smrg	    length = codeset->length;
9881ab64890Smrg            if (*to_left < length)
9891ab64890Smrg		break;
9901ab64890Smrg
9911ab64890Smrg	    if (outbufptr) {
9921ab64890Smrg		output_ulong_value(outbufptr, mb, length, XlcNONE);
9931ab64890Smrg	        outbufptr += length;
9941ab64890Smrg	    }
9951ab64890Smrg
9961ab64890Smrg	    (*to_left) -= length;
9971ab64890Smrg        }
9981ab64890Smrg
9991ab64890Smrg    } /* end of while */
10001ab64890Smrg
10011ab64890Smrg    *from = (XPointer) ((const wchar_t *) *from + from_size);
10021ab64890Smrg    *from_left = 0;
10031ab64890Smrg    *to = (XPointer) outbufptr;
10041ab64890Smrg
10051ab64890Smrg    return unconv_num;
10061ab64890Smrg}
10071ab64890Smrg
10081ab64890Smrgstatic int
10091ab64890Smrgstdc_wcstombs(
10101ab64890Smrg    XlcConv conv,
10111ab64890Smrg    XPointer *from,
10121ab64890Smrg    int *from_left,
10131ab64890Smrg    XPointer *to,
10141ab64890Smrg    int *to_left,
10151ab64890Smrg    XPointer *args,
10161ab64890Smrg    int num_args)
10171ab64890Smrg{
10181ab64890Smrg    const wchar_t *src = *((const wchar_t **) from);
10191ab64890Smrg    char *dst = *((char **) to);
10201ab64890Smrg    int src_left = *from_left;
10211ab64890Smrg    int dst_left = *to_left;
10221ab64890Smrg    int length, unconv_num = 0;
10231ab64890Smrg
10241ab64890Smrg    while (src_left > 0 && dst_left >= MB_CUR_MAX) {
10251ab64890Smrg	length = wctomb(dst, *src);		/* XXX */
10261ab64890Smrg
10271ab64890Smrg        if (length > 0) {
10281ab64890Smrg	    src++;
10291ab64890Smrg	    src_left--;
103061b2299dSmrg	    if (dst)
10311ab64890Smrg		dst += length;
10321ab64890Smrg	    dst_left -= length;
10331ab64890Smrg	} else if (length < 0) {
10341ab64890Smrg	    src++;
10351ab64890Smrg	    src_left--;
10361ab64890Smrg	    unconv_num++;
103761b2299dSmrg	}
10381ab64890Smrg    }
10391ab64890Smrg
10401ab64890Smrg    *from = (XPointer) src;
10411ab64890Smrg    if (dst)
10421ab64890Smrg      *to = (XPointer) dst;
10431ab64890Smrg    *from_left = src_left;
10441ab64890Smrg    *to_left = dst_left;
10451ab64890Smrg
10461ab64890Smrg    return unconv_num;
10471ab64890Smrg}
10481ab64890Smrg
10491ab64890Smrgstatic int
10501ab64890Smrgwcstocts(
10511ab64890Smrg    XlcConv conv,
10521ab64890Smrg    XPointer *from,
10531ab64890Smrg    int *from_left,
10541ab64890Smrg    XPointer *to,
10551ab64890Smrg    int *to_left,
10561ab64890Smrg    XPointer *args,
10571ab64890Smrg    int num_args)
10581ab64890Smrg{
10591ab64890Smrg    State state = (State) conv->state;
10601ab64890Smrg    XLCd lcd = state->lcd;
10611ab64890Smrg
10621ab64890Smrg    unsigned long glyph_index;
10631ab64890Smrg    wchar_t wc;
10641ab64890Smrg
10651ab64890Smrg    int total_len, seq_len, name_len;
10661ab64890Smrg    int unconv_num = 0;
10671ab64890Smrg    Bool first_flag = True, standard_flag;
10681ab64890Smrg    XlcSide side;
10691ab64890Smrg
10701ab64890Smrg    CodeSet codeset;
10711ab64890Smrg    XlcCharSet charset, old_charset = NULL;
10721ab64890Smrg    const char *ct_sequence;
10731ab64890Smrg
10741ab64890Smrg    const wchar_t *inbufptr = (const wchar_t *) *from;
10751ab64890Smrg    char *outbufptr = *to;
10761ab64890Smrg    int from_size = *from_left;
10771ab64890Smrg    char *ext_seg_len = NULL;
10781ab64890Smrg
10791ab64890Smrg    while (*from_left && *to_left) {
10801ab64890Smrg
10811ab64890Smrg        wc = *inbufptr++;
10821ab64890Smrg        (*from_left)--;
10831ab64890Smrg
10841ab64890Smrg        /* null ? */
10851ab64890Smrg        if (!wc) {
10861ab64890Smrg            if (outbufptr) {*outbufptr++ = '\0';}
10871ab64890Smrg            (*to_left)--;
10881ab64890Smrg
10891ab64890Smrg            continue;
10901ab64890Smrg        }
10911ab64890Smrg
10921ab64890Smrg        /* convert */
10931ab64890Smrg	if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
10941ab64890Smrg            unconv_num++;
10951ab64890Smrg	    continue;
10961ab64890Smrg        }
10971ab64890Smrg
10981ab64890Smrg        /* parse charset */
10991ab64890Smrg        if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) {
11001ab64890Smrg            unconv_num++;
11011ab64890Smrg	    continue;
11021ab64890Smrg        }
11031ab64890Smrg
11041ab64890Smrg        /* Standard Character Set Encoding ? */
11051ab64890Smrg	standard_flag = charset->source == CSsrcStd ? True : False;
11061ab64890Smrg
11071ab64890Smrg        /*
11081ab64890Smrg         *   Non-Standard Character Set Encoding
11091ab64890Smrg         *
11101ab64890Smrg         * +-----+-----+-----+-----+-----+-----+-----+----   ----+-----+-----+
11111ab64890Smrg         * |     esc sequence      |  M  |  L  |     encoding name     | STX |
11121ab64890Smrg         * +-----+-----+-----+-----+-----+-----+-----+----   ----+-----+-----+
111361b2299dSmrg         *           4bytes         1byte 1byte     variable length     1byte
11141ab64890Smrg         * 	                   |                                         |
11151ab64890Smrg         * 	                   +-----------------------------------------+
11161ab64890Smrg         * 	                     name length  = ((M - 128) * 128) + (L - 128)
11171ab64890Smrg         */
11181ab64890Smrg
11191ab64890Smrg        /* make encoding data */
11201ab64890Smrg	ct_sequence = charset->ct_sequence;
11211ab64890Smrg	side = charset->side;
11221ab64890Smrg        seq_len = strlen(ct_sequence);
11231ab64890Smrg	if (standard_flag) {
11241ab64890Smrg            name_len = 0;
11251ab64890Smrg	    total_len = seq_len;
11261ab64890Smrg	} else {
11271ab64890Smrg            name_len = strlen(charset->encoding_name) + 1;
11281ab64890Smrg	    total_len = seq_len + name_len + 2;
11291ab64890Smrg	}
11301ab64890Smrg
11311ab64890Smrg        /* output escape sequence of CT */
11321ab64890Smrg	if ( (charset != old_charset) &&
11331ab64890Smrg	    !(first_flag && charset->string_encoding) ){
11341ab64890Smrg
11351ab64890Smrg            if ( (ext_seg_len != NULL) && outbufptr) {
11361ab64890Smrg                int i = (outbufptr - ext_seg_len) - 2;
11371ab64890Smrg                *ext_seg_len++ = i / 128 + 128;
11381ab64890Smrg                *ext_seg_len   = i % 128 + 128;
11391ab64890Smrg                ext_seg_len = NULL;
11401ab64890Smrg            }
114161b2299dSmrg
11421ab64890Smrg	    if (*to_left < total_len + 1) {
11431ab64890Smrg                unconv_num++;
11441ab64890Smrg	        break;
11451ab64890Smrg	    }
11461ab64890Smrg
11471ab64890Smrg	    if (outbufptr) {
11481ab64890Smrg	        strcpy((char *)outbufptr, ct_sequence);
11491ab64890Smrg		outbufptr += seq_len;
11501ab64890Smrg
11511ab64890Smrg                if (!standard_flag) {
11521ab64890Smrg                    const char *i = charset->encoding_name;
11531ab64890Smrg                    ext_seg_len = outbufptr;
11541ab64890Smrg                    outbufptr += 2;
11551ab64890Smrg	            for (; *i ; i++)
11561ab64890Smrg                        *outbufptr++ = ((*i >= 'A') && (*i <= 'Z')) ?
11571ab64890Smrg                                       *i - 'A' + 'a' : *i;
11581ab64890Smrg		    *outbufptr++ = STX;
11591ab64890Smrg                }
11601ab64890Smrg	    }
11611ab64890Smrg
11621ab64890Smrg	    (*to_left) -= total_len;
11631ab64890Smrg
11641ab64890Smrg	    first_flag = False;
11651ab64890Smrg	    old_charset = charset;
11661ab64890Smrg	}
11671ab64890Smrg
11681ab64890Smrg        /* output glyph index */
11691ab64890Smrg	if (codeset->ctconv)
11701ab64890Smrg            glyph_index = conv_to_dest(codeset->ctconv, glyph_index);
11711ab64890Smrg        if (*to_left < charset->char_size) {
11721ab64890Smrg            unconv_num++;
11731ab64890Smrg	    break;
11741ab64890Smrg        }
11751ab64890Smrg
11761ab64890Smrg	if (outbufptr) {
11771ab64890Smrg	   output_ulong_value(outbufptr, glyph_index, charset->char_size, side);
11781ab64890Smrg	   outbufptr += charset->char_size;
11791ab64890Smrg	}
11801ab64890Smrg
11811ab64890Smrg	(*to_left) -= charset->char_size;
11821ab64890Smrg
11831ab64890Smrg    } /* end of while */
11841ab64890Smrg
11851ab64890Smrg    if ( (ext_seg_len != NULL) && outbufptr) {
11861ab64890Smrg        int i = (outbufptr - ext_seg_len) - 2;
11871ab64890Smrg        *ext_seg_len++ = i / 128 + 128;
11881ab64890Smrg        *ext_seg_len   = i % 128 + 128;
11891ab64890Smrg    }
11901ab64890Smrg
11911ab64890Smrg    *from = (XPointer) ((const wchar_t *) *from + from_size);
11921ab64890Smrg    *from_left = 0;
11931ab64890Smrg    *to = (XPointer) outbufptr;
11941ab64890Smrg
11951ab64890Smrg    return unconv_num;
11961ab64890Smrg}
11971ab64890Smrg
11981ab64890Smrgstatic int
11991ab64890Smrgstdc_wcstocts(
12001ab64890Smrg    XlcConv conv,
12011ab64890Smrg    XPointer *from,
12021ab64890Smrg    int *from_left,
12031ab64890Smrg    XPointer *to,
12041ab64890Smrg    int *to_left,
12051ab64890Smrg    XPointer *args,
12061ab64890Smrg    int num_args)
12071ab64890Smrg{
12081ab64890Smrg    XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
12091ab64890Smrg    char *buf_ptr1 = buf;
12101ab64890Smrg    int buf_left1 = (*from_left) * MB_CUR_MAX;
12111ab64890Smrg    char *buf_ptr2 = buf_ptr1;
12121ab64890Smrg    int buf_left2;
12131ab64890Smrg    int unconv_num1 = 0, unconv_num2 = 0;
12141ab64890Smrg
121561b2299dSmrg    unconv_num1 = stdc_wcstombs(conv,
12161ab64890Smrg		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
12171ab64890Smrg    if (unconv_num1 < 0)
12181ab64890Smrg        goto ret;
12191ab64890Smrg
12201ab64890Smrg    buf_left2 = buf_ptr1 - buf_ptr2;
12211ab64890Smrg
122261b2299dSmrg    unconv_num2 = mbstocts(conv,
12231ab64890Smrg		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
12241ab64890Smrg    if (unconv_num2 < 0)
12251ab64890Smrg        goto ret;
12261ab64890Smrg
12271ab64890Smrgret:
1228cf2acddeSmrg    Xfree(buf);
12291ab64890Smrg
12301ab64890Smrg    return (unconv_num1 + unconv_num2);
12311ab64890Smrg}
12321ab64890Smrg
12331ab64890Smrgstatic int
12341ab64890Smrgctstowcs(
12351ab64890Smrg    XlcConv conv,
12361ab64890Smrg    XPointer *from,
12371ab64890Smrg    int *from_left,
12381ab64890Smrg    XPointer *to,
12391ab64890Smrg    int *to_left,
12401ab64890Smrg    XPointer *args,
12411ab64890Smrg    int num_args)
12421ab64890Smrg{
12431ab64890Smrg    State state = (State) conv->state;
12441ab64890Smrg    XLCd lcd = state->lcd;
12451ab64890Smrg
12461ab64890Smrg    unsigned char ch;
12471ab64890Smrg    unsigned long glyph_index = 0;
12481ab64890Smrg    wchar_t wc;
12491ab64890Smrg
12501ab64890Smrg    int ctr_seq_len = 0, gi_len_left = 0, gi_len = 0;
12511ab64890Smrg    int unconv_num = 0;
12521ab64890Smrg
12531ab64890Smrg    CodeSet codeset = NULL;
12541ab64890Smrg    XlcCharSet charset_tmp;
12551ab64890Smrg
1256cf2acddeSmrg    const char *inbufptr;
12571ab64890Smrg    wchar_t *outbufptr = (wchar_t *) *to;
12581ab64890Smrg    int from_size = *from_left;
12591ab64890Smrg
12601ab64890Smrg    _XlcResetConverter(conv); /* ??? */
12611ab64890Smrg
12621ab64890Smrg    if (from == NULL || *from == NULL) {
12631ab64890Smrg	_XlcResetConverter(conv);
12641ab64890Smrg        return( 0 );
12651ab64890Smrg    }
1266cf2acddeSmrg    inbufptr = *from;
12671ab64890Smrg
12681ab64890Smrg    while (*from_left && *to_left) {
12691ab64890Smrg
12701ab64890Smrg	ch = *inbufptr++;
12711ab64890Smrg	(*from_left)--;
12721ab64890Smrg
12731ab64890Smrg	/* null ? */
12741ab64890Smrg	if (!ch) {
12751ab64890Smrg            if (outbufptr) {*outbufptr++ = L'\0';}
12761ab64890Smrg	    (*to_left)--;
12771ab64890Smrg
12781ab64890Smrg	    /* error check */
12791ab64890Smrg            if (gi_len_left) {
12801ab64890Smrg	        unconv_num += (gi_len - gi_len_left);
12811ab64890Smrg		gi_len_left = 0;
12821ab64890Smrg            }
12831ab64890Smrg
12841ab64890Smrg	    continue;
12851ab64890Smrg	}
12861ab64890Smrg
12871ab64890Smrg	/* same glyph_index data */
12881ab64890Smrg        if (gi_len_left)
12891ab64890Smrg	    goto output_one_wc;
12901ab64890Smrg
12911ab64890Smrg        /* control sequence ? */
12921ab64890Smrg        if (ch == CSI) {
12931ab64890Smrg            if ( !ct_parse_csi(inbufptr - 1, &ctr_seq_len) )
12941ab64890Smrg	        goto skip_the_seg;
12951ab64890Smrg
12961ab64890Smrg	    if (*from_left + 1 < ctr_seq_len) {
12971ab64890Smrg		inbufptr--;
12981ab64890Smrg		(*from_left)++;
12991ab64890Smrg		unconv_num += *from_left;
13001ab64890Smrg		break;
13011ab64890Smrg	    }
13021ab64890Smrg
13031ab64890Smrg            /* skip the control sequence */
13041ab64890Smrg	    inbufptr += (ctr_seq_len - 1);
13051ab64890Smrg	    *from_left -= (ctr_seq_len - 1);
13061ab64890Smrg
13071ab64890Smrg            continue;
13081ab64890Smrg	}
13091ab64890Smrg
13101ab64890Smrg        /* escape sequence ? */
13111ab64890Smrg        if (ch == ESC) {
131261b2299dSmrg	    if ( !ct_parse_charset(lcd,
13131ab64890Smrg			inbufptr - 1, &state->charset, &ctr_seq_len) )
13141ab64890Smrg		goto skip_the_seg;
13151ab64890Smrg
131661b2299dSmrg	    if (state->charset->side == XlcC0 ||
13171ab64890Smrg		state->charset->side == XlcGL)
13181ab64890Smrg	      {
13191ab64890Smrg		state->GL_charset = state->charset;
13201ab64890Smrg	      }
132161b2299dSmrg	    else if (state->charset->side == XlcC1 ||
13221ab64890Smrg		     state->charset->side == XlcGR)
13231ab64890Smrg	      {
13241ab64890Smrg		state->GR_charset = state->charset;
132561b2299dSmrg	      }
13261ab64890Smrg	    else if (state->charset->side == XlcGLGR)
13271ab64890Smrg	      {
13281ab64890Smrg		state->GL_charset = state->charset;
13291ab64890Smrg		state->GR_charset = state->charset;
133061b2299dSmrg	      }
13311ab64890Smrg
13321ab64890Smrg	    if (*from_left + 1 < ctr_seq_len) {
13331ab64890Smrg		inbufptr--;
13341ab64890Smrg		(*from_left)++;
13351ab64890Smrg		unconv_num += *from_left;
13361ab64890Smrg		break;
13371ab64890Smrg	    }
13381ab64890Smrg
13391ab64890Smrg            /* skip the escape sequence */
13401ab64890Smrg	    inbufptr += (ctr_seq_len - 1);
13411ab64890Smrg	    *from_left -= (ctr_seq_len - 1);
13421ab64890Smrg
13431ab64890Smrg            continue;
134461b2299dSmrg        }
13451ab64890Smrg
13461ab64890Smrg 	/* check current state */
13471ab64890Smrg	if (isleftside(ch))
13481ab64890Smrg	  state->charset = state->GL_charset;
13491ab64890Smrg	else
13501ab64890Smrg	  state->charset = state->GR_charset;
13511ab64890Smrg
13521ab64890Smrg	gi_len = gi_len_left = state->charset->char_size;
13531ab64890Smrg	glyph_index = 0;
13541ab64890Smrg
13551ab64890Smrgoutput_one_wc:
13561ab64890Smrg        if (state->charset->side == XlcC1 || state->charset->side == XlcGR)
13571ab64890Smrg            glyph_index = (glyph_index << 8) | (ch & GL);
13581ab64890Smrg        else
13591ab64890Smrg            glyph_index = (glyph_index << 8) | ch;
13601ab64890Smrg
13611ab64890Smrg	gi_len_left--;
13621ab64890Smrg
13631ab64890Smrg        /* last of one glyph_index data */
13641ab64890Smrg        if (!gi_len_left) {
13651ab64890Smrg
13661ab64890Smrg	    /* segment conversion */
13671ab64890Smrg	    charset_tmp = state->charset;
13681ab64890Smrg	    segment_conversion(lcd, &charset_tmp, &glyph_index);
13691ab64890Smrg
13701ab64890Smrg            /* get codeset */
137161b2299dSmrg            if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp,
13721ab64890Smrg						&codeset, &glyph_index) ) {
13731ab64890Smrg		unconv_num += gi_len;
13741ab64890Smrg		continue;
13751ab64890Smrg            }
13761ab64890Smrg
13771ab64890Smrg            /* convert glyph index to wicd char */
13781ab64890Smrg            gi_to_wc(lcd, glyph_index, codeset, &wc);
13791ab64890Smrg            if (outbufptr) {*outbufptr++ = wc;}
13801ab64890Smrg	    (*to_left)--;
13811ab64890Smrg        }
13821ab64890Smrg
13831ab64890Smrg        continue;
13841ab64890Smrg
13851ab64890Smrgskip_the_seg:
13861ab64890Smrg	/* skip until next escape or control sequence */
13871ab64890Smrg        while ( *from_left ) {
13881ab64890Smrg	    ch = *inbufptr++;
13891ab64890Smrg	    (*from_left)--;
13901ab64890Smrg	    unconv_num++;
13911ab64890Smrg
13921ab64890Smrg            if (ch == ESC || ch == CSI) {
13931ab64890Smrg		inbufptr--;
13941ab64890Smrg		(*from_left)++;
13951ab64890Smrg		unconv_num--;
13961ab64890Smrg		break;
13971ab64890Smrg	    }
13981ab64890Smrg        }
13991ab64890Smrg
14001ab64890Smrg        if ( !(*from_left) )
14011ab64890Smrg	    break;
14021ab64890Smrg
14031ab64890Smrg    } /* end of while */
14041ab64890Smrg
14051ab64890Smrg    /* error check on last char */
14061ab64890Smrg    if (gi_len_left) {
14071ab64890Smrg	inbufptr -= (gi_len - gi_len_left);
14081ab64890Smrg	(*from_left) += (gi_len - gi_len_left);
14091ab64890Smrg	unconv_num += (gi_len - gi_len_left);
14101ab64890Smrg    }
14111ab64890Smrg
14121ab64890Smrg    *from = (XPointer) ((const char *) *from + from_size);
14131ab64890Smrg    *from_left = 0;
14141ab64890Smrg    *to = (XPointer) outbufptr;
14151ab64890Smrg
14161ab64890Smrg    return unconv_num;
14171ab64890Smrg}
14181ab64890Smrg
14191ab64890Smrgstatic int
14201ab64890Smrgcstowcs(
14211ab64890Smrg    XlcConv conv,
14221ab64890Smrg    XPointer *from,
14231ab64890Smrg    int *from_left,
14241ab64890Smrg    XPointer *to,
14251ab64890Smrg    int *to_left,
14261ab64890Smrg    XPointer *args,
14271ab64890Smrg    int num_args)
14281ab64890Smrg{
14291ab64890Smrg    State state = (State) conv->state;
14301ab64890Smrg    XLCd lcd = state->lcd;
14311ab64890Smrg
14321ab64890Smrg    unsigned char ch;
14331ab64890Smrg    unsigned long glyph_index = 0;
14341ab64890Smrg    wchar_t wc;
14351ab64890Smrg    int gi_len_left = 0, gi_len = 0;
14361ab64890Smrg
14371ab64890Smrg    int unconv_num = 0;
14381ab64890Smrg
14391ab64890Smrg    CodeSet codeset = NULL;
14401ab64890Smrg    XlcCharSet charset, charset_tmp;
14411ab64890Smrg
1442cf2acddeSmrg    const char *inbufptr;
14431ab64890Smrg    wchar_t *outbufptr = (wchar_t *) *to;
14441ab64890Smrg    int from_size = *from_left;
14451ab64890Smrg
14461ab64890Smrg    if (from == NULL || *from == NULL) {
14471ab64890Smrg        return( 0 );
14481ab64890Smrg    }
14491ab64890Smrg
1450cf2acddeSmrg    inbufptr = *from;
1451cf2acddeSmrg
14521ab64890Smrg    charset = (XlcCharSet) args[0];
14531ab64890Smrg
14541ab64890Smrg    while (*from_left && *to_left) {
14551ab64890Smrg
14561ab64890Smrg        if (!gi_len_left) {
14571ab64890Smrg            gi_len_left = gi_len = charset->char_size;
14581ab64890Smrg            glyph_index = 0;
14591ab64890Smrg        }
14601ab64890Smrg
14611ab64890Smrg	ch = *inbufptr++;
14621ab64890Smrg	(*from_left)--;
14631ab64890Smrg
14641ab64890Smrg	/* null ? */
14651ab64890Smrg	if (!ch) {
14661ab64890Smrg            if (outbufptr) {*outbufptr++ = L'\0';}
14671ab64890Smrg	    (*to_left)--;
14681ab64890Smrg
14691ab64890Smrg	    /* error check */
14701ab64890Smrg            if (gi_len_left) {
14711ab64890Smrg	        unconv_num += (gi_len - gi_len_left);
14721ab64890Smrg		gi_len_left = 0;
14731ab64890Smrg            }
14741ab64890Smrg	    continue;
14751ab64890Smrg	}
14761ab64890Smrg
14771ab64890Smrg        if (charset->side == XlcC1 || charset->side == XlcGR)
14781ab64890Smrg            glyph_index = (glyph_index << 8) | (ch & GL);
14791ab64890Smrg        else
14801ab64890Smrg            glyph_index = (glyph_index << 8) | ch;
14811ab64890Smrg
14821ab64890Smrg	gi_len_left--;
14831ab64890Smrg
14841ab64890Smrg        /* last of one glyph_index data */
14851ab64890Smrg        if (!gi_len_left) {
14861ab64890Smrg
14871ab64890Smrg	    /* segment conversion */
14881ab64890Smrg	    charset_tmp = charset;
14891ab64890Smrg	    segment_conversion(lcd, &charset_tmp, &glyph_index);
14901ab64890Smrg
14911ab64890Smrg            /* get codeset */
149261b2299dSmrg            if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp,
14931ab64890Smrg						&codeset, &glyph_index) ) {
14941ab64890Smrg		unconv_num += gi_len;
14951ab64890Smrg		continue;
14961ab64890Smrg            }
14971ab64890Smrg
14981ab64890Smrg            /* convert glyph index to wicd char */
14991ab64890Smrg            gi_to_wc(lcd, glyph_index, codeset, &wc);
15001ab64890Smrg            if (outbufptr) {*outbufptr++ = wc;}
15011ab64890Smrg	    (*to_left)--;
15021ab64890Smrg        }
15031ab64890Smrg
15041ab64890Smrg    } /* end of while */
15051ab64890Smrg
15061ab64890Smrg    /* error check on last char */
15071ab64890Smrg    if (gi_len_left) {
15081ab64890Smrg	inbufptr -= (gi_len - gi_len_left);
15091ab64890Smrg	(*from_left) += (gi_len - gi_len_left);
15101ab64890Smrg	unconv_num += (gi_len - gi_len_left);
15111ab64890Smrg    }
15121ab64890Smrg
15131ab64890Smrg    *from = (XPointer) ((const char *) *from + from_size);
15141ab64890Smrg    *from_left = 0;
15151ab64890Smrg    *to = (XPointer) outbufptr;
15161ab64890Smrg
15171ab64890Smrg    return unconv_num;
15181ab64890Smrg}
15191ab64890Smrg
15201ab64890Smrgstatic int
15211ab64890Smrgstdc_ctstowcs(
15221ab64890Smrg    XlcConv conv,
15231ab64890Smrg    XPointer *from,
15241ab64890Smrg    int *from_left,
15251ab64890Smrg    XPointer *to,
15261ab64890Smrg    int *to_left,
15271ab64890Smrg    XPointer *args,
15281ab64890Smrg    int num_args)
15291ab64890Smrg{
15301ab64890Smrg    XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
15311ab64890Smrg    char *buf_ptr1 = buf;
15321ab64890Smrg    int buf_left1 = (*from_left) * MB_CUR_MAX;
15331ab64890Smrg    char *buf_ptr2 = buf_ptr1;
15341ab64890Smrg    int buf_left2;
15351ab64890Smrg    int unconv_num1 = 0, unconv_num2 = 0;
15361ab64890Smrg
153761b2299dSmrg    unconv_num1 = ctstombs(conv,
15381ab64890Smrg		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
15391ab64890Smrg    if (unconv_num1 < 0)
15401ab64890Smrg        goto ret;
15411ab64890Smrg
15421ab64890Smrg    buf_left2 = buf_ptr1 - buf_ptr2;
15431ab64890Smrg
154461b2299dSmrg    unconv_num2 = stdc_mbstowcs(conv,
15451ab64890Smrg		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
15461ab64890Smrg    if (unconv_num2 < 0)
15471ab64890Smrg        goto ret;
15481ab64890Smrg
15491ab64890Smrgret:
1550cf2acddeSmrg    Xfree(buf);
15511ab64890Smrg
15521ab64890Smrg    return (unconv_num1 + unconv_num2);
15531ab64890Smrg}
15541ab64890Smrg
15551ab64890Smrgstatic int
15561ab64890Smrgstdc_cstowcs(
15571ab64890Smrg    XlcConv conv,
15581ab64890Smrg    XPointer *from,
15591ab64890Smrg    int *from_left,
15601ab64890Smrg    XPointer *to,
15611ab64890Smrg    int *to_left,
15621ab64890Smrg    XPointer *args,
15631ab64890Smrg    int num_args)
15641ab64890Smrg{
15651ab64890Smrg    XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
15661ab64890Smrg    char *buf_ptr1 = buf;
15671ab64890Smrg    int buf_left1 = (*from_left) * MB_CUR_MAX;
15681ab64890Smrg    char *buf_ptr2 = buf_ptr1;
15691ab64890Smrg    int buf_left2;
15701ab64890Smrg    int unconv_num1 = 0, unconv_num2 = 0;
15711ab64890Smrg
157261b2299dSmrg    unconv_num1 = cstombs(conv,
15731ab64890Smrg		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
15741ab64890Smrg    if (unconv_num1 < 0)
15751ab64890Smrg        goto ret;
15761ab64890Smrg
15771ab64890Smrg    buf_left2 = buf_ptr1 - buf_ptr2;
15781ab64890Smrg
157961b2299dSmrg    unconv_num2 = stdc_mbstowcs(conv,
15801ab64890Smrg		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
15811ab64890Smrg    if (unconv_num2 < 0)
15821ab64890Smrg        goto ret;
15831ab64890Smrg
15841ab64890Smrgret:
1585cf2acddeSmrg    Xfree(buf);
15861ab64890Smrg
15871ab64890Smrg    return (unconv_num1 + unconv_num2);
15881ab64890Smrg}
15891ab64890Smrg
15901ab64890Smrgstatic int
15911ab64890Smrgmbstocts(
15921ab64890Smrg    XlcConv conv,
15931ab64890Smrg    XPointer *from,
15941ab64890Smrg    int *from_left,
15951ab64890Smrg    XPointer *to,
15961ab64890Smrg    int *to_left,
15971ab64890Smrg    XPointer *args,
15981ab64890Smrg    int num_args)
15991ab64890Smrg{
16001ab64890Smrg    XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t));
16011ab64890Smrg    char *buf_ptr1 = buf;
16021ab64890Smrg    int buf_left1 = (*from_left);
16031ab64890Smrg    char *buf_ptr2 = buf_ptr1;
16041ab64890Smrg    int buf_left2;
16051ab64890Smrg    int unconv_num1 = 0, unconv_num2 = 0;
16061ab64890Smrg
160761b2299dSmrg    unconv_num1 = mbstowcs_org(conv,
16081ab64890Smrg		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
16091ab64890Smrg    if (unconv_num1 < 0)
16101ab64890Smrg        goto ret;
16111ab64890Smrg
16121ab64890Smrg    buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t);
16131ab64890Smrg
161461b2299dSmrg    unconv_num2 += wcstocts(conv,
16151ab64890Smrg		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
16161ab64890Smrg    if (unconv_num2 < 0)
16171ab64890Smrg        goto ret;
16181ab64890Smrg
16191ab64890Smrgret:
1620cf2acddeSmrg    Xfree(buf);
16211ab64890Smrg
16221ab64890Smrg    return (unconv_num1 + unconv_num2);
16231ab64890Smrg}
16241ab64890Smrg
16251ab64890Smrgstatic int
16261ab64890Smrgmbstostr(
16271ab64890Smrg    XlcConv conv,
16281ab64890Smrg    XPointer *from,
16291ab64890Smrg    int *from_left,
16301ab64890Smrg    XPointer *to,
16311ab64890Smrg    int *to_left,
16321ab64890Smrg    XPointer *args,
16331ab64890Smrg    int num_args)
16341ab64890Smrg{
16351ab64890Smrg    State state = (State) conv->state;
16361ab64890Smrg    XLCd lcd = state->lcd;
16371ab64890Smrg
16381ab64890Smrg    unsigned char ch;
16391ab64890Smrg    unsigned long mb = 0;
16401ab64890Smrg
16411ab64890Smrg    int length = 0, len_left = 0;
16421ab64890Smrg    int unconv_num = 0;
16431ab64890Smrg    int num;
16441ab64890Smrg
16451ab64890Smrg    CodeSet codeset = NULL;
16461ab64890Smrg
1647cf2acddeSmrg    const char *inbufptr;
16481ab64890Smrg    char *outbufptr = *to;
16491ab64890Smrg    int from_size = *from_left;
16501ab64890Smrg
16511ab64890Smrg    unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
16521ab64890Smrg
16531ab64890Smrg    if (from == NULL || *from == NULL) {
16541ab64890Smrg	_XlcResetConverter(conv);
16551ab64890Smrg        return( 0 );
16561ab64890Smrg    }
16571ab64890Smrg
1658cf2acddeSmrg    inbufptr = *from;
1659cf2acddeSmrg
16601ab64890Smrg    while (*from_left && *to_left) {
16611ab64890Smrg
16621ab64890Smrg	ch = *inbufptr++;
16631ab64890Smrg	(*from_left)--;
16641ab64890Smrg
16651ab64890Smrg	/* null ? */
16661ab64890Smrg	if (!ch) {
16671ab64890Smrg            if (outbufptr) {*outbufptr++ = '\0';}
16681ab64890Smrg	    (*to_left)--;
16691ab64890Smrg
16701ab64890Smrg            /* error check */
16711ab64890Smrg            if (len_left) {
16721ab64890Smrg                unconv_num += (length - len_left);
16731ab64890Smrg                len_left = 0;
16741ab64890Smrg            }
16751ab64890Smrg
16761ab64890Smrg	    continue;
16771ab64890Smrg	}
16781ab64890Smrg
16791ab64890Smrg        /* same mb char data */
16801ab64890Smrg        if (len_left)
16811ab64890Smrg            goto output_one_mb;
16821ab64890Smrg
16831ab64890Smrg        /* next mb char data for single shift ? */
16841ab64890Smrg	if (mb_parse_table && (num = mb_parse_table[ch]) ) {
16851ab64890Smrg	    codeset = mb_parse_codeset(state, num, &inbufptr, from_left);
16861ab64890Smrg            if (codeset != NULL) {
16871ab64890Smrg		length = len_left = codeset->length;
16881ab64890Smrg		mb = 0;
16891ab64890Smrg		continue;
16901ab64890Smrg	    }
16911ab64890Smrg        }
16921ab64890Smrg
16931ab64890Smrg	/* next char data : byteM ? */
16941ab64890Smrg	if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1))))
16951ab64890Smrg	    goto next_mb_char;
16961ab64890Smrg
16971ab64890Smrg	/* next char data : GL or GR side ? */
16981ab64890Smrg	if ((codeset = GLGR_parse_codeset(ch)))
16991ab64890Smrg	    goto next_mb_char;
170061b2299dSmrg
17011ab64890Smrg        /* can't find codeset for the ch */
17021ab64890Smrg        unconv_num++;
17031ab64890Smrg        continue;
17041ab64890Smrg
17051ab64890Smrgnext_mb_char:
17061ab64890Smrg        length = len_left = codeset->length;
17071ab64890Smrg        mb = 0;
17081ab64890Smrg
17091ab64890Smrgoutput_one_mb:
17101ab64890Smrg        mb = (mb << 8) | ch;  /* 1 byte left shift */
17111ab64890Smrg        len_left--;
17121ab64890Smrg
17131ab64890Smrg        /* last of one mb char data */
17141ab64890Smrg        if (!len_left) {
17151ab64890Smrg            if (check_string_encoding(codeset)) {
17161ab64890Smrg                if (outbufptr) {*outbufptr++ = mb & 0xff;}
17171ab64890Smrg		(*to_left)--;
17181ab64890Smrg            } else {
17191ab64890Smrg	        unconv_num++;
17201ab64890Smrg            }
17211ab64890Smrg        }
17221ab64890Smrg
17231ab64890Smrg    } /* end of while */
17241ab64890Smrg
17251ab64890Smrg    /* error check on last char */
17261ab64890Smrg    if (len_left) {
17271ab64890Smrg        inbufptr -= (length - len_left);
17281ab64890Smrg        (*from_left) += (length - len_left);
17291ab64890Smrg        unconv_num += (length - len_left);
17301ab64890Smrg    }
17311ab64890Smrg
17321ab64890Smrg    *from = (XPointer) ((const char *) *from + from_size);
17331ab64890Smrg    *from_left = 0;
17341ab64890Smrg    *to = (XPointer) outbufptr;
17351ab64890Smrg
17361ab64890Smrg    return unconv_num;
17371ab64890Smrg}
17381ab64890Smrg
17391ab64890Smrgstatic int
17401ab64890Smrgmbtocs(
17411ab64890Smrg    XlcConv conv,
17421ab64890Smrg    XPointer *from,
17431ab64890Smrg    int *from_left,
17441ab64890Smrg    XPointer *to,
17451ab64890Smrg    int *to_left,
17461ab64890Smrg    XPointer *args,
17471ab64890Smrg    int num_args)
17481ab64890Smrg{
17491ab64890Smrg    State state = (State) conv->state;
17501ab64890Smrg    XLCd lcd = state->lcd;
17511ab64890Smrg
17521ab64890Smrg    unsigned char ch;
17531ab64890Smrg    unsigned long mb = 0;
17541ab64890Smrg    unsigned long glyph_index;
17551ab64890Smrg
17561ab64890Smrg    int length = 0, len_left = 0, char_len;
17571ab64890Smrg    int unconv_num = 0;
17581ab64890Smrg    int num;
17591ab64890Smrg    XlcSide side;
17601ab64890Smrg
17611ab64890Smrg    CodeSet codeset = NULL;
17621ab64890Smrg    XlcCharSet charset = NULL;
17631ab64890Smrg
1764cf2acddeSmrg    const char *inbufptr;
17651ab64890Smrg    char *outbufptr = *to;
17661ab64890Smrg    int from_size = *from_left;
17671ab64890Smrg
17681ab64890Smrg    unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
17691ab64890Smrg
17701ab64890Smrg    if (from == NULL || *from == NULL) {
17711ab64890Smrg	_XlcResetConverter(conv);
17721ab64890Smrg        return( 0 );
17731ab64890Smrg    }
17741ab64890Smrg
1775cf2acddeSmrg    inbufptr = *from;
1776cf2acddeSmrg
17771ab64890Smrg    while (*from_left && *to_left) {
17781ab64890Smrg
17791ab64890Smrg	ch = *inbufptr++;
17801ab64890Smrg	(*from_left)--;
17811ab64890Smrg
17821ab64890Smrg	/* null ? */
17831ab64890Smrg	if (!ch) {
17841ab64890Smrg            unconv_num = 1;
17851ab64890Smrg            if (len_left)
17861ab64890Smrg	        unconv_num += (length - len_left);
17871ab64890Smrg	    break;
17881ab64890Smrg	}
17891ab64890Smrg
17901ab64890Smrg	/* same mb char data */
17911ab64890Smrg        if (len_left)
17921ab64890Smrg	    goto output;
17931ab64890Smrg
17941ab64890Smrg        /* next mb char data for single shift ? */
17951ab64890Smrg	if (mb_parse_table && (num = mb_parse_table[ch]) ) {
17961ab64890Smrg	    codeset = mb_parse_codeset(state, num, &inbufptr, from_left);
17971ab64890Smrg            if (codeset != NULL) {
17981ab64890Smrg		length = len_left = codeset->length;
17991ab64890Smrg		mb = 0;
18001ab64890Smrg		continue;
18011ab64890Smrg	    }
18021ab64890Smrg        }
18031ab64890Smrg
18041ab64890Smrg	/* next mb char data for byteM ? */
18051ab64890Smrg	if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1))))
18061ab64890Smrg	    goto next_mb_char;
18071ab64890Smrg
18081ab64890Smrg	/* next mb char data for GL or GR side ? */
18091ab64890Smrg	if ((codeset = GLGR_parse_codeset(ch)))
18101ab64890Smrg	    goto next_mb_char;
181161b2299dSmrg
18121ab64890Smrg        /* can't find codeset for the ch */
18131ab64890Smrg        unconv_num = 1;
18141ab64890Smrg        break;
18151ab64890Smrg
18161ab64890Smrgnext_mb_char:
18171ab64890Smrg        length = len_left = codeset->length;
18181ab64890Smrg	mb = 0;
18191ab64890Smrg
18201ab64890Smrgoutput:
18211ab64890Smrg	mb = (mb << 8) | ch;  /* 1 byte left shift */
18221ab64890Smrg	len_left--;
18231ab64890Smrg
18241ab64890Smrg        /* last of one mb char data */
18251ab64890Smrg        if (!len_left) {
18261ab64890Smrg            glyph_index = mb_to_gi(mb, codeset);
18271ab64890Smrg            if (!(charset = gi_parse_charset(glyph_index, codeset))) {
18281ab64890Smrg                unconv_num = length;
18291ab64890Smrg                break;
18301ab64890Smrg            }
18311ab64890Smrg            char_len = charset->char_size;
18321ab64890Smrg	    side = charset->side;
18331ab64890Smrg
18341ab64890Smrg            /* output glyph index */
18351ab64890Smrg            if (codeset->ctconv)
18361ab64890Smrg                glyph_index = conv_to_dest(codeset->ctconv, glyph_index);
18371ab64890Smrg            if (*to_left < char_len) {
18381ab64890Smrg                unconv_num = length;
18391ab64890Smrg                break;
18401ab64890Smrg            }
18411ab64890Smrg
18421ab64890Smrg	    if (outbufptr) {
18431ab64890Smrg	        output_ulong_value(outbufptr, glyph_index, char_len, side);
18441ab64890Smrg	        outbufptr += char_len;
18451ab64890Smrg	    }
18461ab64890Smrg
18471ab64890Smrg            (*to_left) -= char_len;
18481ab64890Smrg
18491ab64890Smrg            break;
18501ab64890Smrg        }
18511ab64890Smrg
18521ab64890Smrg    } /* end of while */
18531ab64890Smrg
18541ab64890Smrg    /* error end */
18551ab64890Smrg    if (unconv_num) {
18561ab64890Smrg        *from = (XPointer) ((const char *) *from + from_size);
18571ab64890Smrg        *from_left = 0;
18581ab64890Smrg        *to = (XPointer) outbufptr;
18591ab64890Smrg	return -1;
18601ab64890Smrg    }
18611ab64890Smrg
1862556b6652Smrg    /* normal end */
18631ab64890Smrg    *from = (XPointer) inbufptr;
18641ab64890Smrg    *to = (XPointer) outbufptr;
18651ab64890Smrg
18661ab64890Smrg    if (num_args > 0)
18671ab64890Smrg        *((XlcCharSet *) args[0]) = charset;
18681ab64890Smrg
18691ab64890Smrg    return 0;
18701ab64890Smrg}
18711ab64890Smrg
18721ab64890Smrgstatic int
18731ab64890Smrgmbstocs(
18741ab64890Smrg    XlcConv conv,
18751ab64890Smrg    XPointer *from,
18761ab64890Smrg    int *from_left,
18771ab64890Smrg    XPointer *to,
18781ab64890Smrg    int *to_left,
18791ab64890Smrg    XPointer *args,
18801ab64890Smrg    int num_args)
18811ab64890Smrg{
18821ab64890Smrg    int ret;
18831ab64890Smrg    XlcCharSet charset_old, charset = NULL;
18841ab64890Smrg    XPointer tmp_args[1];
18851ab64890Smrg
18861ab64890Smrg    const char *inbufptr;
18871ab64890Smrg    int	in_left;
18881ab64890Smrg    char *outbufptr;
18891ab64890Smrg    int	out_left;
18901ab64890Smrg    tmp_args[0] = (XPointer) &charset;
18911ab64890Smrg
18921ab64890Smrg    ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1);
18931ab64890Smrg    charset_old = charset;
189461b2299dSmrg
18951ab64890Smrg    while ( ret == 0 && *from_left && *to_left) {
18961ab64890Smrg	inbufptr = *from;
18971ab64890Smrg	in_left = *from_left;
18981ab64890Smrg	outbufptr = *to;
18991ab64890Smrg	out_left = *to_left;
19001ab64890Smrg        ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1);
19011ab64890Smrg        if (charset_old != charset) {
19021ab64890Smrg           *from = (XPointer) inbufptr;
19031ab64890Smrg           *from_left = in_left;
19041ab64890Smrg           *to = (XPointer) outbufptr;
19051ab64890Smrg           *to_left = out_left;
19061ab64890Smrg           break;
19071ab64890Smrg        }
19081ab64890Smrg    }
19091ab64890Smrg
19101ab64890Smrg    if (num_args > 0)
19111ab64890Smrg        *((XlcCharSet *) args[0]) = charset_old;
19121ab64890Smrg
19131ab64890Smrg    /* error end */
19141ab64890Smrg    if (ret != 0)
19151ab64890Smrg	return( -1 );
19161ab64890Smrg
19171ab64890Smrg    return(0);
19181ab64890Smrg}
19191ab64890Smrg
19201ab64890Smrgstatic int
19211ab64890Smrgwcstostr(
19221ab64890Smrg    XlcConv conv,
19231ab64890Smrg    XPointer *from,
19241ab64890Smrg    int *from_left,
19251ab64890Smrg    XPointer *to,
19261ab64890Smrg    int *to_left,
19271ab64890Smrg    XPointer *args,
19281ab64890Smrg    int num_args)
19291ab64890Smrg{
19301ab64890Smrg    State state = (State) conv->state;
19311ab64890Smrg    XLCd lcd = state->lcd;
19321ab64890Smrg
19331ab64890Smrg    char *encoding;
19341ab64890Smrg    unsigned long mb, glyph_index;
19351ab64890Smrg    wchar_t wc;
19361ab64890Smrg
19371ab64890Smrg    int length;
19381ab64890Smrg    int unconv_num = 0;
19391ab64890Smrg
19401ab64890Smrg    CodeSet codeset;
19411ab64890Smrg
19421ab64890Smrg    const wchar_t *inbufptr = (const wchar_t *) *from;
19431ab64890Smrg    char *outbufptr = *to;
19441ab64890Smrg    int from_size = *from_left;
194561b2299dSmrg
19461ab64890Smrg    const char *default_string = XLC_PUBLIC(lcd, default_string);
19471ab64890Smrg    int defstr_len = strlen(default_string);
19481ab64890Smrg
19491ab64890Smrg    while (*from_left && *to_left) {
19501ab64890Smrg
19511ab64890Smrg        wc = *inbufptr++;
19521ab64890Smrg        (*from_left)--;
19531ab64890Smrg
19541ab64890Smrg        /* null ? */
19551ab64890Smrg        if (!wc) {
19561ab64890Smrg            if (outbufptr) {*outbufptr++ = '\0';}
19571ab64890Smrg            (*to_left)--;
19581ab64890Smrg
19591ab64890Smrg            continue;
19601ab64890Smrg        }
19611ab64890Smrg
19621ab64890Smrg        /* convert */
19631ab64890Smrg	if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
19641ab64890Smrg
19651ab64890Smrg	    /* output default_string of XDefaultString() */
19661ab64890Smrg            if (*to_left < defstr_len)
19671ab64890Smrg		break;
19681ab64890Smrg	    if (outbufptr) {
19691ab64890Smrg                strncpy((char *)outbufptr, default_string, defstr_len);
19701ab64890Smrg	        outbufptr += defstr_len;
19711ab64890Smrg            }
19721ab64890Smrg	    (*to_left) -= defstr_len;
19731ab64890Smrg
19741ab64890Smrg            unconv_num++;
19751ab64890Smrg
19761ab64890Smrg        } else {
19771ab64890Smrg            mb = gi_to_mb(glyph_index, codeset);
19781ab64890Smrg
19791ab64890Smrg	    if (check_string_encoding(codeset)) {
19801ab64890Smrg	        if (codeset->parse_info) {
19811ab64890Smrg                    Bool need_shift = False;
19821ab64890Smrg                    switch (codeset->parse_info->type) {
19831ab64890Smrg                        case E_LSL :
19841ab64890Smrg                            if (codeset != state->GL_codeset) {
19851ab64890Smrg                                need_shift = True;
19861ab64890Smrg                                state->GL_codeset = codeset;
19871ab64890Smrg                            }
19881ab64890Smrg                            break;
19891ab64890Smrg                        case E_LSR :
19901ab64890Smrg                            if (codeset != state->GR_codeset) {
19911ab64890Smrg                                need_shift = True;
19921ab64890Smrg                                state->GR_codeset = codeset;
19931ab64890Smrg                            }
19941ab64890Smrg                            break;
19951ab64890Smrg                        /* case E_SS */
19961ab64890Smrg                        default:
19971ab64890Smrg                            need_shift = True;
19981ab64890Smrg                    }
19991ab64890Smrg
20001ab64890Smrg		    /* output shift sequence */
20011ab64890Smrg                    if (need_shift) {
20021ab64890Smrg		        encoding = codeset->parse_info->encoding;
20031ab64890Smrg                        length = strlen(encoding);
20041ab64890Smrg                        if (*to_left < length)
20051ab64890Smrg		            break;
20061ab64890Smrg
20071ab64890Smrg	                if (outbufptr) {
20081ab64890Smrg                            strncpy((char *)outbufptr, encoding, length);
20091ab64890Smrg	                    outbufptr += length;
20101ab64890Smrg                        }
20111ab64890Smrg	                (*to_left) -= length;
20121ab64890Smrg                    }
20131ab64890Smrg                }
20141ab64890Smrg
20151ab64890Smrg                /* output characters */
20161ab64890Smrg	        length = codeset->length;
20171ab64890Smrg                if (*to_left < length)
20181ab64890Smrg		    break;
20191ab64890Smrg
20201ab64890Smrg	        if (outbufptr) {
20211ab64890Smrg	            output_ulong_value(outbufptr, mb, length, XlcNONE);
20221ab64890Smrg	            outbufptr += length;
20231ab64890Smrg	        }
20241ab64890Smrg
20251ab64890Smrg	        (*to_left) -= length;
20261ab64890Smrg            } else {
20271ab64890Smrg		unconv_num++;
20281ab64890Smrg            }
20291ab64890Smrg        }
20301ab64890Smrg
20311ab64890Smrg    } /* end of while */
20321ab64890Smrg
20331ab64890Smrg    *from = (XPointer) ((const wchar_t *) *from + from_size);
20341ab64890Smrg    *from_left = 0;
20351ab64890Smrg    *to = (XPointer) outbufptr;
20361ab64890Smrg
20371ab64890Smrg    return unconv_num;
20381ab64890Smrg}
20391ab64890Smrg
20401ab64890Smrgstatic int
20411ab64890Smrgstdc_wcstostr(
20421ab64890Smrg    XlcConv conv,
20431ab64890Smrg    XPointer *from,
20441ab64890Smrg    int *from_left,
20451ab64890Smrg    XPointer *to,
20461ab64890Smrg    int *to_left,
20471ab64890Smrg    XPointer *args,
20481ab64890Smrg    int num_args)
20491ab64890Smrg{
20501ab64890Smrg    XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
20511ab64890Smrg    char *buf_ptr1 = buf;
20521ab64890Smrg    int buf_left1 = (*from_left) * MB_CUR_MAX;
20531ab64890Smrg    char *buf_ptr2 = buf_ptr1;
20541ab64890Smrg    int buf_left2;
20551ab64890Smrg    int unconv_num1 = 0, unconv_num2 = 0;
20561ab64890Smrg
205761b2299dSmrg    unconv_num1 = stdc_wcstombs(conv,
20581ab64890Smrg		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
20591ab64890Smrg    if (unconv_num1 < 0)
20601ab64890Smrg        goto ret;
20611ab64890Smrg
20621ab64890Smrg    buf_left2 = buf_ptr1 - buf_ptr2;
20631ab64890Smrg
206461b2299dSmrg    unconv_num2 = mbstostr(conv,
20651ab64890Smrg		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
20661ab64890Smrg    if (unconv_num2 < 0)
20671ab64890Smrg        goto ret;
20681ab64890Smrg
20691ab64890Smrgret:
2070cf2acddeSmrg    Xfree(buf);
20711ab64890Smrg
20721ab64890Smrg    return (unconv_num1 + unconv_num2);
20731ab64890Smrg}
20741ab64890Smrg
20751ab64890Smrgstatic int
20761ab64890Smrgwctocs(
20771ab64890Smrg    XlcConv conv,
20781ab64890Smrg    XPointer *from,
20791ab64890Smrg    int *from_left,
20801ab64890Smrg    XPointer *to,
20811ab64890Smrg    int *to_left,
20821ab64890Smrg    XPointer *args,
20831ab64890Smrg    int num_args)
20841ab64890Smrg{
20851ab64890Smrg    State state = (State) conv->state;
20861ab64890Smrg    XLCd lcd = state->lcd;
20871ab64890Smrg
20881ab64890Smrg    wchar_t wc;
20891ab64890Smrg    unsigned long glyph_index;
20901ab64890Smrg
20911ab64890Smrg    int char_len;
20921ab64890Smrg    int unconv_num = 0;
20931ab64890Smrg    XlcSide side;
20941ab64890Smrg
20951ab64890Smrg    CodeSet codeset;
20961ab64890Smrg    XlcCharSet charset = NULL;
20971ab64890Smrg
20981ab64890Smrg    const wchar_t *inbufptr = (const wchar_t *) *from;
20991ab64890Smrg    char *outbufptr = *to;
21001ab64890Smrg    int from_size = *from_left;
21011ab64890Smrg
21021ab64890Smrg    if (*from_left && *to_left) {
21031ab64890Smrg
21041ab64890Smrg        wc = *inbufptr++;
21051ab64890Smrg        (*from_left)--;
21061ab64890Smrg
21071ab64890Smrg        /* null ? */
21081ab64890Smrg        if (!wc) {
21091ab64890Smrg            unconv_num = 1;
21101ab64890Smrg            goto end;
21111ab64890Smrg        }
21121ab64890Smrg
21131ab64890Smrg        /* convert */
21141ab64890Smrg	if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) {
21151ab64890Smrg            unconv_num = 1;
21161ab64890Smrg	    goto end;
21171ab64890Smrg        }
21181ab64890Smrg
21191ab64890Smrg        if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) {
21201ab64890Smrg            unconv_num = 1;
21211ab64890Smrg	    goto end;
21221ab64890Smrg        }
21231ab64890Smrg	char_len = charset->char_size;
21241ab64890Smrg	side = charset->side;
21251ab64890Smrg
21261ab64890Smrg        /* output glyph index */
21271ab64890Smrg	if (codeset->ctconv)
21281ab64890Smrg            glyph_index = conv_to_dest(codeset->ctconv, glyph_index);
21291ab64890Smrg        if (*to_left < char_len) {
21301ab64890Smrg            unconv_num++;
21311ab64890Smrg	    goto end;
21321ab64890Smrg        }
21331ab64890Smrg
21341ab64890Smrg        if (outbufptr) {
21351ab64890Smrg            output_ulong_value(outbufptr, glyph_index, char_len, side);
21361ab64890Smrg            outbufptr += char_len;
21371ab64890Smrg        }
21381ab64890Smrg
21391ab64890Smrg	(*to_left) -= char_len;
21401ab64890Smrg
21411ab64890Smrg    }
21421ab64890Smrg
21431ab64890Smrgend:
21441ab64890Smrg
21451ab64890Smrg     /* error end */
21461ab64890Smrg    if (unconv_num) {
21471ab64890Smrg        *from = (XPointer) ((const wchar_t *) *from + from_size);
21481ab64890Smrg        *from_left = 0;
21491ab64890Smrg        *to = (XPointer) outbufptr;
21501ab64890Smrg        return -1;
21511ab64890Smrg    }
21521ab64890Smrg
2153556b6652Smrg    /* normal end */
21541ab64890Smrg    *from = (XPointer) inbufptr;
21551ab64890Smrg    *to = (XPointer) outbufptr;
21561ab64890Smrg
21571ab64890Smrg    if (num_args > 0)
21581ab64890Smrg        *((XlcCharSet *) args[0]) = charset;
21591ab64890Smrg
21601ab64890Smrg    return 0;
21611ab64890Smrg}
21621ab64890Smrg
21631ab64890Smrgstatic int
21641ab64890Smrgstdc_wctocs(
21651ab64890Smrg    XlcConv conv,
21661ab64890Smrg    XPointer *from,
21671ab64890Smrg    int *from_left,
21681ab64890Smrg    XPointer *to,
21691ab64890Smrg    int *to_left,
21701ab64890Smrg    XPointer *args,
21711ab64890Smrg    int num_args)
21721ab64890Smrg{
21731ab64890Smrg    const wchar_t *src = *((const wchar_t **) from);
21741ab64890Smrg    wchar_t wch;
21751ab64890Smrg    XPointer tmp_from, save_from = *from;
21761ab64890Smrg    char tmp[32];
21771ab64890Smrg    int length, ret, src_left = *from_left;
21781ab64890Smrg    int from_size = *from_left;
21791ab64890Smrg
21801ab64890Smrg    if (src_left > 0 && *to_left > 0) {
21811ab64890Smrg	if ((wch = *src)) {
21821ab64890Smrg	    length = wctomb(tmp, wch);
21831ab64890Smrg	} else {
21841ab64890Smrg	    goto end;
21851ab64890Smrg	}
218661b2299dSmrg
21871ab64890Smrg	if (length < 0)
21881ab64890Smrg	    goto end;
21891ab64890Smrg
21901ab64890Smrg	tmp_from = (XPointer) tmp;
21911ab64890Smrg	ret = mbtocs(conv, &tmp_from, &length, to, to_left, args, num_args);
21921ab64890Smrg	if (ret < 0)
21931ab64890Smrg	    goto end;
21941ab64890Smrg
21951ab64890Smrg	src++;
21961ab64890Smrg	src_left--;
21971ab64890Smrg    }
21981ab64890Smrg
21991ab64890Smrgend:
22001ab64890Smrg     /* error end */
22011ab64890Smrg    if (save_from == (XPointer) src) {
22021ab64890Smrg        *from = (XPointer) ((const wchar_t *) *from + from_size);
22031ab64890Smrg        *from_left = 0;
22041ab64890Smrg	return -1;
22051ab64890Smrg    }
22061ab64890Smrg
2207556b6652Smrg    /* normal end */
22081ab64890Smrg    *from = (XPointer) src;
22091ab64890Smrg    *from_left = src_left;
22101ab64890Smrg
22111ab64890Smrg    return 0;
22121ab64890Smrg}
22131ab64890Smrg
22141ab64890Smrgstatic int
22151ab64890Smrgwcstocs(
22161ab64890Smrg    XlcConv conv,
22171ab64890Smrg    XPointer *from,
22181ab64890Smrg    int *from_left,
22191ab64890Smrg    XPointer *to,
22201ab64890Smrg    int *to_left,
22211ab64890Smrg    XPointer *args,
22221ab64890Smrg    int num_args)
22231ab64890Smrg{
22241ab64890Smrg    int ret;
22251ab64890Smrg    XlcCharSet charset_old, charset = NULL;
22261ab64890Smrg    XPointer tmp_args[1];
22271ab64890Smrg
22281ab64890Smrg    const wchar_t *inbufptr;
22291ab64890Smrg    int	in_left;
22301ab64890Smrg    XPointer outbufptr;
22311ab64890Smrg    int	out_left;
22321ab64890Smrg    tmp_args[0] = (XPointer) &charset;
22331ab64890Smrg
22341ab64890Smrg    ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
22351ab64890Smrg    charset_old = charset;
22361ab64890Smrg
22371ab64890Smrg    while ( ret == 0 && *from_left && *to_left) {
22381ab64890Smrg	inbufptr = (const wchar_t *) *from;
22391ab64890Smrg	in_left = *from_left;
22401ab64890Smrg	outbufptr = *to;
22411ab64890Smrg	out_left = *to_left;
22421ab64890Smrg        ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
22431ab64890Smrg        if (charset_old != charset) {
22441ab64890Smrg           *from = (XPointer) inbufptr;
22451ab64890Smrg           *from_left = in_left;
22461ab64890Smrg           *to = (XPointer) outbufptr;
22471ab64890Smrg           *to_left = out_left;
22481ab64890Smrg           break;
22491ab64890Smrg        }
22501ab64890Smrg    }
22511ab64890Smrg
22521ab64890Smrg    if (num_args > 0)
22531ab64890Smrg        *((XlcCharSet *) args[0]) = charset_old;
22541ab64890Smrg
22551ab64890Smrg    /* error end */
22561ab64890Smrg    if (ret != 0)
22571ab64890Smrg	return( -1 );
22581ab64890Smrg
22591ab64890Smrg    return(0);
22601ab64890Smrg}
22611ab64890Smrg
22621ab64890Smrg#ifdef STDCVT
22631ab64890Smrg
22641ab64890Smrgstatic int
22651ab64890Smrgstdc_wcstocs(
22661ab64890Smrg    XlcConv conv,
22671ab64890Smrg    XPointer *from,
22681ab64890Smrg    int *from_left,
22691ab64890Smrg    XPointer *to,
22701ab64890Smrg    int *to_left,
22711ab64890Smrg    XPointer *args,
22721ab64890Smrg    int num_args)
22731ab64890Smrg{
22741ab64890Smrg    int ret;
22751ab64890Smrg    XlcCharSet charset_old, charset = NULL;
22761ab64890Smrg    XPointer tmp_args[1];
22771ab64890Smrg
22781ab64890Smrg    const wchar_t *inbufptr;
22791ab64890Smrg    int	in_left;
22801ab64890Smrg    XPointer outbufptr;
22811ab64890Smrg    int	out_left;
22821ab64890Smrg    tmp_args[0] = (XPointer) &charset;
22831ab64890Smrg
22841ab64890Smrg    ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
22851ab64890Smrg    charset_old = charset;
22861ab64890Smrg
22871ab64890Smrg    while ( ret == 0 && *from_left && *to_left ) {
22881ab64890Smrg	inbufptr = (const wchar_t *) *from;
22891ab64890Smrg	in_left = *from_left;
22901ab64890Smrg	outbufptr = *to;
22911ab64890Smrg	out_left = *to_left;
22921ab64890Smrg        ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1);
22931ab64890Smrg        if (charset_old != charset) {
22941ab64890Smrg           *from = (XPointer) inbufptr;
22951ab64890Smrg           *from_left = in_left;
22961ab64890Smrg           *to = (XPointer) outbufptr;
22971ab64890Smrg           *to_left = out_left;
22981ab64890Smrg           break;
22991ab64890Smrg        }
23001ab64890Smrg    }
23011ab64890Smrg
23021ab64890Smrg    if (num_args > 0)
23031ab64890Smrg        *((XlcCharSet *) args[0]) = charset_old;
23041ab64890Smrg
23051ab64890Smrg    /* error end */
23061ab64890Smrg    if (ret != 0)
23071ab64890Smrg	return( -1 );
23081ab64890Smrg
23091ab64890Smrg    return(0);
23101ab64890Smrg}
23111ab64890Smrg
23121ab64890Smrg#endif
23131ab64890Smrg
23141ab64890Smrgstatic int
23151ab64890Smrgctstombs(
23161ab64890Smrg    XlcConv conv,
23171ab64890Smrg    XPointer *from,
23181ab64890Smrg    int *from_left,
23191ab64890Smrg    XPointer *to,
23201ab64890Smrg    int *to_left,
23211ab64890Smrg    XPointer *args,
23221ab64890Smrg    int num_args)
23231ab64890Smrg{
23241ab64890Smrg    XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t));
23251ab64890Smrg    char *buf_ptr1 = buf;
23261ab64890Smrg    int buf_left1 = (*from_left);
23271ab64890Smrg    char *buf_ptr2 = buf_ptr1;
23281ab64890Smrg    int buf_left2;
23291ab64890Smrg    int unconv_num1 = 0, unconv_num2 = 0;
23301ab64890Smrg
233161b2299dSmrg    unconv_num1 = ctstowcs(conv,
23321ab64890Smrg		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
23331ab64890Smrg    if (unconv_num1 < 0)
23341ab64890Smrg        goto ret;
23351ab64890Smrg
23361ab64890Smrg    buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t);
23371ab64890Smrg
233861b2299dSmrg    unconv_num2 += wcstombs_org(conv,
23391ab64890Smrg		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
23401ab64890Smrg    if (unconv_num2 < 0)
23411ab64890Smrg        goto ret;
23421ab64890Smrg
23431ab64890Smrgret:
2344cf2acddeSmrg    Xfree(buf);
23451ab64890Smrg
23461ab64890Smrg    return (unconv_num1 + unconv_num2);
23471ab64890Smrg}
23481ab64890Smrg
23491ab64890Smrgstatic int
23501ab64890Smrgcstombs(
23511ab64890Smrg    XlcConv conv,
23521ab64890Smrg    XPointer *from,
23531ab64890Smrg    int *from_left,
23541ab64890Smrg    XPointer *to,
23551ab64890Smrg    int *to_left,
23561ab64890Smrg    XPointer *args,
23571ab64890Smrg    int num_args)
23581ab64890Smrg{
23591ab64890Smrg    XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t));
23601ab64890Smrg    char *buf_ptr1 = buf;
23611ab64890Smrg    int buf_left1 = (*from_left);
23621ab64890Smrg    char *buf_ptr2 = buf_ptr1;
23631ab64890Smrg    int buf_left2;
23641ab64890Smrg    int unconv_num1 = 0, unconv_num2 = 0;
23651ab64890Smrg
236661b2299dSmrg    unconv_num1 = cstowcs(conv,
23671ab64890Smrg		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
23681ab64890Smrg    if (unconv_num1 < 0)
23691ab64890Smrg        goto ret;
23701ab64890Smrg
23711ab64890Smrg    buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t);
23721ab64890Smrg
237361b2299dSmrg    unconv_num2 += wcstombs_org(conv,
23741ab64890Smrg		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
23751ab64890Smrg    if (unconv_num2 < 0)
23761ab64890Smrg        goto ret;
23771ab64890Smrg
23781ab64890Smrgret:
2379cf2acddeSmrg    Xfree(buf);
23801ab64890Smrg
23811ab64890Smrg    return (unconv_num1 + unconv_num2);
23821ab64890Smrg}
23831ab64890Smrg
23841ab64890Smrgstatic int
23851ab64890Smrgstrtombs(
23861ab64890Smrg    XlcConv conv,
23871ab64890Smrg    XPointer *from,
23881ab64890Smrg    int *from_left,
23891ab64890Smrg    XPointer *to,
23901ab64890Smrg    int *to_left,
23911ab64890Smrg    XPointer *args,
23921ab64890Smrg    int num_args)
23931ab64890Smrg{
23941ab64890Smrg    State state = (State) conv->state;
23951ab64890Smrg    XLCd lcd = state->lcd;
23961ab64890Smrg
23971ab64890Smrg    char *encoding;
23981ab64890Smrg    unsigned long mb, glyph_index;
23991ab64890Smrg    unsigned char ch;
24001ab64890Smrg
24011ab64890Smrg    int length;
24021ab64890Smrg    int unconv_num = 0;
24031ab64890Smrg
24041ab64890Smrg    CodeSet codeset;
24051ab64890Smrg
24061ab64890Smrg    const char *inbufptr = *from;
24071ab64890Smrg    char *outbufptr = *to;
24081ab64890Smrg    int from_size = *from_left;
24091ab64890Smrg
24101ab64890Smrg    while (*from_left && *to_left) {
24111ab64890Smrg
24121ab64890Smrg        ch = *inbufptr++;
24131ab64890Smrg        (*from_left)--;
24141ab64890Smrg
24151ab64890Smrg        /* null ? */
24161ab64890Smrg        if (!ch) {
24171ab64890Smrg            if (outbufptr) {*outbufptr++ = '\0';}
24181ab64890Smrg            (*to_left)--;
24191ab64890Smrg
24201ab64890Smrg            continue;
24211ab64890Smrg        }
24221ab64890Smrg
24231ab64890Smrg        /* convert */
24241ab64890Smrg        if (isleftside(ch)) {
24251ab64890Smrg	    glyph_index = ch;
24261ab64890Smrg	    codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL");
24271ab64890Smrg	} else {
24281ab64890Smrg	    glyph_index = ch & GL;
24291ab64890Smrg	    codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR");
24301ab64890Smrg	}
24311ab64890Smrg
24321ab64890Smrg        if (!codeset) {
24331ab64890Smrg	    unconv_num++;
24341ab64890Smrg	    continue;
24351ab64890Smrg        }
24361ab64890Smrg
24371ab64890Smrg        mb = gi_to_mb(glyph_index, codeset);
24381ab64890Smrg	if (codeset->parse_info) {
24391ab64890Smrg            Bool need_shift = False;
24401ab64890Smrg            switch (codeset->parse_info->type) {
24411ab64890Smrg                case E_LSL :
24421ab64890Smrg                    if (codeset != state->GL_codeset) {
24431ab64890Smrg                        need_shift = True;
24441ab64890Smrg                        state->GL_codeset = codeset;
24451ab64890Smrg                    }
24461ab64890Smrg                    break;
24471ab64890Smrg                case E_LSR :
24481ab64890Smrg                    if (codeset != state->GR_codeset) {
24491ab64890Smrg                        need_shift = True;
24501ab64890Smrg                        state->GR_codeset = codeset;
24511ab64890Smrg                    }
24521ab64890Smrg                    break;
24531ab64890Smrg                /* case E_SS */
24541ab64890Smrg                default:
24551ab64890Smrg                    need_shift = True;
24561ab64890Smrg            }
24571ab64890Smrg
24581ab64890Smrg	    /* output shift sequence */
24591ab64890Smrg            if (need_shift) {
24601ab64890Smrg                encoding = codeset->parse_info->encoding;
24611ab64890Smrg                length = strlen(encoding);
24621ab64890Smrg                if (*to_left < length)
24631ab64890Smrg		    break;
24641ab64890Smrg	        if (outbufptr) {
24651ab64890Smrg                    strncpy((char *)outbufptr, encoding, length);
24661ab64890Smrg	            outbufptr += length;
24671ab64890Smrg                }
24681ab64890Smrg	        (*to_left) -= length;
24691ab64890Smrg	    }
24701ab64890Smrg        }
24711ab64890Smrg
24721ab64890Smrg        /* output characters */
24731ab64890Smrg	length = codeset->length;
24741ab64890Smrg        if (*to_left < length)
24751ab64890Smrg	    break;
24761ab64890Smrg
24771ab64890Smrg        if (outbufptr) {
24781ab64890Smrg            output_ulong_value(outbufptr, mb, length, XlcNONE);
24791ab64890Smrg            outbufptr += length;
24801ab64890Smrg        }
24811ab64890Smrg
24821ab64890Smrg	(*to_left) -= length;
24831ab64890Smrg
24841ab64890Smrg    } /* end of while */
24851ab64890Smrg
24861ab64890Smrg    *from = (XPointer) ((const char *) *from + from_size);
24871ab64890Smrg    *from_left = 0;
24881ab64890Smrg    *to = (XPointer) outbufptr;
24891ab64890Smrg
24901ab64890Smrg    return unconv_num;
24911ab64890Smrg}
24921ab64890Smrg
24931ab64890Smrgstatic int
24941ab64890Smrgstrtowcs(
24951ab64890Smrg    XlcConv conv,
24961ab64890Smrg    XPointer *from,
24971ab64890Smrg    int *from_left,
24981ab64890Smrg    XPointer *to,
24991ab64890Smrg    int *to_left,
25001ab64890Smrg    XPointer *args,
25011ab64890Smrg    int num_args)
25021ab64890Smrg{
25031ab64890Smrg    State state = (State) conv->state;
25041ab64890Smrg    XLCd lcd = state->lcd;
25051ab64890Smrg
25061ab64890Smrg    unsigned char ch;
25071ab64890Smrg    unsigned long glyph_index;
25081ab64890Smrg    wchar_t wc;
25091ab64890Smrg
25101ab64890Smrg    int unconv_num = 0;
25111ab64890Smrg    CodeSet codeset;
25121ab64890Smrg
25131ab64890Smrg    const char *inbufptr = *from;
25141ab64890Smrg    wchar_t *outbufptr = (wchar_t *)*to;
25151ab64890Smrg    int from_size = *from_left;
25161ab64890Smrg
25171ab64890Smrg    while (*from_left && *to_left) {
25181ab64890Smrg
25191ab64890Smrg        ch = *inbufptr++;
25201ab64890Smrg        (*from_left)--;
25211ab64890Smrg
25221ab64890Smrg        /* null ? */
25231ab64890Smrg        if (!ch) {
25241ab64890Smrg            if (outbufptr) {*outbufptr++ = L'\0';}
25251ab64890Smrg            (*to_left)--;
25261ab64890Smrg
25271ab64890Smrg            continue;
25281ab64890Smrg        }
25291ab64890Smrg
25301ab64890Smrg        /* convert */
25311ab64890Smrg        if (isleftside(ch)) {
25321ab64890Smrg	    glyph_index = ch;
25331ab64890Smrg	    codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL");
25341ab64890Smrg	} else {
25351ab64890Smrg	    glyph_index = ch & GL;
25361ab64890Smrg	    codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR");
25371ab64890Smrg	}
25381ab64890Smrg
25391ab64890Smrg        if (!codeset) {
25401ab64890Smrg	    unconv_num++;
25411ab64890Smrg	    continue;
25421ab64890Smrg        }
25431ab64890Smrg
25441ab64890Smrg        gi_to_wc(lcd, glyph_index, codeset, &wc);
25451ab64890Smrg	if (outbufptr) {*outbufptr++ = wc;}
25461ab64890Smrg	(*to_left)--;
25471ab64890Smrg
25481ab64890Smrg    } /* end of while */
25491ab64890Smrg
25501ab64890Smrg    *from = (XPointer) ((const char *) *from + from_size);
25511ab64890Smrg    *from_left = 0;
25521ab64890Smrg    *to = (XPointer) outbufptr;
25531ab64890Smrg
25541ab64890Smrg    return unconv_num;
25551ab64890Smrg}
25561ab64890Smrg
25571ab64890Smrgstatic int
25581ab64890Smrgstdc_strtowcs(
25591ab64890Smrg    XlcConv conv,
25601ab64890Smrg    XPointer *from,
25611ab64890Smrg    int *from_left,
25621ab64890Smrg    XPointer *to,
25631ab64890Smrg    int *to_left,
25641ab64890Smrg    XPointer *args,
25651ab64890Smrg    int num_args)
25661ab64890Smrg{
25671ab64890Smrg    XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX);
25681ab64890Smrg    char *buf_ptr1 = buf;
25691ab64890Smrg    int buf_left1 = (*from_left) * MB_CUR_MAX;
25701ab64890Smrg    char *buf_ptr2 = buf_ptr1;
25711ab64890Smrg    int buf_left2;
25721ab64890Smrg    int unconv_num1 = 0, unconv_num2 = 0;
25731ab64890Smrg
257461b2299dSmrg    unconv_num1 = strtombs(conv,
25751ab64890Smrg		from, from_left, &buf_ptr1, &buf_left1, args, num_args);
25761ab64890Smrg    if (unconv_num1 < 0)
25771ab64890Smrg        goto ret;
25781ab64890Smrg
25791ab64890Smrg    buf_left2 = buf_ptr1 - buf_ptr2;
25801ab64890Smrg
258161b2299dSmrg    unconv_num2 = stdc_mbstowcs(conv,
25821ab64890Smrg		&buf_ptr2, &buf_left2, to, to_left, args, num_args);
25831ab64890Smrg    if (unconv_num2 < 0)
25841ab64890Smrg        goto ret;
25851ab64890Smrg
25861ab64890Smrgret:
2587cf2acddeSmrg    Xfree(buf);
25881ab64890Smrg
25891ab64890Smrg    return (unconv_num1 + unconv_num2);
25901ab64890Smrg}
25911ab64890Smrg
25921ab64890Smrg/* -------------------------------------------------------------------------- */
25931ab64890Smrg/*				Close                                         */
25941ab64890Smrg/* -------------------------------------------------------------------------- */
25951ab64890Smrg
25961ab64890Smrgstatic void
25971ab64890Smrgclose_converter(
25981ab64890Smrg    XlcConv conv)
25991ab64890Smrg{
2600cf2acddeSmrg    Xfree(conv->state);
2601cf2acddeSmrg    Xfree(conv->methods);
2602c555af55Smrg    Xfree(conv);
26031ab64890Smrg}
26041ab64890Smrg
26051ab64890Smrg/* -------------------------------------------------------------------------- */
26061ab64890Smrg/*				Open                                          */
26071ab64890Smrg/* -------------------------------------------------------------------------- */
26081ab64890Smrg
26091ab64890Smrgstatic XlcConv
26101ab64890Smrgcreate_conv(
26111ab64890Smrg    XLCd lcd,
26121ab64890Smrg    XlcConvMethods methods)
26131ab64890Smrg{
26141ab64890Smrg    XlcConv conv;
26151ab64890Smrg    State state;
26161ab64890Smrg
2617c555af55Smrg    conv = Xcalloc(1, sizeof(XlcConvRec));
26181ab64890Smrg    if (conv == NULL)
26191ab64890Smrg	return (XlcConv) NULL;
262061b2299dSmrg
2621c555af55Smrg    conv->methods = Xmalloc(sizeof(XlcConvMethodsRec));
26221ab64890Smrg    if (conv->methods == NULL)
26231ab64890Smrg	goto err;
26241ab64890Smrg    *conv->methods = *methods;
262561b2299dSmrg    conv->methods->reset = init_state;
26261ab64890Smrg
2627d8e76104Smrg    conv->state = Xcalloc(1, sizeof(StateRec));
26281ab64890Smrg    if (conv->state == NULL)
26291ab64890Smrg	goto err;
263061b2299dSmrg
26311ab64890Smrg    state = (State) conv->state;
26321ab64890Smrg    state->lcd = lcd;
263361b2299dSmrg
26341ab64890Smrg    _XlcResetConverter(conv);
263561b2299dSmrg
26361ab64890Smrg    return conv;
26371ab64890Smrg
26381ab64890Smrgerr:
26391ab64890Smrg    close_converter(conv);
26401ab64890Smrg
26411ab64890Smrg    return (XlcConv) NULL;
26421ab64890Smrg}
26431ab64890Smrg
26441ab64890Smrgstatic XlcConvMethodsRec mbstocts_methods = {
26451ab64890Smrg    close_converter,
26461ab64890Smrg    mbstocts,
26471ab64890Smrg    NULL
26481ab64890Smrg};
26491ab64890Smrg
26501ab64890Smrgstatic XlcConv
26511ab64890Smrgopen_mbstocts(
26521ab64890Smrg    XLCd from_lcd,
26531ab64890Smrg    const char *from_type,
26541ab64890Smrg    XLCd to_lcd,
26551ab64890Smrg    const char *to_type)
26561ab64890Smrg{
26571ab64890Smrg    return create_conv(from_lcd, &mbstocts_methods);
26581ab64890Smrg}
26591ab64890Smrg
26601ab64890Smrgstatic XlcConvMethodsRec mbstostr_methods = {
26611ab64890Smrg    close_converter,
26621ab64890Smrg    mbstostr,
26631ab64890Smrg    NULL
26641ab64890Smrg};
26651ab64890Smrg
26661ab64890Smrgstatic XlcConv
26671ab64890Smrgopen_mbstostr(
26681ab64890Smrg    XLCd from_lcd,
26691ab64890Smrg    const char *from_type,
26701ab64890Smrg    XLCd to_lcd,
26711ab64890Smrg    const char *to_type)
26721ab64890Smrg{
26731ab64890Smrg    return create_conv(from_lcd, &mbstostr_methods);
26741ab64890Smrg}
26751ab64890Smrg
26761ab64890Smrgstatic XlcConvMethodsRec mbstocs_methods = {
26771ab64890Smrg    close_converter,
26781ab64890Smrg    mbstocs,
26791ab64890Smrg    NULL
26801ab64890Smrg};
26811ab64890Smrg
26821ab64890Smrgstatic XlcConv
26831ab64890Smrgopen_mbstocs(
26841ab64890Smrg    XLCd from_lcd,
26851ab64890Smrg    const char *from_type,
26861ab64890Smrg    XLCd to_lcd,
26871ab64890Smrg    const char *to_type)
26881ab64890Smrg{
26891ab64890Smrg    return create_conv(from_lcd, &mbstocs_methods);
26901ab64890Smrg}
26911ab64890Smrg
26921ab64890Smrgstatic XlcConvMethodsRec mbtocs_methods = {
26931ab64890Smrg    close_converter,
26941ab64890Smrg    mbtocs,
26951ab64890Smrg    NULL
26961ab64890Smrg};
26971ab64890Smrg
26981ab64890Smrgstatic XlcConv
26991ab64890Smrgopen_mbtocs(
27001ab64890Smrg    XLCd from_lcd,
27011ab64890Smrg    const char *from_type,
27021ab64890Smrg    XLCd to_lcd,
27031ab64890Smrg    const char *to_type)
27041ab64890Smrg{
27051ab64890Smrg    return create_conv(from_lcd, &mbtocs_methods);
27061ab64890Smrg}
27071ab64890Smrg
27081ab64890Smrgstatic XlcConvMethodsRec ctstombs_methods = {
27091ab64890Smrg    close_converter,
27101ab64890Smrg    ctstombs,
27111ab64890Smrg    NULL
27121ab64890Smrg};
27131ab64890Smrg
27141ab64890Smrgstatic XlcConv
27151ab64890Smrgopen_ctstombs(
27161ab64890Smrg    XLCd from_lcd,
27171ab64890Smrg    const char *from_type,
27181ab64890Smrg    XLCd to_lcd,
27191ab64890Smrg    const char *to_type)
27201ab64890Smrg{
27211ab64890Smrg    return create_conv(from_lcd, &ctstombs_methods);
27221ab64890Smrg}
27231ab64890Smrg
27241ab64890Smrgstatic XlcConvMethodsRec cstombs_methods = {
27251ab64890Smrg    close_converter,
27261ab64890Smrg    cstombs,
27271ab64890Smrg    NULL
27281ab64890Smrg};
27291ab64890Smrg
27301ab64890Smrgstatic XlcConv
27311ab64890Smrgopen_cstombs(
27321ab64890Smrg    XLCd from_lcd,
27331ab64890Smrg    const char *from_type,
27341ab64890Smrg    XLCd to_lcd,
27351ab64890Smrg    const char *to_type)
27361ab64890Smrg{
27371ab64890Smrg    return create_conv(from_lcd, &cstombs_methods);
27381ab64890Smrg}
27391ab64890Smrg
27401ab64890Smrgstatic XlcConvMethodsRec strtombs_methods = {
27411ab64890Smrg    close_converter,
27421ab64890Smrg    strtombs,
27431ab64890Smrg    NULL
27441ab64890Smrg};
27451ab64890Smrg
27461ab64890Smrgstatic XlcConv
27471ab64890Smrgopen_strtombs(
27481ab64890Smrg    XLCd from_lcd,
27491ab64890Smrg    const char *from_type,
27501ab64890Smrg    XLCd to_lcd,
27511ab64890Smrg    const char *to_type)
27521ab64890Smrg{
27531ab64890Smrg    return create_conv(from_lcd, &strtombs_methods);
27541ab64890Smrg}
27551ab64890Smrg
27561ab64890Smrg#ifdef STDCVT
27571ab64890Smrg
27581ab64890Smrgstatic XlcConvMethodsRec stdc_mbstowcs_methods = {
27591ab64890Smrg    close_converter,
27601ab64890Smrg    stdc_mbstowcs,
27611ab64890Smrg    NULL
27621ab64890Smrg};
27631ab64890Smrg
27641ab64890Smrgstatic XlcConv
27651ab64890Smrgopen_stdc_mbstowcs(
27661ab64890Smrg    XLCd from_lcd,
27671ab64890Smrg    const char *from_type,
27681ab64890Smrg    XLCd to_lcd,
27691ab64890Smrg    const char *to_type)
27701ab64890Smrg{
27711ab64890Smrg    return create_conv(from_lcd, &stdc_mbstowcs_methods);
27721ab64890Smrg}
27731ab64890Smrg
27741ab64890Smrgstatic XlcConvMethodsRec stdc_wcstombs_methods = {
27751ab64890Smrg    close_converter,
27761ab64890Smrg    stdc_wcstombs,
27771ab64890Smrg    NULL
27781ab64890Smrg};
27791ab64890Smrg
27801ab64890Smrgstatic XlcConv
27811ab64890Smrgopen_stdc_wcstombs(
27821ab64890Smrg    XLCd from_lcd,
27831ab64890Smrg    const char *from_type,
27841ab64890Smrg    XLCd to_lcd,
27851ab64890Smrg    const char *to_type)
27861ab64890Smrg{
27871ab64890Smrg    return create_conv(from_lcd, &stdc_wcstombs_methods);
27881ab64890Smrg}
27891ab64890Smrg
27901ab64890Smrgstatic XlcConvMethodsRec stdc_wcstocts_methods = {
27911ab64890Smrg    close_converter,
27921ab64890Smrg    stdc_wcstocts,
27931ab64890Smrg    NULL
27941ab64890Smrg};
27951ab64890Smrg
27961ab64890Smrgstatic XlcConv
27971ab64890Smrgopen_stdc_wcstocts(
27981ab64890Smrg    XLCd from_lcd,
27991ab64890Smrg    const char *from_type,
28001ab64890Smrg    XLCd to_lcd,
28011ab64890Smrg    const char *to_type)
28021ab64890Smrg{
28031ab64890Smrg    return create_conv(from_lcd, &stdc_wcstocts_methods);
28041ab64890Smrg}
28051ab64890Smrg
28061ab64890Smrgstatic XlcConvMethodsRec stdc_wcstostr_methods = {
28071ab64890Smrg    close_converter,
28081ab64890Smrg    stdc_wcstostr,
28091ab64890Smrg    NULL
28101ab64890Smrg};
28111ab64890Smrg
28121ab64890Smrgstatic XlcConv
28131ab64890Smrgopen_stdc_wcstostr(
28141ab64890Smrg    XLCd from_lcd,
28151ab64890Smrg    const char *from_type,
28161ab64890Smrg    XLCd to_lcd,
28171ab64890Smrg    const char *to_type)
28181ab64890Smrg{
28191ab64890Smrg    return create_conv(from_lcd, &stdc_wcstostr_methods);
28201ab64890Smrg}
28211ab64890Smrg
28221ab64890Smrgstatic XlcConvMethodsRec stdc_wcstocs_methods = {
28231ab64890Smrg    close_converter,
28241ab64890Smrg    stdc_wcstocs,
28251ab64890Smrg    NULL
28261ab64890Smrg};
28271ab64890Smrg
28281ab64890Smrgstatic XlcConv
28291ab64890Smrgopen_stdc_wcstocs(
28301ab64890Smrg    XLCd from_lcd,
28311ab64890Smrg    const char *from_type,
28321ab64890Smrg    XLCd to_lcd,
28331ab64890Smrg    const char *to_type)
28341ab64890Smrg{
28351ab64890Smrg    return create_conv(from_lcd, &stdc_wcstocs_methods);
28361ab64890Smrg}
28371ab64890Smrg
28381ab64890Smrgstatic XlcConvMethodsRec stdc_wctocs_methods = {
28391ab64890Smrg    close_converter,
28401ab64890Smrg    stdc_wctocs,
28411ab64890Smrg    NULL
28421ab64890Smrg};
28431ab64890Smrg
28441ab64890Smrgstatic XlcConv
28451ab64890Smrgopen_stdc_wctocs(
28461ab64890Smrg    XLCd from_lcd,
28471ab64890Smrg    const char *from_type,
28481ab64890Smrg    XLCd to_lcd,
28491ab64890Smrg    const char *to_type)
28501ab64890Smrg{
28511ab64890Smrg    return create_conv(from_lcd, &stdc_wctocs_methods);
28521ab64890Smrg}
28531ab64890Smrg
28541ab64890Smrgstatic XlcConvMethodsRec stdc_ctstowcs_methods = {
28551ab64890Smrg    close_converter,
28561ab64890Smrg    stdc_ctstowcs,
28571ab64890Smrg    NULL
28581ab64890Smrg};
28591ab64890Smrg
28601ab64890Smrgstatic XlcConv
28611ab64890Smrgopen_stdc_ctstowcs(
28621ab64890Smrg    XLCd from_lcd,
28631ab64890Smrg    const char *from_type,
28641ab64890Smrg    XLCd to_lcd,
28651ab64890Smrg    const char *to_type)
28661ab64890Smrg{
28671ab64890Smrg    return create_conv(from_lcd, &stdc_ctstowcs_methods);
28681ab64890Smrg}
28691ab64890Smrg
28701ab64890Smrgstatic XlcConvMethodsRec stdc_cstowcs_methods = {
28711ab64890Smrg    close_converter,
28721ab64890Smrg    stdc_cstowcs,
28731ab64890Smrg    NULL
28741ab64890Smrg};
28751ab64890Smrg
28761ab64890Smrgstatic XlcConv
28771ab64890Smrgopen_stdc_cstowcs(
28781ab64890Smrg    XLCd from_lcd,
28791ab64890Smrg    const char *from_type,
28801ab64890Smrg    XLCd to_lcd,
28811ab64890Smrg    const char *to_type)
28821ab64890Smrg{
28831ab64890Smrg    return create_conv(from_lcd, &stdc_cstowcs_methods);
28841ab64890Smrg}
28851ab64890Smrg
28861ab64890Smrgstatic XlcConvMethodsRec stdc_strtowcs_methods = {
28871ab64890Smrg    close_converter,
28881ab64890Smrg    stdc_strtowcs,
28891ab64890Smrg    NULL
28901ab64890Smrg};
28911ab64890Smrg
28921ab64890Smrgstatic XlcConv
28931ab64890Smrgopen_stdc_strtowcs(
28941ab64890Smrg    XLCd from_lcd,
28951ab64890Smrg    const char *from_type,
28961ab64890Smrg    XLCd to_lcd,
28971ab64890Smrg    const char *to_type)
28981ab64890Smrg{
28991ab64890Smrg    return create_conv(from_lcd, &stdc_strtowcs_methods);
29001ab64890Smrg}
29011ab64890Smrg
29021ab64890Smrg#endif /* STDCVT */
29031ab64890Smrg
29041ab64890Smrgstatic XlcConvMethodsRec mbstowcs_methods = {
29051ab64890Smrg    close_converter,
29061ab64890Smrg    mbstowcs_org,
29071ab64890Smrg    NULL
29081ab64890Smrg};
29091ab64890Smrg
29101ab64890Smrgstatic XlcConv
29111ab64890Smrgopen_mbstowcs(
29121ab64890Smrg    XLCd from_lcd,
29131ab64890Smrg    const char *from_type,
29141ab64890Smrg    XLCd to_lcd,
29151ab64890Smrg    const char *to_type)
29161ab64890Smrg{
29171ab64890Smrg    return create_conv(from_lcd, &mbstowcs_methods);
29181ab64890Smrg}
29191ab64890Smrg
29201ab64890Smrgstatic XlcConvMethodsRec wcstombs_methods = {
29211ab64890Smrg    close_converter,
29221ab64890Smrg    wcstombs_org,
29231ab64890Smrg    NULL
29241ab64890Smrg};
29251ab64890Smrg
29261ab64890Smrgstatic XlcConv
29271ab64890Smrgopen_wcstombs(
29281ab64890Smrg    XLCd from_lcd,
29291ab64890Smrg    const char *from_type,
29301ab64890Smrg    XLCd to_lcd,
29311ab64890Smrg    const char *to_type)
29321ab64890Smrg{
29331ab64890Smrg    return create_conv(from_lcd, &wcstombs_methods);
29341ab64890Smrg}
29351ab64890Smrg
29361ab64890Smrgstatic XlcConvMethodsRec wcstocts_methods = {
29371ab64890Smrg    close_converter,
29381ab64890Smrg    wcstocts,
29391ab64890Smrg    NULL
29401ab64890Smrg};
29411ab64890Smrg
29421ab64890Smrgstatic XlcConv
29431ab64890Smrgopen_wcstocts(
29441ab64890Smrg    XLCd from_lcd,
29451ab64890Smrg    const char *from_type,
29461ab64890Smrg    XLCd to_lcd,
29471ab64890Smrg    const char *to_type)
29481ab64890Smrg{
29491ab64890Smrg    return create_conv(from_lcd, &wcstocts_methods);
29501ab64890Smrg}
29511ab64890Smrg
29521ab64890Smrgstatic XlcConvMethodsRec wcstostr_methods = {
29531ab64890Smrg    close_converter,
29541ab64890Smrg    wcstostr,
29551ab64890Smrg    NULL
29561ab64890Smrg};
29571ab64890Smrg
29581ab64890Smrgstatic XlcConv
29591ab64890Smrgopen_wcstostr(
29601ab64890Smrg    XLCd from_lcd,
29611ab64890Smrg    const char *from_type,
29621ab64890Smrg    XLCd to_lcd,
29631ab64890Smrg    const char *to_type)
29641ab64890Smrg{
29651ab64890Smrg    return create_conv(from_lcd, &wcstostr_methods);
29661ab64890Smrg}
29671ab64890Smrg
29681ab64890Smrgstatic XlcConvMethodsRec wcstocs_methods = {
29691ab64890Smrg    close_converter,
29701ab64890Smrg    wcstocs,
29711ab64890Smrg    NULL
29721ab64890Smrg};
29731ab64890Smrg
29741ab64890Smrgstatic XlcConv
29751ab64890Smrgopen_wcstocs(
29761ab64890Smrg    XLCd from_lcd,
29771ab64890Smrg    const char *from_type,
29781ab64890Smrg    XLCd to_lcd,
29791ab64890Smrg    const char *to_type)
29801ab64890Smrg{
29811ab64890Smrg    return create_conv(from_lcd, &wcstocs_methods);
29821ab64890Smrg}
29831ab64890Smrg
29841ab64890Smrgstatic XlcConvMethodsRec wctocs_methods = {
29851ab64890Smrg    close_converter,
29861ab64890Smrg    wctocs,
29871ab64890Smrg    NULL
29881ab64890Smrg};
29891ab64890Smrg
29901ab64890Smrgstatic XlcConv
29911ab64890Smrgopen_wctocs(
29921ab64890Smrg    XLCd from_lcd,
29931ab64890Smrg    const char *from_type,
29941ab64890Smrg    XLCd to_lcd,
29951ab64890Smrg    const char *to_type)
29961ab64890Smrg{
29971ab64890Smrg    return create_conv(from_lcd, &wctocs_methods);
29981ab64890Smrg}
29991ab64890Smrg
30001ab64890Smrgstatic XlcConvMethodsRec ctstowcs_methods = {
30011ab64890Smrg    close_converter,
30021ab64890Smrg    ctstowcs,
30031ab64890Smrg    NULL
30041ab64890Smrg};
30051ab64890Smrg
30061ab64890Smrgstatic XlcConv
30071ab64890Smrgopen_ctstowcs(
30081ab64890Smrg    XLCd from_lcd,
30091ab64890Smrg    const char *from_type,
30101ab64890Smrg    XLCd to_lcd,
30111ab64890Smrg    const char *to_type)
30121ab64890Smrg{
30131ab64890Smrg    return create_conv(from_lcd, &ctstowcs_methods);
30141ab64890Smrg}
30151ab64890Smrg
30161ab64890Smrgstatic XlcConvMethodsRec cstowcs_methods = {
30171ab64890Smrg    close_converter,
30181ab64890Smrg    cstowcs,
30191ab64890Smrg    NULL
30201ab64890Smrg};
30211ab64890Smrg
30221ab64890Smrgstatic XlcConv
30231ab64890Smrgopen_cstowcs(
30241ab64890Smrg    XLCd from_lcd,
30251ab64890Smrg    const char *from_type,
30261ab64890Smrg    XLCd to_lcd,
30271ab64890Smrg    const char *to_type)
30281ab64890Smrg{
30291ab64890Smrg    return create_conv(from_lcd, &cstowcs_methods);
30301ab64890Smrg}
30311ab64890Smrg
30321ab64890Smrgstatic XlcConvMethodsRec strtowcs_methods = {
30331ab64890Smrg    close_converter,
30341ab64890Smrg    strtowcs,
30351ab64890Smrg    NULL
30361ab64890Smrg};
30371ab64890Smrg
30381ab64890Smrgstatic XlcConv
30391ab64890Smrgopen_strtowcs(
30401ab64890Smrg    XLCd from_lcd,
30411ab64890Smrg    const char *from_type,
30421ab64890Smrg    XLCd to_lcd,
30431ab64890Smrg    const char *to_type)
30441ab64890Smrg{
30451ab64890Smrg    return create_conv(from_lcd, &strtowcs_methods);
30461ab64890Smrg}
30471ab64890Smrg
30481ab64890Smrg/* -------------------------------------------------------------------------- */
30491ab64890Smrg/*				Loader                                        */
30501ab64890Smrg/* -------------------------------------------------------------------------- */
30511ab64890Smrg
30521ab64890SmrgXLCd
30531ab64890Smrg_XlcGenericLoader(
30541ab64890Smrg    const char *name)
30551ab64890Smrg{
30561ab64890Smrg    XLCd lcd;
30571ab64890Smrg#ifdef STDCVT
30581ab64890Smrg    XLCdGenericPart *gen;
30591ab64890Smrg#endif
30601ab64890Smrg
30611ab64890Smrg    lcd = _XlcCreateLC(name, _XlcGenericMethods);
30621ab64890Smrg
30631ab64890Smrg    if (lcd == NULL)
30641ab64890Smrg	return lcd;
30651ab64890Smrg
30661ab64890Smrg    default_GL_charset = _XlcGetCharSet("ISO8859-1:GL");
30671ab64890Smrg    default_GR_charset = _XlcGetCharSet("ISO8859-1:GR");
30681ab64890Smrg
30691ab64890Smrg    _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCompoundText, open_mbstocts);
30701ab64890Smrg    _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNString,       open_mbstostr);
30711ab64890Smrg    _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet,      open_mbstocs);
30721ab64890Smrg    _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar,         open_mbtocs);
30731ab64890Smrg    _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte, open_ctstombs);
30741ab64890Smrg    _XlcSetConverter(lcd, XlcNString,    lcd, XlcNMultiByte,    open_strtombs);
30751ab64890Smrg    _XlcSetConverter(lcd, XlcNCharSet,   lcd, XlcNMultiByte,    open_cstombs);
307661b2299dSmrg
30771ab64890Smrg#ifdef STDCVT
30781ab64890Smrg     gen = XLC_GENERIC_PART(lcd);
30791ab64890Smrg
30801ab64890Smrg     if (gen->use_stdc_env != True) {
30811ab64890Smrg#endif
30821ab64890Smrg        _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar,     open_mbstowcs);
30831ab64890Smrg        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNMultiByte,    open_wcstombs);
30841ab64890Smrg        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNCompoundText, open_wcstocts);
30851ab64890Smrg        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNString,       open_wcstostr);
30861ab64890Smrg        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNCharSet,      open_wcstocs);
30871ab64890Smrg        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNChar,         open_wctocs);
30881ab64890Smrg        _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar,  open_ctstowcs);
30891ab64890Smrg        _XlcSetConverter(lcd, XlcNString,    lcd, XlcNWideChar,     open_strtowcs);
30901ab64890Smrg        _XlcSetConverter(lcd, XlcNCharSet,   lcd, XlcNWideChar,     open_cstowcs);
30911ab64890Smrg#ifdef STDCVT
30921ab64890Smrg    }
30931ab64890Smrg#endif
30941ab64890Smrg
30951ab64890Smrg#ifdef STDCVT
30961ab64890Smrg    if (gen->use_stdc_env == True) {
30971ab64890Smrg        _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar,     open_stdc_mbstowcs);
30981ab64890Smrg        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNMultiByte,    open_stdc_wcstombs);
30991ab64890Smrg        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNCompoundText, open_stdc_wcstocts);
31001ab64890Smrg        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNString,       open_stdc_wcstostr);
31011ab64890Smrg        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNCharSet,      open_stdc_wcstocs);
31021ab64890Smrg        _XlcSetConverter(lcd, XlcNWideChar,  lcd, XlcNChar,         open_stdc_wctocs);
31031ab64890Smrg        _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar,  open_stdc_ctstowcs);
31041ab64890Smrg        _XlcSetConverter(lcd, XlcNString,    lcd, XlcNWideChar,     open_stdc_strtowcs);
31051ab64890Smrg        _XlcSetConverter(lcd, XlcNCharSet,   lcd, XlcNWideChar,     open_stdc_cstowcs);
31061ab64890Smrg    }
31071ab64890Smrg#endif
31081ab64890Smrg
31091ab64890Smrg    _XlcAddUtf8Converters(lcd);
31101ab64890Smrg
31111ab64890Smrg    return lcd;
31121ab64890Smrg}
3113