20 #include "map/ucs_wide.map"
21 #include "map/ucs_combining.map"
22 #include "map/ucs_precompose.map"
23 #include "map/ucs_hangul.map"
24 #include "map/ucs_fullwidth.map"
26 #define MAX_TAG_MAP 0x100
27 static int n_tag_map = 0;
28 static char *tag_map[ MAX_TAG_MAP ];
31 wc_get_ucs_table(wc_ccs ccs)
33 int f = WC_CCS_INDEX(ccs);
35 switch (WC_CCS_TYPE(ccs)) {
37 if (f < WC_F_ISO_BASE || f > WC_F_CS94_END)
39 return &ucs_cs94_table[f - WC_F_ISO_BASE];
41 if (f < WC_F_ISO_BASE || f > WC_F_CS94W_END)
43 return &ucs_cs94w_table[f - WC_F_ISO_BASE];
45 if (f < WC_F_ISO_BASE || f > WC_F_CS96_END)
47 return &ucs_cs96_table[f - WC_F_ISO_BASE];
49 if (f < WC_F_ISO_BASE || f > WC_F_CS96W_END)
51 return &ucs_cs96w_table[f - WC_F_ISO_BASE];
53 if (f < WC_F_ISO_BASE || f > WC_F_CS942_END)
55 return &ucs_cs942_table[f - WC_F_ISO_BASE];
57 if (f < WC_F_PCS_BASE || f > WC_F_PCS_END)
59 return &ucs_pcs_table[f - WC_F_PCS_BASE];
61 if (f < WC_F_PCS_BASE || f > WC_F_PCSW_END)
63 return &ucs_pcsw_table[f - WC_F_PCS_BASE];
70 wc_ucs_to_any(wc_uint32 ucs, wc_table *t)
75 if (t && t->map && ucs && ucs <= WC_C_UCS2_END) {
76 map = wc_map_search((wc_uint16)ucs, t->map, t->n);
78 return t->conv(t->ccs, map->code2);
80 if (t && (ucs & ~0xFFFF) == WC_C_UCS4_PLANE2) {
81 if (t->ccs == WC_CCS_JIS_X_0213_1)
82 map = wc_map_search((wc_uint16)(ucs & 0xffff),
83 ucs_p2_jisx02131_map, N_ucs_p2_jisx02131_map);
84 else if (t->ccs == WC_CCS_JIS_X_0213_2)
85 map = wc_map_search((wc_uint16)(ucs & 0xffff),
86 ucs_p2_jisx02132_map, N_ucs_p2_jisx02132_map);
87 else if (t->ccs == WC_CCS_HKSCS ||
88 t->ccs == WC_CCS_HKSCS_1 || t->ccs == WC_CCS_HKSCS_2)
89 map = wc_map_search((wc_uint16)(ucs & 0xffff),
90 ucs_p2_hkscs_map, N_ucs_p2_hkscs_map);
94 return t->conv(t->ccs, map->code2);
96 cc.ccs = WC_CCS_UNKNOWN;
101 wc_any_to_ucs(wc_wchar_t cc)
104 wc_uint16 *map = NULL;
107 f = WC_CCS_INDEX(cc.ccs);
108 switch (WC_CCS_TYPE(cc.ccs)) {
110 if (f < WC_F_ISO_BASE || f > WC_F_CS94_END)
111 return WC_C_UCS4_ERROR;
112 map = cs94_ucs_map[f - WC_F_ISO_BASE];
116 if (cc.ccs == WC_CCS_GB_2312 && WcOption.use_gb12345_map) {
117 cc.ccs = WC_CCS_GB_12345;
118 return wc_any_to_ucs(cc);
119 } else if (cc.ccs == WC_CCS_JIS_X_0213_1) {
120 map2 = wc_map_search((wc_uint16)(cc.code & 0x7f7f),
121 jisx02131_ucs_p2_map, N_jisx02131_ucs_p2_map);
123 return map2->code2 | WC_C_UCS4_PLANE2;
124 } else if (cc.ccs == WC_CCS_JIS_X_0213_2) {
125 map2 = wc_map_search((wc_uint16)(cc.code & 0x7f7f),
126 jisx02132_ucs_p2_map, N_jisx02132_ucs_p2_map);
128 return map2->code2 | WC_C_UCS4_PLANE2;
130 if (f < WC_F_ISO_BASE || f > WC_F_CS94W_END)
132 map = cs94w_ucs_map[f - WC_F_ISO_BASE];
133 cc.code = WC_CS94W_N(cc.code);
136 if (f < WC_F_ISO_BASE || f > WC_F_CS96_END)
137 return WC_C_UCS4_ERROR;
138 map = cs96_ucs_map[f - WC_F_ISO_BASE];
142 if (f < WC_F_ISO_BASE || f > WC_F_CS96W_END)
143 return WC_C_UCS4_ERROR;
144 map = cs96w_ucs_map[f - WC_F_ISO_BASE];
145 cc.code = WC_CS96W_N(cc.code);
148 if (f < WC_F_ISO_BASE || f > WC_F_CS942_END)
149 return WC_C_UCS4_ERROR;
150 map = cs942_ucs_map[f - WC_F_ISO_BASE];
154 if (f < WC_F_PCS_BASE || f > WC_F_PCS_END)
155 return WC_C_UCS4_ERROR;
157 case WC_CCS_CP1258_2:
158 map2 = wc_map_search((wc_uint16)cc.code,
159 cp12582_ucs_map, N_cp12582_ucs_map);
162 return WC_C_UCS4_ERROR;
163 case WC_CCS_TCVN_5712_3:
164 return wc_any_to_ucs(wc_tcvn57123_to_tcvn5712(cc));
166 return WC_C_UCS2_EURO;
168 map = pcs_ucs_map[f - WC_F_PCS_BASE];
172 if (f < WC_F_PCS_BASE || f > WC_F_PCSW_END)
173 return WC_C_UCS4_ERROR;
174 map = pcsw_ucs_map[f - WC_F_PCS_BASE];
177 cc.code = WC_BIG5_N(cc.code);
180 cc.code = WC_CS94W_N(cc.code) + WC_C_BIG5_2_BASE;
184 cc = wc_cs128w_to_hkscs(cc);
186 map2 = wc_map_search((wc_uint16)cc.code,
187 hkscs_ucs_p2_map, N_hkscs_ucs_p2_map);
189 return map2->code2 | WC_C_UCS4_PLANE2;
190 cc.code = wc_hkscs_to_N(cc.code);
193 return wc_any_to_ucs(wc_johab_to_cs128w(cc));
195 return WC_CS94x128_N(cc.code) + WC_C_UCS2_HANGUL;
197 cc.code = WC_CS128W_N(cc.code);
198 cc.code = WC_N_JOHAB2(cc.code);
199 map2 = wc_map_search((wc_uint16)cc.code,
200 johab2_ucs_map, N_johab2_ucs_map);
203 return WC_C_UCS4_ERROR;
205 if ((cc.code & 0x7f7f) < 0x2121)
206 return WC_C_UCS4_ERROR;
207 case WC_CCS_SJIS_EXT:
208 return wc_any_to_ucs(wc_sjis_ext_to_cs94w(cc));
209 case WC_CCS_SJIS_EXT_1:
210 cc.code = wc_sjis_ext1_to_N(cc.code);
211 if (cc.code == WC_C_SJIS_ERROR)
212 return WC_C_UCS4_ERROR;
214 case WC_CCS_SJIS_EXT_2:
215 cc.code = wc_sjis_ext2_to_N(cc.code);
216 if (cc.code == WC_C_SJIS_ERROR)
217 return WC_C_UCS4_ERROR;
221 cc = wc_cs128w_to_gbk(cc);
223 cc.code = wc_gbk_to_N(cc.code);
226 case WC_CCS_GBK_EXT_1:
227 case WC_CCS_GBK_EXT_2:
228 return wc_gb18030_to_ucs(cc);
231 cc = wc_cs128w_to_uhc(cc);
233 if (cc.code > WC_C_UHC_END)
234 return WC_C_UCS4_ERROR;
235 cc.code = wc_uhc_to_N(cc.code);
238 cc.code = WC_CS94W_N(cc.code);
243 switch (WC_CCS_SET(cc.ccs)) {
247 return WC_C_UCS4_ERROR;
249 switch (WC_CCS_SET(cc.ccs)) {
253 return wc_ucs_tag_to_ucs(cc.code);
255 return wc_gb18030_to_ucs(cc);
257 return WC_C_UCS4_ERROR;
258 case WC_CCS_A_UNKNOWN:
259 if (cc.ccs == WC_CCS_C1)
260 return (cc.code | 0x80);
262 return WC_C_UCS4_ERROR;
265 return WC_C_UCS4_ERROR;
266 cc.code = map[cc.code];
267 return cc.code ? cc.code : WC_C_UCS4_ERROR;
271 wc_any_to_any(wc_wchar_t cc, wc_table *t)
273 wc_ccs is_wide = WC_CCS_IS_WIDE(cc.ccs);
274 wc_uint32 ucs = wc_any_to_ucs(cc);
276 if (ucs != WC_C_UCS4_ERROR) {
277 cc = wc_ucs_to_any(ucs, t);
278 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
281 ucs = wc_ucs_to_fullwidth(ucs);
282 if (ucs != WC_C_UCS4_ERROR) {
283 cc = wc_ucs_to_any(ucs, t);
284 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
288 cc.ccs = is_wide ? WC_CCS_UNKNOWN_W : WC_CCS_UNKNOWN;
293 wc_ucs_to_any_list(wc_uint32 ucs, wc_table **tlist)
299 for (t = tlist; *t != NULL; t++) {
300 if ((*t)->map == NULL)
302 cc = wc_ucs_to_any(ucs, *t);
303 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
307 cc.ccs = WC_CCS_UNKNOWN;
312 wc_any_to_any_ces(wc_wchar_t cc, wc_status *st)
314 wc_uint32 ucs = wc_any_to_ucs(cc);
315 wc_ccs is_wide = WC_CCS_IS_WIDE(cc.ccs);
318 cc.ccs = WC_CCS_US_ASCII;
322 if (ucs != WC_C_UCS4_ERROR) {
323 if (st->ces_info->id & WC_CES_T_UTF) {
324 cc.ccs = wc_ucs_to_ccs(ucs);
327 } else if (st->ces_info->id == WC_CES_JOHAB) {
328 cc = wc_ucs_to_johab(ucs);
329 if (WC_CCS_IS_UNKNOWN(cc.ccs))
330 cc.ccs = is_wide ? WC_CCS_UNKNOWN_W : WC_CCS_UNKNOWN;
333 cc = wc_ucs_to_any_list(ucs, is_wide ? st->tlistw : st->tlist);
334 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
336 if (! WcOption.fix_width_conv) {
337 cc = wc_ucs_to_any_list(ucs, is_wide ? st->tlist : st->tlistw);
338 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
341 if (st->ces_info->id == WC_CES_GB18030) {
342 cc = wc_ucs_to_gb18030(ucs);
343 if (WC_CCS_IS_UNKNOWN(cc.ccs))
344 cc.ccs = is_wide ? WC_CCS_UNKNOWN_W : WC_CCS_UNKNOWN;
347 if (ucs == WC_C_UCS2_NBSP) { /* NBSP -> SP */
348 cc.ccs = WC_CCS_US_ASCII;
352 if (st->ces_info->id & (WC_CES_T_ISO_8859|WC_CES_T_EUC) &&
353 0x80 <= ucs && ucs <= 0x9F) {
359 ucs = wc_ucs_to_fullwidth(ucs);
360 if (ucs != WC_C_UCS4_ERROR) {
361 cc = wc_ucs_to_any_list(ucs, is_wide ? st->tlistw : st->tlist);
362 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
364 if (! WcOption.fix_width_conv) {
365 cc = wc_ucs_to_any_list(ucs, is_wide ? st->tlist : st->tlistw);
366 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
371 cc.ccs = is_wide ? WC_CCS_UNKNOWN_W : WC_CCS_UNKNOWN;
376 wc_any_to_iso2022(wc_wchar_t cc, wc_status *st)
378 wc_uint32 ucs = wc_any_to_ucs(cc);
379 wc_ccs is_wide = WC_CCS_IS_WIDE(cc.ccs);
382 cc.ccs = WC_CCS_US_ASCII;
386 if (ucs != WC_C_UCS4_ERROR) {
387 cc = wc_ucs_to_any_list(ucs, is_wide ? st->tlistw : st->tlist);
388 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
390 if (! WcOption.strict_iso2022) {
391 cc = (is_wide) ? wc_ucs_to_iso2022w(ucs) : wc_ucs_to_iso2022(ucs);
392 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
395 if (! WcOption.fix_width_conv) {
396 cc = wc_ucs_to_any_list(ucs, is_wide ? st->tlist : st->tlistw);
397 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
399 if (! WcOption.strict_iso2022) {
400 cc = (is_wide) ? wc_ucs_to_iso2022(ucs) : wc_ucs_to_iso2022w(ucs);
401 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
405 if (ucs == WC_C_UCS2_NBSP) { /* NBSP -> SP */
406 cc.ccs = WC_CCS_US_ASCII;
411 ucs = wc_ucs_to_fullwidth(ucs);
412 if (ucs != WC_C_UCS4_ERROR) {
413 cc = wc_ucs_to_any_list(ucs, is_wide ? st->tlistw : st->tlist);
414 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
416 if (! WcOption.strict_iso2022) {
417 cc = (is_wide) ? wc_ucs_to_iso2022w(ucs) : wc_ucs_to_iso2022(ucs);
418 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
421 if (! WcOption.fix_width_conv) {
422 cc = wc_ucs_to_any_list(ucs, is_wide ? st->tlist : st->tlistw);
423 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
425 if (! WcOption.strict_iso2022) {
426 cc = (is_wide) ? wc_ucs_to_iso2022(ucs) : wc_ucs_to_iso2022w(ucs);
427 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
432 if (ucs == WC_C_UCS2_NBSP) { /* NBSP -> SP */
433 cc.ccs = WC_CCS_US_ASCII;
438 cc.ccs = is_wide ? WC_CCS_UNKNOWN_W : WC_CCS_UNKNOWN;
443 wc_ucs_to_iso2022(wc_uint32 ucs)
449 if (ucs <= WC_C_UCS2_END) {
450 for (f = 0; f <= WC_F_CS96_END - WC_F_ISO_BASE; f++) {
451 t = &ucs_cs96_table[f];
454 cc = wc_ucs_to_any((wc_uint16)ucs, t);
455 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
458 for (f = 0; f <= WC_F_CS94_END - WC_F_ISO_BASE; f++) {
459 t = &ucs_cs94_table[f];
462 cc = wc_ucs_to_any((wc_uint16)ucs, t);
463 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
466 for (f = 0; f <= WC_F_CS942_END - WC_F_ISO_BASE; f++) {
467 t = &ucs_cs942_table[f];
470 cc = wc_ucs_to_any((wc_uint16)ucs, t);
471 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
475 cc.ccs = WC_CCS_UNKNOWN;
480 wc_ucs_to_iso2022w(wc_uint32 ucs)
486 if (ucs <= WC_C_UCS2_END) {
487 for (f = 0; f <= WC_F_CS94W_END - WC_F_ISO_BASE; f++) {
488 t = &ucs_cs94w_table[f];
491 cc = wc_ucs_to_any((wc_uint16)ucs, t);
492 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
495 for (f = 0; f <= WC_F_CS96W_END - WC_F_ISO_BASE; f++) {
496 t = &ucs_cs96w_table[f];
499 cc = wc_ucs_to_any((wc_uint16)ucs, t);
500 if (!WC_CCS_IS_UNKNOWN(cc.ccs))
504 cc.ccs = WC_CCS_UNKNOWN_W;
509 wc_ucs_to_ccs(wc_uint32 ucs)
511 if (0x80 <= ucs && ucs <= 0x9F)
513 return ((ucs <= WC_C_UCS2_END) ? WC_CCS_UCS2 : WC_CCS_UCS4)
514 | (wc_is_ucs_wide(ucs) ? WC_CCS_A_WIDE : 0)
515 | (wc_is_ucs_combining(ucs) ? WC_CCS_A_COMB : 0);
519 wc_is_ucs_wide(wc_uint32 ucs)
521 if (ucs <= WC_C_UCS2_END)
522 return (wc_map_range_search((wc_uint16)ucs,
523 ucs_wide_map, N_ucs_wide_map) != NULL);
525 return ((ucs & ~0xFFFF) == WC_C_UCS4_PLANE2 ||
526 (ucs & ~0xFFFF) == WC_C_UCS4_PLANE3);
530 wc_is_ucs_combining(wc_uint32 ucs)
532 return (WcOption.use_combining && ucs <= WC_C_UCS2_END &&
533 wc_map_range_search((wc_uint16)ucs,
534 ucs_combining_map, N_ucs_combining_map) != NULL);
538 wc_is_ucs_hangul(wc_uint32 ucs)
540 return (ucs <= WC_C_UCS2_END &&
541 wc_map_range_search((wc_uint16)ucs,
542 ucs_hangul_map, N_ucs_hangul_map) != NULL);
546 wc_ucs_precompose(wc_uint32 ucs1, wc_uint32 ucs2)
550 if (WcOption.use_combining &&
551 ucs1 <= WC_C_UCS2_END && ucs2 <= WC_C_UCS2_END &&
552 (map = wc_map3_search((wc_uint16)ucs1, (wc_uint16)ucs2,
553 ucs_precompose_map, N_ucs_precompose_map)) != NULL)
555 return WC_C_UCS4_ERROR;
559 wc_ucs_to_fullwidth(wc_uint32 ucs)
563 if (ucs <= WC_C_UCS2_END &&
564 (map = wc_map_search((wc_uint16)ucs,
565 ucs_fullwidth_map, N_ucs_fullwidth_map)) != NULL)
567 return WC_C_UCS4_ERROR;
571 wc_ucs_put_tag(char *p)
575 if (p == NULL || *p == '\0')
577 for (i = 1; i <= n_tag_map; i++) {
578 if (!strcasecmp(p, tag_map[i]))
582 if (n_tag_map == MAX_TAG_MAP)
584 tag_map[n_tag_map] = p;
589 wc_ucs_get_tag(int ntag)
591 if (ntag == 0 || ntag > n_tag_map)
593 return tag_map[ntag];
597 wtf_push_ucs(Str os, wc_uint32 ucs, wc_status *st)
601 if (ucs >= WC_C_LANGUAGE_TAG0 && ucs <= WC_C_CANCEL_TAG) {
602 if (! WcOption.use_language_tag)
604 if (ucs == WC_C_LANGUAGE_TAG)
605 st->tag = Strnew_size(4);
606 else if (ucs == WC_C_CANCEL_TAG) {
609 } else if (st->tag && ucs >= WC_C_TAG_SPACE)
610 Strcat_char(st->tag, (char)(ucs & 0x7f));
614 st->ntag = wc_ucs_put_tag(st->tag->ptr);
619 wtf_push(os, WC_CCS_UCS_TAG, wc_ucs_to_ucs_tag(ucs, st->ntag));
621 Strcat_char(os, (char)ucs);
623 ccs = wc_ucs_to_ccs(ucs);
624 if (st->ntag && ucs <= WC_C_UNICODE_END) {
625 ccs = wc_ccs_ucs_to_ccs_ucs_tag(ccs);
626 ucs = wc_ucs_to_ucs_tag(ucs, st->ntag);
628 wtf_push(os, ccs, ucs);