home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / evbl0627.zip / everblue_20010627.zip / x11 / Xlc_UTF.c < prev    next >
C/C++ Source or Header  |  1999-11-02  |  34KB  |  1,588 lines

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