From dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0 Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 12 Sep 2011 11:27:51 +0200 Subject: Synchronised line endinge with release branch --- libX11/modules/lc/gen/lcGenConv.c | 6296 ++++++++++++++++++------------------- libX11/modules/lc/xlocale/lcJis.c | 1888 +++++------ 2 files changed, 4092 insertions(+), 4092 deletions(-) (limited to 'libX11/modules/lc') diff --git a/libX11/modules/lc/gen/lcGenConv.c b/libX11/modules/lc/gen/lcGenConv.c index c222c1f2a..7a113a78a 100644 --- a/libX11/modules/lc/gen/lcGenConv.c +++ b/libX11/modules/lc/gen/lcGenConv.c @@ -1,3148 +1,3148 @@ -/* - * Copyright 1992, 1993 by TOSHIBA Corp. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of TOSHIBA not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. TOSHIBA make no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - * Author: Katsuhisa Yano TOSHIBA Corp. - * mopi@osa.ilab.toshiba.co.jp - */ -/* - * (c) Copyright 1995 FUJITSU LIMITED - * This is source code modified by FUJITSU LIMITED under the Joint - * Development Agreement for the CDE/Motif PST. - * - * Modifier: Masayoshi Shimamura FUJITSU LIMITED - * - */ -/* - * 2000 - * Modifier: Ivan Pascal The XFree86 Project - */ - -/* - * A generic locale loader for all kinds of ISO-2022 based codesets. - * Supports: all locales. - * How: Provides generic converters for ISO-2022 based codesets. Extensible as - * far as ISO-2022 is extensible: codesets can be given by name in the - * stream. Overall distinction between GL (0x00..0x7f) and GR (0x80..0xff). - * In every chunk between escape sequences, the number of bytes per - * character (char_size) is constant. - * Platforms: all systems. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include "Xlibint.h" -#include "XlcGeneric.h" -#include - -#if !defined(Lynx_22) && !defined(X_LOCALE) -#define STDCVT -#endif - -typedef struct _CTDataRec { - const char *name; - const char *encoding; /* Compound Text encoding */ -} CTDataRec, *CTData; - -static CTDataRec directionality_data[] = -{ - { "BEGIN_LEFT-TO-RIGHT_TEXT", "\2331]" }, - { "BEGIN_RIGHT-TO-LEFT_TEXT", "\2332]" }, - { "END_OF_STRING", "\233]" }, -}; - -typedef struct _StateRec { - XLCd lcd; - /* CT state */ - XlcCharSet charset; /* charset of current state */ - XlcCharSet GL_charset; /* charset of initial state in GL */ - XlcCharSet GR_charset; /* charset of initial state in GR */ - /* MB shift state */ - CodeSet GL_codeset; - CodeSet GR_codeset; -} StateRec, *State; - -#define GR 0x80 /* begins right-side (non-ascii) region */ -#define GL 0x7f /* ends left-side (ascii) region */ -#define ESC 0x1b -#define CSI 0x9b -#define STX 0x02 - -#define isrightside(c) ((c) & GR) -#define isleftside(c) (!isrightside(c)) - -/* Forward declarations for local routines. */ -static int mbstocts (XlcConv conv, XPointer *from, int *from_left, - XPointer *to, int *to_left, XPointer *args, int num_args); -static int ctstombs (XlcConv conv, XPointer *from, int *from_left, - XPointer *to, int *to_left, XPointer *args, int num_args); -static int cstombs (XlcConv conv, XPointer *from, int *from_left, - XPointer *to, int *to_left, XPointer *args, int num_args); - -/* ------------------------------------------------------------------------- */ -/* Misc */ -/* ------------------------------------------------------------------------- */ - -static int -compare( - const char *src, - const char *encoding, - int length) -{ - const char *start = src; - - while (length-- > 0) { - if (*src++ != *encoding++) - return 0; - if (*encoding == '\0') - return src - start; - } - - return 0; -} - -static unsigned long -conv_to_dest( - Conversion conv, - unsigned long code) -{ - int i; - int conv_num = conv->conv_num; - FontScope convlist = conv->convlist; - - for (i = 0; i < conv_num; i++) { - if (convlist[i].start <= code && code <= convlist[i].end) { - switch (convlist[i].shift_direction) { - case '+': - return(code + convlist[i].shift); - case '-': - return(code - convlist[i].shift); - default: - return(code); - } - } - } - - return(code); -} - -static unsigned long -conv_to_source( - Conversion conv, - unsigned long code) -{ - int i; - int conv_num; - FontScope convlist; - unsigned long start_p; - unsigned long start_m; - unsigned long end_p; - unsigned long end_m; - - if (!conv) - return(code); - - conv_num = conv->conv_num; - convlist = conv->convlist; - - for (i = 0; i < conv_num; i++) { - switch (convlist[i].shift_direction) { - case '+': - start_p = convlist[i].start + convlist[i].shift; - end_p = convlist[i].end + convlist[i].shift; - if (start_p <= code && code <= end_p) - return(code - convlist[i].shift); - break; - case '-': - start_m = convlist[i].start - convlist[i].shift; - end_m = convlist[i].end - convlist[i].shift; - if (start_m <= code && code <= end_m) - return(code + convlist[i].shift); - break; - default: - continue; - } - } - - return(code); -} - -static unsigned long -mb_to_gi( - unsigned long mb, - CodeSet codeset) -{ - int i; - unsigned long mb_tmp, mask = 0; - - if (codeset->mbconv) { - mb_tmp = conv_to_dest(codeset->mbconv, mb); - if (mb_tmp != mb) - return(mb_tmp); - } - - if (codeset->side == XlcC0 || codeset->side == XlcGL || - codeset->side == XlcC1 || codeset->side == XlcGR) { - - for (i = 0; i < codeset->length; i++) - mask = (mask << 8) | GL; - mb = mb & mask; - } - - return(mb); -} - -static unsigned long -gi_to_mb( - unsigned long glyph_index, - CodeSet codeset) -{ - int i; - unsigned long mask = 0; - - if (codeset->side == XlcC1 || codeset->side == XlcGR) { - for (i = 0; i < codeset->length; i++) - mask = (mask << 8) | GR; - glyph_index = glyph_index | mask; - } - - if (codeset->mbconv) - return( conv_to_source(codeset->mbconv, glyph_index) ); - - return(glyph_index); -} - -static Bool -gi_to_wc( - XLCd lcd, - unsigned long glyph_index, - CodeSet codeset, - wchar_t *wc) -{ - unsigned char mask = 0; - unsigned long wc_encoding = codeset->wc_encoding; - int length = codeset->length; - unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits); - - mask = (1 << wc_shift_bits) - 1 ; - - for (*wc = 0, length--; length >= 0; length--) - *wc = (*wc << wc_shift_bits) | ((glyph_index >> (length * 8 )) & mask); - - *wc = *wc | wc_encoding; - - return(True); -} - -static Bool -wc_to_gi( - XLCd lcd, - wchar_t wc, - unsigned long *glyph_index, - CodeSet *codeset) -{ - int i; - unsigned char mask = 0; - unsigned long wc_encoding; - unsigned long wc_encode_mask = XLC_GENERIC(lcd, wc_encode_mask); - unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits); - int codeset_num = XLC_GENERIC(lcd, codeset_num); - CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); - - wc_encoding = wc & wc_encode_mask; - for (*codeset = NULL, i = 0; i < codeset_num; i++) { - if (wc_encoding == codeset_list[i]->wc_encoding) { - *codeset = codeset_list[i]; - break; - } - } - if (*codeset == NULL) - return(False); - - mask = (1 << wc_shift_bits) - 1 ; - - wc = wc & ~wc_encode_mask; - for (*glyph_index = 0, i = (*codeset)->length - 1; i >= 0; i--) - *glyph_index = (*glyph_index << 8) | - ( ((unsigned long)wc >> (i * wc_shift_bits)) & mask ); - - return(True); -} - -static CodeSet -mb_parse_codeset( - State state, - int num, - const char **inbufptr, - int *from_left) -{ - int len; - int from_len = (*from_left) + 1; - const char *src = (*inbufptr) - 1; - ParseInfo *mb_parse_list = XLC_GENERIC(state->lcd, mb_parse_list); - ParseInfo parse_info; - CodeSet codeset; - - for (--num ; (parse_info = mb_parse_list[num]) != NULL; num++) { - len = compare(src, parse_info->encoding, from_len); - if (len > 0) { - codeset = parse_info->codeset; - if (parse_info->type == E_LSL) - state->GL_codeset = codeset; - else if (parse_info->type == E_LSR) - state->GR_codeset = codeset; - --len; - *inbufptr += len; - *from_left -= len; - return codeset; - } - } - return (CodeSet) NULL; -} - -static CodeSet -byteM_parse_codeset( - XLCd lcd, - const char *inbufptr) -{ - unsigned char ch; - CodeSet codeset; - ByteInfoList byteM; - ByteInfoListRec byteM_rec; - ByteInfo byteinfo; - ByteInfoRec byteinfo_rec; - Bool hit = False; - int i, j, k; - - int codeset_num = XLC_GENERIC(lcd, codeset_num); - CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); - - for (i = 0; i < codeset_num; i++) { - codeset = codeset_list[i]; - byteM = codeset->byteM; - if (codeset->side != XlcNONE || byteM == NULL) - continue; - - for (j = 0; j < codeset->length; j++) { - ch = *((unsigned char *)(inbufptr + j)); - byteM_rec = byteM[j]; - byteinfo = byteM_rec.byteinfo; - - for (hit = False, k = 0; k < byteM_rec.byteinfo_num; k++) { - byteinfo_rec = byteinfo[k]; - if (byteinfo_rec.start <= ch && ch <= byteinfo_rec.end) { - hit = True; - break; - } - } - - if (!hit) - break; - } - - if (hit) - return(codeset); - } - - return(NULL); -} - -#define GLGR_parse_codeset(ch) \ - (isrightside(ch) ? (state->GR_codeset) : \ - (state->GL_codeset) ) - -static XlcCharSet -gi_parse_charset( - unsigned long glyph_index, - CodeSet codeset) -{ - int i; - XlcCharSet *charset_list = codeset->charset_list; - int num_charsets = codeset->num_charsets; - ExtdSegment ctextseg = codeset->ctextseg; - XlcCharSet charset = NULL; - int area_num; - FontScope area; - - /* lockup ct sequence */ - for (i = 0; i < num_charsets; i++) { - charset = charset_list[i]; - if (*charset->ct_sequence != '\0') - break; - } - if (i >= num_charsets) - return(NULL); - - if (charset->source != CSsrcStd) - return (charset); - - if (!ctextseg) - return(charset); - - area = ctextseg->area; - area_num = ctextseg->area_num; - - for (i = 0; i < area_num; i++) { - - if (area[i].start <= glyph_index && glyph_index <= area[i].end) { - - charset = ctextseg->charset; - - if (*charset->ct_sequence == '\0') - return(NULL); - - break; - } - } - - return(charset); -} - -static Bool -ct_parse_csi( - const char *inbufptr, - int *ctr_seq_len) -{ - int i; - int num = sizeof(directionality_data) / sizeof(directionality_data[0]); - - for (i = 0; i < num; i++) { - if ( !(*ctr_seq_len = strlen(directionality_data[i].encoding)) ) - continue; - - if ( strncmp(inbufptr, directionality_data[i].encoding, - *ctr_seq_len) == 0) - return(True); - } - - return(False); -} - -static int -cmp_esc_sequence( - const char *inbufptr, - XlcCharSet charset) -{ - int seq_len, name_len, total_len; - unsigned char byte_m, byte_l; - const char *ct_sequence = charset->ct_sequence; - const char *encoding_name = charset->encoding_name; - - /* check esc sequence */ - if ( !(seq_len = strlen(ct_sequence) ) ) - return(0); - if ( strncmp(inbufptr, ct_sequence, seq_len) != 0) - return(0); - - /* Standard Character Set Encoding ? */ - if (charset->source == CSsrcStd) - return(seq_len); - - /* - * Non-Standard Character Set Encoding - * - * +--- ---+-----+-----+-----+---- ----+-----+-----+------- ------+ - * | ctseq | M | L | encoding name | STX | contents | - * +--- ---+-----+-----+-----+---- ----+-----+-----+------- ------+ - * 4bytes 1byte 1byte variable length 1byte variable length - * | | - * +----------------------------------------------+ - * rest length = ((M - 128) * 128) + (L - 128) - */ - - /* get length of encoding name */ - inbufptr += seq_len; - byte_m = *inbufptr++; - byte_l = *inbufptr++; - name_len = strlen(encoding_name); - - if (((byte_m - 128) * 128 + (byte_l - 128) - 1) < name_len) - return(0); - - if ( _XlcNCompareISOLatin1(inbufptr, encoding_name, name_len) != 0 ) - return(0); - - /* check STX (Start of Text) */ - inbufptr = inbufptr + name_len; - if ( *inbufptr != STX ) - return(0); - - total_len = seq_len + name_len + 3; - return(total_len); -} - -static Bool -ct_parse_charset( - XLCd lcd, - const char *inbufptr, - XlcCharSet *charset, - int *ctr_seq_len) -{ - int i, j; - ExtdSegment ctextseg; - int num_charsets; - XlcCharSet *charset_list; - CodeSet codeset; - int codeset_num = XLC_GENERIC(lcd, codeset_num); - CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); - int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num); - SegConv segment_conv = XLC_GENERIC(lcd, segment_conv); - - /* get charset from XLC_XLOCALE by escape sequence */ - - for (i = 0; i < codeset_num; i++) { - codeset = codeset_list[i]; - - num_charsets = codeset->num_charsets; - charset_list = codeset->charset_list; - ctextseg = codeset->ctextseg; - - for (j = 0; j < num_charsets; j++) { - *charset = charset_list[j]; - if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) - return(True); - } - - if (ctextseg) { - *charset = ctextseg->charset; - if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) - return(True); - } - } - - /* get charset from XLC_SEGMENTCONVERSION by escape sequence */ - - if (!segment_conv) - return(False); - - for (i = 0; i < segment_conv_num; i++) { - *charset = segment_conv[i].source; - if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) - return(True); - *charset = segment_conv[i].dest; - if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) - return(True); - } - - return(False); -} - -static Bool -segment_conversion( - XLCd lcd, - XlcCharSet *charset, - unsigned long *glyph_index) -{ - int i; - int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num); - SegConv segment_conv = XLC_GENERIC(lcd, segment_conv); - FontScopeRec range; - ConversionRec conv_rec; - - if (!segment_conv) - return(True); - - for (i = 0; i < segment_conv_num; i++) { - if (segment_conv[i].source == *charset) - break; - } - - if (i >= segment_conv_num) - return(True); - - range = segment_conv[i].range; - if (*glyph_index < range.start || range.end < *glyph_index) - return(True); - - *charset = segment_conv[i].dest; - conv_rec.conv_num = segment_conv[i].conv_num; - conv_rec.convlist = segment_conv[i].conv; - *glyph_index = conv_to_dest(&conv_rec, *glyph_index); - - return(True); -} - -static CodeSet -_XlcGetCodeSetFromName( - XLCd lcd, - const char *name) -{ - int i, j; - XlcCharSet charset; - int num_charsets; - XlcCharSet *charset_list; - CodeSet codeset; - - int codeset_num = XLC_GENERIC(lcd, codeset_num); - CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); - - for (i = 0; i < codeset_num; i++) { - codeset = codeset_list[i]; - - num_charsets = codeset->num_charsets; - charset_list = codeset->charset_list; - - for (j = 0; j < num_charsets; j++) { - charset = charset_list[j]; - - if (!strlen(charset->name)) - continue; - if ( strcmp(charset->name, name) == 0) - return(codeset); - } - } - - return(NULL); -} - -static Bool -_XlcGetCodeSetFromCharSet( - XLCd lcd, - XlcCharSet charset, - CodeSet *codeset, - unsigned long *glyph_index) -{ - int j, num; - CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); - XlcCharSet *charset_list; - int codeset_num, num_charsets; - Conversion ctconv; - unsigned long glyph_index_tmp = 0; - ExtdSegment ctextseg; - - codeset_num = XLC_GENERIC(lcd, codeset_num); - - for (num = 0 ; num < codeset_num; num++) { - *codeset = codeset_list[num]; - ctconv = (*codeset)->ctconv; - ctextseg = (*codeset)->ctextseg; - - num_charsets = (*codeset)->num_charsets; - charset_list = (*codeset)->charset_list; - - glyph_index_tmp = conv_to_source(ctconv, *glyph_index); - - if (charset->source == CSsrcStd) { - - /* Standard Character Set Encoding */ - if (glyph_index_tmp == *glyph_index) { - for (j = 0; j < num_charsets; j++) { - if (charset_list[j] == charset) { - goto end_loop; - } - } - } - - } else { - - /* Non-Standard Character Set Encoding */ - for (j = 0; j < num_charsets; j++) { - if (charset_list[j] == charset) { - goto end_loop; - } - } - - if (glyph_index_tmp != *glyph_index) { - if (ctextseg && ctextseg->charset == charset) { - goto end_loop; - } - } - - } - - } - -end_loop: - if (num < codeset_num) { - *glyph_index = glyph_index_tmp; - return(True); - } - - return(False); -} - -#define check_string_encoding(codeset) (codeset->string_encoding) - -static void -output_ulong_value( - char *outbufptr, - unsigned long code, - int length, - XlcSide side) -{ - int i; - - for (i = (length - 1) * 8; i >= 0; i -= 8) { - *outbufptr = ( code >> i) & 0xff; - - if (side == XlcC0 || side == XlcGL) { - *outbufptr = *outbufptr & GL; - } else if (side == XlcC1 || side == XlcGR) { - *outbufptr = *outbufptr | GR; - } - - outbufptr++; - } -} - -/* -------------------------------------------------------------------------- */ -/* Init */ -/* -------------------------------------------------------------------------- */ - -static XlcCharSet default_GL_charset = 0; -static XlcCharSet default_GR_charset = 0; - -static void -init_state( - XlcConv conv) -{ - State state = (State) conv->state; - - /* for CT */ - state->charset = NULL; - state->GL_charset = default_GL_charset; - state->GR_charset = default_GR_charset; - - /* for MB shift state */ - state->GL_codeset = XLC_GENERIC(state->lcd, initial_state_GL); - state->GR_codeset = XLC_GENERIC(state->lcd, initial_state_GR); -} - -/* -------------------------------------------------------------------------- */ -/* Convert */ -/* -------------------------------------------------------------------------- */ - -static int -mbstowcs_org( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - unsigned char ch; - unsigned long mb = 0; - wchar_t wc; - - int length = 0, len_left = 0; - int unconv_num = 0; - int num; - - CodeSet codeset = NULL; - - const char *inbufptr = *from; - wchar_t *outbufptr = (wchar_t *) *to; - int from_size = *from_left; - - unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); - - if (from == NULL || *from == NULL) { - _XlcResetConverter(conv); - return( 0 ); - } - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - ch = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!ch) { - if (outbufptr) {*outbufptr++ = L'\0';} - (*to_left)--; - - /* error check */ - if (len_left) { - unconv_num += (length - len_left); - len_left = 0; - } - - continue; - } - - /* same mb char data */ - if (len_left) - goto output_one_wc; - - /* next mb char data for single shift ? */ - if (mb_parse_table && (num = mb_parse_table[ch]) ) { - codeset = mb_parse_codeset(state, num, &inbufptr, from_left); - if (codeset != NULL) { - length = len_left = codeset->length; - mb = 0; - continue; - } - } - - /* next mb char data for byteM ? */ - if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) - goto next_mb_char; - - /* next mb char data for GL or GR side ? */ - if ((codeset = GLGR_parse_codeset(ch))) - goto next_mb_char; - - /* can't find codeset for the ch */ - unconv_num++; - continue; - -next_mb_char: - length = len_left = codeset->length; - mb = 0; - -output_one_wc: - mb = (mb << 8) | ch; /* 1 byte left shift */ - len_left--; - - /* last of one mb char data */ - if (!len_left) { - gi_to_wc(lcd, mb_to_gi(mb, codeset), codeset, &wc); - if (outbufptr) {*outbufptr++ = wc;} - (*to_left)--; - } - - } /* end of while */ - - /* error check on last char */ - if (len_left) { - inbufptr -= (length - len_left); - (*from_left) += (length - len_left); - unconv_num += (length - len_left); - } - - *from = (XPointer) ((const char *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -stdc_mbstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - const char *src = *((const char **) from); - wchar_t *dst = *((wchar_t **) to); - int src_left = *from_left; - int dst_left = *to_left; - int length, unconv_num = 0; - - while (src_left > 0 && dst_left > 0) { - length = mbtowc(dst, src, src_left); - - if (length > 0) { - src += length; - src_left -= length; - if (dst) - dst++; - dst_left--; - } else if (length < 0) { - src++; - src_left--; - unconv_num++; - } else { - /* null ? */ - src++; - src_left--; - if (dst) - *dst++ = L'\0'; - dst_left--; - } - } - - *from = (XPointer) src; - if (dst) - *to = (XPointer) dst; - *from_left = src_left; - *to_left = dst_left; - - return unconv_num; -} - -static int -wcstombs_org( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - char *encoding; - unsigned long mb, glyph_index; - wchar_t wc; - - int length; - int unconv_num = 0; - - CodeSet codeset; - - const wchar_t *inbufptr = (const wchar_t *) *from; - char *outbufptr = *to; - int from_size = *from_left; - - const char *default_string = XLC_PUBLIC(lcd, default_string); - int defstr_len = strlen(default_string); - - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - wc = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!wc) { - if (outbufptr) {*outbufptr++ = '\0';} - (*to_left)--; - - continue; - } - - /* convert */ - if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { - - /* output default_string of XDefaultString() */ - if (*to_left < defstr_len) - break; - if (outbufptr) { - strncpy((char *)outbufptr, default_string, defstr_len); - outbufptr += defstr_len; - } - (*to_left) -= defstr_len; - - unconv_num++; - - } else { - mb = gi_to_mb(glyph_index, codeset); - if (codeset->parse_info) { - Bool need_shift = False; - switch (codeset->parse_info->type) { - case E_LSL : - if (codeset != state->GL_codeset) { - need_shift = True; - state->GL_codeset = codeset; - } - break; - case E_LSR : - if (codeset != state->GR_codeset) { - need_shift = True; - state->GR_codeset = codeset; - } - break; - /* case E_SS */ - default: - need_shift = True; - } - - /* output shift sequence */ - if (need_shift) { - encoding = codeset->parse_info->encoding; - length = strlen(encoding); - if (*to_left < length) - break; - if (outbufptr) { - strncpy((char *)outbufptr, encoding, length); - outbufptr += length; - } - (*to_left) -= length; - } - } - - /* output characters */ - length = codeset->length; - if (*to_left < length) - break; - - if (outbufptr) { - output_ulong_value(outbufptr, mb, length, XlcNONE); - outbufptr += length; - } - - (*to_left) -= length; - } - - } /* end of while */ - - *from = (XPointer) ((const wchar_t *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -stdc_wcstombs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - const wchar_t *src = *((const wchar_t **) from); - char *dst = *((char **) to); - int src_left = *from_left; - int dst_left = *to_left; - int length, unconv_num = 0; - - while (src_left > 0 && dst_left >= MB_CUR_MAX) { - length = wctomb(dst, *src); /* XXX */ - - if (length > 0) { - src++; - src_left--; - if (dst) - dst += length; - dst_left -= length; - } else if (length < 0) { - src++; - src_left--; - unconv_num++; - } - } - - *from = (XPointer) src; - if (dst) - *to = (XPointer) dst; - *from_left = src_left; - *to_left = dst_left; - - return unconv_num; -} - -static int -wcstocts( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - unsigned long glyph_index; - wchar_t wc; - - int total_len, seq_len, name_len; - int unconv_num = 0; - Bool first_flag = True, standard_flag; - XlcSide side; - - CodeSet codeset; - XlcCharSet charset, old_charset = NULL; - const char *ct_sequence; - - const wchar_t *inbufptr = (const wchar_t *) *from; - char *outbufptr = *to; - int from_size = *from_left; - char *ext_seg_len = NULL; - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - wc = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!wc) { - if (outbufptr) {*outbufptr++ = '\0';} - (*to_left)--; - - continue; - } - - /* convert */ - if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { - unconv_num++; - continue; - } - - /* parse charset */ - if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) { - unconv_num++; - continue; - } - - /* Standard Character Set Encoding ? */ - standard_flag = charset->source == CSsrcStd ? True : False; - - /* - * Non-Standard Character Set Encoding - * - * +-----+-----+-----+-----+-----+-----+-----+---- ----+-----+-----+ - * | esc sequence | M | L | encoding name | STX | - * +-----+-----+-----+-----+-----+-----+-----+---- ----+-----+-----+ - * 4bytes 1byte 1byte variable length 1byte - * | | - * +-----------------------------------------+ - * name length = ((M - 128) * 128) + (L - 128) - */ - - /* make encoding data */ - ct_sequence = charset->ct_sequence; - side = charset->side; - seq_len = strlen(ct_sequence); - if (standard_flag) { - name_len = 0; - total_len = seq_len; - } else { - name_len = strlen(charset->encoding_name) + 1; - total_len = seq_len + name_len + 2; - } - - /* output escape sequence of CT */ - if ( (charset != old_charset) && - !(first_flag && charset->string_encoding) ){ - - if ( (ext_seg_len != NULL) && outbufptr) { - int i = (outbufptr - ext_seg_len) - 2; - *ext_seg_len++ = i / 128 + 128; - *ext_seg_len = i % 128 + 128; - ext_seg_len = NULL; - } - - if (*to_left < total_len + 1) { - unconv_num++; - break; - } - - if (outbufptr) { - strcpy((char *)outbufptr, ct_sequence); - outbufptr += seq_len; - - if (!standard_flag) { - const char *i = charset->encoding_name; - ext_seg_len = outbufptr; - outbufptr += 2; - for (; *i ; i++) - *outbufptr++ = ((*i >= 'A') && (*i <= 'Z')) ? - *i - 'A' + 'a' : *i; - *outbufptr++ = STX; - } - } - - (*to_left) -= total_len; - - first_flag = False; - old_charset = charset; - } - - /* output glyph index */ - if (codeset->ctconv) - glyph_index = conv_to_dest(codeset->ctconv, glyph_index); - if (*to_left < charset->char_size) { - unconv_num++; - break; - } - - if (outbufptr) { - output_ulong_value(outbufptr, glyph_index, charset->char_size, side); - outbufptr += charset->char_size; - } - - (*to_left) -= charset->char_size; - - } /* end of while */ - - if ( (ext_seg_len != NULL) && outbufptr) { - int i = (outbufptr - ext_seg_len) - 2; - *ext_seg_len++ = i / 128 + 128; - *ext_seg_len = i % 128 + 128; - } - - *from = (XPointer) ((const wchar_t *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -stdc_wcstocts( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left) * MB_CUR_MAX; - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = stdc_wcstombs(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = buf_ptr1 - buf_ptr2; - - unconv_num2 = mbstocts(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -static int -ctstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - unsigned char ch; - unsigned long glyph_index = 0; - wchar_t wc; - - int ctr_seq_len = 0, gi_len_left = 0, gi_len = 0; - int unconv_num = 0; - - CodeSet codeset = NULL; - XlcCharSet charset_tmp; - - const char *inbufptr = *from; - wchar_t *outbufptr = (wchar_t *) *to; - int from_size = *from_left; - - _XlcResetConverter(conv); /* ??? */ - - if (from == NULL || *from == NULL) { - _XlcResetConverter(conv); - return( 0 ); - } - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - ch = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!ch) { - if (outbufptr) {*outbufptr++ = L'\0';} - (*to_left)--; - - /* error check */ - if (gi_len_left) { - unconv_num += (gi_len - gi_len_left); - gi_len_left = 0; - } - - continue; - } - - /* same glyph_index data */ - if (gi_len_left) - goto output_one_wc; - - /* control sequence ? */ - if (ch == CSI) { - if ( !ct_parse_csi(inbufptr - 1, &ctr_seq_len) ) - goto skip_the_seg; - - if (*from_left + 1 < ctr_seq_len) { - inbufptr--; - (*from_left)++; - unconv_num += *from_left; - break; - } - - /* skip the control sequence */ - inbufptr += (ctr_seq_len - 1); - *from_left -= (ctr_seq_len - 1); - - continue; - } - - /* escape sequence ? */ - if (ch == ESC) { - if ( !ct_parse_charset(lcd, - inbufptr - 1, &state->charset, &ctr_seq_len) ) - goto skip_the_seg; - - if (state->charset->side == XlcC0 || - state->charset->side == XlcGL) - { - state->GL_charset = state->charset; - } - else if (state->charset->side == XlcC1 || - state->charset->side == XlcGR) - { - state->GR_charset = state->charset; - } - else if (state->charset->side == XlcGLGR) - { - state->GL_charset = state->charset; - state->GR_charset = state->charset; - } - - if (*from_left + 1 < ctr_seq_len) { - inbufptr--; - (*from_left)++; - unconv_num += *from_left; - break; - } - - /* skip the escape sequence */ - inbufptr += (ctr_seq_len - 1); - *from_left -= (ctr_seq_len - 1); - - continue; - } - - /* check current state */ - if (isleftside(ch)) - state->charset = state->GL_charset; - else - state->charset = state->GR_charset; - - gi_len = gi_len_left = state->charset->char_size; - glyph_index = 0; - -output_one_wc: - if (state->charset->side == XlcC1 || state->charset->side == XlcGR) - glyph_index = (glyph_index << 8) | (ch & GL); - else - glyph_index = (glyph_index << 8) | ch; - - gi_len_left--; - - /* last of one glyph_index data */ - if (!gi_len_left) { - - /* segment conversion */ - charset_tmp = state->charset; - segment_conversion(lcd, &charset_tmp, &glyph_index); - - /* get codeset */ - if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp, - &codeset, &glyph_index) ) { - unconv_num += gi_len; - continue; - } - - /* convert glyph index to wicd char */ - gi_to_wc(lcd, glyph_index, codeset, &wc); - if (outbufptr) {*outbufptr++ = wc;} - (*to_left)--; - } - - continue; - -skip_the_seg: - /* skip until next escape or control sequence */ - while ( *from_left ) { - ch = *inbufptr++; - (*from_left)--; - unconv_num++; - - if (ch == ESC || ch == CSI) { - inbufptr--; - (*from_left)++; - unconv_num--; - break; - } - } - - if ( !(*from_left) ) - break; - - } /* end of while */ - - /* error check on last char */ - if (gi_len_left) { - inbufptr -= (gi_len - gi_len_left); - (*from_left) += (gi_len - gi_len_left); - unconv_num += (gi_len - gi_len_left); - } - - *from = (XPointer) ((const char *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -cstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - unsigned char ch; - unsigned long glyph_index = 0; - wchar_t wc; - int gi_len_left = 0, gi_len = 0; - - int unconv_num = 0; - - CodeSet codeset = NULL; - XlcCharSet charset, charset_tmp; - - const char *inbufptr = *from; - wchar_t *outbufptr = (wchar_t *) *to; - int from_size = *from_left; - - if (from == NULL || *from == NULL) { - return( 0 ); - } - - charset = (XlcCharSet) args[0]; - - while (*from_left && *to_left) { - - if (!gi_len_left) { - gi_len_left = gi_len = charset->char_size; - glyph_index = 0; - } - - ch = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!ch) { - if (outbufptr) {*outbufptr++ = L'\0';} - (*to_left)--; - - /* error check */ - if (gi_len_left) { - unconv_num += (gi_len - gi_len_left); - gi_len_left = 0; - } - continue; - } - - if (charset->side == XlcC1 || charset->side == XlcGR) - glyph_index = (glyph_index << 8) | (ch & GL); - else - glyph_index = (glyph_index << 8) | ch; - - gi_len_left--; - - /* last of one glyph_index data */ - if (!gi_len_left) { - - /* segment conversion */ - charset_tmp = charset; - segment_conversion(lcd, &charset_tmp, &glyph_index); - - /* get codeset */ - if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp, - &codeset, &glyph_index) ) { - unconv_num += gi_len; - continue; - } - - /* convert glyph index to wicd char */ - gi_to_wc(lcd, glyph_index, codeset, &wc); - if (outbufptr) {*outbufptr++ = wc;} - (*to_left)--; - } - - } /* end of while */ - - /* error check on last char */ - if (gi_len_left) { - inbufptr -= (gi_len - gi_len_left); - (*from_left) += (gi_len - gi_len_left); - unconv_num += (gi_len - gi_len_left); - } - - *from = (XPointer) ((const char *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -stdc_ctstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left) * MB_CUR_MAX; - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = ctstombs(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = buf_ptr1 - buf_ptr2; - - unconv_num2 = stdc_mbstowcs(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -static int -stdc_cstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left) * MB_CUR_MAX; - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = cstombs(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = buf_ptr1 - buf_ptr2; - - unconv_num2 = stdc_mbstowcs(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -static int -mbstocts( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left); - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = mbstowcs_org(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); - - unconv_num2 += wcstocts(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -static int -mbstostr( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - unsigned char ch; - unsigned long mb = 0; - - int length = 0, len_left = 0; - int unconv_num = 0; - int num; - - CodeSet codeset = NULL; - - const char *inbufptr = *from; - char *outbufptr = *to; - int from_size = *from_left; - - unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); - - if (from == NULL || *from == NULL) { - _XlcResetConverter(conv); - return( 0 ); - } - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - ch = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!ch) { - if (outbufptr) {*outbufptr++ = '\0';} - (*to_left)--; - - /* error check */ - if (len_left) { - unconv_num += (length - len_left); - len_left = 0; - } - - continue; - } - - /* same mb char data */ - if (len_left) - goto output_one_mb; - - /* next mb char data for single shift ? */ - if (mb_parse_table && (num = mb_parse_table[ch]) ) { - codeset = mb_parse_codeset(state, num, &inbufptr, from_left); - if (codeset != NULL) { - length = len_left = codeset->length; - mb = 0; - continue; - } - } - - /* next char data : byteM ? */ - if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) - goto next_mb_char; - - /* next char data : GL or GR side ? */ - if ((codeset = GLGR_parse_codeset(ch))) - goto next_mb_char; - - /* can't find codeset for the ch */ - unconv_num++; - continue; - -next_mb_char: - length = len_left = codeset->length; - mb = 0; - -output_one_mb: - mb = (mb << 8) | ch; /* 1 byte left shift */ - len_left--; - - /* last of one mb char data */ - if (!len_left) { - if (check_string_encoding(codeset)) { - if (outbufptr) {*outbufptr++ = mb & 0xff;} - (*to_left)--; - } else { - unconv_num++; - } - } - - } /* end of while */ - - /* error check on last char */ - if (len_left) { - inbufptr -= (length - len_left); - (*from_left) += (length - len_left); - unconv_num += (length - len_left); - } - - *from = (XPointer) ((const char *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -mbtocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - unsigned char ch; - unsigned long mb = 0; - unsigned long glyph_index; - - int length = 0, len_left = 0, char_len; - int unconv_num = 0; - int num; - XlcSide side; - - CodeSet codeset = NULL; - XlcCharSet charset = NULL; - - const char *inbufptr = *from; - char *outbufptr = *to; - int from_size = *from_left; - - unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); - - if (from == NULL || *from == NULL) { - _XlcResetConverter(conv); - return( 0 ); - } - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - ch = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!ch) { - unconv_num = 1; - if (len_left) - unconv_num += (length - len_left); - break; - } - - /* same mb char data */ - if (len_left) - goto output; - - /* next mb char data for single shift ? */ - if (mb_parse_table && (num = mb_parse_table[ch]) ) { - codeset = mb_parse_codeset(state, num, &inbufptr, from_left); - if (codeset != NULL) { - length = len_left = codeset->length; - mb = 0; - continue; - } - } - - /* next mb char data for byteM ? */ - if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) - goto next_mb_char; - - /* next mb char data for GL or GR side ? */ - if ((codeset = GLGR_parse_codeset(ch))) - goto next_mb_char; - - /* can't find codeset for the ch */ - unconv_num = 1; - break; - -next_mb_char: - length = len_left = codeset->length; - mb = 0; - -output: - mb = (mb << 8) | ch; /* 1 byte left shift */ - len_left--; - - /* last of one mb char data */ - if (!len_left) { - glyph_index = mb_to_gi(mb, codeset); - if (!(charset = gi_parse_charset(glyph_index, codeset))) { - unconv_num = length; - break; - } - char_len = charset->char_size; - side = charset->side; - - /* output glyph index */ - if (codeset->ctconv) - glyph_index = conv_to_dest(codeset->ctconv, glyph_index); - if (*to_left < char_len) { - unconv_num = length; - break; - } - - if (outbufptr) { - output_ulong_value(outbufptr, glyph_index, char_len, side); - outbufptr += char_len; - } - - (*to_left) -= char_len; - - break; - } - - } /* end of while */ - - /* error end */ - if (unconv_num) { - *from = (XPointer) ((const char *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - return -1; - } - - /* nomal end */ - *from = (XPointer) inbufptr; - *to = (XPointer) outbufptr; - - if (num_args > 0) - *((XlcCharSet *) args[0]) = charset; - - return 0; -} - -static int -mbstocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - int ret; - XlcCharSet charset_old, charset = NULL; - XPointer tmp_args[1]; - - const char *inbufptr; - int in_left; - char *outbufptr; - int out_left; - tmp_args[0] = (XPointer) &charset; - - ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1); - charset_old = charset; - - while ( ret == 0 && *from_left && *to_left) { - inbufptr = *from; - in_left = *from_left; - outbufptr = *to; - out_left = *to_left; - ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1); - if (charset_old != charset) { - *from = (XPointer) inbufptr; - *from_left = in_left; - *to = (XPointer) outbufptr; - *to_left = out_left; - break; - } - } - - if (num_args > 0) - *((XlcCharSet *) args[0]) = charset_old; - - /* error end */ - if (ret != 0) - return( -1 ); - - return(0); -} - -static int -wcstostr( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - char *encoding; - unsigned long mb, glyph_index; - wchar_t wc; - - int length; - int unconv_num = 0; - - CodeSet codeset; - - const wchar_t *inbufptr = (const wchar_t *) *from; - char *outbufptr = *to; - int from_size = *from_left; - - const char *default_string = XLC_PUBLIC(lcd, default_string); - int defstr_len = strlen(default_string); - - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - wc = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!wc) { - if (outbufptr) {*outbufptr++ = '\0';} - (*to_left)--; - - continue; - } - - /* convert */ - if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { - - /* output default_string of XDefaultString() */ - if (*to_left < defstr_len) - break; - if (outbufptr) { - strncpy((char *)outbufptr, default_string, defstr_len); - outbufptr += defstr_len; - } - (*to_left) -= defstr_len; - - unconv_num++; - - } else { - mb = gi_to_mb(glyph_index, codeset); - - if (check_string_encoding(codeset)) { - if (codeset->parse_info) { - Bool need_shift = False; - switch (codeset->parse_info->type) { - case E_LSL : - if (codeset != state->GL_codeset) { - need_shift = True; - state->GL_codeset = codeset; - } - break; - case E_LSR : - if (codeset != state->GR_codeset) { - need_shift = True; - state->GR_codeset = codeset; - } - break; - /* case E_SS */ - default: - need_shift = True; - } - - /* output shift sequence */ - if (need_shift) { - encoding = codeset->parse_info->encoding; - length = strlen(encoding); - if (*to_left < length) - break; - - if (outbufptr) { - strncpy((char *)outbufptr, encoding, length); - outbufptr += length; - } - (*to_left) -= length; - } - } - - /* output characters */ - length = codeset->length; - if (*to_left < length) - break; - - if (outbufptr) { - output_ulong_value(outbufptr, mb, length, XlcNONE); - outbufptr += length; - } - - (*to_left) -= length; - } else { - unconv_num++; - } - } - - } /* end of while */ - - *from = (XPointer) ((const wchar_t *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -stdc_wcstostr( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left) * MB_CUR_MAX; - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = stdc_wcstombs(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = buf_ptr1 - buf_ptr2; - - unconv_num2 = mbstostr(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -static int -wctocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - wchar_t wc; - unsigned long glyph_index; - - int char_len; - int unconv_num = 0; - XlcSide side; - - CodeSet codeset; - XlcCharSet charset = NULL; - - const wchar_t *inbufptr = (const wchar_t *) *from; - char *outbufptr = *to; - int from_size = *from_left; - - if (*from_left > *to_left) - *from_left = *to_left; - - if (*from_left && *to_left) { - - wc = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!wc) { - unconv_num = 1; - goto end; - } - - /* convert */ - if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { - unconv_num = 1; - goto end; - } - - if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) { - unconv_num = 1; - goto end; - } - char_len = charset->char_size; - side = charset->side; - - /* output glyph index */ - if (codeset->ctconv) - glyph_index = conv_to_dest(codeset->ctconv, glyph_index); - if (*to_left < char_len) { - unconv_num++; - goto end; - } - - if (outbufptr) { - output_ulong_value(outbufptr, glyph_index, char_len, side); - outbufptr += char_len; - } - - (*to_left) -= char_len; - - } - -end: - - /* error end */ - if (unconv_num) { - *from = (XPointer) ((const wchar_t *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - return -1; - } - - /* nomal end */ - *from = (XPointer) inbufptr; - *to = (XPointer) outbufptr; - - if (num_args > 0) - *((XlcCharSet *) args[0]) = charset; - - return 0; -} - -static int -stdc_wctocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - const wchar_t *src = *((const wchar_t **) from); - wchar_t wch; - XPointer tmp_from, save_from = *from; - char tmp[32]; - int length, ret, src_left = *from_left; - int from_size = *from_left; - - if (src_left > 0 && *to_left > 0) { - if ((wch = *src)) { - length = wctomb(tmp, wch); - } else { - goto end; - } - - if (length < 0) - goto end; - - tmp_from = (XPointer) tmp; - ret = mbtocs(conv, &tmp_from, &length, to, to_left, args, num_args); - if (ret < 0) - goto end; - - src++; - src_left--; - } - -end: - /* error end */ - if (save_from == (XPointer) src) { - *from = (XPointer) ((const wchar_t *) *from + from_size); - *from_left = 0; - return -1; - } - - /* nomal end */ - *from = (XPointer) src; - *from_left = src_left; - - return 0; -} - -static int -wcstocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - int ret; - XlcCharSet charset_old, charset = NULL; - XPointer tmp_args[1]; - - const wchar_t *inbufptr; - int in_left; - XPointer outbufptr; - int out_left; - tmp_args[0] = (XPointer) &charset; - - ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1); - charset_old = charset; - - while ( ret == 0 && *from_left && *to_left) { - inbufptr = (const wchar_t *) *from; - in_left = *from_left; - outbufptr = *to; - out_left = *to_left; - ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1); - if (charset_old != charset) { - *from = (XPointer) inbufptr; - *from_left = in_left; - *to = (XPointer) outbufptr; - *to_left = out_left; - break; - } - } - - if (num_args > 0) - *((XlcCharSet *) args[0]) = charset_old; - - /* error end */ - if (ret != 0) - return( -1 ); - - return(0); -} - -#ifdef STDCVT - -static int -stdc_wcstocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - int ret; - XlcCharSet charset_old, charset = NULL; - XPointer tmp_args[1]; - - const wchar_t *inbufptr; - int in_left; - XPointer outbufptr; - int out_left; - tmp_args[0] = (XPointer) &charset; - - ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1); - charset_old = charset; - - while ( ret == 0 && *from_left && *to_left ) { - inbufptr = (const wchar_t *) *from; - in_left = *from_left; - outbufptr = *to; - out_left = *to_left; - ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1); - if (charset_old != charset) { - *from = (XPointer) inbufptr; - *from_left = in_left; - *to = (XPointer) outbufptr; - *to_left = out_left; - break; - } - } - - if (num_args > 0) - *((XlcCharSet *) args[0]) = charset_old; - - /* error end */ - if (ret != 0) - return( -1 ); - - return(0); -} - -#endif - -static int -ctstombs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left); - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = ctstowcs(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); - - unconv_num2 += wcstombs_org(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -static int -cstombs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left); - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = cstowcs(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); - - unconv_num2 += wcstombs_org(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -static int -strtombs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - char *encoding; - unsigned long mb, glyph_index; - unsigned char ch; - - int length; - int unconv_num = 0; - - CodeSet codeset; - - const char *inbufptr = *from; - char *outbufptr = *to; - int from_size = *from_left; - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - ch = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!ch) { - if (outbufptr) {*outbufptr++ = '\0';} - (*to_left)--; - - continue; - } - - /* convert */ - if (isleftside(ch)) { - glyph_index = ch; - codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL"); - } else { - glyph_index = ch & GL; - codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR"); - } - - if (!codeset) { - unconv_num++; - continue; - } - - mb = gi_to_mb(glyph_index, codeset); - if (codeset->parse_info) { - Bool need_shift = False; - switch (codeset->parse_info->type) { - case E_LSL : - if (codeset != state->GL_codeset) { - need_shift = True; - state->GL_codeset = codeset; - } - break; - case E_LSR : - if (codeset != state->GR_codeset) { - need_shift = True; - state->GR_codeset = codeset; - } - break; - /* case E_SS */ - default: - need_shift = True; - } - - /* output shift sequence */ - if (need_shift) { - encoding = codeset->parse_info->encoding; - length = strlen(encoding); - if (*to_left < length) - break; - if (outbufptr) { - strncpy((char *)outbufptr, encoding, length); - outbufptr += length; - } - (*to_left) -= length; - } - } - - /* output characters */ - length = codeset->length; - if (*to_left < length) - break; - - if (outbufptr) { - output_ulong_value(outbufptr, mb, length, XlcNONE); - outbufptr += length; - } - - (*to_left) -= length; - - } /* end of while */ - - *from = (XPointer) ((const char *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -strtowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - - unsigned char ch; - unsigned long glyph_index; - wchar_t wc; - - int unconv_num = 0; - CodeSet codeset; - - const char *inbufptr = *from; - wchar_t *outbufptr = (wchar_t *)*to; - int from_size = *from_left; - - if (*from_left > *to_left) - *from_left = *to_left; - - while (*from_left && *to_left) { - - ch = *inbufptr++; - (*from_left)--; - - /* null ? */ - if (!ch) { - if (outbufptr) {*outbufptr++ = L'\0';} - (*to_left)--; - - continue; - } - - /* convert */ - if (isleftside(ch)) { - glyph_index = ch; - codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL"); - } else { - glyph_index = ch & GL; - codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR"); - } - - if (!codeset) { - unconv_num++; - continue; - } - - gi_to_wc(lcd, glyph_index, codeset, &wc); - if (outbufptr) {*outbufptr++ = wc;} - (*to_left)--; - - } /* end of while */ - - *from = (XPointer) ((const char *) *from + from_size); - *from_left = 0; - *to = (XPointer) outbufptr; - - return unconv_num; -} - -static int -stdc_strtowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); - char *buf_ptr1 = buf; - int buf_left1 = (*from_left) * MB_CUR_MAX; - char *buf_ptr2 = buf_ptr1; - int buf_left2; - int unconv_num1 = 0, unconv_num2 = 0; - - unconv_num1 = strtombs(conv, - from, from_left, &buf_ptr1, &buf_left1, args, num_args); - if (unconv_num1 < 0) - goto ret; - - buf_left2 = buf_ptr1 - buf_ptr2; - - unconv_num2 = stdc_mbstowcs(conv, - &buf_ptr2, &buf_left2, to, to_left, args, num_args); - if (unconv_num2 < 0) - goto ret; - -ret: - if (buf) - Xfree((char *)buf); - - return (unconv_num1 + unconv_num2); -} - -/* -------------------------------------------------------------------------- */ -/* Close */ -/* -------------------------------------------------------------------------- */ - -static void -close_converter( - XlcConv conv) -{ - if (conv->state) { - Xfree((char *) conv->state); - } - - if (conv->methods) { - Xfree((char *) conv->methods); - } - - Xfree((char *) conv); -} - -/* -------------------------------------------------------------------------- */ -/* Open */ -/* -------------------------------------------------------------------------- */ - -static XlcConv -create_conv( - XLCd lcd, - XlcConvMethods methods) -{ - XlcConv conv; - State state; - - conv = (XlcConv) Xcalloc(1, sizeof(XlcConvRec)); - if (conv == NULL) - return (XlcConv) NULL; - - conv->methods = (XlcConvMethods) Xmalloc(sizeof(XlcConvMethodsRec)); - if (conv->methods == NULL) - goto err; - *conv->methods = *methods; - conv->methods->reset = init_state; - - conv->state = Xcalloc(1, sizeof(StateRec)); - if (conv->state == NULL) - goto err; - - state = (State) conv->state; - state->lcd = lcd; - - _XlcResetConverter(conv); - - return conv; - -err: - close_converter(conv); - - return (XlcConv) NULL; -} - -static XlcConvMethodsRec mbstocts_methods = { - close_converter, - mbstocts, - NULL -}; - -static XlcConv -open_mbstocts( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &mbstocts_methods); -} - -static XlcConvMethodsRec mbstostr_methods = { - close_converter, - mbstostr, - NULL -}; - -static XlcConv -open_mbstostr( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &mbstostr_methods); -} - -static XlcConvMethodsRec mbstocs_methods = { - close_converter, - mbstocs, - NULL -}; - -static XlcConv -open_mbstocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &mbstocs_methods); -} - -static XlcConvMethodsRec mbtocs_methods = { - close_converter, - mbtocs, - NULL -}; - -static XlcConv -open_mbtocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &mbtocs_methods); -} - -static XlcConvMethodsRec ctstombs_methods = { - close_converter, - ctstombs, - NULL -}; - -static XlcConv -open_ctstombs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &ctstombs_methods); -} - -static XlcConvMethodsRec cstombs_methods = { - close_converter, - cstombs, - NULL -}; - -static XlcConv -open_cstombs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &cstombs_methods); -} - -static XlcConvMethodsRec strtombs_methods = { - close_converter, - strtombs, - NULL -}; - -static XlcConv -open_strtombs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &strtombs_methods); -} - -#ifdef STDCVT - -static XlcConvMethodsRec stdc_mbstowcs_methods = { - close_converter, - stdc_mbstowcs, - NULL -}; - -static XlcConv -open_stdc_mbstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_mbstowcs_methods); -} - -static XlcConvMethodsRec stdc_wcstombs_methods = { - close_converter, - stdc_wcstombs, - NULL -}; - -static XlcConv -open_stdc_wcstombs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_wcstombs_methods); -} - -static XlcConvMethodsRec stdc_wcstocts_methods = { - close_converter, - stdc_wcstocts, - NULL -}; - -static XlcConv -open_stdc_wcstocts( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_wcstocts_methods); -} - -static XlcConvMethodsRec stdc_wcstostr_methods = { - close_converter, - stdc_wcstostr, - NULL -}; - -static XlcConv -open_stdc_wcstostr( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_wcstostr_methods); -} - -static XlcConvMethodsRec stdc_wcstocs_methods = { - close_converter, - stdc_wcstocs, - NULL -}; - -static XlcConv -open_stdc_wcstocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_wcstocs_methods); -} - -static XlcConvMethodsRec stdc_wctocs_methods = { - close_converter, - stdc_wctocs, - NULL -}; - -static XlcConv -open_stdc_wctocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_wctocs_methods); -} - -static XlcConvMethodsRec stdc_ctstowcs_methods = { - close_converter, - stdc_ctstowcs, - NULL -}; - -static XlcConv -open_stdc_ctstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_ctstowcs_methods); -} - -static XlcConvMethodsRec stdc_cstowcs_methods = { - close_converter, - stdc_cstowcs, - NULL -}; - -static XlcConv -open_stdc_cstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_cstowcs_methods); -} - -static XlcConvMethodsRec stdc_strtowcs_methods = { - close_converter, - stdc_strtowcs, - NULL -}; - -static XlcConv -open_stdc_strtowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_strtowcs_methods); -} - -#endif /* STDCVT */ - -static XlcConvMethodsRec mbstowcs_methods = { - close_converter, - mbstowcs_org, - NULL -}; - -static XlcConv -open_mbstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &mbstowcs_methods); -} - -static XlcConvMethodsRec wcstombs_methods = { - close_converter, - wcstombs_org, - NULL -}; - -static XlcConv -open_wcstombs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &wcstombs_methods); -} - -static XlcConvMethodsRec wcstocts_methods = { - close_converter, - wcstocts, - NULL -}; - -static XlcConv -open_wcstocts( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &wcstocts_methods); -} - -static XlcConvMethodsRec wcstostr_methods = { - close_converter, - wcstostr, - NULL -}; - -static XlcConv -open_wcstostr( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &wcstostr_methods); -} - -static XlcConvMethodsRec wcstocs_methods = { - close_converter, - wcstocs, - NULL -}; - -static XlcConv -open_wcstocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &wcstocs_methods); -} - -static XlcConvMethodsRec wctocs_methods = { - close_converter, - wctocs, - NULL -}; - -static XlcConv -open_wctocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &wctocs_methods); -} - -static XlcConvMethodsRec ctstowcs_methods = { - close_converter, - ctstowcs, - NULL -}; - -static XlcConv -open_ctstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &ctstowcs_methods); -} - -static XlcConvMethodsRec cstowcs_methods = { - close_converter, - cstowcs, - NULL -}; - -static XlcConv -open_cstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &cstowcs_methods); -} - -static XlcConvMethodsRec strtowcs_methods = { - close_converter, - strtowcs, - NULL -}; - -static XlcConv -open_strtowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &strtowcs_methods); -} - -/* -------------------------------------------------------------------------- */ -/* Loader */ -/* -------------------------------------------------------------------------- */ - -XLCd -_XlcGenericLoader( - const char *name) -{ - XLCd lcd; -#ifdef STDCVT - XLCdGenericPart *gen; -#endif - - lcd = _XlcCreateLC(name, _XlcGenericMethods); - - if (lcd == NULL) - return lcd; - - default_GL_charset = _XlcGetCharSet("ISO8859-1:GL"); - default_GR_charset = _XlcGetCharSet("ISO8859-1:GR"); - - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCompoundText, open_mbstocts); - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNString, open_mbstostr); - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs); - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs); - _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte, open_ctstombs); - _XlcSetConverter(lcd, XlcNString, lcd, XlcNMultiByte, open_strtombs); - _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs); - -#ifdef STDCVT - gen = XLC_GENERIC_PART(lcd); - - if (gen->use_stdc_env != True) { -#endif - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_mbstowcs); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_wcstombs); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_wcstocts); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_wcstostr); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNChar, open_wctocs); - _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_ctstowcs); - _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_strtowcs); - _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs); -#ifdef STDCVT - } -#endif - -#ifdef STDCVT - if (gen->use_stdc_env == True) { - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_stdc_mbstowcs); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_stdc_wcstombs); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_stdc_wcstocts); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_stdc_wcstostr); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_stdc_wcstocs); - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNChar, open_stdc_wctocs); - _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_stdc_ctstowcs); - _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_stdc_strtowcs); - _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_stdc_cstowcs); - } -#endif - - _XlcAddUtf8Converters(lcd); - - return lcd; -} +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ +/* + * (c) Copyright 1995 FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + * + * Modifier: Masayoshi Shimamura FUJITSU LIMITED + * + */ +/* + * 2000 + * Modifier: Ivan Pascal The XFree86 Project + */ + +/* + * A generic locale loader for all kinds of ISO-2022 based codesets. + * Supports: all locales. + * How: Provides generic converters for ISO-2022 based codesets. Extensible as + * far as ISO-2022 is extensible: codesets can be given by name in the + * stream. Overall distinction between GL (0x00..0x7f) and GR (0x80..0xff). + * In every chunk between escape sequences, the number of bytes per + * character (char_size) is constant. + * Platforms: all systems. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "Xlibint.h" +#include "XlcGeneric.h" +#include + +#if !defined(Lynx_22) && !defined(X_LOCALE) +#define STDCVT +#endif + +typedef struct _CTDataRec { + const char *name; + const char *encoding; /* Compound Text encoding */ +} CTDataRec, *CTData; + +static CTDataRec directionality_data[] = +{ + { "BEGIN_LEFT-TO-RIGHT_TEXT", "\2331]" }, + { "BEGIN_RIGHT-TO-LEFT_TEXT", "\2332]" }, + { "END_OF_STRING", "\233]" }, +}; + +typedef struct _StateRec { + XLCd lcd; + /* CT state */ + XlcCharSet charset; /* charset of current state */ + XlcCharSet GL_charset; /* charset of initial state in GL */ + XlcCharSet GR_charset; /* charset of initial state in GR */ + /* MB shift state */ + CodeSet GL_codeset; + CodeSet GR_codeset; +} StateRec, *State; + +#define GR 0x80 /* begins right-side (non-ascii) region */ +#define GL 0x7f /* ends left-side (ascii) region */ +#define ESC 0x1b +#define CSI 0x9b +#define STX 0x02 + +#define isrightside(c) ((c) & GR) +#define isleftside(c) (!isrightside(c)) + +/* Forward declarations for local routines. */ +static int mbstocts (XlcConv conv, XPointer *from, int *from_left, + XPointer *to, int *to_left, XPointer *args, int num_args); +static int ctstombs (XlcConv conv, XPointer *from, int *from_left, + XPointer *to, int *to_left, XPointer *args, int num_args); +static int cstombs (XlcConv conv, XPointer *from, int *from_left, + XPointer *to, int *to_left, XPointer *args, int num_args); + +/* ------------------------------------------------------------------------- */ +/* Misc */ +/* ------------------------------------------------------------------------- */ + +static int +compare( + const char *src, + const char *encoding, + int length) +{ + const char *start = src; + + while (length-- > 0) { + if (*src++ != *encoding++) + return 0; + if (*encoding == '\0') + return src - start; + } + + return 0; +} + +static unsigned long +conv_to_dest( + Conversion conv, + unsigned long code) +{ + int i; + int conv_num = conv->conv_num; + FontScope convlist = conv->convlist; + + for (i = 0; i < conv_num; i++) { + if (convlist[i].start <= code && code <= convlist[i].end) { + switch (convlist[i].shift_direction) { + case '+': + return(code + convlist[i].shift); + case '-': + return(code - convlist[i].shift); + default: + return(code); + } + } + } + + return(code); +} + +static unsigned long +conv_to_source( + Conversion conv, + unsigned long code) +{ + int i; + int conv_num; + FontScope convlist; + unsigned long start_p; + unsigned long start_m; + unsigned long end_p; + unsigned long end_m; + + if (!conv) + return(code); + + conv_num = conv->conv_num; + convlist = conv->convlist; + + for (i = 0; i < conv_num; i++) { + switch (convlist[i].shift_direction) { + case '+': + start_p = convlist[i].start + convlist[i].shift; + end_p = convlist[i].end + convlist[i].shift; + if (start_p <= code && code <= end_p) + return(code - convlist[i].shift); + break; + case '-': + start_m = convlist[i].start - convlist[i].shift; + end_m = convlist[i].end - convlist[i].shift; + if (start_m <= code && code <= end_m) + return(code + convlist[i].shift); + break; + default: + continue; + } + } + + return(code); +} + +static unsigned long +mb_to_gi( + unsigned long mb, + CodeSet codeset) +{ + int i; + unsigned long mb_tmp, mask = 0; + + if (codeset->mbconv) { + mb_tmp = conv_to_dest(codeset->mbconv, mb); + if (mb_tmp != mb) + return(mb_tmp); + } + + if (codeset->side == XlcC0 || codeset->side == XlcGL || + codeset->side == XlcC1 || codeset->side == XlcGR) { + + for (i = 0; i < codeset->length; i++) + mask = (mask << 8) | GL; + mb = mb & mask; + } + + return(mb); +} + +static unsigned long +gi_to_mb( + unsigned long glyph_index, + CodeSet codeset) +{ + int i; + unsigned long mask = 0; + + if (codeset->side == XlcC1 || codeset->side == XlcGR) { + for (i = 0; i < codeset->length; i++) + mask = (mask << 8) | GR; + glyph_index = glyph_index | mask; + } + + if (codeset->mbconv) + return( conv_to_source(codeset->mbconv, glyph_index) ); + + return(glyph_index); +} + +static Bool +gi_to_wc( + XLCd lcd, + unsigned long glyph_index, + CodeSet codeset, + wchar_t *wc) +{ + unsigned char mask = 0; + unsigned long wc_encoding = codeset->wc_encoding; + int length = codeset->length; + unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits); + + mask = (1 << wc_shift_bits) - 1 ; + + for (*wc = 0, length--; length >= 0; length--) + *wc = (*wc << wc_shift_bits) | ((glyph_index >> (length * 8 )) & mask); + + *wc = *wc | wc_encoding; + + return(True); +} + +static Bool +wc_to_gi( + XLCd lcd, + wchar_t wc, + unsigned long *glyph_index, + CodeSet *codeset) +{ + int i; + unsigned char mask = 0; + unsigned long wc_encoding; + unsigned long wc_encode_mask = XLC_GENERIC(lcd, wc_encode_mask); + unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits); + int codeset_num = XLC_GENERIC(lcd, codeset_num); + CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); + + wc_encoding = wc & wc_encode_mask; + for (*codeset = NULL, i = 0; i < codeset_num; i++) { + if (wc_encoding == codeset_list[i]->wc_encoding) { + *codeset = codeset_list[i]; + break; + } + } + if (*codeset == NULL) + return(False); + + mask = (1 << wc_shift_bits) - 1 ; + + wc = wc & ~wc_encode_mask; + for (*glyph_index = 0, i = (*codeset)->length - 1; i >= 0; i--) + *glyph_index = (*glyph_index << 8) | + ( ((unsigned long)wc >> (i * wc_shift_bits)) & mask ); + + return(True); +} + +static CodeSet +mb_parse_codeset( + State state, + int num, + const char **inbufptr, + int *from_left) +{ + int len; + int from_len = (*from_left) + 1; + const char *src = (*inbufptr) - 1; + ParseInfo *mb_parse_list = XLC_GENERIC(state->lcd, mb_parse_list); + ParseInfo parse_info; + CodeSet codeset; + + for (--num ; (parse_info = mb_parse_list[num]) != NULL; num++) { + len = compare(src, parse_info->encoding, from_len); + if (len > 0) { + codeset = parse_info->codeset; + if (parse_info->type == E_LSL) + state->GL_codeset = codeset; + else if (parse_info->type == E_LSR) + state->GR_codeset = codeset; + --len; + *inbufptr += len; + *from_left -= len; + return codeset; + } + } + return (CodeSet) NULL; +} + +static CodeSet +byteM_parse_codeset( + XLCd lcd, + const char *inbufptr) +{ + unsigned char ch; + CodeSet codeset; + ByteInfoList byteM; + ByteInfoListRec byteM_rec; + ByteInfo byteinfo; + ByteInfoRec byteinfo_rec; + Bool hit = False; + int i, j, k; + + int codeset_num = XLC_GENERIC(lcd, codeset_num); + CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); + + for (i = 0; i < codeset_num; i++) { + codeset = codeset_list[i]; + byteM = codeset->byteM; + if (codeset->side != XlcNONE || byteM == NULL) + continue; + + for (j = 0; j < codeset->length; j++) { + ch = *((unsigned char *)(inbufptr + j)); + byteM_rec = byteM[j]; + byteinfo = byteM_rec.byteinfo; + + for (hit = False, k = 0; k < byteM_rec.byteinfo_num; k++) { + byteinfo_rec = byteinfo[k]; + if (byteinfo_rec.start <= ch && ch <= byteinfo_rec.end) { + hit = True; + break; + } + } + + if (!hit) + break; + } + + if (hit) + return(codeset); + } + + return(NULL); +} + +#define GLGR_parse_codeset(ch) \ + (isrightside(ch) ? (state->GR_codeset) : \ + (state->GL_codeset) ) + +static XlcCharSet +gi_parse_charset( + unsigned long glyph_index, + CodeSet codeset) +{ + int i; + XlcCharSet *charset_list = codeset->charset_list; + int num_charsets = codeset->num_charsets; + ExtdSegment ctextseg = codeset->ctextseg; + XlcCharSet charset = NULL; + int area_num; + FontScope area; + + /* lockup ct sequence */ + for (i = 0; i < num_charsets; i++) { + charset = charset_list[i]; + if (*charset->ct_sequence != '\0') + break; + } + if (i >= num_charsets) + return(NULL); + + if (charset->source != CSsrcStd) + return (charset); + + if (!ctextseg) + return(charset); + + area = ctextseg->area; + area_num = ctextseg->area_num; + + for (i = 0; i < area_num; i++) { + + if (area[i].start <= glyph_index && glyph_index <= area[i].end) { + + charset = ctextseg->charset; + + if (*charset->ct_sequence == '\0') + return(NULL); + + break; + } + } + + return(charset); +} + +static Bool +ct_parse_csi( + const char *inbufptr, + int *ctr_seq_len) +{ + int i; + int num = sizeof(directionality_data) / sizeof(directionality_data[0]); + + for (i = 0; i < num; i++) { + if ( !(*ctr_seq_len = strlen(directionality_data[i].encoding)) ) + continue; + + if ( strncmp(inbufptr, directionality_data[i].encoding, + *ctr_seq_len) == 0) + return(True); + } + + return(False); +} + +static int +cmp_esc_sequence( + const char *inbufptr, + XlcCharSet charset) +{ + int seq_len, name_len, total_len; + unsigned char byte_m, byte_l; + const char *ct_sequence = charset->ct_sequence; + const char *encoding_name = charset->encoding_name; + + /* check esc sequence */ + if ( !(seq_len = strlen(ct_sequence) ) ) + return(0); + if ( strncmp(inbufptr, ct_sequence, seq_len) != 0) + return(0); + + /* Standard Character Set Encoding ? */ + if (charset->source == CSsrcStd) + return(seq_len); + + /* + * Non-Standard Character Set Encoding + * + * +--- ---+-----+-----+-----+---- ----+-----+-----+------- ------+ + * | ctseq | M | L | encoding name | STX | contents | + * +--- ---+-----+-----+-----+---- ----+-----+-----+------- ------+ + * 4bytes 1byte 1byte variable length 1byte variable length + * | | + * +----------------------------------------------+ + * rest length = ((M - 128) * 128) + (L - 128) + */ + + /* get length of encoding name */ + inbufptr += seq_len; + byte_m = *inbufptr++; + byte_l = *inbufptr++; + name_len = strlen(encoding_name); + + if (((byte_m - 128) * 128 + (byte_l - 128) - 1) < name_len) + return(0); + + if ( _XlcNCompareISOLatin1(inbufptr, encoding_name, name_len) != 0 ) + return(0); + + /* check STX (Start of Text) */ + inbufptr = inbufptr + name_len; + if ( *inbufptr != STX ) + return(0); + + total_len = seq_len + name_len + 3; + return(total_len); +} + +static Bool +ct_parse_charset( + XLCd lcd, + const char *inbufptr, + XlcCharSet *charset, + int *ctr_seq_len) +{ + int i, j; + ExtdSegment ctextseg; + int num_charsets; + XlcCharSet *charset_list; + CodeSet codeset; + int codeset_num = XLC_GENERIC(lcd, codeset_num); + CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); + int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num); + SegConv segment_conv = XLC_GENERIC(lcd, segment_conv); + + /* get charset from XLC_XLOCALE by escape sequence */ + + for (i = 0; i < codeset_num; i++) { + codeset = codeset_list[i]; + + num_charsets = codeset->num_charsets; + charset_list = codeset->charset_list; + ctextseg = codeset->ctextseg; + + for (j = 0; j < num_charsets; j++) { + *charset = charset_list[j]; + if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) + return(True); + } + + if (ctextseg) { + *charset = ctextseg->charset; + if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) + return(True); + } + } + + /* get charset from XLC_SEGMENTCONVERSION by escape sequence */ + + if (!segment_conv) + return(False); + + for (i = 0; i < segment_conv_num; i++) { + *charset = segment_conv[i].source; + if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) + return(True); + *charset = segment_conv[i].dest; + if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) + return(True); + } + + return(False); +} + +static Bool +segment_conversion( + XLCd lcd, + XlcCharSet *charset, + unsigned long *glyph_index) +{ + int i; + int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num); + SegConv segment_conv = XLC_GENERIC(lcd, segment_conv); + FontScopeRec range; + ConversionRec conv_rec; + + if (!segment_conv) + return(True); + + for (i = 0; i < segment_conv_num; i++) { + if (segment_conv[i].source == *charset) + break; + } + + if (i >= segment_conv_num) + return(True); + + range = segment_conv[i].range; + if (*glyph_index < range.start || range.end < *glyph_index) + return(True); + + *charset = segment_conv[i].dest; + conv_rec.conv_num = segment_conv[i].conv_num; + conv_rec.convlist = segment_conv[i].conv; + *glyph_index = conv_to_dest(&conv_rec, *glyph_index); + + return(True); +} + +static CodeSet +_XlcGetCodeSetFromName( + XLCd lcd, + const char *name) +{ + int i, j; + XlcCharSet charset; + int num_charsets; + XlcCharSet *charset_list; + CodeSet codeset; + + int codeset_num = XLC_GENERIC(lcd, codeset_num); + CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); + + for (i = 0; i < codeset_num; i++) { + codeset = codeset_list[i]; + + num_charsets = codeset->num_charsets; + charset_list = codeset->charset_list; + + for (j = 0; j < num_charsets; j++) { + charset = charset_list[j]; + + if (!strlen(charset->name)) + continue; + if ( strcmp(charset->name, name) == 0) + return(codeset); + } + } + + return(NULL); +} + +static Bool +_XlcGetCodeSetFromCharSet( + XLCd lcd, + XlcCharSet charset, + CodeSet *codeset, + unsigned long *glyph_index) +{ + int j, num; + CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); + XlcCharSet *charset_list; + int codeset_num, num_charsets; + Conversion ctconv; + unsigned long glyph_index_tmp = 0; + ExtdSegment ctextseg; + + codeset_num = XLC_GENERIC(lcd, codeset_num); + + for (num = 0 ; num < codeset_num; num++) { + *codeset = codeset_list[num]; + ctconv = (*codeset)->ctconv; + ctextseg = (*codeset)->ctextseg; + + num_charsets = (*codeset)->num_charsets; + charset_list = (*codeset)->charset_list; + + glyph_index_tmp = conv_to_source(ctconv, *glyph_index); + + if (charset->source == CSsrcStd) { + + /* Standard Character Set Encoding */ + if (glyph_index_tmp == *glyph_index) { + for (j = 0; j < num_charsets; j++) { + if (charset_list[j] == charset) { + goto end_loop; + } + } + } + + } else { + + /* Non-Standard Character Set Encoding */ + for (j = 0; j < num_charsets; j++) { + if (charset_list[j] == charset) { + goto end_loop; + } + } + + if (glyph_index_tmp != *glyph_index) { + if (ctextseg && ctextseg->charset == charset) { + goto end_loop; + } + } + + } + + } + +end_loop: + if (num < codeset_num) { + *glyph_index = glyph_index_tmp; + return(True); + } + + return(False); +} + +#define check_string_encoding(codeset) (codeset->string_encoding) + +static void +output_ulong_value( + char *outbufptr, + unsigned long code, + int length, + XlcSide side) +{ + int i; + + for (i = (length - 1) * 8; i >= 0; i -= 8) { + *outbufptr = ( code >> i) & 0xff; + + if (side == XlcC0 || side == XlcGL) { + *outbufptr = *outbufptr & GL; + } else if (side == XlcC1 || side == XlcGR) { + *outbufptr = *outbufptr | GR; + } + + outbufptr++; + } +} + +/* -------------------------------------------------------------------------- */ +/* Init */ +/* -------------------------------------------------------------------------- */ + +static XlcCharSet default_GL_charset = 0; +static XlcCharSet default_GR_charset = 0; + +static void +init_state( + XlcConv conv) +{ + State state = (State) conv->state; + + /* for CT */ + state->charset = NULL; + state->GL_charset = default_GL_charset; + state->GR_charset = default_GR_charset; + + /* for MB shift state */ + state->GL_codeset = XLC_GENERIC(state->lcd, initial_state_GL); + state->GR_codeset = XLC_GENERIC(state->lcd, initial_state_GR); +} + +/* -------------------------------------------------------------------------- */ +/* Convert */ +/* -------------------------------------------------------------------------- */ + +static int +mbstowcs_org( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + + unsigned char ch; + unsigned long mb = 0; + wchar_t wc; + + int length = 0, len_left = 0; + int unconv_num = 0; + int num; + + CodeSet codeset = NULL; + + const char *inbufptr = *from; + wchar_t *outbufptr = (wchar_t *) *to; + int from_size = *from_left; + + unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); + + if (from == NULL || *from == NULL) { + _XlcResetConverter(conv); + return( 0 ); + } + + if (*from_left > *to_left) + *from_left = *to_left; + + while (*from_left && *to_left) { + + ch = *inbufptr++; + (*from_left)--; + + /* null ? */ + if (!ch) { + if (outbufptr) {*outbufptr++ = L'\0';} + (*to_left)--; + + /* error check */ + if (len_left) { + unconv_num += (length - len_left); + len_left = 0; + } + + continue; + } + + /* same mb char data */ + if (len_left) + goto output_one_wc; + + /* next mb char data for single shift ? */ + if (mb_parse_table && (num = mb_parse_table[ch]) ) { + codeset = mb_parse_codeset(state, num, &inbufptr, from_left); + if (codeset != NULL) { + length = len_left = codeset->length; + mb = 0; + continue; + } + } + + /* next mb char data for byteM ? */ + if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) + goto next_mb_char; + + /* next mb char data for GL or GR side ? */ + if ((codeset = GLGR_parse_codeset(ch))) + goto next_mb_char; + + /* can't find codeset for the ch */ + unconv_num++; + continue; + +next_mb_char: + length = len_left = codeset->length; + mb = 0; + +output_one_wc: + mb = (mb << 8) | ch; /* 1 byte left shift */ + len_left--; + + /* last of one mb char data */ + if (!len_left) { + gi_to_wc(lcd, mb_to_gi(mb, codeset), codeset, &wc); + if (outbufptr) {*outbufptr++ = wc;} + (*to_left)--; + } + + } /* end of while */ + + /* error check on last char */ + if (len_left) { + inbufptr -= (length - len_left); + (*from_left) += (length - len_left); + unconv_num += (length - len_left); + } + + *from = (XPointer) ((const char *) *from + from_size); + *from_left = 0; + *to = (XPointer) outbufptr; + + return unconv_num; +} + +static int +stdc_mbstowcs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + const char *src = *((const char **) from); + wchar_t *dst = *((wchar_t **) to); + int src_left = *from_left; + int dst_left = *to_left; + int length, unconv_num = 0; + + while (src_left > 0 && dst_left > 0) { + length = mbtowc(dst, src, src_left); + + if (length > 0) { + src += length; + src_left -= length; + if (dst) + dst++; + dst_left--; + } else if (length < 0) { + src++; + src_left--; + unconv_num++; + } else { + /* null ? */ + src++; + src_left--; + if (dst) + *dst++ = L'\0'; + dst_left--; + } + } + + *from = (XPointer) src; + if (dst) + *to = (XPointer) dst; + *from_left = src_left; + *to_left = dst_left; + + return unconv_num; +} + +static int +wcstombs_org( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + + char *encoding; + unsigned long mb, glyph_index; + wchar_t wc; + + int length; + int unconv_num = 0; + + CodeSet codeset; + + const wchar_t *inbufptr = (const wchar_t *) *from; + char *outbufptr = *to; + int from_size = *from_left; + + const char *default_string = XLC_PUBLIC(lcd, default_string); + int defstr_len = strlen(default_string); + + + if (*from_left > *to_left) + *from_left = *to_left; + + while (*from_left && *to_left) { + + wc = *inbufptr++; + (*from_left)--; + + /* null ? */ + if (!wc) { + if (outbufptr) {*outbufptr++ = '\0';} + (*to_left)--; + + continue; + } + + /* convert */ + if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { + + /* output default_string of XDefaultString() */ + if (*to_left < defstr_len) + break; + if (outbufptr) { + strncpy((char *)outbufptr, default_string, defstr_len); + outbufptr += defstr_len; + } + (*to_left) -= defstr_len; + + unconv_num++; + + } else { + mb = gi_to_mb(glyph_index, codeset); + if (codeset->parse_info) { + Bool need_shift = False; + switch (codeset->parse_info->type) { + case E_LSL : + if (codeset != state->GL_codeset) { + need_shift = True; + state->GL_codeset = codeset; + } + break; + case E_LSR : + if (codeset != state->GR_codeset) { + need_shift = True; + state->GR_codeset = codeset; + } + break; + /* case E_SS */ + default: + need_shift = True; + } + + /* output shift sequence */ + if (need_shift) { + encoding = codeset->parse_info->encoding; + length = strlen(encoding); + if (*to_left < length) + break; + if (outbufptr) { + strncpy((char *)outbufptr, encoding, length); + outbufptr += length; + } + (*to_left) -= length; + } + } + + /* output characters */ + length = codeset->length; + if (*to_left < length) + break; + + if (outbufptr) { + output_ulong_value(outbufptr, mb, length, XlcNONE); + outbufptr += length; + } + + (*to_left) -= length; + } + + } /* end of while */ + + *from = (XPointer) ((const wchar_t *) *from + from_size); + *from_left = 0; + *to = (XPointer) outbufptr; + + return unconv_num; +} + +static int +stdc_wcstombs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + const wchar_t *src = *((const wchar_t **) from); + char *dst = *((char **) to); + int src_left = *from_left; + int dst_left = *to_left; + int length, unconv_num = 0; + + while (src_left > 0 && dst_left >= MB_CUR_MAX) { + length = wctomb(dst, *src); /* XXX */ + + if (length > 0) { + src++; + src_left--; + if (dst) + dst += length; + dst_left -= length; + } else if (length < 0) { + src++; + src_left--; + unconv_num++; + } + } + + *from = (XPointer) src; + if (dst) + *to = (XPointer) dst; + *from_left = src_left; + *to_left = dst_left; + + return unconv_num; +} + +static int +wcstocts( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + + unsigned long glyph_index; + wchar_t wc; + + int total_len, seq_len, name_len; + int unconv_num = 0; + Bool first_flag = True, standard_flag; + XlcSide side; + + CodeSet codeset; + XlcCharSet charset, old_charset = NULL; + const char *ct_sequence; + + const wchar_t *inbufptr = (const wchar_t *) *from; + char *outbufptr = *to; + int from_size = *from_left; + char *ext_seg_len = NULL; + + if (*from_left > *to_left) + *from_left = *to_left; + + while (*from_left && *to_left) { + + wc = *inbufptr++; + (*from_left)--; + + /* null ? */ + if (!wc) { + if (outbufptr) {*outbufptr++ = '\0';} + (*to_left)--; + + continue; + } + + /* convert */ + if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { + unconv_num++; + continue; + } + + /* parse charset */ + if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) { + unconv_num++; + continue; + } + + /* Standard Character Set Encoding ? */ + standard_flag = charset->source == CSsrcStd ? True : False; + + /* + * Non-Standard Character Set Encoding + * + * +-----+-----+-----+-----+-----+-----+-----+---- ----+-----+-----+ + * | esc sequence | M | L | encoding name | STX | + * +-----+-----+-----+-----+-----+-----+-----+---- ----+-----+-----+ + * 4bytes 1byte 1byte variable length 1byte + * | | + * +-----------------------------------------+ + * name length = ((M - 128) * 128) + (L - 128) + */ + + /* make encoding data */ + ct_sequence = charset->ct_sequence; + side = charset->side; + seq_len = strlen(ct_sequence); + if (standard_flag) { + name_len = 0; + total_len = seq_len; + } else { + name_len = strlen(charset->encoding_name) + 1; + total_len = seq_len + name_len + 2; + } + + /* output escape sequence of CT */ + if ( (charset != old_charset) && + !(first_flag && charset->string_encoding) ){ + + if ( (ext_seg_len != NULL) && outbufptr) { + int i = (outbufptr - ext_seg_len) - 2; + *ext_seg_len++ = i / 128 + 128; + *ext_seg_len = i % 128 + 128; + ext_seg_len = NULL; + } + + if (*to_left < total_len + 1) { + unconv_num++; + break; + } + + if (outbufptr) { + strcpy((char *)outbufptr, ct_sequence); + outbufptr += seq_len; + + if (!standard_flag) { + const char *i = charset->encoding_name; + ext_seg_len = outbufptr; + outbufptr += 2; + for (; *i ; i++) + *outbufptr++ = ((*i >= 'A') && (*i <= 'Z')) ? + *i - 'A' + 'a' : *i; + *outbufptr++ = STX; + } + } + + (*to_left) -= total_len; + + first_flag = False; + old_charset = charset; + } + + /* output glyph index */ + if (codeset->ctconv) + glyph_index = conv_to_dest(codeset->ctconv, glyph_index); + if (*to_left < charset->char_size) { + unconv_num++; + break; + } + + if (outbufptr) { + output_ulong_value(outbufptr, glyph_index, charset->char_size, side); + outbufptr += charset->char_size; + } + + (*to_left) -= charset->char_size; + + } /* end of while */ + + if ( (ext_seg_len != NULL) && outbufptr) { + int i = (outbufptr - ext_seg_len) - 2; + *ext_seg_len++ = i / 128 + 128; + *ext_seg_len = i % 128 + 128; + } + + *from = (XPointer) ((const wchar_t *) *from + from_size); + *from_left = 0; + *to = (XPointer) outbufptr; + + return unconv_num; +} + +static int +stdc_wcstocts( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); + char *buf_ptr1 = buf; + int buf_left1 = (*from_left) * MB_CUR_MAX; + char *buf_ptr2 = buf_ptr1; + int buf_left2; + int unconv_num1 = 0, unconv_num2 = 0; + + unconv_num1 = stdc_wcstombs(conv, + from, from_left, &buf_ptr1, &buf_left1, args, num_args); + if (unconv_num1 < 0) + goto ret; + + buf_left2 = buf_ptr1 - buf_ptr2; + + unconv_num2 = mbstocts(conv, + &buf_ptr2, &buf_left2, to, to_left, args, num_args); + if (unconv_num2 < 0) + goto ret; + +ret: + if (buf) + Xfree((char *)buf); + + return (unconv_num1 + unconv_num2); +} + +static int +ctstowcs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + + unsigned char ch; + unsigned long glyph_index = 0; + wchar_t wc; + + int ctr_seq_len = 0, gi_len_left = 0, gi_len = 0; + int unconv_num = 0; + + CodeSet codeset = NULL; + XlcCharSet charset_tmp; + + const char *inbufptr = *from; + wchar_t *outbufptr = (wchar_t *) *to; + int from_size = *from_left; + + _XlcResetConverter(conv); /* ??? */ + + if (from == NULL || *from == NULL) { + _XlcResetConverter(conv); + return( 0 ); + } + + if (*from_left > *to_left) + *from_left = *to_left; + + while (*from_left && *to_left) { + + ch = *inbufptr++; + (*from_left)--; + + /* null ? */ + if (!ch) { + if (outbufptr) {*outbufptr++ = L'\0';} + (*to_left)--; + + /* error check */ + if (gi_len_left) { + unconv_num += (gi_len - gi_len_left); + gi_len_left = 0; + } + + continue; + } + + /* same glyph_index data */ + if (gi_len_left) + goto output_one_wc; + + /* control sequence ? */ + if (ch == CSI) { + if ( !ct_parse_csi(inbufptr - 1, &ctr_seq_len) ) + goto skip_the_seg; + + if (*from_left + 1 < ctr_seq_len) { + inbufptr--; + (*from_left)++; + unconv_num += *from_left; + break; + } + + /* skip the control sequence */ + inbufptr += (ctr_seq_len - 1); + *from_left -= (ctr_seq_len - 1); + + continue; + } + + /* escape sequence ? */ + if (ch == ESC) { + if ( !ct_parse_charset(lcd, + inbufptr - 1, &state->charset, &ctr_seq_len) ) + goto skip_the_seg; + + if (state->charset->side == XlcC0 || + state->charset->side == XlcGL) + { + state->GL_charset = state->charset; + } + else if (state->charset->side == XlcC1 || + state->charset->side == XlcGR) + { + state->GR_charset = state->charset; + } + else if (state->charset->side == XlcGLGR) + { + state->GL_charset = state->charset; + state->GR_charset = state->charset; + } + + if (*from_left + 1 < ctr_seq_len) { + inbufptr--; + (*from_left)++; + unconv_num += *from_left; + break; + } + + /* skip the escape sequence */ + inbufptr += (ctr_seq_len - 1); + *from_left -= (ctr_seq_len - 1); + + continue; + } + + /* check current state */ + if (isleftside(ch)) + state->charset = state->GL_charset; + else + state->charset = state->GR_charset; + + gi_len = gi_len_left = state->charset->char_size; + glyph_index = 0; + +output_one_wc: + if (state->charset->side == XlcC1 || state->charset->side == XlcGR) + glyph_index = (glyph_index << 8) | (ch & GL); + else + glyph_index = (glyph_index << 8) | ch; + + gi_len_left--; + + /* last of one glyph_index data */ + if (!gi_len_left) { + + /* segment conversion */ + charset_tmp = state->charset; + segment_conversion(lcd, &charset_tmp, &glyph_index); + + /* get codeset */ + if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp, + &codeset, &glyph_index) ) { + unconv_num += gi_len; + continue; + } + + /* convert glyph index to wicd char */ + gi_to_wc(lcd, glyph_index, codeset, &wc); + if (outbufptr) {*outbufptr++ = wc;} + (*to_left)--; + } + + continue; + +skip_the_seg: + /* skip until next escape or control sequence */ + while ( *from_left ) { + ch = *inbufptr++; + (*from_left)--; + unconv_num++; + + if (ch == ESC || ch == CSI) { + inbufptr--; + (*from_left)++; + unconv_num--; + break; + } + } + + if ( !(*from_left) ) + break; + + } /* end of while */ + + /* error check on last char */ + if (gi_len_left) { + inbufptr -= (gi_len - gi_len_left); + (*from_left) += (gi_len - gi_len_left); + unconv_num += (gi_len - gi_len_left); + } + + *from = (XPointer) ((const char *) *from + from_size); + *from_left = 0; + *to = (XPointer) outbufptr; + + return unconv_num; +} + +static int +cstowcs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + + unsigned char ch; + unsigned long glyph_index = 0; + wchar_t wc; + int gi_len_left = 0, gi_len = 0; + + int unconv_num = 0; + + CodeSet codeset = NULL; + XlcCharSet charset, charset_tmp; + + const char *inbufptr = *from; + wchar_t *outbufptr = (wchar_t *) *to; + int from_size = *from_left; + + if (from == NULL || *from == NULL) { + return( 0 ); + } + + charset = (XlcCharSet) args[0]; + + while (*from_left && *to_left) { + + if (!gi_len_left) { + gi_len_left = gi_len = charset->char_size; + glyph_index = 0; + } + + ch = *inbufptr++; + (*from_left)--; + + /* null ? */ + if (!ch) { + if (outbufptr) {*outbufptr++ = L'\0';} + (*to_left)--; + + /* error check */ + if (gi_len_left) { + unconv_num += (gi_len - gi_len_left); + gi_len_left = 0; + } + continue; + } + + if (charset->side == XlcC1 || charset->side == XlcGR) + glyph_index = (glyph_index << 8) | (ch & GL); + else + glyph_index = (glyph_index << 8) | ch; + + gi_len_left--; + + /* last of one glyph_index data */ + if (!gi_len_left) { + + /* segment conversion */ + charset_tmp = charset; + segment_conversion(lcd, &charset_tmp, &glyph_index); + + /* get codeset */ + if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp, + &codeset, &glyph_index) ) { + unconv_num += gi_len; + continue; + } + + /* convert glyph index to wicd char */ + gi_to_wc(lcd, glyph_index, codeset, &wc); + if (outbufptr) {*outbufptr++ = wc;} + (*to_left)--; + } + + } /* end of while */ + + /* error check on last char */ + if (gi_len_left) { + inbufptr -= (gi_len - gi_len_left); + (*from_left) += (gi_len - gi_len_left); + unconv_num += (gi_len - gi_len_left); + } + + *from = (XPointer) ((const char *) *from + from_size); + *from_left = 0; + *to = (XPointer) outbufptr; + + return unconv_num; +} + +static int +stdc_ctstowcs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); + char *buf_ptr1 = buf; + int buf_left1 = (*from_left) * MB_CUR_MAX; + char *buf_ptr2 = buf_ptr1; + int buf_left2; + int unconv_num1 = 0, unconv_num2 = 0; + + unconv_num1 = ctstombs(conv, + from, from_left, &buf_ptr1, &buf_left1, args, num_args); + if (unconv_num1 < 0) + goto ret; + + buf_left2 = buf_ptr1 - buf_ptr2; + + unconv_num2 = stdc_mbstowcs(conv, + &buf_ptr2, &buf_left2, to, to_left, args, num_args); + if (unconv_num2 < 0) + goto ret; + +ret: + if (buf) + Xfree((char *)buf); + + return (unconv_num1 + unconv_num2); +} + +static int +stdc_cstowcs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); + char *buf_ptr1 = buf; + int buf_left1 = (*from_left) * MB_CUR_MAX; + char *buf_ptr2 = buf_ptr1; + int buf_left2; + int unconv_num1 = 0, unconv_num2 = 0; + + unconv_num1 = cstombs(conv, + from, from_left, &buf_ptr1, &buf_left1, args, num_args); + if (unconv_num1 < 0) + goto ret; + + buf_left2 = buf_ptr1 - buf_ptr2; + + unconv_num2 = stdc_mbstowcs(conv, + &buf_ptr2, &buf_left2, to, to_left, args, num_args); + if (unconv_num2 < 0) + goto ret; + +ret: + if (buf) + Xfree((char *)buf); + + return (unconv_num1 + unconv_num2); +} + +static int +mbstocts( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); + char *buf_ptr1 = buf; + int buf_left1 = (*from_left); + char *buf_ptr2 = buf_ptr1; + int buf_left2; + int unconv_num1 = 0, unconv_num2 = 0; + + unconv_num1 = mbstowcs_org(conv, + from, from_left, &buf_ptr1, &buf_left1, args, num_args); + if (unconv_num1 < 0) + goto ret; + + buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); + + unconv_num2 += wcstocts(conv, + &buf_ptr2, &buf_left2, to, to_left, args, num_args); + if (unconv_num2 < 0) + goto ret; + +ret: + if (buf) + Xfree((char *)buf); + + return (unconv_num1 + unconv_num2); +} + +static int +mbstostr( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + + unsigned char ch; + unsigned long mb = 0; + + int length = 0, len_left = 0; + int unconv_num = 0; + int num; + + CodeSet codeset = NULL; + + const char *inbufptr = *from; + char *outbufptr = *to; + int from_size = *from_left; + + unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); + + if (from == NULL || *from == NULL) { + _XlcResetConverter(conv); + return( 0 ); + } + + if (*from_left > *to_left) + *from_left = *to_left; + + while (*from_left && *to_left) { + + ch = *inbufptr++; + (*from_left)--; + + /* null ? */ + if (!ch) { + if (outbufptr) {*outbufptr++ = '\0';} + (*to_left)--; + + /* error check */ + if (len_left) { + unconv_num += (length - len_left); + len_left = 0; + } + + continue; + } + + /* same mb char data */ + if (len_left) + goto output_one_mb; + + /* next mb char data for single shift ? */ + if (mb_parse_table && (num = mb_parse_table[ch]) ) { + codeset = mb_parse_codeset(state, num, &inbufptr, from_left); + if (codeset != NULL) { + length = len_left = codeset->length; + mb = 0; + continue; + } + } + + /* next char data : byteM ? */ + if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) + goto next_mb_char; + + /* next char data : GL or GR side ? */ + if ((codeset = GLGR_parse_codeset(ch))) + goto next_mb_char; + + /* can't find codeset for the ch */ + unconv_num++; + continue; + +next_mb_char: + length = len_left = codeset->length; + mb = 0; + +output_one_mb: + mb = (mb << 8) | ch; /* 1 byte left shift */ + len_left--; + + /* last of one mb char data */ + if (!len_left) { + if (check_string_encoding(codeset)) { + if (outbufptr) {*outbufptr++ = mb & 0xff;} + (*to_left)--; + } else { + unconv_num++; + } + } + + } /* end of while */ + + /* error check on last char */ + if (len_left) { + inbufptr -= (length - len_left); + (*from_left) += (length - len_left); + unconv_num += (length - len_left); + } + + *from = (XPointer) ((const char *) *from + from_size); + *from_left = 0; + *to = (XPointer) outbufptr; + + return unconv_num; +} + +static int +mbtocs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + + unsigned char ch; + unsigned long mb = 0; + unsigned long glyph_index; + + int length = 0, len_left = 0, char_len; + int unconv_num = 0; + int num; + XlcSide side; + + CodeSet codeset = NULL; + XlcCharSet charset = NULL; + + const char *inbufptr = *from; + char *outbufptr = *to; + int from_size = *from_left; + + unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); + + if (from == NULL || *from == NULL) { + _XlcResetConverter(conv); + return( 0 ); + } + + if (*from_left > *to_left) + *from_left = *to_left; + + while (*from_left && *to_left) { + + ch = *inbufptr++; + (*from_left)--; + + /* null ? */ + if (!ch) { + unconv_num = 1; + if (len_left) + unconv_num += (length - len_left); + break; + } + + /* same mb char data */ + if (len_left) + goto output; + + /* next mb char data for single shift ? */ + if (mb_parse_table && (num = mb_parse_table[ch]) ) { + codeset = mb_parse_codeset(state, num, &inbufptr, from_left); + if (codeset != NULL) { + length = len_left = codeset->length; + mb = 0; + continue; + } + } + + /* next mb char data for byteM ? */ + if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) + goto next_mb_char; + + /* next mb char data for GL or GR side ? */ + if ((codeset = GLGR_parse_codeset(ch))) + goto next_mb_char; + + /* can't find codeset for the ch */ + unconv_num = 1; + break; + +next_mb_char: + length = len_left = codeset->length; + mb = 0; + +output: + mb = (mb << 8) | ch; /* 1 byte left shift */ + len_left--; + + /* last of one mb char data */ + if (!len_left) { + glyph_index = mb_to_gi(mb, codeset); + if (!(charset = gi_parse_charset(glyph_index, codeset))) { + unconv_num = length; + break; + } + char_len = charset->char_size; + side = charset->side; + + /* output glyph index */ + if (codeset->ctconv) + glyph_index = conv_to_dest(codeset->ctconv, glyph_index); + if (*to_left < char_len) { + unconv_num = length; + break; + } + + if (outbufptr) { + output_ulong_value(outbufptr, glyph_index, char_len, side); + outbufptr += char_len; + } + + (*to_left) -= char_len; + + break; + } + + } /* end of while */ + + /* error end */ + if (unconv_num) { + *from = (XPointer) ((const char *) *from + from_size); + *from_left = 0; + *to = (XPointer) outbufptr; + return -1; + } + + /* nomal end */ + *from = (XPointer) inbufptr; + *to = (XPointer) outbufptr; + + if (num_args > 0) + *((XlcCharSet *) args[0]) = charset; + + return 0; +} + +static int +mbstocs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + int ret; + XlcCharSet charset_old, charset = NULL; + XPointer tmp_args[1]; + + const char *inbufptr; + int in_left; + char *outbufptr; + int out_left; + tmp_args[0] = (XPointer) &charset; + + ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1); + charset_old = charset; + + while ( ret == 0 && *from_left && *to_left) { + inbufptr = *from; + in_left = *from_left; + outbufptr = *to; + out_left = *to_left; + ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1); + if (charset_old != charset) { + *from = (XPointer) inbufptr; + *from_left = in_left; + *to = (XPointer) outbufptr; + *to_left = out_left; + break; + } + } + + if (num_args > 0) + *((XlcCharSet *) args[0]) = charset_old; + + /* error end */ + if (ret != 0) + return( -1 ); + + return(0); +} + +static int +wcstostr( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + + char *encoding; + unsigned long mb, glyph_index; + wchar_t wc; + + int length; + int unconv_num = 0; + + CodeSet codeset; + + const wchar_t *inbufptr = (const wchar_t *) *from; + char *outbufptr = *to; + int from_size = *from_left; + + const char *default_string = XLC_PUBLIC(lcd, default_string); + int defstr_len = strlen(default_string); + + + if (*from_left > *to_left) + *from_left = *to_left; + + while (*from_left && *to_left) { + + wc = *inbufptr++; + (*from_left)--; + + /* null ? */ + if (!wc) { + if (outbufptr) {*outbufptr++ = '\0';} + (*to_left)--; + + continue; + } + + /* convert */ + if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { + + /* output default_string of XDefaultString() */ + if (*to_left < defstr_len) + break; + if (outbufptr) { + strncpy((char *)outbufptr, default_string, defstr_len); + outbufptr += defstr_len; + } + (*to_left) -= defstr_len; + + unconv_num++; + + } else { + mb = gi_to_mb(glyph_index, codeset); + + if (check_string_encoding(codeset)) { + if (codeset->parse_info) { + Bool need_shift = False; + switch (codeset->parse_info->type) { + case E_LSL : + if (codeset != state->GL_codeset) { + need_shift = True; + state->GL_codeset = codeset; + } + break; + case E_LSR : + if (codeset != state->GR_codeset) { + need_shift = True; + state->GR_codeset = codeset; + } + break; + /* case E_SS */ + default: + need_shift = True; + } + + /* output shift sequence */ + if (need_shift) { + encoding = codeset->parse_info->encoding; + length = strlen(encoding); + if (*to_left < length) + break; + + if (outbufptr) { + strncpy((char *)outbufptr, encoding, length); + outbufptr += length; + } + (*to_left) -= length; + } + } + + /* output characters */ + length = codeset->length; + if (*to_left < length) + break; + + if (outbufptr) { + output_ulong_value(outbufptr, mb, length, XlcNONE); + outbufptr += length; + } + + (*to_left) -= length; + } else { + unconv_num++; + } + } + + } /* end of while */ + + *from = (XPointer) ((const wchar_t *) *from + from_size); + *from_left = 0; + *to = (XPointer) outbufptr; + + return unconv_num; +} + +static int +stdc_wcstostr( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); + char *buf_ptr1 = buf; + int buf_left1 = (*from_left) * MB_CUR_MAX; + char *buf_ptr2 = buf_ptr1; + int buf_left2; + int unconv_num1 = 0, unconv_num2 = 0; + + unconv_num1 = stdc_wcstombs(conv, + from, from_left, &buf_ptr1, &buf_left1, args, num_args); + if (unconv_num1 < 0) + goto ret; + + buf_left2 = buf_ptr1 - buf_ptr2; + + unconv_num2 = mbstostr(conv, + &buf_ptr2, &buf_left2, to, to_left, args, num_args); + if (unconv_num2 < 0) + goto ret; + +ret: + if (buf) + Xfree((char *)buf); + + return (unconv_num1 + unconv_num2); +} + +static int +wctocs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + + wchar_t wc; + unsigned long glyph_index; + + int char_len; + int unconv_num = 0; + XlcSide side; + + CodeSet codeset; + XlcCharSet charset = NULL; + + const wchar_t *inbufptr = (const wchar_t *) *from; + char *outbufptr = *to; + int from_size = *from_left; + + if (*from_left > *to_left) + *from_left = *to_left; + + if (*from_left && *to_left) { + + wc = *inbufptr++; + (*from_left)--; + + /* null ? */ + if (!wc) { + unconv_num = 1; + goto end; + } + + /* convert */ + if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { + unconv_num = 1; + goto end; + } + + if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) { + unconv_num = 1; + goto end; + } + char_len = charset->char_size; + side = charset->side; + + /* output glyph index */ + if (codeset->ctconv) + glyph_index = conv_to_dest(codeset->ctconv, glyph_index); + if (*to_left < char_len) { + unconv_num++; + goto end; + } + + if (outbufptr) { + output_ulong_value(outbufptr, glyph_index, char_len, side); + outbufptr += char_len; + } + + (*to_left) -= char_len; + + } + +end: + + /* error end */ + if (unconv_num) { + *from = (XPointer) ((const wchar_t *) *from + from_size); + *from_left = 0; + *to = (XPointer) outbufptr; + return -1; + } + + /* nomal end */ + *from = (XPointer) inbufptr; + *to = (XPointer) outbufptr; + + if (num_args > 0) + *((XlcCharSet *) args[0]) = charset; + + return 0; +} + +static int +stdc_wctocs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + const wchar_t *src = *((const wchar_t **) from); + wchar_t wch; + XPointer tmp_from, save_from = *from; + char tmp[32]; + int length, ret, src_left = *from_left; + int from_size = *from_left; + + if (src_left > 0 && *to_left > 0) { + if ((wch = *src)) { + length = wctomb(tmp, wch); + } else { + goto end; + } + + if (length < 0) + goto end; + + tmp_from = (XPointer) tmp; + ret = mbtocs(conv, &tmp_from, &length, to, to_left, args, num_args); + if (ret < 0) + goto end; + + src++; + src_left--; + } + +end: + /* error end */ + if (save_from == (XPointer) src) { + *from = (XPointer) ((const wchar_t *) *from + from_size); + *from_left = 0; + return -1; + } + + /* nomal end */ + *from = (XPointer) src; + *from_left = src_left; + + return 0; +} + +static int +wcstocs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + int ret; + XlcCharSet charset_old, charset = NULL; + XPointer tmp_args[1]; + + const wchar_t *inbufptr; + int in_left; + XPointer outbufptr; + int out_left; + tmp_args[0] = (XPointer) &charset; + + ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1); + charset_old = charset; + + while ( ret == 0 && *from_left && *to_left) { + inbufptr = (const wchar_t *) *from; + in_left = *from_left; + outbufptr = *to; + out_left = *to_left; + ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1); + if (charset_old != charset) { + *from = (XPointer) inbufptr; + *from_left = in_left; + *to = (XPointer) outbufptr; + *to_left = out_left; + break; + } + } + + if (num_args > 0) + *((XlcCharSet *) args[0]) = charset_old; + + /* error end */ + if (ret != 0) + return( -1 ); + + return(0); +} + +#ifdef STDCVT + +static int +stdc_wcstocs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + int ret; + XlcCharSet charset_old, charset = NULL; + XPointer tmp_args[1]; + + const wchar_t *inbufptr; + int in_left; + XPointer outbufptr; + int out_left; + tmp_args[0] = (XPointer) &charset; + + ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1); + charset_old = charset; + + while ( ret == 0 && *from_left && *to_left ) { + inbufptr = (const wchar_t *) *from; + in_left = *from_left; + outbufptr = *to; + out_left = *to_left; + ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1); + if (charset_old != charset) { + *from = (XPointer) inbufptr; + *from_left = in_left; + *to = (XPointer) outbufptr; + *to_left = out_left; + break; + } + } + + if (num_args > 0) + *((XlcCharSet *) args[0]) = charset_old; + + /* error end */ + if (ret != 0) + return( -1 ); + + return(0); +} + +#endif + +static int +ctstombs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); + char *buf_ptr1 = buf; + int buf_left1 = (*from_left); + char *buf_ptr2 = buf_ptr1; + int buf_left2; + int unconv_num1 = 0, unconv_num2 = 0; + + unconv_num1 = ctstowcs(conv, + from, from_left, &buf_ptr1, &buf_left1, args, num_args); + if (unconv_num1 < 0) + goto ret; + + buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); + + unconv_num2 += wcstombs_org(conv, + &buf_ptr2, &buf_left2, to, to_left, args, num_args); + if (unconv_num2 < 0) + goto ret; + +ret: + if (buf) + Xfree((char *)buf); + + return (unconv_num1 + unconv_num2); +} + +static int +cstombs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); + char *buf_ptr1 = buf; + int buf_left1 = (*from_left); + char *buf_ptr2 = buf_ptr1; + int buf_left2; + int unconv_num1 = 0, unconv_num2 = 0; + + unconv_num1 = cstowcs(conv, + from, from_left, &buf_ptr1, &buf_left1, args, num_args); + if (unconv_num1 < 0) + goto ret; + + buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); + + unconv_num2 += wcstombs_org(conv, + &buf_ptr2, &buf_left2, to, to_left, args, num_args); + if (unconv_num2 < 0) + goto ret; + +ret: + if (buf) + Xfree((char *)buf); + + return (unconv_num1 + unconv_num2); +} + +static int +strtombs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + + char *encoding; + unsigned long mb, glyph_index; + unsigned char ch; + + int length; + int unconv_num = 0; + + CodeSet codeset; + + const char *inbufptr = *from; + char *outbufptr = *to; + int from_size = *from_left; + + if (*from_left > *to_left) + *from_left = *to_left; + + while (*from_left && *to_left) { + + ch = *inbufptr++; + (*from_left)--; + + /* null ? */ + if (!ch) { + if (outbufptr) {*outbufptr++ = '\0';} + (*to_left)--; + + continue; + } + + /* convert */ + if (isleftside(ch)) { + glyph_index = ch; + codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL"); + } else { + glyph_index = ch & GL; + codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR"); + } + + if (!codeset) { + unconv_num++; + continue; + } + + mb = gi_to_mb(glyph_index, codeset); + if (codeset->parse_info) { + Bool need_shift = False; + switch (codeset->parse_info->type) { + case E_LSL : + if (codeset != state->GL_codeset) { + need_shift = True; + state->GL_codeset = codeset; + } + break; + case E_LSR : + if (codeset != state->GR_codeset) { + need_shift = True; + state->GR_codeset = codeset; + } + break; + /* case E_SS */ + default: + need_shift = True; + } + + /* output shift sequence */ + if (need_shift) { + encoding = codeset->parse_info->encoding; + length = strlen(encoding); + if (*to_left < length) + break; + if (outbufptr) { + strncpy((char *)outbufptr, encoding, length); + outbufptr += length; + } + (*to_left) -= length; + } + } + + /* output characters */ + length = codeset->length; + if (*to_left < length) + break; + + if (outbufptr) { + output_ulong_value(outbufptr, mb, length, XlcNONE); + outbufptr += length; + } + + (*to_left) -= length; + + } /* end of while */ + + *from = (XPointer) ((const char *) *from + from_size); + *from_left = 0; + *to = (XPointer) outbufptr; + + return unconv_num; +} + +static int +strtowcs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + + unsigned char ch; + unsigned long glyph_index; + wchar_t wc; + + int unconv_num = 0; + CodeSet codeset; + + const char *inbufptr = *from; + wchar_t *outbufptr = (wchar_t *)*to; + int from_size = *from_left; + + if (*from_left > *to_left) + *from_left = *to_left; + + while (*from_left && *to_left) { + + ch = *inbufptr++; + (*from_left)--; + + /* null ? */ + if (!ch) { + if (outbufptr) {*outbufptr++ = L'\0';} + (*to_left)--; + + continue; + } + + /* convert */ + if (isleftside(ch)) { + glyph_index = ch; + codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL"); + } else { + glyph_index = ch & GL; + codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR"); + } + + if (!codeset) { + unconv_num++; + continue; + } + + gi_to_wc(lcd, glyph_index, codeset, &wc); + if (outbufptr) {*outbufptr++ = wc;} + (*to_left)--; + + } /* end of while */ + + *from = (XPointer) ((const char *) *from + from_size); + *from_left = 0; + *to = (XPointer) outbufptr; + + return unconv_num; +} + +static int +stdc_strtowcs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); + char *buf_ptr1 = buf; + int buf_left1 = (*from_left) * MB_CUR_MAX; + char *buf_ptr2 = buf_ptr1; + int buf_left2; + int unconv_num1 = 0, unconv_num2 = 0; + + unconv_num1 = strtombs(conv, + from, from_left, &buf_ptr1, &buf_left1, args, num_args); + if (unconv_num1 < 0) + goto ret; + + buf_left2 = buf_ptr1 - buf_ptr2; + + unconv_num2 = stdc_mbstowcs(conv, + &buf_ptr2, &buf_left2, to, to_left, args, num_args); + if (unconv_num2 < 0) + goto ret; + +ret: + if (buf) + Xfree((char *)buf); + + return (unconv_num1 + unconv_num2); +} + +/* -------------------------------------------------------------------------- */ +/* Close */ +/* -------------------------------------------------------------------------- */ + +static void +close_converter( + XlcConv conv) +{ + if (conv->state) { + Xfree((char *) conv->state); + } + + if (conv->methods) { + Xfree((char *) conv->methods); + } + + Xfree((char *) conv); +} + +/* -------------------------------------------------------------------------- */ +/* Open */ +/* -------------------------------------------------------------------------- */ + +static XlcConv +create_conv( + XLCd lcd, + XlcConvMethods methods) +{ + XlcConv conv; + State state; + + conv = (XlcConv) Xcalloc(1, sizeof(XlcConvRec)); + if (conv == NULL) + return (XlcConv) NULL; + + conv->methods = (XlcConvMethods) Xmalloc(sizeof(XlcConvMethodsRec)); + if (conv->methods == NULL) + goto err; + *conv->methods = *methods; + conv->methods->reset = init_state; + + conv->state = Xcalloc(1, sizeof(StateRec)); + if (conv->state == NULL) + goto err; + + state = (State) conv->state; + state->lcd = lcd; + + _XlcResetConverter(conv); + + return conv; + +err: + close_converter(conv); + + return (XlcConv) NULL; +} + +static XlcConvMethodsRec mbstocts_methods = { + close_converter, + mbstocts, + NULL +}; + +static XlcConv +open_mbstocts( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &mbstocts_methods); +} + +static XlcConvMethodsRec mbstostr_methods = { + close_converter, + mbstostr, + NULL +}; + +static XlcConv +open_mbstostr( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &mbstostr_methods); +} + +static XlcConvMethodsRec mbstocs_methods = { + close_converter, + mbstocs, + NULL +}; + +static XlcConv +open_mbstocs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &mbstocs_methods); +} + +static XlcConvMethodsRec mbtocs_methods = { + close_converter, + mbtocs, + NULL +}; + +static XlcConv +open_mbtocs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &mbtocs_methods); +} + +static XlcConvMethodsRec ctstombs_methods = { + close_converter, + ctstombs, + NULL +}; + +static XlcConv +open_ctstombs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &ctstombs_methods); +} + +static XlcConvMethodsRec cstombs_methods = { + close_converter, + cstombs, + NULL +}; + +static XlcConv +open_cstombs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &cstombs_methods); +} + +static XlcConvMethodsRec strtombs_methods = { + close_converter, + strtombs, + NULL +}; + +static XlcConv +open_strtombs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &strtombs_methods); +} + +#ifdef STDCVT + +static XlcConvMethodsRec stdc_mbstowcs_methods = { + close_converter, + stdc_mbstowcs, + NULL +}; + +static XlcConv +open_stdc_mbstowcs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_mbstowcs_methods); +} + +static XlcConvMethodsRec stdc_wcstombs_methods = { + close_converter, + stdc_wcstombs, + NULL +}; + +static XlcConv +open_stdc_wcstombs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_wcstombs_methods); +} + +static XlcConvMethodsRec stdc_wcstocts_methods = { + close_converter, + stdc_wcstocts, + NULL +}; + +static XlcConv +open_stdc_wcstocts( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_wcstocts_methods); +} + +static XlcConvMethodsRec stdc_wcstostr_methods = { + close_converter, + stdc_wcstostr, + NULL +}; + +static XlcConv +open_stdc_wcstostr( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_wcstostr_methods); +} + +static XlcConvMethodsRec stdc_wcstocs_methods = { + close_converter, + stdc_wcstocs, + NULL +}; + +static XlcConv +open_stdc_wcstocs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_wcstocs_methods); +} + +static XlcConvMethodsRec stdc_wctocs_methods = { + close_converter, + stdc_wctocs, + NULL +}; + +static XlcConv +open_stdc_wctocs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_wctocs_methods); +} + +static XlcConvMethodsRec stdc_ctstowcs_methods = { + close_converter, + stdc_ctstowcs, + NULL +}; + +static XlcConv +open_stdc_ctstowcs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_ctstowcs_methods); +} + +static XlcConvMethodsRec stdc_cstowcs_methods = { + close_converter, + stdc_cstowcs, + NULL +}; + +static XlcConv +open_stdc_cstowcs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_cstowcs_methods); +} + +static XlcConvMethodsRec stdc_strtowcs_methods = { + close_converter, + stdc_strtowcs, + NULL +}; + +static XlcConv +open_stdc_strtowcs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_strtowcs_methods); +} + +#endif /* STDCVT */ + +static XlcConvMethodsRec mbstowcs_methods = { + close_converter, + mbstowcs_org, + NULL +}; + +static XlcConv +open_mbstowcs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &mbstowcs_methods); +} + +static XlcConvMethodsRec wcstombs_methods = { + close_converter, + wcstombs_org, + NULL +}; + +static XlcConv +open_wcstombs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &wcstombs_methods); +} + +static XlcConvMethodsRec wcstocts_methods = { + close_converter, + wcstocts, + NULL +}; + +static XlcConv +open_wcstocts( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &wcstocts_methods); +} + +static XlcConvMethodsRec wcstostr_methods = { + close_converter, + wcstostr, + NULL +}; + +static XlcConv +open_wcstostr( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &wcstostr_methods); +} + +static XlcConvMethodsRec wcstocs_methods = { + close_converter, + wcstocs, + NULL +}; + +static XlcConv +open_wcstocs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &wcstocs_methods); +} + +static XlcConvMethodsRec wctocs_methods = { + close_converter, + wctocs, + NULL +}; + +static XlcConv +open_wctocs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &wctocs_methods); +} + +static XlcConvMethodsRec ctstowcs_methods = { + close_converter, + ctstowcs, + NULL +}; + +static XlcConv +open_ctstowcs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &ctstowcs_methods); +} + +static XlcConvMethodsRec cstowcs_methods = { + close_converter, + cstowcs, + NULL +}; + +static XlcConv +open_cstowcs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &cstowcs_methods); +} + +static XlcConvMethodsRec strtowcs_methods = { + close_converter, + strtowcs, + NULL +}; + +static XlcConv +open_strtowcs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &strtowcs_methods); +} + +/* -------------------------------------------------------------------------- */ +/* Loader */ +/* -------------------------------------------------------------------------- */ + +XLCd +_XlcGenericLoader( + const char *name) +{ + XLCd lcd; +#ifdef STDCVT + XLCdGenericPart *gen; +#endif + + lcd = _XlcCreateLC(name, _XlcGenericMethods); + + if (lcd == NULL) + return lcd; + + default_GL_charset = _XlcGetCharSet("ISO8859-1:GL"); + default_GR_charset = _XlcGetCharSet("ISO8859-1:GR"); + + _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCompoundText, open_mbstocts); + _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNString, open_mbstostr); + _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs); + _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs); + _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte, open_ctstombs); + _XlcSetConverter(lcd, XlcNString, lcd, XlcNMultiByte, open_strtombs); + _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs); + +#ifdef STDCVT + gen = XLC_GENERIC_PART(lcd); + + if (gen->use_stdc_env != True) { +#endif + _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_mbstowcs); + _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_wcstombs); + _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_wcstocts); + _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_wcstostr); + _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs); + _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNChar, open_wctocs); + _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_ctstowcs); + _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_strtowcs); + _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs); +#ifdef STDCVT + } +#endif + +#ifdef STDCVT + if (gen->use_stdc_env == True) { + _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_stdc_mbstowcs); + _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_stdc_wcstombs); + _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_stdc_wcstocts); + _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_stdc_wcstostr); + _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_stdc_wcstocs); + _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNChar, open_stdc_wctocs); + _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_stdc_ctstowcs); + _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_stdc_strtowcs); + _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_stdc_cstowcs); + } +#endif + + _XlcAddUtf8Converters(lcd); + + return lcd; +} diff --git a/libX11/modules/lc/xlocale/lcJis.c b/libX11/modules/lc/xlocale/lcJis.c index c2ca2f560..551862d9b 100644 --- a/libX11/modules/lc/xlocale/lcJis.c +++ b/libX11/modules/lc/xlocale/lcJis.c @@ -1,944 +1,944 @@ -/* - * Copyright 1992, 1993 by TOSHIBA Corp. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of TOSHIBA not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. TOSHIBA make no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - * Author: Katsuhisa Yano TOSHIBA Corp. - * mopi@osa.ilab.toshiba.co.jp - */ - -/* - * A Japanese JIS locale. - * Supports: all locales with codeset JIS7. - * How: Provides converters for JIS. - * Platforms: Only those defining X_LOCALE (only Lynx, Linux-libc5, OS/2). - */ - -#ifdef X_LOCALE - -#ifdef HAVE_CONFIG_H -#include -#endif -#include "Xlibint.h" -#include "XlcGeneric.h" -#include - -#if !defined(X_LOCALE) -#define STDCVT -#endif - -typedef struct _StateRec { - XLCd lcd; - XlcCharSet charset; - XlcCharSet GL_charset; - XlcCharSet GR_charset; -} StateRec, *State; - -static void -init_state( - XlcConv conv) -{ - State state = (State) conv->state; - XLCdGenericPart *gen = XLC_GENERIC_PART(state->lcd); - CodeSet codeset; - - codeset = gen->initial_state_GL; - if (codeset && codeset->charset_list) - state->GL_charset = *codeset->charset_list; - codeset = gen->initial_state_GR; - if (codeset && codeset->charset_list) - state->GR_charset = *codeset->charset_list; - - if (state->GL_charset == NULL) - if ((codeset = *gen->codeset_list) != NULL) - state->GL_charset = *codeset->charset_list; -} - -static int -compare( - const char *src, - const char *encoding, - int length) -{ - const char *start = src; - - while (length-- > 0) { - if (*src++ != *encoding++) - return 0; - if (*encoding == '\0') - return src - start; - } - - return 0; -} - -static int -mbtocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - const char *src; - char *dst; - unsigned char *mb_parse_table; - ParseInfo *parse_list, parse_info; - XlcCharSet charset; - int length, number, encoding_len = 0; - int i; - - src = *((const char **) from); - dst = *((char **) to); - - mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); - if (mb_parse_table != NULL) { - number = mb_parse_table[(unsigned char) *src]; - if (number > 0) { - parse_list = XLC_GENERIC(lcd, mb_parse_list) + number - 1; - for ( ; (parse_info = *parse_list) != NULL; parse_list++) { - encoding_len = compare(src, parse_info->encoding, *from_left); - if (encoding_len > 0) { - switch (parse_info->type) { - case E_SS: - src += encoding_len; - charset = *parse_info->codeset->charset_list; - goto found; - case E_LSL: - case E_LSR: - src += encoding_len; - charset = *parse_info->codeset->charset_list; - if (parse_info->type == E_LSL) - state->GL_charset = charset; - else - state->GR_charset = charset; - length = 0; - goto end; - case E_GL: - charset = state->GL_charset; - goto found; - case E_GR: - charset = state->GR_charset; - goto found; - default: - break; - } - } - } - } - } - - if ((*src & 0x80) && state->GR_charset) - charset = state->GR_charset; - else - charset = state->GL_charset; - -found: - if (charset == NULL || - (num_args == 2 && (XlcCharSet) args[1] != charset)) - return -1; - - length = charset->char_size; - if (length > *from_left - encoding_len) - return -1; - - if (dst) { - if (length > *to_left) - return -1; - if (charset->side == XlcGL) { - for (i = 0; i < length; i++) - *dst++ = *src++ & 0x7f; - } else if (charset->side == XlcGR) { - for (i = 0; i < length; i++) - *dst++ = *src++ | 0x80; - } else { - for (i = 0; i < length; i++) - *dst++ = *src++; - } - *to = (XPointer) dst; - *to_left -= length; - } -end: - *from = (XPointer) src; - *from_left -= encoding_len + length; - state->charset = charset; - if (num_args == 1) - *((XlcCharSet *) args[0]) = charset; - - return 0; -} - -static int -mbstocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XlcCharSet charset = NULL; - XPointer tmp_args[2], save_from = *from; - int ret, unconv_num = 0, tmp_num = 1; - - tmp_args[0] = (XPointer) &charset; - - while (*from_left > 0 && *to_left > 0) { - ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, tmp_num); - if (ret < 0) - break; - unconv_num += ret; - if (tmp_num == 1 && charset) { - tmp_args[1] = (XPointer) charset; - tmp_num = 2; - } - } - - if (save_from == *from) - return -1; - - if (num_args > 0) - *((XlcCharSet *) args[0]) = charset; - - return unconv_num; -} - -static CodeSet -wc_parse_codeset( - XLCd lcd, - const wchar_t *wcstr) -{ - CodeSet *codeset; - unsigned long wc_encoding; - int num; - - wc_encoding = *wcstr & XLC_GENERIC(lcd, wc_encode_mask); - num = XLC_GENERIC(lcd, codeset_num); - codeset = XLC_GENERIC(lcd, codeset_list); - while (num-- > 0) { - if (wc_encoding == (*codeset)->wc_encoding) - return *codeset; - codeset++; - } - - return NULL; -} - -static int -wcstocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - const wchar_t *wcptr; - char *bufptr; - wchar_t wch; - char *tmpptr; - int length; - CodeSet codeset; - unsigned long wc_encoding; - int wcstr_len, buf_len; - - if (from == NULL || *from == NULL) - return 0; - - wcptr = *((const wchar_t **) from); - bufptr = *((char **) to); - wcstr_len = *from_left; - buf_len = *to_left; - - codeset = wc_parse_codeset(lcd, wcptr); - if (codeset == NULL) - return -1; - wc_encoding = codeset->wc_encoding; - - if (wcstr_len < buf_len / codeset->length) - buf_len = wcstr_len * codeset->length; - - for ( ; wcstr_len > 0 && buf_len > 0; wcptr++, wcstr_len--) { - wch = *wcptr; - if ((wch & XLC_GENERIC(lcd, wc_encode_mask)) != wc_encoding) - break; - length = codeset->length; - buf_len -= length; - bufptr += length; - - tmpptr = bufptr - 1; - if ((*codeset->charset_list)->side == XlcGL) { - while (length--) { - *tmpptr-- = (unsigned char) (wch & 0x7f); - wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits); - } - } else if ((*codeset->charset_list)->side == XlcGR) { - while (length--) { - *tmpptr-- = (unsigned char) (wch | 0x80); - wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits); - } - } else { - while (length--) { - *tmpptr-- = (unsigned char) wch; - wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits); - } - } - } - - if (num_args > 0) - *((XlcCharSet *) args[0]) = *codeset->charset_list; - - *from_left -= wcptr - *((wchar_t **) from); - *from = (XPointer) wcptr; - - *to_left -= bufptr - *((char **) to); - *to = bufptr; - - return 0; -} - -static CodeSet -GetCodeSetFromCharSet( - XLCd lcd, - XlcCharSet charset) -{ - CodeSet *codeset = XLC_GENERIC(lcd, codeset_list); - XlcCharSet *charset_list; - int codeset_num, num_charsets; - - codeset_num = XLC_GENERIC(lcd, codeset_num); - - for ( ; codeset_num-- > 0; codeset++) { - num_charsets = (*codeset)->num_charsets; - charset_list = (*codeset)->charset_list; - - for ( ; num_charsets-- > 0; charset_list++) - if (*charset_list == charset) - return *codeset; - } - - return (CodeSet) NULL; -} - -static int -cstombs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - const char *csptr; - char *bufptr; - int csstr_len; - int buf_len; - int num, encoding_len = 0; - CodeSet codeset; - XlcCharSet charset; - EncodingType type; - int cvt_length; - - csptr = *((const char **) from); - bufptr = *((char **) to); - csstr_len = *from_left; - buf_len = *to_left; - - if (num_args < 1) - return -1; - - charset = (XlcCharSet) args[0]; - - codeset = GetCodeSetFromCharSet(state->lcd, charset); - if (codeset == NULL) - return -1; - - cvt_length = 0; - if (codeset->parse_info) { - switch (type = codeset->parse_info->type) { - case E_SS: - encoding_len = strlen(codeset->parse_info->encoding); - break; - case E_LSL: - case E_LSR: - if (type == E_LSL) { - if (charset == state->GL_charset) - break; - } else { - if (charset == state->GR_charset) - break; - } - encoding_len = strlen(codeset->parse_info->encoding); - if (encoding_len > buf_len) - return -1; - cvt_length += encoding_len; - if (bufptr) { - strcpy(bufptr, codeset->parse_info->encoding); - bufptr += encoding_len; - } - buf_len -= encoding_len; - encoding_len = 0; - if (type == E_LSL) - state->GL_charset = charset; - else - state->GR_charset = charset; - break; - default: - break; - } - } - - csstr_len /= codeset->length; - buf_len /= codeset->length + encoding_len; - if (csstr_len < buf_len) - buf_len = csstr_len; - - cvt_length += buf_len * (encoding_len + codeset->length); - if (bufptr) { - while (buf_len--) { - if (encoding_len) { - strcpy(bufptr, codeset->parse_info->encoding); - bufptr += encoding_len; - } - num = codeset->length; - if (codeset->side == XlcGL) { - while (num--) - *bufptr++ = *csptr++ & 0x7f; - } else if (codeset->side == XlcGR) { - while (num--) - *bufptr++ = *csptr++ | 0x80; - } else { - while (num--) - *bufptr++ = *csptr++; - } - } - } - - *from_left -= csptr - *((char **) from); - *from = (XPointer) csptr; - - if (bufptr) - *to = (XPointer) bufptr; - *to_left -= cvt_length; - - return 0; -} - -static int -cstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - State state = (State) conv->state; - XLCd lcd = state->lcd; - const char *csptr; - wchar_t *bufptr; - int csstr_len; - int buf_len; - wchar_t wch; - unsigned long code_mask, wc_encoding; - int num, length, wc_shift_bits; - CodeSet codeset; - - csptr = *((const char **) from); - bufptr = *((wchar_t **) to); - csstr_len = *from_left; - buf_len = *to_left; - - if (num_args < 1) - return -1; - - codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0]); - if (codeset == NULL) - return -1; - - length = codeset->length; - csstr_len /= length; - if (csstr_len < buf_len) - buf_len = csstr_len; - - code_mask = ~XLC_GENERIC(lcd, wc_encode_mask); - wc_encoding = codeset->wc_encoding; - wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits); - - *to_left -= buf_len; - - if (bufptr) { - while (buf_len--) { - wch = (wchar_t) (*csptr++ & 0x7f); - num = length - 1; - while (num--) - wch = (wch << wc_shift_bits) | (*csptr++ & 0x7f); - - *bufptr++ = (wch & code_mask) | wc_encoding; - } - } - - *from_left -= csptr - *((char **) from); - *from = (XPointer) csptr; - - if (bufptr) - *to = (XPointer) bufptr; - - return 0; -} - - -static void -close_converter( - XlcConv conv) -{ - if (conv->state) { - Xfree((char *) conv->state); - } - - Xfree((char *) conv); -} - -static XlcConv -create_conv( - XLCd lcd, - XlcConvMethods methods) -{ - XlcConv conv; - State state; - - conv = (XlcConv) Xmalloc(sizeof(XlcConvRec)); - if (conv == NULL) - return (XlcConv) NULL; - - conv->methods = (XlcConvMethods) Xmalloc(sizeof(XlcConvMethodsRec)); - if (conv->methods == NULL) - goto err; - *conv->methods = *methods; - if (XLC_PUBLIC(lcd, is_state_depend)) - conv->methods->reset = init_state; - - conv->state = Xcalloc(1, sizeof(StateRec)); - if (conv->state == NULL) - goto err; - - state = (State) conv->state; - state->lcd = lcd; - init_state(conv); - - return conv; - -err: - close_converter(conv); - - return (XlcConv) NULL; -} - -static XlcConvMethodsRec mbstocs_methods = { - close_converter, - mbstocs, - NULL -}; - -static XlcConv -open_mbstocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &mbstocs_methods); -} - -static XlcConvMethodsRec wcstocs_methods = { - close_converter, - wcstocs, - NULL -}; - -static XlcConv -open_wcstocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &wcstocs_methods); -} - -static XlcConvMethodsRec mbtocs_methods = { - close_converter, - mbtocs, - NULL -}; - -static XlcConv -open_mbtocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &mbtocs_methods); -} - -static XlcConvMethodsRec cstombs_methods = { - close_converter, - cstombs, - NULL -}; - -static XlcConv -open_cstombs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &cstombs_methods); -} - -static XlcConvMethodsRec cstowcs_methods = { - close_converter, - cstowcs, - NULL -}; - -static XlcConv -open_cstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &cstowcs_methods); -} - -#ifdef STDCVT -static int -stdc_mbstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - const char *src = *((const char **) from); - wchar_t *dst = *((wchar_t **) to); - int src_left = *from_left; - int dst_left = *to_left; - int length; - - while (src_left > 0 && dst_left > 0) { - length = mbtowc(dst, src, src_left); - if (length < 0) - break; - - src += length; - src_left -= length; - if (dst) - dst++; - dst_left--; - - if (length == 0) { - src++; - src_left--; - break; - } - } - - if (*from_left == src_left) - return -1; - - *from = (XPointer) src; - if (dst) - *to = (XPointer) dst; - *from_left = src_left; - *to_left = dst_left; - - return 0; -} - -static int -stdc_wcstombs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - const wchar_t *src = *((const wchar_t **) from); - char *dst = *((char **) to); - int src_left = *from_left; - int dst_left = *to_left; - int length; - - while (src_left > 0 && dst_left > 0) { - length = wctomb(dst, *src); /* XXX */ - if (length < 0 || dst_left < length) - break; - - src++; - src_left--; - dst += length; - dst_left -= length; - - if (length == 0) { - dst++; - dst_left--; - break; - } - } - - if (*from_left == src_left) - return -1; - - *from = (XPointer) src; - *to = (XPointer) dst; - *from_left = src_left; - *to_left = dst_left; - - return 0; -} - -static int -stdc_wcstocs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - const wchar_t *src = *((const wchar_t **) from); - wchar_t wch; - XlcCharSet charset = NULL; - XPointer tmp_args[2], tmp_from, save_from = *from; - char tmp[32]; - int length, ret, src_left = *from_left; - int unconv_num = 0, tmp_num = 1; - - tmp_args[0] = (XPointer) &charset; - - while (src_left > 0 && *to_left > 0) { - if (wch = *src) { - length = wctomb(tmp, wch); - } else { - length = 1; - *tmp = '\0'; - } - - if (length < 0) - break; - - tmp_from = (XPointer) tmp; - ret = mbtocs(conv, &tmp_from, &length, to, to_left, tmp_args, tmp_num); - if (ret < 0) - break; - unconv_num += ret; - if (tmp_num == 1 && charset) { - tmp_args[1] = (XPointer) charset; - tmp_num = 2; - } - - src++; - src_left--; - } - - if (save_from == (XPointer) src) - return -1; - - *from = (XPointer) src; - *from_left = src_left; - - if (num_args > 0) - *((XlcCharSet *) args[0]) = charset; - - return unconv_num; -} - -#define DefineLocalBuf char local_buf[BUFSIZ] -#define AllocLocalBuf(length) (length > BUFSIZ ? (char*) Xmalloc(length) : local_buf) -#define FreeLocalBuf(ptr) if (ptr != local_buf) Xfree(ptr) - -static int -stdc_cstowcs( - XlcConv conv, - XPointer *from, - int *from_left, - XPointer *to, - int *to_left, - XPointer *args, - int num_args) -{ - XLCd lcd = ((State) conv->state)->lcd; - DefineLocalBuf; - XPointer buf, save_buf; - int length, left, ret; - - left = length = *to_left * XLC_PUBLIC(lcd, mb_cur_max); - buf = save_buf = (XPointer) AllocLocalBuf(length); - if (buf == NULL) - return -1; - - ret = cstombs(conv, from, from_left, &buf, &left, args, num_args); - if (ret < 0) - goto err; - - buf = save_buf; - length -= left; - if (stdc_mbstowcs(conv, &buf, &length, to, to_left, args, num_args) < 0) - ret = -1; - -err: - FreeLocalBuf(save_buf); - - return ret; -} - -static XlcConvMethodsRec stdc_mbstowcs_methods = { - close_converter, - stdc_mbstowcs, - NULL -}; - -static XlcConv -open_stdc_mbstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_mbstowcs_methods); -} - -static XlcConvMethodsRec stdc_wcstombs_methods = { - close_converter, - stdc_wcstombs, - NULL -}; - -static XlcConv -open_stdc_wcstombs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_wcstombs_methods); -} - -static XlcConvMethodsRec stdc_wcstocs_methods = { - close_converter, - stdc_wcstocs, - NULL -}; - -static XlcConv -open_stdc_wcstocs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_wcstocs_methods); -} - -static XlcConvMethodsRec stdc_cstowcs_methods = { - close_converter, - stdc_cstowcs, - NULL -}; - -static XlcConv -open_stdc_cstowcs( - XLCd from_lcd, - const char *from_type, - XLCd to_lcd, - const char *to_type) -{ - return create_conv(from_lcd, &stdc_cstowcs_methods); -} -#endif /* STDCVT */ - -XLCd -_XlcJisLoader( - const char *name) -{ - XLCd lcd; -#ifdef STDCVT - XLCdGenericPart *gen; -#endif - - lcd = _XlcCreateLC(name, _XlcGenericMethods); - if (lcd == NULL) - return lcd; - - if (!XLC_PUBLIC_PART(lcd)->codeset || - (_XlcCompareISOLatin1(XLC_PUBLIC_PART(lcd)->codeset, "JIS7"))) { - _XlcDestroyLC(lcd); - return (XLCd) NULL; - } - - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs); - _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs); - _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs); - -#ifdef STDCVT - gen = XLC_GENERIC_PART(lcd); - - if (gen->use_stdc_env == True) { - _XlcSetConverter(lcd,XlcNMultiByte,lcd,XlcNWideChar,open_stdc_mbstowcs); - _XlcSetConverter(lcd,XlcNWideChar,lcd,XlcNMultiByte,open_stdc_wcstombs); - } - if (gen->force_convert_to_mb == True) { - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet,open_stdc_wcstocs); - _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar,open_stdc_cstowcs); - } else { -#endif - _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs); - _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs); -#ifdef STDCVT - } -#endif - - _XlcAddUtf8Converters(lcd); - - return lcd; -} - -#else -typedef int dummy; -#endif /* X_LOCALE */ +/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + +/* + * A Japanese JIS locale. + * Supports: all locales with codeset JIS7. + * How: Provides converters for JIS. + * Platforms: Only those defining X_LOCALE (only Lynx, Linux-libc5, OS/2). + */ + +#ifdef X_LOCALE + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "Xlibint.h" +#include "XlcGeneric.h" +#include + +#if !defined(X_LOCALE) +#define STDCVT +#endif + +typedef struct _StateRec { + XLCd lcd; + XlcCharSet charset; + XlcCharSet GL_charset; + XlcCharSet GR_charset; +} StateRec, *State; + +static void +init_state( + XlcConv conv) +{ + State state = (State) conv->state; + XLCdGenericPart *gen = XLC_GENERIC_PART(state->lcd); + CodeSet codeset; + + codeset = gen->initial_state_GL; + if (codeset && codeset->charset_list) + state->GL_charset = *codeset->charset_list; + codeset = gen->initial_state_GR; + if (codeset && codeset->charset_list) + state->GR_charset = *codeset->charset_list; + + if (state->GL_charset == NULL) + if ((codeset = *gen->codeset_list) != NULL) + state->GL_charset = *codeset->charset_list; +} + +static int +compare( + const char *src, + const char *encoding, + int length) +{ + const char *start = src; + + while (length-- > 0) { + if (*src++ != *encoding++) + return 0; + if (*encoding == '\0') + return src - start; + } + + return 0; +} + +static int +mbtocs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + const char *src; + char *dst; + unsigned char *mb_parse_table; + ParseInfo *parse_list, parse_info; + XlcCharSet charset; + int length, number, encoding_len = 0; + int i; + + src = *((const char **) from); + dst = *((char **) to); + + mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); + if (mb_parse_table != NULL) { + number = mb_parse_table[(unsigned char) *src]; + if (number > 0) { + parse_list = XLC_GENERIC(lcd, mb_parse_list) + number - 1; + for ( ; (parse_info = *parse_list) != NULL; parse_list++) { + encoding_len = compare(src, parse_info->encoding, *from_left); + if (encoding_len > 0) { + switch (parse_info->type) { + case E_SS: + src += encoding_len; + charset = *parse_info->codeset->charset_list; + goto found; + case E_LSL: + case E_LSR: + src += encoding_len; + charset = *parse_info->codeset->charset_list; + if (parse_info->type == E_LSL) + state->GL_charset = charset; + else + state->GR_charset = charset; + length = 0; + goto end; + case E_GL: + charset = state->GL_charset; + goto found; + case E_GR: + charset = state->GR_charset; + goto found; + default: + break; + } + } + } + } + } + + if ((*src & 0x80) && state->GR_charset) + charset = state->GR_charset; + else + charset = state->GL_charset; + +found: + if (charset == NULL || + (num_args == 2 && (XlcCharSet) args[1] != charset)) + return -1; + + length = charset->char_size; + if (length > *from_left - encoding_len) + return -1; + + if (dst) { + if (length > *to_left) + return -1; + if (charset->side == XlcGL) { + for (i = 0; i < length; i++) + *dst++ = *src++ & 0x7f; + } else if (charset->side == XlcGR) { + for (i = 0; i < length; i++) + *dst++ = *src++ | 0x80; + } else { + for (i = 0; i < length; i++) + *dst++ = *src++; + } + *to = (XPointer) dst; + *to_left -= length; + } +end: + *from = (XPointer) src; + *from_left -= encoding_len + length; + state->charset = charset; + if (num_args == 1) + *((XlcCharSet *) args[0]) = charset; + + return 0; +} + +static int +mbstocs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + XlcCharSet charset = NULL; + XPointer tmp_args[2], save_from = *from; + int ret, unconv_num = 0, tmp_num = 1; + + tmp_args[0] = (XPointer) &charset; + + while (*from_left > 0 && *to_left > 0) { + ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, tmp_num); + if (ret < 0) + break; + unconv_num += ret; + if (tmp_num == 1 && charset) { + tmp_args[1] = (XPointer) charset; + tmp_num = 2; + } + } + + if (save_from == *from) + return -1; + + if (num_args > 0) + *((XlcCharSet *) args[0]) = charset; + + return unconv_num; +} + +static CodeSet +wc_parse_codeset( + XLCd lcd, + const wchar_t *wcstr) +{ + CodeSet *codeset; + unsigned long wc_encoding; + int num; + + wc_encoding = *wcstr & XLC_GENERIC(lcd, wc_encode_mask); + num = XLC_GENERIC(lcd, codeset_num); + codeset = XLC_GENERIC(lcd, codeset_list); + while (num-- > 0) { + if (wc_encoding == (*codeset)->wc_encoding) + return *codeset; + codeset++; + } + + return NULL; +} + +static int +wcstocs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + const wchar_t *wcptr; + char *bufptr; + wchar_t wch; + char *tmpptr; + int length; + CodeSet codeset; + unsigned long wc_encoding; + int wcstr_len, buf_len; + + if (from == NULL || *from == NULL) + return 0; + + wcptr = *((const wchar_t **) from); + bufptr = *((char **) to); + wcstr_len = *from_left; + buf_len = *to_left; + + codeset = wc_parse_codeset(lcd, wcptr); + if (codeset == NULL) + return -1; + wc_encoding = codeset->wc_encoding; + + if (wcstr_len < buf_len / codeset->length) + buf_len = wcstr_len * codeset->length; + + for ( ; wcstr_len > 0 && buf_len > 0; wcptr++, wcstr_len--) { + wch = *wcptr; + if ((wch & XLC_GENERIC(lcd, wc_encode_mask)) != wc_encoding) + break; + length = codeset->length; + buf_len -= length; + bufptr += length; + + tmpptr = bufptr - 1; + if ((*codeset->charset_list)->side == XlcGL) { + while (length--) { + *tmpptr-- = (unsigned char) (wch & 0x7f); + wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits); + } + } else if ((*codeset->charset_list)->side == XlcGR) { + while (length--) { + *tmpptr-- = (unsigned char) (wch | 0x80); + wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits); + } + } else { + while (length--) { + *tmpptr-- = (unsigned char) wch; + wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits); + } + } + } + + if (num_args > 0) + *((XlcCharSet *) args[0]) = *codeset->charset_list; + + *from_left -= wcptr - *((wchar_t **) from); + *from = (XPointer) wcptr; + + *to_left -= bufptr - *((char **) to); + *to = bufptr; + + return 0; +} + +static CodeSet +GetCodeSetFromCharSet( + XLCd lcd, + XlcCharSet charset) +{ + CodeSet *codeset = XLC_GENERIC(lcd, codeset_list); + XlcCharSet *charset_list; + int codeset_num, num_charsets; + + codeset_num = XLC_GENERIC(lcd, codeset_num); + + for ( ; codeset_num-- > 0; codeset++) { + num_charsets = (*codeset)->num_charsets; + charset_list = (*codeset)->charset_list; + + for ( ; num_charsets-- > 0; charset_list++) + if (*charset_list == charset) + return *codeset; + } + + return (CodeSet) NULL; +} + +static int +cstombs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + const char *csptr; + char *bufptr; + int csstr_len; + int buf_len; + int num, encoding_len = 0; + CodeSet codeset; + XlcCharSet charset; + EncodingType type; + int cvt_length; + + csptr = *((const char **) from); + bufptr = *((char **) to); + csstr_len = *from_left; + buf_len = *to_left; + + if (num_args < 1) + return -1; + + charset = (XlcCharSet) args[0]; + + codeset = GetCodeSetFromCharSet(state->lcd, charset); + if (codeset == NULL) + return -1; + + cvt_length = 0; + if (codeset->parse_info) { + switch (type = codeset->parse_info->type) { + case E_SS: + encoding_len = strlen(codeset->parse_info->encoding); + break; + case E_LSL: + case E_LSR: + if (type == E_LSL) { + if (charset == state->GL_charset) + break; + } else { + if (charset == state->GR_charset) + break; + } + encoding_len = strlen(codeset->parse_info->encoding); + if (encoding_len > buf_len) + return -1; + cvt_length += encoding_len; + if (bufptr) { + strcpy(bufptr, codeset->parse_info->encoding); + bufptr += encoding_len; + } + buf_len -= encoding_len; + encoding_len = 0; + if (type == E_LSL) + state->GL_charset = charset; + else + state->GR_charset = charset; + break; + default: + break; + } + } + + csstr_len /= codeset->length; + buf_len /= codeset->length + encoding_len; + if (csstr_len < buf_len) + buf_len = csstr_len; + + cvt_length += buf_len * (encoding_len + codeset->length); + if (bufptr) { + while (buf_len--) { + if (encoding_len) { + strcpy(bufptr, codeset->parse_info->encoding); + bufptr += encoding_len; + } + num = codeset->length; + if (codeset->side == XlcGL) { + while (num--) + *bufptr++ = *csptr++ & 0x7f; + } else if (codeset->side == XlcGR) { + while (num--) + *bufptr++ = *csptr++ | 0x80; + } else { + while (num--) + *bufptr++ = *csptr++; + } + } + } + + *from_left -= csptr - *((char **) from); + *from = (XPointer) csptr; + + if (bufptr) + *to = (XPointer) bufptr; + *to_left -= cvt_length; + + return 0; +} + +static int +cstowcs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + const char *csptr; + wchar_t *bufptr; + int csstr_len; + int buf_len; + wchar_t wch; + unsigned long code_mask, wc_encoding; + int num, length, wc_shift_bits; + CodeSet codeset; + + csptr = *((const char **) from); + bufptr = *((wchar_t **) to); + csstr_len = *from_left; + buf_len = *to_left; + + if (num_args < 1) + return -1; + + codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0]); + if (codeset == NULL) + return -1; + + length = codeset->length; + csstr_len /= length; + if (csstr_len < buf_len) + buf_len = csstr_len; + + code_mask = ~XLC_GENERIC(lcd, wc_encode_mask); + wc_encoding = codeset->wc_encoding; + wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits); + + *to_left -= buf_len; + + if (bufptr) { + while (buf_len--) { + wch = (wchar_t) (*csptr++ & 0x7f); + num = length - 1; + while (num--) + wch = (wch << wc_shift_bits) | (*csptr++ & 0x7f); + + *bufptr++ = (wch & code_mask) | wc_encoding; + } + } + + *from_left -= csptr - *((char **) from); + *from = (XPointer) csptr; + + if (bufptr) + *to = (XPointer) bufptr; + + return 0; +} + + +static void +close_converter( + XlcConv conv) +{ + if (conv->state) { + Xfree((char *) conv->state); + } + + Xfree((char *) conv); +} + +static XlcConv +create_conv( + XLCd lcd, + XlcConvMethods methods) +{ + XlcConv conv; + State state; + + conv = (XlcConv) Xmalloc(sizeof(XlcConvRec)); + if (conv == NULL) + return (XlcConv) NULL; + + conv->methods = (XlcConvMethods) Xmalloc(sizeof(XlcConvMethodsRec)); + if (conv->methods == NULL) + goto err; + *conv->methods = *methods; + if (XLC_PUBLIC(lcd, is_state_depend)) + conv->methods->reset = init_state; + + conv->state = Xcalloc(1, sizeof(StateRec)); + if (conv->state == NULL) + goto err; + + state = (State) conv->state; + state->lcd = lcd; + init_state(conv); + + return conv; + +err: + close_converter(conv); + + return (XlcConv) NULL; +} + +static XlcConvMethodsRec mbstocs_methods = { + close_converter, + mbstocs, + NULL +}; + +static XlcConv +open_mbstocs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &mbstocs_methods); +} + +static XlcConvMethodsRec wcstocs_methods = { + close_converter, + wcstocs, + NULL +}; + +static XlcConv +open_wcstocs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &wcstocs_methods); +} + +static XlcConvMethodsRec mbtocs_methods = { + close_converter, + mbtocs, + NULL +}; + +static XlcConv +open_mbtocs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &mbtocs_methods); +} + +static XlcConvMethodsRec cstombs_methods = { + close_converter, + cstombs, + NULL +}; + +static XlcConv +open_cstombs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &cstombs_methods); +} + +static XlcConvMethodsRec cstowcs_methods = { + close_converter, + cstowcs, + NULL +}; + +static XlcConv +open_cstowcs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &cstowcs_methods); +} + +#ifdef STDCVT +static int +stdc_mbstowcs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + const char *src = *((const char **) from); + wchar_t *dst = *((wchar_t **) to); + int src_left = *from_left; + int dst_left = *to_left; + int length; + + while (src_left > 0 && dst_left > 0) { + length = mbtowc(dst, src, src_left); + if (length < 0) + break; + + src += length; + src_left -= length; + if (dst) + dst++; + dst_left--; + + if (length == 0) { + src++; + src_left--; + break; + } + } + + if (*from_left == src_left) + return -1; + + *from = (XPointer) src; + if (dst) + *to = (XPointer) dst; + *from_left = src_left; + *to_left = dst_left; + + return 0; +} + +static int +stdc_wcstombs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + const wchar_t *src = *((const wchar_t **) from); + char *dst = *((char **) to); + int src_left = *from_left; + int dst_left = *to_left; + int length; + + while (src_left > 0 && dst_left > 0) { + length = wctomb(dst, *src); /* XXX */ + if (length < 0 || dst_left < length) + break; + + src++; + src_left--; + dst += length; + dst_left -= length; + + if (length == 0) { + dst++; + dst_left--; + break; + } + } + + if (*from_left == src_left) + return -1; + + *from = (XPointer) src; + *to = (XPointer) dst; + *from_left = src_left; + *to_left = dst_left; + + return 0; +} + +static int +stdc_wcstocs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + const wchar_t *src = *((const wchar_t **) from); + wchar_t wch; + XlcCharSet charset = NULL; + XPointer tmp_args[2], tmp_from, save_from = *from; + char tmp[32]; + int length, ret, src_left = *from_left; + int unconv_num = 0, tmp_num = 1; + + tmp_args[0] = (XPointer) &charset; + + while (src_left > 0 && *to_left > 0) { + if (wch = *src) { + length = wctomb(tmp, wch); + } else { + length = 1; + *tmp = '\0'; + } + + if (length < 0) + break; + + tmp_from = (XPointer) tmp; + ret = mbtocs(conv, &tmp_from, &length, to, to_left, tmp_args, tmp_num); + if (ret < 0) + break; + unconv_num += ret; + if (tmp_num == 1 && charset) { + tmp_args[1] = (XPointer) charset; + tmp_num = 2; + } + + src++; + src_left--; + } + + if (save_from == (XPointer) src) + return -1; + + *from = (XPointer) src; + *from_left = src_left; + + if (num_args > 0) + *((XlcCharSet *) args[0]) = charset; + + return unconv_num; +} + +#define DefineLocalBuf char local_buf[BUFSIZ] +#define AllocLocalBuf(length) (length > BUFSIZ ? (char*) Xmalloc(length) : local_buf) +#define FreeLocalBuf(ptr) if (ptr != local_buf) Xfree(ptr) + +static int +stdc_cstowcs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + XLCd lcd = ((State) conv->state)->lcd; + DefineLocalBuf; + XPointer buf, save_buf; + int length, left, ret; + + left = length = *to_left * XLC_PUBLIC(lcd, mb_cur_max); + buf = save_buf = (XPointer) AllocLocalBuf(length); + if (buf == NULL) + return -1; + + ret = cstombs(conv, from, from_left, &buf, &left, args, num_args); + if (ret < 0) + goto err; + + buf = save_buf; + length -= left; + if (stdc_mbstowcs(conv, &buf, &length, to, to_left, args, num_args) < 0) + ret = -1; + +err: + FreeLocalBuf(save_buf); + + return ret; +} + +static XlcConvMethodsRec stdc_mbstowcs_methods = { + close_converter, + stdc_mbstowcs, + NULL +}; + +static XlcConv +open_stdc_mbstowcs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_mbstowcs_methods); +} + +static XlcConvMethodsRec stdc_wcstombs_methods = { + close_converter, + stdc_wcstombs, + NULL +}; + +static XlcConv +open_stdc_wcstombs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_wcstombs_methods); +} + +static XlcConvMethodsRec stdc_wcstocs_methods = { + close_converter, + stdc_wcstocs, + NULL +}; + +static XlcConv +open_stdc_wcstocs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_wcstocs_methods); +} + +static XlcConvMethodsRec stdc_cstowcs_methods = { + close_converter, + stdc_cstowcs, + NULL +}; + +static XlcConv +open_stdc_cstowcs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_cstowcs_methods); +} +#endif /* STDCVT */ + +XLCd +_XlcJisLoader( + const char *name) +{ + XLCd lcd; +#ifdef STDCVT + XLCdGenericPart *gen; +#endif + + lcd = _XlcCreateLC(name, _XlcGenericMethods); + if (lcd == NULL) + return lcd; + + if (!XLC_PUBLIC_PART(lcd)->codeset || + (_XlcCompareISOLatin1(XLC_PUBLIC_PART(lcd)->codeset, "JIS7"))) { + _XlcDestroyLC(lcd); + return (XLCd) NULL; + } + + _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs); + _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs); + _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs); + +#ifdef STDCVT + gen = XLC_GENERIC_PART(lcd); + + if (gen->use_stdc_env == True) { + _XlcSetConverter(lcd,XlcNMultiByte,lcd,XlcNWideChar,open_stdc_mbstowcs); + _XlcSetConverter(lcd,XlcNWideChar,lcd,XlcNMultiByte,open_stdc_wcstombs); + } + if (gen->force_convert_to_mb == True) { + _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet,open_stdc_wcstocs); + _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar,open_stdc_cstowcs); + } else { +#endif + _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs); + _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs); +#ifdef STDCVT + } +#endif + + _XlcAddUtf8Converters(lcd); + + return lcd; +} + +#else +typedef int dummy; +#endif /* X_LOCALE */ -- cgit v1.2.3