aboutsummaryrefslogtreecommitdiff
path: root/libX11/modules/lc/def/lcDefConv.c
diff options
context:
space:
mode:
Diffstat (limited to 'libX11/modules/lc/def/lcDefConv.c')
-rw-r--r--libX11/modules/lc/def/lcDefConv.c793
1 files changed, 793 insertions, 0 deletions
diff --git a/libX11/modules/lc/def/lcDefConv.c b/libX11/modules/lc/def/lcDefConv.c
new file mode 100644
index 000000000..fb504d11d
--- /dev/null
+++ b/libX11/modules/lc/def/lcDefConv.c
@@ -0,0 +1,793 @@
+/* $Xorg: lcDefConv.c,v 1.3 2000/08/17 19:45:17 cpqbld Exp $ */
+/*
+ * 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
+ */
+/*
+ * 2000
+ * Modifier: Ivan Pascal The XFree86 Project
+ */
+/* $XFree86: xc/lib/X11/lcDefConv.c,v 1.6 2001/01/17 19:41:53 dawes Exp $ */
+
+/*
+ * The default locale loader.
+ * Supports: one byte per char (iso8859 like) locales.
+ * How: converts bytes to wide characters in a 1:1 manner.
+ * Platforms: all systems.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+#include "XlcGeneric.h"
+
+#ifndef MB_LEN_MAX
+#define MB_LEN_MAX 6
+#endif
+
+#if !defined(macII) && !defined(Lynx_22) && !defined(X_LOCALE)
+#define STDCVT
+#endif
+
+#define GR 0x80
+#define GL 0x7f
+
+typedef struct _StateRec *State;
+typedef struct _StateRec {
+ CodeSet GL_codeset;
+ CodeSet GR_codeset;
+ wchar_t wc_mask;
+ wchar_t wc_encode_mask;
+ Bool (*MBtoWC) (State state, const char *ch, wchar_t *wc);
+ Bool (*WCtoMB) (State state, wchar_t wc, char *ch);
+} StateRec;
+
+static
+Bool MBtoWCdef(
+ State state,
+ const char *ch,
+ wchar_t *wc)
+{
+ wchar_t wc_encoding;
+ CodeSet codeset = (*ch & GR) ? state->GR_codeset : state->GL_codeset;
+ if (!codeset)
+ return False;
+ wc_encoding = codeset->wc_encoding;
+ *wc = ((wchar_t) *ch & state->wc_mask) | wc_encoding;
+ return True;
+}
+
+#ifdef STDCVT
+static
+Bool MBtoWCstd(
+ State state,
+ const char *ch,
+ wchar_t *wc)
+{
+ return (mbtowc(wc, ch, 1) == 1);
+}
+#endif
+
+static
+Bool WCtoMBdef(
+ State state,
+ wchar_t wc,
+ char *ch)
+{
+ wchar_t wc_encoding = wc & state->wc_encode_mask;
+ CodeSet codeset;
+
+ codeset = state->GL_codeset;
+ if (codeset && (wc_encoding == codeset->wc_encoding)) {
+ *ch = wc & state->wc_mask;
+ return True;
+ }
+ codeset = state->GR_codeset;
+ if (codeset && (wc_encoding == codeset->wc_encoding)) {
+ *ch = (wc & state->wc_mask) | GR;
+ return True;
+ }
+ return False;
+}
+
+#ifdef STDCVT
+static
+Bool WCtoMBstd(
+ State state,
+ wchar_t wc,
+ char *ch)
+{
+ return (wctomb(ch, wc) == 1);
+}
+#endif
+
+static
+XlcCharSet get_charset(
+ State state,
+ char side)
+{
+ CodeSet codeset = side ? state->GR_codeset : state->GL_codeset;
+ if (codeset) {
+ int i;
+ XlcCharSet charset;
+ for (i = 0; i < codeset->num_charsets; i++) {
+ charset = codeset->charset_list[i];
+ if (*charset->ct_sequence != '\0')
+ return charset;
+ }
+ return *(codeset->charset_list);
+ }
+ return (XlcCharSet) NULL;
+}
+
+static int
+def_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;
+ State state = (State) conv->state;
+ int unconv = 0;
+
+ if (from == NULL || *from == NULL)
+ return 0;
+
+ while (*from_left && *to_left) {
+ (*from_left)--;
+ if (state->MBtoWC (state, src++, dst)) {
+ dst++;
+ (*to_left)--;
+ } else {
+ unconv++;
+ }
+ }
+ *from = (XPointer) src;
+ *to = (XPointer) dst;
+ return unconv;
+}
+
+static int
+def_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;
+ State state = (State) conv->state;
+ char ch[MB_LEN_MAX];
+ int unconv = 0;
+
+ if (from == NULL || *from == NULL)
+ return 0;
+
+ while (*from_left && *to_left) {
+ (*from_left)--;
+ if (state->WCtoMB (state, *src++, ch)) {
+ *dst++ = *ch;
+ (*to_left)--;
+ } else {
+ unconv++;
+ }
+ }
+ *from = (XPointer) src;
+ *to = (XPointer) dst;
+ return unconv;
+}
+
+static int
+mbstostr(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ const char *src = (const char *) *from;
+ char *dst = (char *) *to;
+ CodeSet codeset;
+ State state = (State) conv->state;
+ char ch;
+ int unconv = 0;
+
+ if (from == NULL || *from == NULL)
+ return 0;
+
+ while (*from_left && *to_left) {
+ ch = *src++;
+ (*from_left)--;
+
+ codeset = (ch & GR) ? state->GR_codeset : state->GL_codeset;
+ if (codeset && codeset->string_encoding) {
+ *dst++ = ch;
+ (*to_left)--;
+ } else {
+ unconv++;
+ }
+ }
+ *from = (XPointer) src;
+ *to = (XPointer) dst;
+ return unconv;
+}
+
+static int
+wcstostr(
+ 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;
+ CodeSet codeset;
+ State state = (State) conv->state;
+ char ch[MB_LEN_MAX];
+ int unconv = 0;
+
+ if (from == NULL || *from == NULL)
+ return 0;
+
+ while (*from_left && *to_left) {
+ (*from_left)--;
+ if (state->WCtoMB (state, *src++, ch)) {
+ codeset = (*ch & GR) ? state->GR_codeset : state->GL_codeset;
+ if (codeset && codeset->string_encoding) {
+ *dst++ = *ch;
+ (*to_left)--;
+ } else {
+ unconv++;
+ }
+ } else {
+ unconv++;
+ }
+ }
+ *from = (XPointer) src;
+ *to = (XPointer) dst;
+ return unconv;
+}
+
+static int
+mbstocs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ const char *src = (const char *) *from;
+ char *dst = (char *) *to;
+ int length;
+ State state = (State) conv->state;
+ char cur_side;
+ int unconv = 0;
+
+ if (from == NULL || *from == NULL)
+ return 0;
+
+ length = min(*from_left, *to_left);
+
+ cur_side = *src & GR;
+ while (length) {
+ if ((char) (*src & GR) != cur_side)
+ break;
+ *dst++ = *src++;
+ length--;
+ }
+
+ if (num_args > 0) {
+ XlcCharSet charset = get_charset(state, cur_side);
+ if (charset) {
+ *((XlcCharSet *) args[0]) = charset;
+ } else {
+ dst = *to;
+ unconv = -1;
+ }
+ }
+ *from_left -= src - (char *) *from;
+ *to_left -= dst - (char *) *to;
+ *from = (XPointer) src;
+ *to = (XPointer) dst;
+ return unconv;
+}
+
+static int
+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;
+ char *dst = (char *) *to;
+ State state = (State) conv->state;
+ char cur_side = 0, ch[MB_LEN_MAX];
+ int unconv = 0;
+ Bool found = False;
+
+ if (from == NULL || *from == NULL)
+ return 0;
+
+ while (*from_left) {
+ if ((found = state->WCtoMB (state, *src, ch)))
+ break;
+ unconv++;
+ src++;
+ (*from_left)--;
+ }
+
+ if (found) {
+ cur_side = *ch & GR;
+ while (*from_left && *to_left) {
+ (*from_left)--;
+ if (state->WCtoMB (state, *src++, ch)) {
+ if ((char) (*ch & GR) != cur_side) {
+ src--;
+ (*from_left)++;
+ break;
+ } else {
+ *dst++ = *ch;
+ (*to_left)--;
+ }
+ } else {
+ unconv++;
+ }
+ }
+ } else {
+ unconv++;
+ }
+
+ if (num_args > 0) {
+ XlcCharSet charset = get_charset(state, cur_side);
+ if (charset) {
+ *((XlcCharSet *) args[0]) = charset;
+ } else {
+ unconv = -1;
+ }
+ }
+ *from = (XPointer) src;
+ *to = (XPointer) dst;
+ return unconv;
+}
+
+static int
+cstombs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ const char *src = (const char *) *from;
+ char *dst = (char *) *to;
+ CodeSet codeset;
+ XlcCharSet charset;
+ State state = (State) conv->state;
+ unsigned char cur_side = 0;
+ int i;
+ Bool found = False;
+
+ if (from == NULL || *from == NULL)
+ return 0;
+
+ if (num_args > 0) {
+ charset = (XlcCharSet) args[0];
+ if (charset == NULL)
+ return -1;
+ } else {
+ return -1;
+ }
+
+ if ((charset->side == XlcGL) || (charset->side == XlcGLGR)) {
+ codeset = state->GL_codeset;
+ if (codeset) {
+ for (i = 0; i < codeset->num_charsets; i++)
+ if (charset == codeset->charset_list[i]) {
+ found = True;
+ cur_side = 0;
+ break;
+ }
+ }
+ }
+ if (!found && ((charset->side == XlcGR) || (charset->side == XlcGLGR))) {
+ codeset = state->GR_codeset;
+ if (codeset) {
+ for (i = 0; i < codeset->num_charsets; i++)
+ if (charset == codeset->charset_list[i]) {
+ found = True;
+ cur_side = GR;
+ break;
+ }
+ }
+ }
+ if (found) {
+ int length = min(*from_left, *to_left);
+ while (length) {
+ *dst++ = *src++ | cur_side;
+ length--;
+ }
+ } else {
+ return -1;
+ }
+
+ *from_left -= src - (char *) *from;
+ *to_left -= dst - (char *) *to;
+ *from = (XPointer) src;
+ *to = (XPointer) dst;
+ return 0;
+}
+
+static int
+cstowcs(
+ 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;
+ CodeSet codeset;
+ XlcCharSet charset;
+ State state = (State) conv->state;
+ Bool found = False;
+ int i, unconv = 0;
+ unsigned char cur_side = 0;
+
+ if (from == NULL || *from == NULL)
+ return 0;
+
+ if (num_args > 0) {
+ charset = (XlcCharSet) args[0];
+ if (charset == NULL)
+ return -1;
+ } else {
+ return -1;
+ }
+
+ if ((charset->side == XlcGL) || (charset->side == XlcGLGR)) {
+ codeset = state->GL_codeset;
+ if (codeset) {
+ for (i = 0; i < codeset->num_charsets; i++)
+ if (charset == codeset->charset_list[i]) {
+ found = True;
+ cur_side = 0;
+ break;
+ }
+ }
+ }
+ if (!found && ((charset->side == XlcGR) || (charset->side == XlcGLGR))) {
+ codeset = state->GR_codeset;
+ if (codeset) {
+ for (i = 0; i < codeset->num_charsets; i++)
+ if (charset == codeset->charset_list[i]) {
+ found = True;
+ cur_side = GR;
+ break;
+ }
+ }
+ }
+ if (found) {
+ char ch;
+ while (*from_left && *to_left) {
+ ch = *src++ | cur_side;
+ (*from_left)--;
+ if (state->MBtoWC (state, &ch, dst)) {
+ dst++;
+ (*to_left)--;
+ } else {
+ unconv++;
+ }
+ }
+ } else {
+ return -1;
+ }
+ *from = (XPointer) src;
+ *to = (XPointer) dst;
+ return unconv;
+}
+
+static int
+strtombs(
+ XlcConv conv,
+ XPointer *from,
+ int *from_left,
+ XPointer *to,
+ int *to_left,
+ XPointer *args,
+ int num_args)
+{
+ const char *src = (const char *) *from;
+ char *dst = (char *) *to;
+ int length;
+
+ if (from == NULL || *from == NULL)
+ return 0;
+
+ length = min(*from_left, *to_left);
+ while (length) {
+ *dst++ = *src++;
+ length--;
+ }
+
+ *from_left -= src - (char *) *from;
+ *to_left -= dst - (char *) *to;
+ *from = (XPointer) src;
+ *to = (XPointer) dst;
+ 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;
+
+ state = (State) Xmalloc(sizeof(StateRec));
+ if (state == NULL) {
+ close_converter(conv);
+ return (XlcConv) NULL;
+ }
+ state->GL_codeset = XLC_GENERIC(lcd, initial_state_GL);
+ state->GR_codeset = XLC_GENERIC(lcd, initial_state_GR);
+ state->wc_mask = (1 << XLC_GENERIC(lcd, wc_shift_bits)) - 1;
+ state->wc_encode_mask = XLC_GENERIC(lcd, wc_encode_mask);
+
+#ifdef STDCVT
+ if (XLC_GENERIC(lcd, use_stdc_env) == True)
+ state->MBtoWC = &MBtoWCstd;
+ else
+#endif
+ state->MBtoWC = &MBtoWCdef;
+
+#ifdef STDCVT
+ if (XLC_GENERIC(lcd, use_stdc_env) == True)
+ state->WCtoMB = &WCtoMBstd;
+ else
+#endif
+ state->WCtoMB = &WCtoMBdef;
+
+ conv->methods = methods;
+ conv->state = (XPointer) state;
+
+ return conv;
+}
+
+static XlcConvMethodsRec mbstowcs_methods = {
+ close_converter,
+ def_mbstowcs,
+ 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 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 wcstombs_methods = {
+ close_converter,
+ def_wcstombs,
+ 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 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 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);
+}
+
+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);
+}
+
+XLCd
+_XlcDefaultLoader(
+ const char *name)
+{
+ XLCd lcd;
+
+ lcd = _XlcCreateLC(name, _XlcGenericMethods);
+ if (lcd == NULL)
+ return lcd;
+
+ if (XLC_PUBLIC(lcd, mb_cur_max) != 1){
+ _XlcDestroyLC(lcd);
+ return (XLCd) NULL;
+ }
+
+ _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_mbstowcs);
+ _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNString, open_mbstostr);
+ _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs);
+ _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbstocs);
+
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_wcstombs);
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_wcstostr);
+ _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs);
+
+ _XlcSetConverter(lcd, XlcNString, lcd, XlcNMultiByte, open_strtombs);
+ _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_mbstowcs);
+
+ _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs);
+ _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs);
+
+ _XlcAddUtf8Converters(lcd);
+
+ return lcd;
+}