aboutsummaryrefslogtreecommitdiff
path: root/libX11/modules/lc/gen/lcGenConv.c
diff options
context:
space:
mode:
Diffstat (limited to 'libX11/modules/lc/gen/lcGenConv.c')
-rw-r--r--libX11/modules/lc/gen/lcGenConv.c6297
1 files changed, 3148 insertions, 3149 deletions
diff --git a/libX11/modules/lc/gen/lcGenConv.c b/libX11/modules/lc/gen/lcGenConv.c
index baac73a39..c222c1f2a 100644
--- a/libX11/modules/lc/gen/lcGenConv.c
+++ b/libX11/modules/lc/gen/lcGenConv.c
@@ -1,3149 +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 <config.h>
-#endif
-#include "Xlibint.h"
-#include "XlcGeneric.h"
-#include <stdio.h>
-
-#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 = (XPointer) Xmalloc(sizeof(StateRec));
- if (conv->state == NULL)
- goto err;
- bzero((char *) conv->state, sizeof(StateRec));
-
- 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 <config.h>
+#endif
+#include "Xlibint.h"
+#include "XlcGeneric.h"
+#include <stdio.h>
+
+#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;
+}