diff options
Diffstat (limited to 'libX11/modules/lc/xlocale/lcJis.c')
-rw-r--r-- | libX11/modules/lc/xlocale/lcJis.c | 1888 |
1 files changed, 944 insertions, 944 deletions
diff --git a/libX11/modules/lc/xlocale/lcJis.c b/libX11/modules/lc/xlocale/lcJis.c index c2ca2f560..551862d9b 100644 --- a/libX11/modules/lc/xlocale/lcJis.c +++ b/libX11/modules/lc/xlocale/lcJis.c @@ -1,944 +1,944 @@ -/*
- * Copyright 1992, 1993 by TOSHIBA Corp.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of TOSHIBA not be used in advertising
- * or publicity pertaining to distribution of the software without specific,
- * written prior permission. TOSHIBA make no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- *
- * Author: Katsuhisa Yano TOSHIBA Corp.
- * mopi@osa.ilab.toshiba.co.jp
- */
-
-/*
- * A Japanese JIS locale.
- * Supports: all locales with codeset JIS7.
- * How: Provides converters for JIS.
- * Platforms: Only those defining X_LOCALE (only Lynx, Linux-libc5, OS/2).
- */
-
-#ifdef X_LOCALE
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "Xlibint.h"
-#include "XlcGeneric.h"
-#include <stdio.h>
-
-#if !defined(X_LOCALE)
-#define STDCVT
-#endif
-
-typedef struct _StateRec {
- XLCd lcd;
- XlcCharSet charset;
- XlcCharSet GL_charset;
- XlcCharSet GR_charset;
-} StateRec, *State;
-
-static void
-init_state(
- XlcConv conv)
-{
- State state = (State) conv->state;
- XLCdGenericPart *gen = XLC_GENERIC_PART(state->lcd);
- CodeSet codeset;
-
- codeset = gen->initial_state_GL;
- if (codeset && codeset->charset_list)
- state->GL_charset = *codeset->charset_list;
- codeset = gen->initial_state_GR;
- if (codeset && codeset->charset_list)
- state->GR_charset = *codeset->charset_list;
-
- if (state->GL_charset == NULL)
- if ((codeset = *gen->codeset_list) != NULL)
- state->GL_charset = *codeset->charset_list;
-}
-
-static int
-compare(
- const char *src,
- const char *encoding,
- int length)
-{
- const char *start = src;
-
- while (length-- > 0) {
- if (*src++ != *encoding++)
- return 0;
- if (*encoding == '\0')
- return src - start;
- }
-
- return 0;
-}
-
-static int
-mbtocs(
- XlcConv conv,
- XPointer *from,
- int *from_left,
- XPointer *to,
- int *to_left,
- XPointer *args,
- int num_args)
-{
- State state = (State) conv->state;
- XLCd lcd = state->lcd;
- const char *src;
- char *dst;
- unsigned char *mb_parse_table;
- ParseInfo *parse_list, parse_info;
- XlcCharSet charset;
- int length, number, encoding_len = 0;
- int i;
-
- src = *((const char **) from);
- dst = *((char **) to);
-
- mb_parse_table = XLC_GENERIC(lcd, mb_parse_table);
- if (mb_parse_table != NULL) {
- number = mb_parse_table[(unsigned char) *src];
- if (number > 0) {
- parse_list = XLC_GENERIC(lcd, mb_parse_list) + number - 1;
- for ( ; (parse_info = *parse_list) != NULL; parse_list++) {
- encoding_len = compare(src, parse_info->encoding, *from_left);
- if (encoding_len > 0) {
- switch (parse_info->type) {
- case E_SS:
- src += encoding_len;
- charset = *parse_info->codeset->charset_list;
- goto found;
- case E_LSL:
- case E_LSR:
- src += encoding_len;
- charset = *parse_info->codeset->charset_list;
- if (parse_info->type == E_LSL)
- state->GL_charset = charset;
- else
- state->GR_charset = charset;
- length = 0;
- goto end;
- case E_GL:
- charset = state->GL_charset;
- goto found;
- case E_GR:
- charset = state->GR_charset;
- goto found;
- default:
- break;
- }
- }
- }
- }
- }
-
- if ((*src & 0x80) && state->GR_charset)
- charset = state->GR_charset;
- else
- charset = state->GL_charset;
-
-found:
- if (charset == NULL ||
- (num_args == 2 && (XlcCharSet) args[1] != charset))
- return -1;
-
- length = charset->char_size;
- if (length > *from_left - encoding_len)
- return -1;
-
- if (dst) {
- if (length > *to_left)
- return -1;
- if (charset->side == XlcGL) {
- for (i = 0; i < length; i++)
- *dst++ = *src++ & 0x7f;
- } else if (charset->side == XlcGR) {
- for (i = 0; i < length; i++)
- *dst++ = *src++ | 0x80;
- } else {
- for (i = 0; i < length; i++)
- *dst++ = *src++;
- }
- *to = (XPointer) dst;
- *to_left -= length;
- }
-end:
- *from = (XPointer) src;
- *from_left -= encoding_len + length;
- state->charset = charset;
- if (num_args == 1)
- *((XlcCharSet *) args[0]) = charset;
-
- return 0;
-}
-
-static int
-mbstocs(
- XlcConv conv,
- XPointer *from,
- int *from_left,
- XPointer *to,
- int *to_left,
- XPointer *args,
- int num_args)
-{
- XlcCharSet charset = NULL;
- XPointer tmp_args[2], save_from = *from;
- int ret, unconv_num = 0, tmp_num = 1;
-
- tmp_args[0] = (XPointer) &charset;
-
- while (*from_left > 0 && *to_left > 0) {
- ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, tmp_num);
- if (ret < 0)
- break;
- unconv_num += ret;
- if (tmp_num == 1 && charset) {
- tmp_args[1] = (XPointer) charset;
- tmp_num = 2;
- }
- }
-
- if (save_from == *from)
- return -1;
-
- if (num_args > 0)
- *((XlcCharSet *) args[0]) = charset;
-
- return unconv_num;
-}
-
-static CodeSet
-wc_parse_codeset(
- XLCd lcd,
- const wchar_t *wcstr)
-{
- CodeSet *codeset;
- unsigned long wc_encoding;
- int num;
-
- wc_encoding = *wcstr & XLC_GENERIC(lcd, wc_encode_mask);
- num = XLC_GENERIC(lcd, codeset_num);
- codeset = XLC_GENERIC(lcd, codeset_list);
- while (num-- > 0) {
- if (wc_encoding == (*codeset)->wc_encoding)
- return *codeset;
- codeset++;
- }
-
- return NULL;
-}
-
-static int
-wcstocs(
- XlcConv conv,
- XPointer *from,
- int *from_left,
- XPointer *to,
- int *to_left,
- XPointer *args,
- int num_args)
-{
- State state = (State) conv->state;
- XLCd lcd = state->lcd;
- const wchar_t *wcptr;
- char *bufptr;
- wchar_t wch;
- char *tmpptr;
- int length;
- CodeSet codeset;
- unsigned long wc_encoding;
- int wcstr_len, buf_len;
-
- if (from == NULL || *from == NULL)
- return 0;
-
- wcptr = *((const wchar_t **) from);
- bufptr = *((char **) to);
- wcstr_len = *from_left;
- buf_len = *to_left;
-
- codeset = wc_parse_codeset(lcd, wcptr);
- if (codeset == NULL)
- return -1;
- wc_encoding = codeset->wc_encoding;
-
- if (wcstr_len < buf_len / codeset->length)
- buf_len = wcstr_len * codeset->length;
-
- for ( ; wcstr_len > 0 && buf_len > 0; wcptr++, wcstr_len--) {
- wch = *wcptr;
- if ((wch & XLC_GENERIC(lcd, wc_encode_mask)) != wc_encoding)
- break;
- length = codeset->length;
- buf_len -= length;
- bufptr += length;
-
- tmpptr = bufptr - 1;
- if ((*codeset->charset_list)->side == XlcGL) {
- while (length--) {
- *tmpptr-- = (unsigned char) (wch & 0x7f);
- wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
- }
- } else if ((*codeset->charset_list)->side == XlcGR) {
- while (length--) {
- *tmpptr-- = (unsigned char) (wch | 0x80);
- wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
- }
- } else {
- while (length--) {
- *tmpptr-- = (unsigned char) wch;
- wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits);
- }
- }
- }
-
- if (num_args > 0)
- *((XlcCharSet *) args[0]) = *codeset->charset_list;
-
- *from_left -= wcptr - *((wchar_t **) from);
- *from = (XPointer) wcptr;
-
- *to_left -= bufptr - *((char **) to);
- *to = bufptr;
-
- return 0;
-}
-
-static CodeSet
-GetCodeSetFromCharSet(
- XLCd lcd,
- XlcCharSet charset)
-{
- CodeSet *codeset = XLC_GENERIC(lcd, codeset_list);
- XlcCharSet *charset_list;
- int codeset_num, num_charsets;
-
- codeset_num = XLC_GENERIC(lcd, codeset_num);
-
- for ( ; codeset_num-- > 0; codeset++) {
- num_charsets = (*codeset)->num_charsets;
- charset_list = (*codeset)->charset_list;
-
- for ( ; num_charsets-- > 0; charset_list++)
- if (*charset_list == charset)
- return *codeset;
- }
-
- return (CodeSet) NULL;
-}
-
-static int
-cstombs(
- XlcConv conv,
- XPointer *from,
- int *from_left,
- XPointer *to,
- int *to_left,
- XPointer *args,
- int num_args)
-{
- State state = (State) conv->state;
- const char *csptr;
- char *bufptr;
- int csstr_len;
- int buf_len;
- int num, encoding_len = 0;
- CodeSet codeset;
- XlcCharSet charset;
- EncodingType type;
- int cvt_length;
-
- csptr = *((const char **) from);
- bufptr = *((char **) to);
- csstr_len = *from_left;
- buf_len = *to_left;
-
- if (num_args < 1)
- return -1;
-
- charset = (XlcCharSet) args[0];
-
- codeset = GetCodeSetFromCharSet(state->lcd, charset);
- if (codeset == NULL)
- return -1;
-
- cvt_length = 0;
- if (codeset->parse_info) {
- switch (type = codeset->parse_info->type) {
- case E_SS:
- encoding_len = strlen(codeset->parse_info->encoding);
- break;
- case E_LSL:
- case E_LSR:
- if (type == E_LSL) {
- if (charset == state->GL_charset)
- break;
- } else {
- if (charset == state->GR_charset)
- break;
- }
- encoding_len = strlen(codeset->parse_info->encoding);
- if (encoding_len > buf_len)
- return -1;
- cvt_length += encoding_len;
- if (bufptr) {
- strcpy(bufptr, codeset->parse_info->encoding);
- bufptr += encoding_len;
- }
- buf_len -= encoding_len;
- encoding_len = 0;
- if (type == E_LSL)
- state->GL_charset = charset;
- else
- state->GR_charset = charset;
- break;
- default:
- break;
- }
- }
-
- csstr_len /= codeset->length;
- buf_len /= codeset->length + encoding_len;
- if (csstr_len < buf_len)
- buf_len = csstr_len;
-
- cvt_length += buf_len * (encoding_len + codeset->length);
- if (bufptr) {
- while (buf_len--) {
- if (encoding_len) {
- strcpy(bufptr, codeset->parse_info->encoding);
- bufptr += encoding_len;
- }
- num = codeset->length;
- if (codeset->side == XlcGL) {
- while (num--)
- *bufptr++ = *csptr++ & 0x7f;
- } else if (codeset->side == XlcGR) {
- while (num--)
- *bufptr++ = *csptr++ | 0x80;
- } else {
- while (num--)
- *bufptr++ = *csptr++;
- }
- }
- }
-
- *from_left -= csptr - *((char **) from);
- *from = (XPointer) csptr;
-
- if (bufptr)
- *to = (XPointer) bufptr;
- *to_left -= cvt_length;
-
- return 0;
-}
-
-static int
-cstowcs(
- XlcConv conv,
- XPointer *from,
- int *from_left,
- XPointer *to,
- int *to_left,
- XPointer *args,
- int num_args)
-{
- State state = (State) conv->state;
- XLCd lcd = state->lcd;
- const char *csptr;
- wchar_t *bufptr;
- int csstr_len;
- int buf_len;
- wchar_t wch;
- unsigned long code_mask, wc_encoding;
- int num, length, wc_shift_bits;
- CodeSet codeset;
-
- csptr = *((const char **) from);
- bufptr = *((wchar_t **) to);
- csstr_len = *from_left;
- buf_len = *to_left;
-
- if (num_args < 1)
- return -1;
-
- codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0]);
- if (codeset == NULL)
- return -1;
-
- length = codeset->length;
- csstr_len /= length;
- if (csstr_len < buf_len)
- buf_len = csstr_len;
-
- code_mask = ~XLC_GENERIC(lcd, wc_encode_mask);
- wc_encoding = codeset->wc_encoding;
- wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits);
-
- *to_left -= buf_len;
-
- if (bufptr) {
- while (buf_len--) {
- wch = (wchar_t) (*csptr++ & 0x7f);
- num = length - 1;
- while (num--)
- wch = (wch << wc_shift_bits) | (*csptr++ & 0x7f);
-
- *bufptr++ = (wch & code_mask) | wc_encoding;
- }
- }
-
- *from_left -= csptr - *((char **) from);
- *from = (XPointer) csptr;
-
- if (bufptr)
- *to = (XPointer) bufptr;
-
- return 0;
-}
-
-
-static void
-close_converter(
- XlcConv conv)
-{
- if (conv->state) {
- Xfree((char *) conv->state);
- }
-
- Xfree((char *) conv);
-}
-
-static XlcConv
-create_conv(
- XLCd lcd,
- XlcConvMethods methods)
-{
- XlcConv conv;
- State state;
-
- conv = (XlcConv) Xmalloc(sizeof(XlcConvRec));
- if (conv == NULL)
- return (XlcConv) NULL;
-
- conv->methods = (XlcConvMethods) Xmalloc(sizeof(XlcConvMethodsRec));
- if (conv->methods == NULL)
- goto err;
- *conv->methods = *methods;
- if (XLC_PUBLIC(lcd, is_state_depend))
- conv->methods->reset = init_state;
-
- conv->state = Xcalloc(1, sizeof(StateRec));
- if (conv->state == NULL)
- goto err;
-
- state = (State) conv->state;
- state->lcd = lcd;
- init_state(conv);
-
- return conv;
-
-err:
- close_converter(conv);
-
- return (XlcConv) NULL;
-}
-
-static XlcConvMethodsRec mbstocs_methods = {
- close_converter,
- mbstocs,
- NULL
-};
-
-static XlcConv
-open_mbstocs(
- XLCd from_lcd,
- const char *from_type,
- XLCd to_lcd,
- const char *to_type)
-{
- return create_conv(from_lcd, &mbstocs_methods);
-}
-
-static XlcConvMethodsRec wcstocs_methods = {
- close_converter,
- wcstocs,
- NULL
-};
-
-static XlcConv
-open_wcstocs(
- XLCd from_lcd,
- const char *from_type,
- XLCd to_lcd,
- const char *to_type)
-{
- return create_conv(from_lcd, &wcstocs_methods);
-}
-
-static XlcConvMethodsRec mbtocs_methods = {
- close_converter,
- mbtocs,
- NULL
-};
-
-static XlcConv
-open_mbtocs(
- XLCd from_lcd,
- const char *from_type,
- XLCd to_lcd,
- const char *to_type)
-{
- return create_conv(from_lcd, &mbtocs_methods);
-}
-
-static XlcConvMethodsRec cstombs_methods = {
- close_converter,
- cstombs,
- NULL
-};
-
-static XlcConv
-open_cstombs(
- XLCd from_lcd,
- const char *from_type,
- XLCd to_lcd,
- const char *to_type)
-{
- return create_conv(from_lcd, &cstombs_methods);
-}
-
-static XlcConvMethodsRec cstowcs_methods = {
- close_converter,
- cstowcs,
- NULL
-};
-
-static XlcConv
-open_cstowcs(
- XLCd from_lcd,
- const char *from_type,
- XLCd to_lcd,
- const char *to_type)
-{
- return create_conv(from_lcd, &cstowcs_methods);
-}
-
-#ifdef STDCVT
-static int
-stdc_mbstowcs(
- XlcConv conv,
- XPointer *from,
- int *from_left,
- XPointer *to,
- int *to_left,
- XPointer *args,
- int num_args)
-{
- const char *src = *((const char **) from);
- wchar_t *dst = *((wchar_t **) to);
- int src_left = *from_left;
- int dst_left = *to_left;
- int length;
-
- while (src_left > 0 && dst_left > 0) {
- length = mbtowc(dst, src, src_left);
- if (length < 0)
- break;
-
- src += length;
- src_left -= length;
- if (dst)
- dst++;
- dst_left--;
-
- if (length == 0) {
- src++;
- src_left--;
- break;
- }
- }
-
- if (*from_left == src_left)
- return -1;
-
- *from = (XPointer) src;
- if (dst)
- *to = (XPointer) dst;
- *from_left = src_left;
- *to_left = dst_left;
-
- return 0;
-}
-
-static int
-stdc_wcstombs(
- XlcConv conv,
- XPointer *from,
- int *from_left,
- XPointer *to,
- int *to_left,
- XPointer *args,
- int num_args)
-{
- const wchar_t *src = *((const wchar_t **) from);
- char *dst = *((char **) to);
- int src_left = *from_left;
- int dst_left = *to_left;
- int length;
-
- while (src_left > 0 && dst_left > 0) {
- length = wctomb(dst, *src); /* XXX */
- if (length < 0 || dst_left < length)
- break;
-
- src++;
- src_left--;
- dst += length;
- dst_left -= length;
-
- if (length == 0) {
- dst++;
- dst_left--;
- break;
- }
- }
-
- if (*from_left == src_left)
- return -1;
-
- *from = (XPointer) src;
- *to = (XPointer) dst;
- *from_left = src_left;
- *to_left = dst_left;
-
- return 0;
-}
-
-static int
-stdc_wcstocs(
- XlcConv conv,
- XPointer *from,
- int *from_left,
- XPointer *to,
- int *to_left,
- XPointer *args,
- int num_args)
-{
- const wchar_t *src = *((const wchar_t **) from);
- wchar_t wch;
- XlcCharSet charset = NULL;
- XPointer tmp_args[2], tmp_from, save_from = *from;
- char tmp[32];
- int length, ret, src_left = *from_left;
- int unconv_num = 0, tmp_num = 1;
-
- tmp_args[0] = (XPointer) &charset;
-
- while (src_left > 0 && *to_left > 0) {
- if (wch = *src) {
- length = wctomb(tmp, wch);
- } else {
- length = 1;
- *tmp = '\0';
- }
-
- if (length < 0)
- break;
-
- tmp_from = (XPointer) tmp;
- ret = mbtocs(conv, &tmp_from, &length, to, to_left, tmp_args, tmp_num);
- if (ret < 0)
- break;
- unconv_num += ret;
- if (tmp_num == 1 && charset) {
- tmp_args[1] = (XPointer) charset;
- tmp_num = 2;
- }
-
- src++;
- src_left--;
- }
-
- if (save_from == (XPointer) src)
- return -1;
-
- *from = (XPointer) src;
- *from_left = src_left;
-
- if (num_args > 0)
- *((XlcCharSet *) args[0]) = charset;
-
- return unconv_num;
-}
-
-#define DefineLocalBuf char local_buf[BUFSIZ]
-#define AllocLocalBuf(length) (length > BUFSIZ ? (char*) Xmalloc(length) : local_buf)
-#define FreeLocalBuf(ptr) if (ptr != local_buf) Xfree(ptr)
-
-static int
-stdc_cstowcs(
- XlcConv conv,
- XPointer *from,
- int *from_left,
- XPointer *to,
- int *to_left,
- XPointer *args,
- int num_args)
-{
- XLCd lcd = ((State) conv->state)->lcd;
- DefineLocalBuf;
- XPointer buf, save_buf;
- int length, left, ret;
-
- left = length = *to_left * XLC_PUBLIC(lcd, mb_cur_max);
- buf = save_buf = (XPointer) AllocLocalBuf(length);
- if (buf == NULL)
- return -1;
-
- ret = cstombs(conv, from, from_left, &buf, &left, args, num_args);
- if (ret < 0)
- goto err;
-
- buf = save_buf;
- length -= left;
- if (stdc_mbstowcs(conv, &buf, &length, to, to_left, args, num_args) < 0)
- ret = -1;
-
-err:
- FreeLocalBuf(save_buf);
-
- return ret;
-}
-
-static XlcConvMethodsRec stdc_mbstowcs_methods = {
- close_converter,
- stdc_mbstowcs,
- NULL
-};
-
-static XlcConv
-open_stdc_mbstowcs(
- XLCd from_lcd,
- const char *from_type,
- XLCd to_lcd,
- const char *to_type)
-{
- return create_conv(from_lcd, &stdc_mbstowcs_methods);
-}
-
-static XlcConvMethodsRec stdc_wcstombs_methods = {
- close_converter,
- stdc_wcstombs,
- NULL
-};
-
-static XlcConv
-open_stdc_wcstombs(
- XLCd from_lcd,
- const char *from_type,
- XLCd to_lcd,
- const char *to_type)
-{
- return create_conv(from_lcd, &stdc_wcstombs_methods);
-}
-
-static XlcConvMethodsRec stdc_wcstocs_methods = {
- close_converter,
- stdc_wcstocs,
- NULL
-};
-
-static XlcConv
-open_stdc_wcstocs(
- XLCd from_lcd,
- const char *from_type,
- XLCd to_lcd,
- const char *to_type)
-{
- return create_conv(from_lcd, &stdc_wcstocs_methods);
-}
-
-static XlcConvMethodsRec stdc_cstowcs_methods = {
- close_converter,
- stdc_cstowcs,
- NULL
-};
-
-static XlcConv
-open_stdc_cstowcs(
- XLCd from_lcd,
- const char *from_type,
- XLCd to_lcd,
- const char *to_type)
-{
- return create_conv(from_lcd, &stdc_cstowcs_methods);
-}
-#endif /* STDCVT */
-
-XLCd
-_XlcJisLoader(
- const char *name)
-{
- XLCd lcd;
-#ifdef STDCVT
- XLCdGenericPart *gen;
-#endif
-
- lcd = _XlcCreateLC(name, _XlcGenericMethods);
- if (lcd == NULL)
- return lcd;
-
- if (!XLC_PUBLIC_PART(lcd)->codeset ||
- (_XlcCompareISOLatin1(XLC_PUBLIC_PART(lcd)->codeset, "JIS7"))) {
- _XlcDestroyLC(lcd);
- return (XLCd) NULL;
- }
-
- _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs);
- _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs);
- _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs);
-
-#ifdef STDCVT
- gen = XLC_GENERIC_PART(lcd);
-
- if (gen->use_stdc_env == True) {
- _XlcSetConverter(lcd,XlcNMultiByte,lcd,XlcNWideChar,open_stdc_mbstowcs);
- _XlcSetConverter(lcd,XlcNWideChar,lcd,XlcNMultiByte,open_stdc_wcstombs);
- }
- if (gen->force_convert_to_mb == True) {
- _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet,open_stdc_wcstocs);
- _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar,open_stdc_cstowcs);
- } else {
-#endif
- _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs);
- _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs);
-#ifdef STDCVT
- }
-#endif
-
- _XlcAddUtf8Converters(lcd);
-
- return lcd;
-}
-
-#else
-typedef int dummy;
-#endif /* X_LOCALE */
+/* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + +/* + * A Japanese JIS locale. + * Supports: all locales with codeset JIS7. + * How: Provides converters for JIS. + * Platforms: Only those defining X_LOCALE (only Lynx, Linux-libc5, OS/2). + */ + +#ifdef X_LOCALE + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "Xlibint.h" +#include "XlcGeneric.h" +#include <stdio.h> + +#if !defined(X_LOCALE) +#define STDCVT +#endif + +typedef struct _StateRec { + XLCd lcd; + XlcCharSet charset; + XlcCharSet GL_charset; + XlcCharSet GR_charset; +} StateRec, *State; + +static void +init_state( + XlcConv conv) +{ + State state = (State) conv->state; + XLCdGenericPart *gen = XLC_GENERIC_PART(state->lcd); + CodeSet codeset; + + codeset = gen->initial_state_GL; + if (codeset && codeset->charset_list) + state->GL_charset = *codeset->charset_list; + codeset = gen->initial_state_GR; + if (codeset && codeset->charset_list) + state->GR_charset = *codeset->charset_list; + + if (state->GL_charset == NULL) + if ((codeset = *gen->codeset_list) != NULL) + state->GL_charset = *codeset->charset_list; +} + +static int +compare( + const char *src, + const char *encoding, + int length) +{ + const char *start = src; + + while (length-- > 0) { + if (*src++ != *encoding++) + return 0; + if (*encoding == '\0') + return src - start; + } + + return 0; +} + +static int +mbtocs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + const char *src; + char *dst; + unsigned char *mb_parse_table; + ParseInfo *parse_list, parse_info; + XlcCharSet charset; + int length, number, encoding_len = 0; + int i; + + src = *((const char **) from); + dst = *((char **) to); + + mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); + if (mb_parse_table != NULL) { + number = mb_parse_table[(unsigned char) *src]; + if (number > 0) { + parse_list = XLC_GENERIC(lcd, mb_parse_list) + number - 1; + for ( ; (parse_info = *parse_list) != NULL; parse_list++) { + encoding_len = compare(src, parse_info->encoding, *from_left); + if (encoding_len > 0) { + switch (parse_info->type) { + case E_SS: + src += encoding_len; + charset = *parse_info->codeset->charset_list; + goto found; + case E_LSL: + case E_LSR: + src += encoding_len; + charset = *parse_info->codeset->charset_list; + if (parse_info->type == E_LSL) + state->GL_charset = charset; + else + state->GR_charset = charset; + length = 0; + goto end; + case E_GL: + charset = state->GL_charset; + goto found; + case E_GR: + charset = state->GR_charset; + goto found; + default: + break; + } + } + } + } + } + + if ((*src & 0x80) && state->GR_charset) + charset = state->GR_charset; + else + charset = state->GL_charset; + +found: + if (charset == NULL || + (num_args == 2 && (XlcCharSet) args[1] != charset)) + return -1; + + length = charset->char_size; + if (length > *from_left - encoding_len) + return -1; + + if (dst) { + if (length > *to_left) + return -1; + if (charset->side == XlcGL) { + for (i = 0; i < length; i++) + *dst++ = *src++ & 0x7f; + } else if (charset->side == XlcGR) { + for (i = 0; i < length; i++) + *dst++ = *src++ | 0x80; + } else { + for (i = 0; i < length; i++) + *dst++ = *src++; + } + *to = (XPointer) dst; + *to_left -= length; + } +end: + *from = (XPointer) src; + *from_left -= encoding_len + length; + state->charset = charset; + if (num_args == 1) + *((XlcCharSet *) args[0]) = charset; + + return 0; +} + +static int +mbstocs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + XlcCharSet charset = NULL; + XPointer tmp_args[2], save_from = *from; + int ret, unconv_num = 0, tmp_num = 1; + + tmp_args[0] = (XPointer) &charset; + + while (*from_left > 0 && *to_left > 0) { + ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, tmp_num); + if (ret < 0) + break; + unconv_num += ret; + if (tmp_num == 1 && charset) { + tmp_args[1] = (XPointer) charset; + tmp_num = 2; + } + } + + if (save_from == *from) + return -1; + + if (num_args > 0) + *((XlcCharSet *) args[0]) = charset; + + return unconv_num; +} + +static CodeSet +wc_parse_codeset( + XLCd lcd, + const wchar_t *wcstr) +{ + CodeSet *codeset; + unsigned long wc_encoding; + int num; + + wc_encoding = *wcstr & XLC_GENERIC(lcd, wc_encode_mask); + num = XLC_GENERIC(lcd, codeset_num); + codeset = XLC_GENERIC(lcd, codeset_list); + while (num-- > 0) { + if (wc_encoding == (*codeset)->wc_encoding) + return *codeset; + codeset++; + } + + return NULL; +} + +static int +wcstocs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + const wchar_t *wcptr; + char *bufptr; + wchar_t wch; + char *tmpptr; + int length; + CodeSet codeset; + unsigned long wc_encoding; + int wcstr_len, buf_len; + + if (from == NULL || *from == NULL) + return 0; + + wcptr = *((const wchar_t **) from); + bufptr = *((char **) to); + wcstr_len = *from_left; + buf_len = *to_left; + + codeset = wc_parse_codeset(lcd, wcptr); + if (codeset == NULL) + return -1; + wc_encoding = codeset->wc_encoding; + + if (wcstr_len < buf_len / codeset->length) + buf_len = wcstr_len * codeset->length; + + for ( ; wcstr_len > 0 && buf_len > 0; wcptr++, wcstr_len--) { + wch = *wcptr; + if ((wch & XLC_GENERIC(lcd, wc_encode_mask)) != wc_encoding) + break; + length = codeset->length; + buf_len -= length; + bufptr += length; + + tmpptr = bufptr - 1; + if ((*codeset->charset_list)->side == XlcGL) { + while (length--) { + *tmpptr-- = (unsigned char) (wch & 0x7f); + wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits); + } + } else if ((*codeset->charset_list)->side == XlcGR) { + while (length--) { + *tmpptr-- = (unsigned char) (wch | 0x80); + wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits); + } + } else { + while (length--) { + *tmpptr-- = (unsigned char) wch; + wch >>= (wchar_t)XLC_GENERIC(lcd, wc_shift_bits); + } + } + } + + if (num_args > 0) + *((XlcCharSet *) args[0]) = *codeset->charset_list; + + *from_left -= wcptr - *((wchar_t **) from); + *from = (XPointer) wcptr; + + *to_left -= bufptr - *((char **) to); + *to = bufptr; + + return 0; +} + +static CodeSet +GetCodeSetFromCharSet( + XLCd lcd, + XlcCharSet charset) +{ + CodeSet *codeset = XLC_GENERIC(lcd, codeset_list); + XlcCharSet *charset_list; + int codeset_num, num_charsets; + + codeset_num = XLC_GENERIC(lcd, codeset_num); + + for ( ; codeset_num-- > 0; codeset++) { + num_charsets = (*codeset)->num_charsets; + charset_list = (*codeset)->charset_list; + + for ( ; num_charsets-- > 0; charset_list++) + if (*charset_list == charset) + return *codeset; + } + + return (CodeSet) NULL; +} + +static int +cstombs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + const char *csptr; + char *bufptr; + int csstr_len; + int buf_len; + int num, encoding_len = 0; + CodeSet codeset; + XlcCharSet charset; + EncodingType type; + int cvt_length; + + csptr = *((const char **) from); + bufptr = *((char **) to); + csstr_len = *from_left; + buf_len = *to_left; + + if (num_args < 1) + return -1; + + charset = (XlcCharSet) args[0]; + + codeset = GetCodeSetFromCharSet(state->lcd, charset); + if (codeset == NULL) + return -1; + + cvt_length = 0; + if (codeset->parse_info) { + switch (type = codeset->parse_info->type) { + case E_SS: + encoding_len = strlen(codeset->parse_info->encoding); + break; + case E_LSL: + case E_LSR: + if (type == E_LSL) { + if (charset == state->GL_charset) + break; + } else { + if (charset == state->GR_charset) + break; + } + encoding_len = strlen(codeset->parse_info->encoding); + if (encoding_len > buf_len) + return -1; + cvt_length += encoding_len; + if (bufptr) { + strcpy(bufptr, codeset->parse_info->encoding); + bufptr += encoding_len; + } + buf_len -= encoding_len; + encoding_len = 0; + if (type == E_LSL) + state->GL_charset = charset; + else + state->GR_charset = charset; + break; + default: + break; + } + } + + csstr_len /= codeset->length; + buf_len /= codeset->length + encoding_len; + if (csstr_len < buf_len) + buf_len = csstr_len; + + cvt_length += buf_len * (encoding_len + codeset->length); + if (bufptr) { + while (buf_len--) { + if (encoding_len) { + strcpy(bufptr, codeset->parse_info->encoding); + bufptr += encoding_len; + } + num = codeset->length; + if (codeset->side == XlcGL) { + while (num--) + *bufptr++ = *csptr++ & 0x7f; + } else if (codeset->side == XlcGR) { + while (num--) + *bufptr++ = *csptr++ | 0x80; + } else { + while (num--) + *bufptr++ = *csptr++; + } + } + } + + *from_left -= csptr - *((char **) from); + *from = (XPointer) csptr; + + if (bufptr) + *to = (XPointer) bufptr; + *to_left -= cvt_length; + + return 0; +} + +static int +cstowcs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + State state = (State) conv->state; + XLCd lcd = state->lcd; + const char *csptr; + wchar_t *bufptr; + int csstr_len; + int buf_len; + wchar_t wch; + unsigned long code_mask, wc_encoding; + int num, length, wc_shift_bits; + CodeSet codeset; + + csptr = *((const char **) from); + bufptr = *((wchar_t **) to); + csstr_len = *from_left; + buf_len = *to_left; + + if (num_args < 1) + return -1; + + codeset = GetCodeSetFromCharSet(lcd, (XlcCharSet) args[0]); + if (codeset == NULL) + return -1; + + length = codeset->length; + csstr_len /= length; + if (csstr_len < buf_len) + buf_len = csstr_len; + + code_mask = ~XLC_GENERIC(lcd, wc_encode_mask); + wc_encoding = codeset->wc_encoding; + wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits); + + *to_left -= buf_len; + + if (bufptr) { + while (buf_len--) { + wch = (wchar_t) (*csptr++ & 0x7f); + num = length - 1; + while (num--) + wch = (wch << wc_shift_bits) | (*csptr++ & 0x7f); + + *bufptr++ = (wch & code_mask) | wc_encoding; + } + } + + *from_left -= csptr - *((char **) from); + *from = (XPointer) csptr; + + if (bufptr) + *to = (XPointer) bufptr; + + return 0; +} + + +static void +close_converter( + XlcConv conv) +{ + if (conv->state) { + Xfree((char *) conv->state); + } + + Xfree((char *) conv); +} + +static XlcConv +create_conv( + XLCd lcd, + XlcConvMethods methods) +{ + XlcConv conv; + State state; + + conv = (XlcConv) Xmalloc(sizeof(XlcConvRec)); + if (conv == NULL) + return (XlcConv) NULL; + + conv->methods = (XlcConvMethods) Xmalloc(sizeof(XlcConvMethodsRec)); + if (conv->methods == NULL) + goto err; + *conv->methods = *methods; + if (XLC_PUBLIC(lcd, is_state_depend)) + conv->methods->reset = init_state; + + conv->state = Xcalloc(1, sizeof(StateRec)); + if (conv->state == NULL) + goto err; + + state = (State) conv->state; + state->lcd = lcd; + init_state(conv); + + return conv; + +err: + close_converter(conv); + + return (XlcConv) NULL; +} + +static XlcConvMethodsRec mbstocs_methods = { + close_converter, + mbstocs, + NULL +}; + +static XlcConv +open_mbstocs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &mbstocs_methods); +} + +static XlcConvMethodsRec wcstocs_methods = { + close_converter, + wcstocs, + NULL +}; + +static XlcConv +open_wcstocs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &wcstocs_methods); +} + +static XlcConvMethodsRec mbtocs_methods = { + close_converter, + mbtocs, + NULL +}; + +static XlcConv +open_mbtocs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &mbtocs_methods); +} + +static XlcConvMethodsRec cstombs_methods = { + close_converter, + cstombs, + NULL +}; + +static XlcConv +open_cstombs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &cstombs_methods); +} + +static XlcConvMethodsRec cstowcs_methods = { + close_converter, + cstowcs, + NULL +}; + +static XlcConv +open_cstowcs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &cstowcs_methods); +} + +#ifdef STDCVT +static int +stdc_mbstowcs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + const char *src = *((const char **) from); + wchar_t *dst = *((wchar_t **) to); + int src_left = *from_left; + int dst_left = *to_left; + int length; + + while (src_left > 0 && dst_left > 0) { + length = mbtowc(dst, src, src_left); + if (length < 0) + break; + + src += length; + src_left -= length; + if (dst) + dst++; + dst_left--; + + if (length == 0) { + src++; + src_left--; + break; + } + } + + if (*from_left == src_left) + return -1; + + *from = (XPointer) src; + if (dst) + *to = (XPointer) dst; + *from_left = src_left; + *to_left = dst_left; + + return 0; +} + +static int +stdc_wcstombs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + const wchar_t *src = *((const wchar_t **) from); + char *dst = *((char **) to); + int src_left = *from_left; + int dst_left = *to_left; + int length; + + while (src_left > 0 && dst_left > 0) { + length = wctomb(dst, *src); /* XXX */ + if (length < 0 || dst_left < length) + break; + + src++; + src_left--; + dst += length; + dst_left -= length; + + if (length == 0) { + dst++; + dst_left--; + break; + } + } + + if (*from_left == src_left) + return -1; + + *from = (XPointer) src; + *to = (XPointer) dst; + *from_left = src_left; + *to_left = dst_left; + + return 0; +} + +static int +stdc_wcstocs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + const wchar_t *src = *((const wchar_t **) from); + wchar_t wch; + XlcCharSet charset = NULL; + XPointer tmp_args[2], tmp_from, save_from = *from; + char tmp[32]; + int length, ret, src_left = *from_left; + int unconv_num = 0, tmp_num = 1; + + tmp_args[0] = (XPointer) &charset; + + while (src_left > 0 && *to_left > 0) { + if (wch = *src) { + length = wctomb(tmp, wch); + } else { + length = 1; + *tmp = '\0'; + } + + if (length < 0) + break; + + tmp_from = (XPointer) tmp; + ret = mbtocs(conv, &tmp_from, &length, to, to_left, tmp_args, tmp_num); + if (ret < 0) + break; + unconv_num += ret; + if (tmp_num == 1 && charset) { + tmp_args[1] = (XPointer) charset; + tmp_num = 2; + } + + src++; + src_left--; + } + + if (save_from == (XPointer) src) + return -1; + + *from = (XPointer) src; + *from_left = src_left; + + if (num_args > 0) + *((XlcCharSet *) args[0]) = charset; + + return unconv_num; +} + +#define DefineLocalBuf char local_buf[BUFSIZ] +#define AllocLocalBuf(length) (length > BUFSIZ ? (char*) Xmalloc(length) : local_buf) +#define FreeLocalBuf(ptr) if (ptr != local_buf) Xfree(ptr) + +static int +stdc_cstowcs( + XlcConv conv, + XPointer *from, + int *from_left, + XPointer *to, + int *to_left, + XPointer *args, + int num_args) +{ + XLCd lcd = ((State) conv->state)->lcd; + DefineLocalBuf; + XPointer buf, save_buf; + int length, left, ret; + + left = length = *to_left * XLC_PUBLIC(lcd, mb_cur_max); + buf = save_buf = (XPointer) AllocLocalBuf(length); + if (buf == NULL) + return -1; + + ret = cstombs(conv, from, from_left, &buf, &left, args, num_args); + if (ret < 0) + goto err; + + buf = save_buf; + length -= left; + if (stdc_mbstowcs(conv, &buf, &length, to, to_left, args, num_args) < 0) + ret = -1; + +err: + FreeLocalBuf(save_buf); + + return ret; +} + +static XlcConvMethodsRec stdc_mbstowcs_methods = { + close_converter, + stdc_mbstowcs, + NULL +}; + +static XlcConv +open_stdc_mbstowcs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_mbstowcs_methods); +} + +static XlcConvMethodsRec stdc_wcstombs_methods = { + close_converter, + stdc_wcstombs, + NULL +}; + +static XlcConv +open_stdc_wcstombs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_wcstombs_methods); +} + +static XlcConvMethodsRec stdc_wcstocs_methods = { + close_converter, + stdc_wcstocs, + NULL +}; + +static XlcConv +open_stdc_wcstocs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_wcstocs_methods); +} + +static XlcConvMethodsRec stdc_cstowcs_methods = { + close_converter, + stdc_cstowcs, + NULL +}; + +static XlcConv +open_stdc_cstowcs( + XLCd from_lcd, + const char *from_type, + XLCd to_lcd, + const char *to_type) +{ + return create_conv(from_lcd, &stdc_cstowcs_methods); +} +#endif /* STDCVT */ + +XLCd +_XlcJisLoader( + const char *name) +{ + XLCd lcd; +#ifdef STDCVT + XLCdGenericPart *gen; +#endif + + lcd = _XlcCreateLC(name, _XlcGenericMethods); + if (lcd == NULL) + return lcd; + + if (!XLC_PUBLIC_PART(lcd)->codeset || + (_XlcCompareISOLatin1(XLC_PUBLIC_PART(lcd)->codeset, "JIS7"))) { + _XlcDestroyLC(lcd); + return (XLCd) NULL; + } + + _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs); + _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs); + _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs); + +#ifdef STDCVT + gen = XLC_GENERIC_PART(lcd); + + if (gen->use_stdc_env == True) { + _XlcSetConverter(lcd,XlcNMultiByte,lcd,XlcNWideChar,open_stdc_mbstowcs); + _XlcSetConverter(lcd,XlcNWideChar,lcd,XlcNMultiByte,open_stdc_wcstombs); + } + if (gen->force_convert_to_mb == True) { + _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet,open_stdc_wcstocs); + _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar,open_stdc_cstowcs); + } else { +#endif + _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs); + _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs); +#ifdef STDCVT + } +#endif + + _XlcAddUtf8Converters(lcd); + + return lcd; +} + +#else +typedef int dummy; +#endif /* X_LOCALE */ |