lcRM.c revision 1ab64890
1/* $Xorg: lcRM.c,v 1.3 2000/08/17 19:45:19 cpqbld Exp $ */
2/*
3 * Copyright 1992, 1993 by TOSHIBA Corp.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation for any purpose and without fee is hereby granted, provided
7 * that the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of TOSHIBA not be used in advertising
10 * or publicity pertaining to distribution of the software without specific,
11 * written prior permission. TOSHIBA make no representations about the
12 * suitability of this software for any purpose.  It is provided "as is"
13 * without express or implied warranty.
14 *
15 * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17 * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21 * SOFTWARE.
22 *
23 * Author: Katsuhisa Yano	TOSHIBA Corp.
24 *			   	mopi@osa.ilab.toshiba.co.jp
25 * Bug fixes: Bruno Haible	XFree86 Inc.
26 */
27/* $XFree86: xc/lib/X11/lcRM.c,v 1.4 2000/11/28 18:49:48 dawes Exp $ */
28
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32#include "Xlibint.h"
33#include "XlcPubI.h"
34#include <stdio.h>
35
36/*
37 * Default implementation of methods for Xrm parsing.
38 */
39
40/* ======================= Unibyte implementation ======================= */
41
42/* Only for efficiency, to speed up things. */
43
44/* This implementation must keep the locale, for lcname. */
45typedef struct _UbStateRec {
46    XLCd	lcd;
47} UbStateRec, *UbState;
48
49/* Sets the state to the initial state.
50   Initiates a sequence of calls to mbchar. */
51static void
52ub_mbinit(
53    XPointer state)
54{
55}
56
57/* Transforms one multibyte character, and return a 'char' in the same
58   parsing class. Returns the number of consumed bytes in *lenp. */
59static char
60ub_mbchar(
61    XPointer state,
62    const char *str,
63    int	*lenp)
64{
65    *lenp = 1;
66    return *str;
67}
68
69/* Terminates a sequence of calls to mbchar. */
70static void
71ub_mbfinish(
72    XPointer state)
73{
74}
75
76/* Returns the name of the state's locale, as a static string. */
77static const char *
78ub_lcname(
79    XPointer state)
80{
81    return ((UbState) state)->lcd->core->name;
82}
83
84/* Frees the state, which was allocated by _XrmDefaultInitParseInfo. */
85static void
86ub_destroy(
87    XPointer state)
88{
89    _XCloseLC(((UbState) state)->lcd);
90    Xfree((char *) state);
91}
92
93static const XrmMethodsRec ub_methods = {
94    ub_mbinit,
95    ub_mbchar,
96    ub_mbfinish,
97    ub_lcname,
98    ub_destroy
99};
100
101/* ======================= Multibyte implementation ======================= */
102
103/* This implementation uses an XlcConv from XlcNMultiByte to XlcNWideChar. */
104typedef struct _MbStateRec {
105    XLCd	lcd;
106    XlcConv	conv;
107} MbStateRec, *MbState;
108
109/* Sets the state to the initial state.
110   Initiates a sequence of calls to mbchar. */
111static void
112mb_mbinit(
113    XPointer state)
114{
115    _XlcResetConverter(((MbState) state)->conv);
116}
117
118/* Transforms one multibyte character, and return a 'char' in the same
119   parsing class. Returns the number of consumed bytes in *lenp. */
120static char
121mb_mbchar(
122    XPointer state,
123    const char *str,
124    int	*lenp)
125{
126    XlcConv conv = ((MbState) state)->conv;
127    const char *from;
128    wchar_t *to, wc;
129    int cur_max, i, from_left, to_left, ret;
130
131    cur_max = XLC_PUBLIC(((MbState) state)->lcd, mb_cur_max);
132
133    from = str;
134    /* Determine from_left. Avoid overrun error which could occur if
135       from_left > strlen(str). */
136    from_left = cur_max;
137    for (i = 0; i < cur_max; i++)
138	if (str[i] == '\0') {
139	    from_left = i;
140	    break;
141	}
142    *lenp = from_left;
143
144    to = &wc;
145    to_left = 1;
146
147    ret = _XlcConvert(conv, (XPointer *) &from, &from_left,
148		      (XPointer *) &to, &to_left, NULL, 0);
149    *lenp -= from_left;
150
151    if (ret < 0 || to_left > 0) {
152	/* Invalid or incomplete multibyte character seen. */
153	*lenp = 1;
154	return 0x7f;
155    }
156    /* Return a 'char' equivalent to wc. */
157    return (wc >= 0 && wc <= 0x7f ? wc : 0x7f);
158}
159
160/* Terminates a sequence of calls to mbchar. */
161static void
162mb_mbfinish(
163    XPointer state)
164{
165}
166
167/* Returns the name of the state's locale, as a static string. */
168static const char *
169mb_lcname(
170    XPointer state)
171{
172    return ((MbState) state)->lcd->core->name;
173}
174
175/* Frees the state, which was allocated by _XrmDefaultInitParseInfo. */
176static void
177mb_destroy(
178    XPointer state)
179{
180    _XlcCloseConverter(((MbState) state)->conv);
181    _XCloseLC(((MbState) state)->lcd);
182    Xfree((char *) state);
183}
184
185static const XrmMethodsRec mb_methods = {
186    mb_mbinit,
187    mb_mbchar,
188    mb_mbfinish,
189    mb_lcname,
190    mb_destroy
191};
192
193/* ======================= Exported function ======================= */
194
195XrmMethods
196_XrmDefaultInitParseInfo(
197    XLCd lcd,
198    XPointer *rm_state)
199{
200    if (XLC_PUBLIC(lcd, mb_cur_max) == 1) {
201	/* Unibyte case. */
202	UbState state = (UbState) Xmalloc(sizeof(UbStateRec));
203	if (state == NULL)
204	    return (XrmMethods) NULL;
205
206	state->lcd = lcd;
207
208	*rm_state = (XPointer) state;
209	return &ub_methods;
210    } else {
211	/* Multibyte case. */
212	MbState state = (MbState) Xmalloc(sizeof(MbStateRec));
213	if (state == NULL)
214	    return (XrmMethods) NULL;
215
216	state->lcd = lcd;
217	state->conv = _XlcOpenConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar);
218	if (state->conv == NULL) {
219	    Xfree((char *) state);
220	    return (XrmMethods) NULL;
221	}
222
223	*rm_state = (XPointer) state;
224	return &mb_methods;
225    }
226}
227