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