2
0

_fallcUTF.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* lcUTF.c 1.1 - Fujitsu source for CDEnext 95/11/06 20:32:41 */
  24. /* $XConsortium: _fallcUTF.c /main/2 1996/09/27 19:03:38 drk $ */
  25. /******************************************************************
  26. Copyright 1993 by SunSoft, Inc.
  27. Permission to use, copy, modify, distribute, and sell this software
  28. and its documentation for any purpose is hereby granted without fee,
  29. provided that the above copyright notice appear in all copies and
  30. that both that copyright notice and this permission notice appear
  31. in supporting documentation, and that the name of SunSoft, Inc.
  32. not be used in advertising or publicity pertaining to distribution
  33. of the software without specific, written prior permission.
  34. SunSoft, Inc. makes no representations about the suitability of
  35. this software for any purpose. It is provided "as is" without
  36. express or implied warranty.
  37. SunSoft Inc. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  38. SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  39. IN NO EVENT SHALL SunSoft, Inc. BE LIABLE FOR ANY SPECIAL, INDIRECT
  40. OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  41. OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  42. OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  43. OR PERFORMANCE OF THIS SOFTWARE.
  44. Author: Hiromu Inukai (inukai@Japan.Sun.COM) SunSoft, inc.
  45. ******************************************************************/
  46. #include "_fallcUTF.h"
  47. #include <stdlib.h>
  48. static long getutfrune(char **read_from, int *from_len);
  49. static void our_wctomb(
  50. unsigned short r,
  51. char **bufptr,
  52. int *buf_len
  53. );
  54. static int our_mbtowc(
  55. unsigned long *p,
  56. char *s,
  57. size_t n
  58. );
  59. static void latin2rune(
  60. unsigned char c,
  61. Rune *r
  62. );
  63. static void jis02012rune(
  64. unsigned char c,
  65. Rune *r
  66. );
  67. static void jis02082rune(
  68. unsigned char c,
  69. Rune *r
  70. );
  71. static void ksc2rune(
  72. unsigned char c,
  73. Rune *r
  74. );
  75. static void gb2rune(
  76. unsigned char c,
  77. Rune *r
  78. );
  79. static void init_latin1tab(long *tbl, long fb_default);
  80. static void init_latin2tab(long *tbl, long fb_default);
  81. static void init_latin3tab(long *tbl, long fb_default);
  82. static void init_latin4tab(long *tbl, long fb_default);
  83. static void init_latin5tab(long *tbl, long fb_default);
  84. static void init_latin6tab(long *tbl, long fb_default);
  85. static void init_latin7tab(long *tbl, long fb_default);
  86. static void init_latin8tab(long *tbl, long fb_default);
  87. static void init_latin9tab(long *tbl, long fb_default);
  88. static void init_jis0201tab(long *tbl, long fb_default);
  89. static void init_jis0208tab(long *tbl, long fb_default);
  90. static void init_ksc5601tab(long *tbl, long fb_default);
  91. static void init_gb2312tab(long *tbl, long fb_default);
  92. static char *int_locale = NULL;
  93. static long *tabkuten = NULL;
  94. static long *tabksc5601 = NULL;
  95. static long *tabgb = NULL;
  96. static UtfData utfdata_list = (UtfData)NULL;
  97. static XlcUTFDataRec default_utf_data[] =
  98. {
  99. {"ISO8859-1", XlcGL, init_latin1tab, latin2rune, N11n_none, 0x20},
  100. {"ISO8859-1", XlcGR, init_latin1tab, latin2rune, N11n_none, 0x20},
  101. {"ISO8859-1", XlcGL, init_latin2tab, latin2rune, N11n_none, 0x20},
  102. {"ISO8859-1", XlcGR, init_latin2tab, latin2rune, N11n_none, 0x20},
  103. {"ISO8859-1", XlcGL, init_latin3tab, latin2rune, N11n_none, 0x20},
  104. {"ISO8859-1", XlcGR, init_latin3tab, latin2rune, N11n_none, 0x20},
  105. {"ISO8859-1", XlcGL, init_latin4tab, latin2rune, N11n_none, 0x20},
  106. {"ISO8859-1", XlcGR, init_latin4tab, latin2rune, N11n_none, 0x20},
  107. {"ISO8859-1", XlcGL, init_latin5tab, latin2rune, N11n_none, 0x20},
  108. {"ISO8859-1", XlcGR, init_latin5tab, latin2rune, N11n_none, 0x20},
  109. {"ISO8859-1", XlcGL, init_latin6tab, latin2rune, N11n_none, 0x20},
  110. {"ISO8859-1", XlcGR, init_latin6tab, latin2rune, N11n_none, 0x20},
  111. {"ISO8859-1", XlcGL, init_latin7tab, latin2rune, N11n_none, 0x20},
  112. {"ISO8859-1", XlcGR, init_latin7tab, latin2rune, N11n_none, 0x20},
  113. {"ISO8859-1", XlcGL, init_latin8tab, latin2rune, N11n_none, 0x20},
  114. {"ISO8859-1", XlcGR, init_latin8tab, latin2rune, N11n_none, 0x20},
  115. {"ISO8859-1", XlcGL, init_latin9tab, latin2rune, N11n_none, 0x20},
  116. {"ISO8859-1", XlcGR, init_latin9tab, latin2rune, N11n_none, 0x20},
  117. {"JISX0201.1976-0", XlcGL, init_jis0201tab, jis02012rune, N11n_none, 0x20},
  118. {"JISX0201.1976-0", XlcGR, init_jis0201tab, jis02012rune, N11n_none, 0x20},
  119. {"JISX0208.1983-0", XlcGL, init_jis0208tab, jis02082rune, N11n_ja, 0x2222},
  120. {"JISX0208.1983-0", XlcGR, init_jis0208tab, jis02082rune, N11n_ja, 0x2222},
  121. {"KSC5601.1987-0", XlcGL, init_ksc5601tab, ksc2rune, N11n_ko, 0x2160},
  122. {"KSC5601.1987-0", XlcGR, init_ksc5601tab, ksc2rune, N11n_ko, 0x2160},
  123. {"GB2312.1980-0", XlcGL, init_gb2312tab, gb2rune, N11n_zh, 0x2175},
  124. {"GB2312.1980-0", XlcGR, init_gb2312tab, gb2rune, N11n_zh, 0x2175},
  125. };
  126. static void
  127. set_latin_nop(long *table, long default_val)
  128. {
  129. int i;
  130. for(i = 0; i < 0x1fff; i++)
  131. table[i] = default_val;
  132. return;
  133. }
  134. static void
  135. set_latin_tab(FILE *fptr, long *table, long fb_default)
  136. {
  137. int i = 0;
  138. int j = 0;
  139. int rv = 0;
  140. long value;
  141. for(i = 0; i < NRUNE; i++)
  142. table[i] = -1;
  143. while((rv = fscanf(fptr, "%lx", (long unsigned *) &value)) != EOF) {
  144. if(rv != 0 && value >= 0) {
  145. table[value] = j++;
  146. } else {
  147. set_latin_nop(table, fb_default);
  148. return;
  149. }
  150. }
  151. }
  152. extern int _fallcResolveI18NPath();
  153. #define TBL_DATA_DIR "tbl_data"
  154. static void
  155. init_latin1tab(long *tbl, long fb_default)
  156. {
  157. FILE *fp = NULL;
  158. char dirname[BUFSIZE];
  159. char filename[BUFSIZE];
  160. char *p, *q;
  161. _fallcResolveI18NPath(dirname);
  162. p = dirname;
  163. while(p) {
  164. q = strchr(p, ':');
  165. if(q) {
  166. *q = '\0';
  167. }
  168. sprintf(filename, "%s/%s/%s", p, TBL_DATA_DIR, tab8859_1);
  169. fp = fopen(filename, "r");
  170. if(fp) {
  171. set_latin_tab(fp, tbl, fb_default);
  172. fclose(fp);
  173. return;
  174. }
  175. if(q) {
  176. p = q + 1;
  177. } else {
  178. p = q;
  179. }
  180. }
  181. if(!fp) {
  182. set_latin_nop(tbl, fb_default);
  183. }
  184. }
  185. static void
  186. init_latin2tab(long *tbl, long fb_default)
  187. {
  188. FILE *fp;
  189. char dirname[BUFSIZE];
  190. char filename[BUFSIZE];
  191. char *p, *q;
  192. _fallcResolveI18NPath(dirname);
  193. p = dirname;
  194. while(p) {
  195. q = strchr(p, ':');
  196. if(q) {
  197. *q = '\0';
  198. }
  199. sprintf(filename, "%s/%s/%s", p, TBL_DATA_DIR, tab8859_2);
  200. fp = fopen(filename, "r");
  201. if(fp) {
  202. set_latin_tab(fp, tbl, fb_default);
  203. fclose(fp);
  204. return;
  205. }
  206. if(q) {
  207. p = q + 1;
  208. } else {
  209. p = q;
  210. }
  211. }
  212. if(!fp) {
  213. set_latin_nop(tbl, fb_default);
  214. }
  215. }
  216. static void
  217. init_latin3tab(long *tbl, long fb_default)
  218. {
  219. FILE *fp;
  220. char dirname[BUFSIZE];
  221. char filename[BUFSIZE];
  222. char *p, *q;
  223. _fallcResolveI18NPath(dirname);
  224. p = dirname;
  225. while(p) {
  226. q = strchr(p, ':');
  227. if(q) {
  228. *q = '\0';
  229. }
  230. sprintf(filename, "%s/%s/%s", p, TBL_DATA_DIR, tab8859_3);
  231. fp = fopen(filename, "r");
  232. if(fp) {
  233. set_latin_tab(fp, tbl, fb_default);
  234. fclose(fp);
  235. return;
  236. }
  237. if(q) {
  238. p = q + 1;
  239. } else {
  240. p = q;
  241. }
  242. }
  243. if(!fp) {
  244. set_latin_nop(tbl, fb_default);
  245. }
  246. }
  247. static void
  248. init_latin4tab(long *tbl, long fb_default)
  249. {
  250. FILE *fp;
  251. char dirname[BUFSIZE];
  252. char filename[BUFSIZE];
  253. char *p, *q;
  254. _fallcResolveI18NPath(dirname);
  255. p = dirname;
  256. while(p) {
  257. q = strchr(p, ':');
  258. if(q) {
  259. *q = '\0';
  260. }
  261. sprintf(filename, "%s/%s/%s", p, TBL_DATA_DIR, tab8859_4);
  262. fp = fopen(filename, "r");
  263. if(fp) {
  264. set_latin_tab(fp, tbl, fb_default);
  265. fclose(fp);
  266. return;
  267. }
  268. if(q) {
  269. p = q + 1;
  270. } else {
  271. p = q;
  272. }
  273. }
  274. if(!fp) {
  275. set_latin_nop(tbl, fb_default);
  276. }
  277. }
  278. static void
  279. init_latin5tab(long *tbl, long fb_default)
  280. {
  281. FILE *fp;
  282. char dirname[BUFSIZE];
  283. char filename[BUFSIZE];
  284. char *p, *q;
  285. _fallcResolveI18NPath(dirname);
  286. p = dirname;
  287. while(p) {
  288. q = strchr(p, ':');
  289. if(q) {
  290. *q = '\0';
  291. }
  292. sprintf(filename, "%s/%s/%s", p, TBL_DATA_DIR, tab8859_5);
  293. fp = fopen(filename, "r");
  294. if(fp) {
  295. set_latin_tab(fp, tbl, fb_default);
  296. fclose(fp);
  297. return;
  298. }
  299. if(q) {
  300. p = q + 1;
  301. } else {
  302. p = q;
  303. }
  304. }
  305. if(!fp) {
  306. set_latin_nop(tbl, fb_default);
  307. }
  308. }
  309. static void
  310. init_latin6tab(long *tbl, long fb_default)
  311. {
  312. FILE *fp;
  313. char dirname[BUFSIZE];
  314. char filename[BUFSIZE];
  315. char *p, *q;
  316. _fallcResolveI18NPath(dirname);
  317. p = dirname;
  318. while(p) {
  319. q = strchr(p, ':');
  320. if(q) {
  321. *q = '\0';
  322. }
  323. sprintf(filename, "%s/%s/%s", p, TBL_DATA_DIR, tab8859_6);
  324. fp = fopen(filename, "r");
  325. if(fp) {
  326. set_latin_tab(fp, tbl, fb_default);
  327. fclose(fp);
  328. return;
  329. }
  330. if(q) {
  331. p = q + 1;
  332. } else {
  333. p = q;
  334. }
  335. }
  336. if(!fp) {
  337. set_latin_nop(tbl, fb_default);
  338. }
  339. }
  340. static void
  341. init_latin7tab(long *tbl, long fb_default)
  342. {
  343. FILE *fp;
  344. char dirname[BUFSIZE];
  345. char filename[BUFSIZE];
  346. char *p, *q;
  347. _fallcResolveI18NPath(dirname);
  348. p = dirname;
  349. while(p) {
  350. q = strchr(p, ':');
  351. if(q) {
  352. *q = '\0';
  353. }
  354. sprintf(filename, "%s/%s/%s", p, TBL_DATA_DIR, tab8859_7);
  355. fp = fopen(filename, "r");
  356. if(fp) {
  357. set_latin_tab(fp, tbl, fb_default);
  358. fclose(fp);
  359. return;
  360. }
  361. if(q) {
  362. p = q + 1;
  363. } else {
  364. p = q;
  365. }
  366. }
  367. if(!fp) {
  368. set_latin_nop(tbl, fb_default);
  369. }
  370. }
  371. static void
  372. init_latin8tab(long *tbl, long fb_default)
  373. {
  374. FILE *fp;
  375. char dirname[BUFSIZE];
  376. char filename[BUFSIZE];
  377. char *p, *q;
  378. _fallcResolveI18NPath(dirname);
  379. p = dirname;
  380. while(p) {
  381. q = strchr(p, ':');
  382. if(q) {
  383. *q = '\0';
  384. }
  385. sprintf(filename, "%s/%s/%s", p, TBL_DATA_DIR, tab8859_8);
  386. fp = fopen(filename, "r");
  387. if(fp) {
  388. set_latin_tab(fp, tbl, fb_default);
  389. fclose(fp);
  390. return;
  391. }
  392. if(q) {
  393. p = q + 1;
  394. } else {
  395. p = q;
  396. }
  397. }
  398. if(!fp) {
  399. set_latin_nop(tbl, fb_default);
  400. }
  401. }
  402. static void
  403. init_latin9tab(long *tbl, long fb_default)
  404. {
  405. FILE *fp;
  406. char dirname[BUFSIZE];
  407. char filename[BUFSIZE];
  408. char *p, *q;
  409. _fallcResolveI18NPath(dirname);
  410. p = dirname;
  411. while(p) {
  412. q = strchr(p, ':');
  413. if(q) {
  414. *q = '\0';
  415. }
  416. sprintf(filename, "%s/%s/%s", p, TBL_DATA_DIR, tab8859_9);
  417. fp = fopen(filename, "r");
  418. if(fp) {
  419. set_latin_tab(fp, tbl, fb_default);
  420. fclose(fp);
  421. return;
  422. }
  423. if(q) {
  424. p = q + 1;
  425. } else {
  426. p = q;
  427. }
  428. }
  429. if(!fp) {
  430. set_latin_nop(tbl, fb_default);
  431. }
  432. }
  433. static void
  434. init_jis0201tab(long *tbl, long fb_default)
  435. {
  436. int i;
  437. for(i = 0; i < NRUNE; i++)
  438. tbl[i] = -1;
  439. }
  440. static void
  441. set_cjk_nop(long **to_tbl, int to_max, long default_val)
  442. {
  443. int i;
  444. for(i = 0; i < to_max; i++)
  445. (*to_tbl)[i] = default_val;
  446. return;
  447. }
  448. static void
  449. set_table(
  450. FILE *fptr,
  451. long **to_tbl,
  452. long *from_tbl,
  453. int to_max,
  454. long fb_default)
  455. {
  456. int i = 0;
  457. int j = 0;
  458. int rv = 0;
  459. long value;
  460. for(i = 0; i < NRUNE; i++)
  461. from_tbl[i] = -1;
  462. while((rv = fscanf(fptr, "%lx", (long unsigned *) &value)) != EOF) {
  463. if(rv != 0) {
  464. (*to_tbl)[j++] = value;
  465. } else {
  466. set_cjk_nop(to_tbl, to_max, fb_default);
  467. break;
  468. }
  469. }
  470. for(i = 0; i < to_max; i++) {
  471. if((value = (*to_tbl)[i]) != -1){
  472. from_tbl[abs(value)] = i;
  473. }
  474. }
  475. }
  476. static void
  477. init_jis0208tab(long *tbl, long fb_default)
  478. {
  479. FILE *fp;
  480. char dirname[BUFSIZE];
  481. char filename[BUFSIZE];
  482. char *p, *q;
  483. if((tabkuten = (long *)Xmalloc(KUTENMAX * sizeof(long))) == NULL) {
  484. return;
  485. }
  486. _fallcResolveI18NPath(dirname);
  487. p = dirname;
  488. while(p) {
  489. q = strchr(p, ':');
  490. if(q) {
  491. *q = '\0';
  492. }
  493. sprintf(filename, "%s/%s/%s", p, TBL_DATA_DIR, jis0208);
  494. fp = fopen(filename, "r");
  495. if(fp) {
  496. set_table(fp, &tabkuten, tbl, KUTENMAX, fb_default);
  497. fclose(fp);
  498. return;
  499. }
  500. if(q) {
  501. p = q + 1;
  502. } else {
  503. p = q;
  504. }
  505. }
  506. if(!fp) {
  507. set_cjk_nop(&tabkuten, KUTENMAX, fb_default);
  508. }
  509. }
  510. static void
  511. init_ksc5601tab(long *tbl, long fb_default)
  512. {
  513. FILE *fp;
  514. char dirname[BUFSIZE];
  515. char filename[BUFSIZE];
  516. char *p, *q;
  517. if((tabksc5601 = (long *)Xmalloc(KSCMAX * sizeof(long))) == NULL) {
  518. return;
  519. }
  520. _fallcResolveI18NPath(dirname);
  521. p = dirname;
  522. while(p) {
  523. q = strchr(p, ':');
  524. if(q) {
  525. *q = '\0';
  526. }
  527. sprintf(filename, "%s/%s/%s", p, TBL_DATA_DIR, ksc5601);
  528. fp = fopen(filename, "r");
  529. if(fp) {
  530. set_table(fp, &tabksc5601, tbl, KSCMAX, fb_default);
  531. fclose(fp);
  532. return;
  533. }
  534. if(q) {
  535. p = q + 1;
  536. } else {
  537. p = q;
  538. }
  539. }
  540. if(!fp) {
  541. set_cjk_nop(&tabksc5601, KSCMAX, fb_default);
  542. }
  543. }
  544. static void
  545. init_gb2312tab(long *tbl, long fb_default)
  546. {
  547. FILE *fp;
  548. char dirname[BUFSIZE];
  549. char filename[BUFSIZE];
  550. char *p, *q;
  551. if((tabgb = (long *)Xmalloc(GBMAX * sizeof(long))) == NULL) {
  552. return;
  553. }
  554. _fallcResolveI18NPath(dirname);
  555. p = dirname;
  556. while(p) {
  557. q = strchr(p, ':');
  558. if(q) {
  559. *q = '\0';
  560. }
  561. sprintf(filename, "%s/%s/%s", p, TBL_DATA_DIR, gb2312);
  562. fp = fopen(filename, "r");
  563. if(fp) {
  564. set_table(fp, &tabgb, tbl, GBMAX, fb_default);
  565. fclose(fp);
  566. return;
  567. }
  568. if(q) {
  569. p = q + 1;
  570. } else {
  571. p = q;
  572. }
  573. }
  574. if(!fp) {
  575. set_cjk_nop(&tabgb, GBMAX, fb_default);
  576. }
  577. }
  578. static UtfData
  579. make_entry(void)
  580. {
  581. UtfData tmp = (UtfData)Xmalloc(sizeof(UtfDataRec));
  582. bzero(tmp, sizeof(UtfDataRec));
  583. return tmp;
  584. }
  585. static int once = 0;
  586. static int
  587. _XlcInitUTFInfo(XLCd lcd)
  588. {
  589. if(!once) {
  590. int i;
  591. CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list);
  592. int codeset_num = XLC_GENERIC(lcd, codeset_num);
  593. UtfData pdata;
  594. if(!utfdata_list) {
  595. utfdata_list = make_entry();
  596. }
  597. pdata = utfdata_list;
  598. for(i=0; i < codeset_num; i++) {
  599. XlcCharSet charset = *codeset_list[i]->charset_list;
  600. while(pdata->next) {
  601. if(charset == pdata->charset) {
  602. break;
  603. }
  604. pdata = pdata->next;
  605. }
  606. if(pdata->next) {
  607. continue;
  608. } else {
  609. int j;
  610. for(j = 0; j < MAX_UTF_CHARSET; j++) {
  611. if(_fallcCompareISOLatin1(charset->encoding_name, default_utf_data[j].name) ||
  612. charset->side != default_utf_data[j].side) {
  613. continue;
  614. } else {
  615. pdata->initialize = default_utf_data[j].initialize;
  616. pdata->fromtbl = (long *)Xmalloc(NRUNE * sizeof(long));
  617. (*pdata->initialize)(pdata->fromtbl, default_utf_data[j].fallback_value);
  618. pdata->already_init = True;
  619. pdata->charset = charset;
  620. pdata->cstorune = default_utf_data[j].cstorune;
  621. pdata->type = default_utf_data[j].type;
  622. pdata->next = make_entry();
  623. break;
  624. }
  625. }
  626. }
  627. }
  628. once = 1;
  629. }
  630. return 1;
  631. }
  632. static int
  633. utftocs(
  634. XlcConv conv,
  635. char **from,
  636. int *from_left,
  637. char **to,
  638. int *to_left,
  639. XPointer *args,
  640. int num_args)
  641. {
  642. char *utfptr;
  643. char *bufptr;
  644. int utf_len, buf_len;
  645. long l;
  646. XlcCharSet tmpcharset = (XlcCharSet)NULL;
  647. UtfData pdata = utfdata_list;
  648. if (from == NULL || *from == NULL)
  649. return 0;
  650. utfptr = *from;
  651. bufptr = *to;
  652. utf_len = *from_left;
  653. buf_len = *to_left;
  654. while(utf_len > 0 && buf_len > 0) {
  655. char *p = utfptr;
  656. if((l = getutfrune(&p, &utf_len)) == -2) {
  657. return -1;
  658. } else {
  659. while(pdata->next) {
  660. long r;
  661. long *tbl;
  662. tbl = pdata->fromtbl;
  663. tbl += l;
  664. if((r = *tbl) == -1) {
  665. if(tmpcharset) {
  666. if((num_args > 0) && tmpcharset)
  667. *((XlcCharSet *) args[0]) = tmpcharset;
  668. *from_left -= utfptr - *from;
  669. *from = utfptr;
  670. *to_left -= bufptr - *to;
  671. *to = bufptr;
  672. return 0;
  673. } else {
  674. pdata = pdata->next;
  675. continue;
  676. }
  677. } else {
  678. utfptr = p;
  679. if(!tmpcharset) tmpcharset = pdata->charset;
  680. }
  681. if(r < 128) {
  682. *bufptr++ = r;
  683. buf_len--;
  684. } else {
  685. switch(pdata->type) {
  686. case N11n_ja:
  687. *bufptr++ = (r/100 + ' ');
  688. *bufptr++ = (r%100 + ' ');
  689. break;
  690. case N11n_ko:
  691. *bufptr++ = (r/94 + 0x21);
  692. *bufptr++ = (r%94 + 0x21);
  693. break;
  694. case N11n_zh:
  695. *bufptr++ = 0x20 + (r/100);
  696. *bufptr++ = 0x20 + (r%100);
  697. break;
  698. default:
  699. break;
  700. }
  701. buf_len -= 2;
  702. }
  703. break;
  704. }
  705. if(!tmpcharset) return (-1); /* Unknown Codepoint */
  706. }
  707. }
  708. }
  709. static int
  710. utf1tocs(
  711. XlcConv conv,
  712. char **from,
  713. int *from_left,
  714. char **to,
  715. int *to_left,
  716. XPointer *args,
  717. int num_args)
  718. {
  719. char **ptr = NULL;
  720. char char_ptr[UTFmax];
  721. int i = 0;
  722. unsigned long dummy = (unsigned long)0;
  723. if (from == NULL || *from == NULL)
  724. return utftocs(conv, from, from_left, to, to_left, args, num_args);
  725. ptr = from;
  726. for(i = 0; i < UTFmax; char_ptr[i++] = *(*ptr)++);
  727. i=0;
  728. while(our_mbtowc(&dummy, (char*)&char_ptr[0], i) <= 0)
  729. i++;
  730. utftocs(conv, from, &i, to, to_left, args, num_args);
  731. }
  732. static int
  733. ucstocs(
  734. XlcConv conv,
  735. XPointer *from,
  736. int *from_left,
  737. char **to,
  738. int *to_left,
  739. XPointer *args,
  740. int num_args)
  741. {
  742. wchar_t *ucsptr;
  743. char *bufptr;
  744. int ucs_len, buf_len;
  745. XlcCharSet tmpcharset = (XlcCharSet)NULL;
  746. UtfData pdata = utfdata_list;
  747. if (from == NULL || *from == NULL)
  748. return 0;
  749. ucsptr = (wchar_t *)*from;
  750. bufptr = *to;
  751. ucs_len = *from_left;
  752. buf_len = *to_left;
  753. while(ucs_len > 0 && buf_len > 0) {
  754. while(pdata->next) {
  755. long r;
  756. long *tbl;
  757. tbl = pdata->fromtbl;
  758. tbl += *ucsptr;
  759. if((r = *tbl) == -1) {
  760. if(tmpcharset) {
  761. if((num_args > 0) && tmpcharset)
  762. *((XlcCharSet *) args[0]) = tmpcharset;
  763. *from_left -= ucsptr - (wchar_t *)*from;
  764. *from = (XPointer)ucsptr;
  765. *to_left -= bufptr - *to;
  766. *to = bufptr;
  767. return 0;
  768. } else {
  769. pdata = pdata->next;
  770. continue;
  771. }
  772. } else {
  773. if(!tmpcharset) tmpcharset = pdata->charset;
  774. }
  775. ucsptr++;
  776. if(r < 128) {
  777. *bufptr++ = r;
  778. ucs_len--;
  779. buf_len--;
  780. } else {
  781. switch(pdata->type) {
  782. case N11n_ja:
  783. *bufptr++ = (r/100 + ' ');
  784. *bufptr++ = (r%100 + ' ');
  785. break;
  786. case N11n_ko:
  787. *bufptr++ = (r/94 + 0x21);
  788. *bufptr++ = (r%94 + 0x21);
  789. break;
  790. case N11n_zh:
  791. *bufptr++ = 0x20 + (r/100);
  792. *bufptr++ = 0x20 + (r%100);
  793. break;
  794. default:
  795. break;
  796. }
  797. ucs_len--;
  798. buf_len -= 2;
  799. }
  800. break;
  801. }
  802. if(!tmpcharset) return (-1); /* Unknown Codepoint */
  803. }
  804. }
  805. static long
  806. getutfrune(char **read_from, int *from_len)
  807. {
  808. int c, i;
  809. char str[UTFmax]; /* MB_LEN_MAX really */
  810. unsigned long l;
  811. int n;
  812. str[0] = '\0';
  813. for(i = 0; i <= UTFmax;) {
  814. c = **read_from;
  815. (*read_from)++;
  816. str[i++] = c;
  817. n = our_mbtowc(&l, str, i);
  818. if(n == -1)
  819. return(-2);
  820. if(n > 0) {
  821. *from_len -= n;
  822. return(l);
  823. }
  824. }
  825. return(-2);
  826. }
  827. static
  828. cstoutf(
  829. XlcConv conv,
  830. char **from,
  831. int *from_left,
  832. char **to,
  833. int *to_left,
  834. XPointer *args,
  835. int num_args)
  836. {
  837. XlcCharSet charset;
  838. char *csptr, *utfptr;
  839. int csstr_len, utf_len;
  840. int cmp_len = 0;
  841. void (*putrune)(
  842. unsigned char c,
  843. Rune *r
  844. ) = NULL;
  845. Rune r = (Rune)0;
  846. UtfData pdata = utfdata_list;
  847. if (from == NULL || *from == NULL)
  848. return 0;
  849. if (num_args < 1)
  850. return -1;
  851. csptr = *from;
  852. utfptr = *to;
  853. csstr_len = *from_left;
  854. utf_len = *to_left;
  855. charset = (XlcCharSet)args[0];
  856. cmp_len = strchr(charset->name, ':') - charset->name;
  857. while(pdata->next) {
  858. if(!_fallcNCompareISOLatin1(charset->name, pdata->charset->name, cmp_len)) {
  859. putrune = pdata->cstorune;
  860. break;
  861. } else {
  862. pdata = pdata->next;
  863. }
  864. }
  865. if(!putrune)
  866. return -1;
  867. while(csstr_len-- > 0 && utf_len > 0) {
  868. (*putrune)(*csptr++, &r);
  869. if(!r) {
  870. continue;
  871. }
  872. our_wctomb(r, &utfptr, &utf_len);
  873. r = 0;
  874. }
  875. *from_left -= csptr - *from;
  876. *from = csptr;
  877. *to_left -= utfptr - *to;
  878. *to = utfptr;
  879. return 0;
  880. }
  881. static
  882. cstoucs(
  883. XlcConv conv,
  884. char **from,
  885. int *from_left,
  886. XPointer *to,
  887. int *to_left,
  888. XPointer *args,
  889. int num_args)
  890. {
  891. XlcCharSet charset;
  892. char *csptr;
  893. wchar_t *ucsptr;
  894. int csstr_len, ucs_len;
  895. int cmp_len = 0;
  896. void (*putrune)(
  897. unsigned char c,
  898. Rune *r
  899. ) = NULL;
  900. Rune r = (Rune)0;
  901. UtfData pdata = utfdata_list;
  902. if (from == NULL || *from == NULL)
  903. return 0;
  904. if (num_args < 1)
  905. return -1;
  906. csptr = *from;
  907. ucsptr = (wchar_t *)*to;
  908. csstr_len = *from_left;
  909. ucs_len = *to_left;
  910. charset = (XlcCharSet)args[0];
  911. cmp_len = strchr(charset->name, ':') - charset->name;
  912. while(pdata->next) {
  913. if(!_fallcNCompareISOLatin1(charset->name, pdata->charset->name, cmp_len)) {
  914. putrune = pdata->cstorune;
  915. break;
  916. } else {
  917. pdata = pdata->next;
  918. }
  919. }
  920. if(!putrune)
  921. return -1;
  922. while(csstr_len-- > 0 && ucs_len > 0) {
  923. (*putrune)(*csptr++, &r);
  924. if(!r) {
  925. continue;
  926. }
  927. *ucsptr = (long)r;
  928. ucsptr++;
  929. ucs_len--;
  930. r = 0;
  931. }
  932. *from_left -= csptr - *from;
  933. *from = csptr;
  934. *to_left -= ucsptr - (wchar_t *)*to;
  935. *to = (XPointer)ucsptr;
  936. return 0;
  937. }
  938. static void
  939. our_wctomb(Rune r, char **utfptr, int *utf_len)
  940. {
  941. long l = (long)r;
  942. if(!utfptr || !*utfptr)
  943. return; /* no shift states */
  944. if(l & ~Wchar2) {
  945. if(l & ~Wchar4) {
  946. if(l & ~Wchar5) {
  947. /* 6 bytes */
  948. *(*utfptr)++ = T6 | ((l >> 5*Bitx) & Mask6);
  949. *(*utfptr)++ = Tx | ((l >> 4*Bitx) & Maskx);
  950. *(*utfptr)++ = Tx | ((l >> 3*Bitx) & Maskx);
  951. *(*utfptr)++ = Tx | ((l >> 2*Bitx) & Maskx);
  952. *(*utfptr)++ = Tx | ((l >> 1*Bitx) & Maskx);
  953. *(*utfptr)++ = Tx | (l & Maskx);
  954. *utf_len -= 6;
  955. return;
  956. }
  957. /* 5 bytes */
  958. *(*utfptr)++ = T5 | (l >> 4*Bitx);
  959. *(*utfptr)++ = Tx | ((l >> 3*Bitx) & Maskx);
  960. *(*utfptr)++ = Tx | ((l >> 2*Bitx) & Maskx);
  961. *(*utfptr)++ = Tx | ((l >> 1*Bitx) & Maskx);
  962. *(*utfptr)++ = Tx | (l & Maskx);
  963. *utf_len -= 5;
  964. return;
  965. }
  966. if(l & ~Wchar3) {
  967. /* 4 bytes */
  968. *(*utfptr)++ = T4 | (l >> 3*Bitx);
  969. *(*utfptr)++ = Tx | ((l >> 2*Bitx) & Maskx);
  970. *(*utfptr)++ = Tx | ((l >> 1*Bitx) & Maskx);
  971. *(*utfptr)++ = Tx | (l & Maskx);
  972. *utf_len -= 4;
  973. return;
  974. }
  975. /* 3 bytes */
  976. *(*utfptr)++ = T3 | (l >> 2*Bitx);
  977. *(*utfptr)++ = Tx | ((l >> 1*Bitx) & Maskx);
  978. *(*utfptr)++ = Tx | (l & Maskx);
  979. *utf_len -= 3;
  980. return;
  981. }
  982. if(l & ~Wchar1) {
  983. /* 2 bytes */
  984. *(*utfptr)++ = T2 | (l >> 1*Bitx);
  985. *(*utfptr)++ = Tx | (l & Maskx);
  986. *utf_len -= 2;
  987. return;
  988. }
  989. /* 1 byte */
  990. *(*utfptr)++ = T1 | l;
  991. *utf_len -= 1;
  992. return;
  993. }
  994. static void
  995. latin2rune(unsigned char c, Rune *r)
  996. {
  997. *r = (Rune)c;
  998. return;
  999. }
  1000. static void
  1001. ksc2rune(unsigned char c, Rune *r)
  1002. {
  1003. static enum { init, cs1last} state = init;
  1004. static int korean646 = 1; /* fixed to 1 for now. */
  1005. static int lastc;
  1006. unsigned char ch = (c|0x80); /* XXX */
  1007. int n;
  1008. long l;
  1009. switch(state)
  1010. {
  1011. case init:
  1012. if (ch < 128){
  1013. if(korean646 && (ch=='\\')){
  1014. emit(0x20A9);
  1015. } else {
  1016. emit(ch);
  1017. }
  1018. }else{
  1019. lastc = ch;
  1020. state = cs1last;
  1021. }
  1022. return;
  1023. case cs1last: /* 2nd byte of codeset 1 (KSC 5601) */
  1024. n = ((lastc&0x7f)-33)*94 + (ch&0x7f)-33;
  1025. if((l = tabksc5601[n]) == 0){
  1026. emit(BADMAP);
  1027. } else {
  1028. emit(l);
  1029. }
  1030. state = init;
  1031. return;
  1032. }
  1033. }
  1034. static void
  1035. jis02012rune(unsigned char c, Rune *r)
  1036. {
  1037. /* To Be Implemented */
  1038. }
  1039. static void
  1040. gb2rune(unsigned char c, Rune *r)
  1041. {
  1042. static enum { state0, state1 } state = state0;
  1043. static int lastc;
  1044. long n, ch;
  1045. unsigned char ch1 = (c|0x80); /* XXX */
  1046. switch(state)
  1047. {
  1048. case state0: /* idle state */
  1049. if(ch1 >= 0xA1){
  1050. lastc = ch1;
  1051. state = state1;
  1052. return;
  1053. }
  1054. emit(ch1);
  1055. return;
  1056. case state1: /* seen a font spec */
  1057. if(ch1 >= 0xA1)
  1058. n = (lastc-0xA0)*100 + (ch1-0xA0);
  1059. else {
  1060. emit(BADMAP);
  1061. state = state0;
  1062. return;
  1063. }
  1064. ch = tabgb[n];
  1065. if(ch < 0){
  1066. emit(BADMAP);
  1067. } else
  1068. emit(ch);
  1069. state = state0;
  1070. }
  1071. }
  1072. static void
  1073. jis02082rune(unsigned char c, Rune *r)
  1074. {
  1075. static enum { state0, state1} state = state0;
  1076. static int lastc;
  1077. unsigned char ch = (c|0x80); /* XXX */
  1078. int n, again;
  1079. long l;
  1080. do {
  1081. again = 0;
  1082. switch(state)
  1083. {
  1084. case state0: /* idle state */
  1085. lastc = ch;
  1086. state = state1;
  1087. return;
  1088. case state1: /* two part char */
  1089. if((lastc&0x80) != (ch&0x80)){
  1090. emit(lastc);
  1091. state = state0;
  1092. again += 1;
  1093. }
  1094. if(CANS2J(lastc, ch)){
  1095. int h = lastc, l = ch;
  1096. S2J(h, l);
  1097. n = h*100 + l - 3232;
  1098. } else
  1099. n = (lastc&0x7F)*100 + (ch&0x7f) - 3232; /* kuten */
  1100. if((l = tabkuten[n]) == -1){
  1101. emit(BADMAP);
  1102. } else {
  1103. if(l < 0){
  1104. l = -l;
  1105. }
  1106. emit(l);
  1107. }
  1108. state = state0;
  1109. }
  1110. } while (again == 1);
  1111. }
  1112. static int
  1113. our_mbtowc(unsigned long *p, char *s, size_t n)
  1114. {
  1115. unsigned char *us;
  1116. int c0, c1, c2, c3, c4, c5;
  1117. unsigned long wc;
  1118. if(s == 0)
  1119. return 0; /* no shift states */
  1120. if(n < 1)
  1121. return -2; /* bad length */
  1122. us = (unsigned char*)s;
  1123. c0 = us[0];
  1124. if(c0 >= T3) {
  1125. if(n < 3)
  1126. return -2;
  1127. c1 = us[1] ^ Tx;
  1128. c2 = us[2] ^ Tx;
  1129. if((c1|c2) & T2) {
  1130. errno = EILSEQ;
  1131. return -1;
  1132. }
  1133. if(c0 >= T5) {
  1134. if(n < 5)
  1135. return -2;
  1136. c3 = us[3] ^ Tx;
  1137. c4 = us[4] ^ Tx;
  1138. if((c3|c4) & T2) {
  1139. errno = EILSEQ;
  1140. return -1;
  1141. }
  1142. if(c0 >= T6) {
  1143. /* 6 bytes */
  1144. if(n < 6)
  1145. return -2;
  1146. c5 = us[5] ^ Tx;
  1147. if(c5 & T2) {
  1148. errno = EILSEQ;
  1149. return -1;
  1150. }
  1151. wc = ((((((((((c0 & Mask6) << Bitx) |
  1152. c1) << Bitx) | c2) << Bitx) |
  1153. c3) << Bitx) | c4) << Bitx) | c5;
  1154. if(wc <= Wchar5) {
  1155. errno = EILSEQ;
  1156. return -1;
  1157. }
  1158. *p = wc;
  1159. return 6;
  1160. }
  1161. /* 5 bytes */
  1162. wc = ((((((((c0 & Mask5) << Bitx) |
  1163. c1) << Bitx) | c2) << Bitx) |
  1164. c3) << Bitx) | c4;
  1165. if(wc <= Wchar4) {
  1166. errno = EILSEQ;
  1167. return -1;
  1168. }
  1169. *p = wc;
  1170. return 5;
  1171. }
  1172. if(c0 >= T4) {
  1173. /* 4 bytes */
  1174. if(n < 4)
  1175. return -2;
  1176. c3 = us[3] ^ Tx;
  1177. if(c3 & T2) {
  1178. errno = EILSEQ;
  1179. return -1;
  1180. }
  1181. wc = ((((((c0 & Mask4) << Bitx) |
  1182. c1) << Bitx) | c2) << Bitx) |
  1183. c3;
  1184. if(wc <= Wchar3) {
  1185. errno = EILSEQ;
  1186. return -1;
  1187. }
  1188. *p = wc;
  1189. return 4;
  1190. }
  1191. /* 3 bytes */
  1192. wc = ((((c0 & Mask3) << Bitx) |
  1193. c1) << Bitx) | c2;
  1194. if(wc <= Wchar2) {
  1195. errno = EILSEQ;
  1196. return -1;
  1197. }
  1198. *p = wc;
  1199. return 3;
  1200. }
  1201. if(c0 >= T2) {
  1202. /* 2 bytes */
  1203. if(n < 2)
  1204. return -2;
  1205. c1 = us[1] ^ Tx;
  1206. if(c1 & T2) {
  1207. errno = EILSEQ;
  1208. return -1;
  1209. }
  1210. wc = ((c0 & Mask2) << Bitx) |
  1211. c1;
  1212. if(wc <= Wchar1) {
  1213. errno = EILSEQ;
  1214. return -1;
  1215. }
  1216. *p = wc;
  1217. return 2;
  1218. }
  1219. /* 1 byte */
  1220. if(c0 >= Tx) {
  1221. errno = EILSEQ;
  1222. return -1;
  1223. }
  1224. *p = c0;
  1225. return 1;
  1226. }
  1227. static void
  1228. close_converter(XlcConv conv)
  1229. {
  1230. Xfree((char *) conv);
  1231. }
  1232. static XlcConv
  1233. create_conv(XLCd lcd, XlcConvMethods methods)
  1234. {
  1235. XlcConv conv;
  1236. conv = (XlcConv) Xmalloc(sizeof(XlcConvRec));
  1237. if (conv == (XlcConv) NULL)
  1238. return (XlcConv) NULL;
  1239. conv->methods = methods;
  1240. conv->state = NULL;
  1241. _XlcInitUTFInfo(lcd);
  1242. return conv;
  1243. /* if an error occurs somewhere
  1244. close_converter(conv);
  1245. return (XlcConv) NULL;
  1246. */
  1247. }
  1248. static XlcConvMethodsRec mbtocs_methods = {
  1249. close_converter,
  1250. utf1tocs,
  1251. NULL
  1252. };
  1253. static XlcConv
  1254. open_mbtocs(XLCd from_lcd, char *from, XLCd to_lcd, char *to)
  1255. {
  1256. return create_conv(from_lcd, &mbtocs_methods);
  1257. }
  1258. static XlcConvMethodsRec mbstocs_methods = {
  1259. close_converter,
  1260. utftocs,
  1261. NULL
  1262. };
  1263. static XlcConv
  1264. open_mbstocs(XLCd from_lcd, char *from, XLCd to_lcd, char *to)
  1265. {
  1266. return create_conv(from_lcd, &mbstocs_methods);
  1267. }
  1268. static XlcConvMethodsRec wcstocs_methods = {
  1269. close_converter,
  1270. ucstocs,
  1271. NULL
  1272. };
  1273. static XlcConv
  1274. open_wcstocs(XLCd from_lcd, char *from, XLCd to_lcd, char *to)
  1275. {
  1276. return create_conv(from_lcd, &wcstocs_methods);
  1277. }
  1278. static XlcConvMethodsRec cstombs_methods = {
  1279. close_converter,
  1280. cstoutf,
  1281. NULL
  1282. };
  1283. static XlcConv
  1284. open_cstombs(XLCd from_lcd, char *from, XLCd to_lcd, char *to)
  1285. {
  1286. return create_conv(from_lcd, &cstombs_methods);
  1287. }
  1288. static XlcConvMethodsRec cstowcs_methods = {
  1289. close_converter,
  1290. cstoucs,
  1291. NULL
  1292. };
  1293. static XlcConv
  1294. open_cstowcs(XLCd from_lcd, char *from, XLCd to_lcd, char *to)
  1295. {
  1296. return create_conv(from_lcd, &cstowcs_methods);
  1297. }
  1298. XLCd
  1299. _fallcUtfLoader(char *name)
  1300. {
  1301. XLCd lcd;
  1302. lcd = _fallcCreateLC(name, _fallcGenericMethods);
  1303. if (lcd == (XLCd) NULL)
  1304. return lcd;
  1305. if ((_fallcCompareISOLatin1(XLC_PUBLIC_PART(lcd)->codeset, "utf"))) {
  1306. _fallcDestroyLC(lcd);
  1307. return (XLCd) NULL;
  1308. }
  1309. _fallcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs);
  1310. _fallcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs);
  1311. _fallcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs);
  1312. _fallcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs);
  1313. _fallcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs);
  1314. return lcd;
  1315. }