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