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