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