SCO ACS patch from RDB. Apparently required for the Linux console
[sgt/putty] / unicode.c
CommitLineData
4eeb7d09 1#include <windows.h>
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <ctype.h>
6
7#include <time.h>
8#include "putty.h"
9
10void init_ucs_tables(void);
11void lpage_send(int codepage, char *buf, int len);
12void luni_send(wchar_t * widebuf, int len);
13
14static void get_unitab(int codepage, wchar_t * unitab, int ftype);
15
16/* Character conversion arrays; they are usually taken from windows,
17 * the xterm one has the four scanlines that have no unicode 2.0
18 * equlivents mapped into the private area.
19 */
20static char **uni_tbl;
21
22static WCHAR unitab_xterm_std[32] = {
23 0x2666, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
24 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
25 0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
26 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x0020
27};
28
29extern struct cp_list_item {
30 char *name;
31 int codepage;
32 int cp_size;
33 wchar_t *cp_table;
34} cp_list[];
35
36static void link_font(WCHAR * line_tbl, WCHAR * font_tbl, WCHAR attr);
37
38void init_ucs_tables(void)
39{
40 int i, j;
41 int used_dtf = 0;
42 char tbuf[256];
43 for (i = 0; i < 256; i++)
44 tbuf[i] = i;
45
46 /* Decide on the Line and Font codepages */
47 line_codepage = decode_codepage(cfg.line_codepage);
48
49 if (cfg.vtmode == VT_OEMONLY) {
50 font_codepage = 437;
51 dbcs_screenfont = 0;
52 if (line_codepage <= 0)
53 line_codepage = GetACP();
54 } else if (line_codepage <= 0)
55 line_codepage = font_codepage;
56 utf = (line_codepage == CP_UTF8);
57
58 /* Collect screen font ucs table */
59 if (dbcs_screenfont) {
60 get_unitab(font_codepage, unitab_font, 2);
61 for (i = 128; i < 256; i++)
62 unitab_font[i] = (WCHAR) (ATTR_ACP + i);
63 } else {
64 get_unitab(font_codepage, unitab_font, 1);
65
66 /* CP437 fonts are often broken ... */
67 if (font_codepage == 437)
68 unitab_font[0] = unitab_font[255] = 0xFFFF;
69 }
70 if (cfg.vtmode == VT_XWINDOWS)
71 memcpy(unitab_font + 1, unitab_xterm_std,
72 sizeof(unitab_xterm_std));
73
74 /* Collect OEMCP ucs table */
75 get_unitab(CP_OEMCP, unitab_oemcp, 1);
76
d3cb5465 77 /* Collect CP437 ucs table for SCO acs */
78 if (cfg.vtmode == VT_OEMANSI || cfg.vtmode == VT_XWINDOWS)
79 memcpy(unitab_scoacs, unitab_oemcp, sizeof(unitab_scoacs));
80 else
81 get_unitab(437, unitab_scoacs, 1);
82
4eeb7d09 83 /* Collect line set ucs table */
84 if (line_codepage == font_codepage &&
85 (dbcs_screenfont || cfg.vtmode == VT_POORMAN)) {
86
87 /* For DBCS and POOR fonts force direct to font */
88 used_dtf = 1;
89 for (i = 0; i < 32; i++)
90 unitab_line[i] = (WCHAR) i;
91 for (i = 32; i < 256; i++)
92 unitab_line[i] = (WCHAR) (ATTR_ACP + i);
93 unitab_line[127] = (WCHAR) 127;
94 } else {
95 get_unitab(line_codepage, unitab_line, 0);
96 }
97
98#if 0
99 debug(
100 ("Line cp%d, Font cp%d%s\n", line_codepage, font_codepage,
101 dbcs_screenfont ? " DBCS" : ""));
102
103 for (i = 0; i < 256; i += 16) {
104 for (j = 0; j < 16; j++) {
105 debug(("%04x%s", unitab_line[i + j], j == 15 ? "" : ","));
106 }
107 debug(("\n"));
108 }
109#endif
110
111 /* VT100 graphics - NB: Broken for non-ascii CP's */
112 memcpy(unitab_xterm, unitab_line, sizeof(unitab_xterm));
113 memcpy(unitab_xterm + '`', unitab_xterm_std, sizeof(unitab_xterm_std));
114 unitab_xterm['_'] = ' ';
115
116 /* Generate UCS ->line page table. */
117 if (uni_tbl) {
118 for (i = 0; i < 256; i++)
119 if (uni_tbl[i])
120 sfree(uni_tbl[i]);
121 sfree(uni_tbl);
122 uni_tbl = 0;
123 }
124 if (!used_dtf) {
125 for (i = 0; i < 256; i++) {
126 if (DIRECT_CHAR(unitab_line[i]))
127 continue;
128 if (DIRECT_FONT(unitab_line[i]))
129 continue;
130 if (!uni_tbl) {
131 uni_tbl = smalloc(256 * sizeof(char *));
132 memset(uni_tbl, 0, 256 * sizeof(char *));
133 }
134 j = ((unitab_line[i] >> 8) & 0xFF);
135 if (!uni_tbl[j]) {
136 uni_tbl[j] = smalloc(256 * sizeof(char));
137 memset(uni_tbl[j], 0, 256 * sizeof(char));
138 }
139 uni_tbl[j][unitab_line[i] & 0xFF] = i;
140 }
141 }
142
143 /* Find the line control characters. */
144 for (i = 0; i < 256; i++)
145 if (unitab_line[i] < ' '
146 || (unitab_line[i] >= 0x7F && unitab_line[i] < 0xA0))
147 unitab_ctrl[i] = i;
148 else
149 unitab_ctrl[i] = 0xFF;
150
151 /* Generate line->screen direct conversion links. */
d3cb5465 152 if (cfg.vtmode == VT_OEMANSI || cfg.vtmode == VT_XWINDOWS)
153 link_font(unitab_scoacs, unitab_oemcp, ATTR_OEMCP);
154
4eeb7d09 155 link_font(unitab_line, unitab_font, ATTR_ACP);
d3cb5465 156 link_font(unitab_scoacs, unitab_font, ATTR_ACP);
4eeb7d09 157 link_font(unitab_xterm, unitab_font, ATTR_ACP);
158
159 if (cfg.vtmode == VT_OEMANSI || cfg.vtmode == VT_XWINDOWS) {
160 link_font(unitab_line, unitab_oemcp, ATTR_OEMCP);
161 link_font(unitab_xterm, unitab_oemcp, ATTR_OEMCP);
162 }
163
164 /* Last chance, if !unicode then try poorman links. */
165 if (cfg.vtmode != VT_UNICODE) {
d3cb5465 166 static char poorman_scoacs[] =
167 "CueaaaaceeeiiiAAE**ooouuyOUc$YPsaiounNao?++**!<>###||||++||++++++--|-+||++--|-+----++++++++##||#aBTPEsyt******EN=+><++-=... n2* ";
4eeb7d09 168 static char poorman_latin1[] =
169 " !cL.Y|S\"Ca<--R~o+23'u|.,1o>///?AAAAAAACEEEEIIIIDNOOOOOxOUUUUYPBaaaaaaaceeeeiiiionooooo/ouuuuypy";
170 static char poorman_vt100[] = "*#****o~**+++++-----++++|****L.";
171
172 for (i = 160; i < 256; i++)
173 if (!DIRECT_FONT(unitab_line[i]) &&
174 unitab_line[i] >= 160 && unitab_line[i] < 256)
175 unitab_line[i] = (WCHAR) (ATTR_ACP
176 + poorman_latin1[unitab_line[i] -
177 160]);
178 for (i = 96; i < 127; i++)
179 if (!DIRECT_FONT(unitab_xterm[i]))
180 unitab_xterm[i] =
181 (WCHAR) (ATTR_ACP + poorman_vt100[i - 96]);
d3cb5465 182 for(i=128;i<256;i++)
183 if (!DIRECT_FONT(unitab_scoacs[i]))
184 unitab_scoacs[i] =
185 (WCHAR) (ATTR_ACP + poorman_scoacs[i - 128]);
4eeb7d09 186 }
187}
188
189static void link_font(WCHAR * line_tbl, WCHAR * font_tbl, WCHAR attr)
190{
191 int i, j, k;
192 for (k = 0; k < 256; k++) {
193 i = ((k + 32) & 0xFF);
194 if (DIRECT_FONT(line_tbl[i]))
195 continue;
196 for (j = 0; j < 256; j++) {
197 if (line_tbl[i] == font_tbl[j]) {
198 line_tbl[i] = (WCHAR) (attr + j);
199 break;
200 }
201 }
202 }
203}
204
205void lpage_send(int codepage, char *buf, int len)
206{
207 static wchar_t *widebuffer = 0;
208 static int widesize = 0;
209 int wclen;
210
211 if (codepage < 0) {
212 ldisc_send(buf, len);
213 return;
214 }
215
216 if (len > widesize) {
217 sfree(widebuffer);
218 widebuffer = smalloc(len * 2 * sizeof(wchar_t));
219 widesize = len * 2;
220 }
221
222 wclen =
223 MultiByteToWideChar(codepage, 0, buf, len, widebuffer, widesize);
224 luni_send(widebuffer, wclen);
225}
226
227void luni_send(wchar_t * widebuf, int len)
228{
229 static char *linebuffer = 0;
230 static int linesize = 0;
231 int ratio = (utf) ? 3 : 1;
232 int i;
233 char *p;
234
235 if (len * ratio > linesize) {
236 sfree(linebuffer);
237 linebuffer = smalloc(len * ratio * 2 * sizeof(wchar_t));
238 linesize = len * ratio * 2;
239 }
240
241 if (utf) {
242 /* UTF is a simple algorithm */
243 for (p = linebuffer, i = 0; i < len; i++) {
244 wchar_t ch = widebuf[i];
245 if (ch < 0x80) {
246 *p++ = (char) (ch);
247 } else if (ch < 0x800) {
248 *p++ = (0xC0 | (ch >> 6));
249 *p++ = (0x80 | (ch & 0x3F));
250 } else {
251 *p++ = (0xE0 | (ch >> 12));
252 *p++ = (0x80 | ((ch >> 6) & 0x3F));
253 *p++ = (0x80 | (ch & 0x3F));
254 }
255 }
256 } else if (!uni_tbl) {
257 int rv;
258 rv = WideCharToMultiByte(line_codepage, 0, widebuf, len,
259 linebuffer, linesize, NULL, NULL);
260 if (rv >= 0)
261 p = linebuffer + rv;
262 else
263 p = linebuffer;
264 } else {
265 /* Others are a lookup in an array */
266 for (p = linebuffer, i = 0; i < len; i++) {
267 wchar_t ch = widebuf[i];
268 int by;
269 char *p1;
270 if (uni_tbl && (p1 = uni_tbl[(ch >> 8) & 0xFF])
271 && (by = p1[ch & 0xFF]))
272 *p++ = by;
273 else if (ch < 0x80)
274 *p++ = (char) ch;
275#if 1
276 else
277 *p++ = '.';
278#endif
279 }
280 }
281 if (p > linebuffer)
282 ldisc_send(linebuffer, p - linebuffer);
283}
284
285int check_compose(int first, int second)
286{
287
288 static struct {
289 char first, second;
290 wchar_t composed;
291 } composetbl[] = {
292 {
293 0x2b, 0x2b, 0x0023}, {
294 0x41, 0x41, 0x0040}, {
295 0x28, 0x28, 0x005b}, {
296 0x2f, 0x2f, 0x005c}, {
297 0x29, 0x29, 0x005d}, {
298 0x28, 0x2d, 0x007b}, {
299 0x2d, 0x29, 0x007d}, {
300 0x2f, 0x5e, 0x007c}, {
301 0x21, 0x21, 0x00a1}, {
302 0x43, 0x2f, 0x00a2}, {
303 0x43, 0x7c, 0x00a2}, {
304 0x4c, 0x2d, 0x00a3}, {
305 0x4c, 0x3d, 0x00a3}, {
306 0x58, 0x4f, 0x00a4}, {
307 0x58, 0x30, 0x00a4}, {
308 0x59, 0x2d, 0x00a5}, {
309 0x59, 0x3d, 0x00a5}, {
310 0x7c, 0x7c, 0x00a6}, {
311 0x53, 0x4f, 0x00a7}, {
312 0x53, 0x21, 0x00a7}, {
313 0x53, 0x30, 0x00a7}, {
314 0x22, 0x22, 0x00a8}, {
315 0x43, 0x4f, 0x00a9}, {
316 0x43, 0x30, 0x00a9}, {
317 0x41, 0x5f, 0x00aa}, {
318 0x3c, 0x3c, 0x00ab}, {
319 0x2c, 0x2d, 0x00ac}, {
320 0x2d, 0x2d, 0x00ad}, {
321 0x52, 0x4f, 0x00ae}, {
322 0x2d, 0x5e, 0x00af}, {
323 0x30, 0x5e, 0x00b0}, {
324 0x2b, 0x2d, 0x00b1}, {
325 0x32, 0x5e, 0x00b2}, {
326 0x33, 0x5e, 0x00b3}, {
327 0x27, 0x27, 0x00b4}, {
328 0x2f, 0x55, 0x00b5}, {
329 0x50, 0x21, 0x00b6}, {
330 0x2e, 0x5e, 0x00b7}, {
331 0x2c, 0x2c, 0x00b8}, {
332 0x31, 0x5e, 0x00b9}, {
333 0x4f, 0x5f, 0x00ba}, {
334 0x3e, 0x3e, 0x00bb}, {
335 0x31, 0x34, 0x00bc}, {
336 0x31, 0x32, 0x00bd}, {
337 0x33, 0x34, 0x00be}, {
338 0x3f, 0x3f, 0x00bf}, {
339 0x60, 0x41, 0x00c0}, {
340 0x27, 0x41, 0x00c1}, {
341 0x5e, 0x41, 0x00c2}, {
342 0x7e, 0x41, 0x00c3}, {
343 0x22, 0x41, 0x00c4}, {
344 0x2a, 0x41, 0x00c5}, {
345 0x41, 0x45, 0x00c6}, {
346 0x2c, 0x43, 0x00c7}, {
347 0x60, 0x45, 0x00c8}, {
348 0x27, 0x45, 0x00c9}, {
349 0x5e, 0x45, 0x00ca}, {
350 0x22, 0x45, 0x00cb}, {
351 0x60, 0x49, 0x00cc}, {
352 0x27, 0x49, 0x00cd}, {
353 0x5e, 0x49, 0x00ce}, {
354 0x22, 0x49, 0x00cf}, {
355 0x2d, 0x44, 0x00d0}, {
356 0x7e, 0x4e, 0x00d1}, {
357 0x60, 0x4f, 0x00d2}, {
358 0x27, 0x4f, 0x00d3}, {
359 0x5e, 0x4f, 0x00d4}, {
360 0x7e, 0x4f, 0x00d5}, {
361 0x22, 0x4f, 0x00d6}, {
362 0x58, 0x58, 0x00d7}, {
363 0x2f, 0x4f, 0x00d8}, {
364 0x60, 0x55, 0x00d9}, {
365 0x27, 0x55, 0x00da}, {
366 0x5e, 0x55, 0x00db}, {
367 0x22, 0x55, 0x00dc}, {
368 0x27, 0x59, 0x00dd}, {
369 0x48, 0x54, 0x00de}, {
370 0x73, 0x73, 0x00df}, {
371 0x60, 0x61, 0x00e0}, {
372 0x27, 0x61, 0x00e1}, {
373 0x5e, 0x61, 0x00e2}, {
374 0x7e, 0x61, 0x00e3}, {
375 0x22, 0x61, 0x00e4}, {
376 0x2a, 0x61, 0x00e5}, {
377 0x61, 0x65, 0x00e6}, {
378 0x2c, 0x63, 0x00e7}, {
379 0x60, 0x65, 0x00e8}, {
380 0x27, 0x65, 0x00e9}, {
381 0x5e, 0x65, 0x00ea}, {
382 0x22, 0x65, 0x00eb}, {
383 0x60, 0x69, 0x00ec}, {
384 0x27, 0x69, 0x00ed}, {
385 0x5e, 0x69, 0x00ee}, {
386 0x22, 0x69, 0x00ef}, {
387 0x2d, 0x64, 0x00f0}, {
388 0x7e, 0x6e, 0x00f1}, {
389 0x60, 0x6f, 0x00f2}, {
390 0x27, 0x6f, 0x00f3}, {
391 0x5e, 0x6f, 0x00f4}, {
392 0x7e, 0x6f, 0x00f5}, {
393 0x22, 0x6f, 0x00f6}, {
394 0x3a, 0x2d, 0x00f7}, {
395 0x6f, 0x2f, 0x00f8}, {
396 0x60, 0x75, 0x00f9}, {
397 0x27, 0x75, 0x00fa}, {
398 0x5e, 0x75, 0x00fb}, {
399 0x22, 0x75, 0x00fc}, {
400 0x27, 0x79, 0x00fd}, {
401 0x68, 0x74, 0x00fe}, {
402 0x22, 0x79, 0x00ff},
403 /* Unicode extras. */
404 {
405 0x6f, 0x65, 0x0153}, {
406 0x4f, 0x45, 0x0152},
407 /* Compose pairs from UCS */
408 {
409 0x41, 0x2D, 0x0100}, {
410 0x61, 0x2D, 0x0101}, {
411 0x43, 0x27, 0x0106}, {
412 0x63, 0x27, 0x0107}, {
413 0x43, 0x5E, 0x0108}, {
414 0x63, 0x5E, 0x0109}, {
415 0x45, 0x2D, 0x0112}, {
416 0x65, 0x2D, 0x0113}, {
417 0x47, 0x5E, 0x011C}, {
418 0x67, 0x5E, 0x011D}, {
419 0x47, 0x2C, 0x0122}, {
420 0x67, 0x2C, 0x0123}, {
421 0x48, 0x5E, 0x0124}, {
422 0x68, 0x5E, 0x0125}, {
423 0x49, 0x7E, 0x0128}, {
424 0x69, 0x7E, 0x0129}, {
425 0x49, 0x2D, 0x012A}, {
426 0x69, 0x2D, 0x012B}, {
427 0x4A, 0x5E, 0x0134}, {
428 0x6A, 0x5E, 0x0135}, {
429 0x4B, 0x2C, 0x0136}, {
430 0x6B, 0x2C, 0x0137}, {
431 0x4C, 0x27, 0x0139}, {
432 0x6C, 0x27, 0x013A}, {
433 0x4C, 0x2C, 0x013B}, {
434 0x6C, 0x2C, 0x013C}, {
435 0x4E, 0x27, 0x0143}, {
436 0x6E, 0x27, 0x0144}, {
437 0x4E, 0x2C, 0x0145}, {
438 0x6E, 0x2C, 0x0146}, {
439 0x4F, 0x2D, 0x014C}, {
440 0x6F, 0x2D, 0x014D}, {
441 0x52, 0x27, 0x0154}, {
442 0x72, 0x27, 0x0155}, {
443 0x52, 0x2C, 0x0156}, {
444 0x72, 0x2C, 0x0157}, {
445 0x53, 0x27, 0x015A}, {
446 0x73, 0x27, 0x015B}, {
447 0x53, 0x5E, 0x015C}, {
448 0x73, 0x5E, 0x015D}, {
449 0x53, 0x2C, 0x015E}, {
450 0x73, 0x2C, 0x015F}, {
451 0x54, 0x2C, 0x0162}, {
452 0x74, 0x2C, 0x0163}, {
453 0x55, 0x7E, 0x0168}, {
454 0x75, 0x7E, 0x0169}, {
455 0x55, 0x2D, 0x016A}, {
456 0x75, 0x2D, 0x016B}, {
457 0x55, 0x2A, 0x016E}, {
458 0x75, 0x2A, 0x016F}, {
459 0x57, 0x5E, 0x0174}, {
460 0x77, 0x5E, 0x0175}, {
461 0x59, 0x5E, 0x0176}, {
462 0x79, 0x5E, 0x0177}, {
463 0x59, 0x22, 0x0178}, {
464 0x5A, 0x27, 0x0179}, {
465 0x7A, 0x27, 0x017A}, {
466 0x47, 0x27, 0x01F4}, {
467 0x67, 0x27, 0x01F5}, {
468 0x4E, 0x60, 0x01F8}, {
469 0x6E, 0x60, 0x01F9}, {
470 0x45, 0x2C, 0x0228}, {
471 0x65, 0x2C, 0x0229}, {
472 0x59, 0x2D, 0x0232}, {
473 0x79, 0x2D, 0x0233}, {
474 0x44, 0x2C, 0x1E10}, {
475 0x64, 0x2C, 0x1E11}, {
476 0x47, 0x2D, 0x1E20}, {
477 0x67, 0x2D, 0x1E21}, {
478 0x48, 0x22, 0x1E26}, {
479 0x68, 0x22, 0x1E27}, {
480 0x48, 0x2C, 0x1E28}, {
481 0x68, 0x2C, 0x1E29}, {
482 0x4B, 0x27, 0x1E30}, {
483 0x6B, 0x27, 0x1E31}, {
484 0x4D, 0x27, 0x1E3E}, {
485 0x6D, 0x27, 0x1E3F}, {
486 0x50, 0x27, 0x1E54}, {
487 0x70, 0x27, 0x1E55}, {
488 0x56, 0x7E, 0x1E7C}, {
489 0x76, 0x7E, 0x1E7D}, {
490 0x57, 0x60, 0x1E80}, {
491 0x77, 0x60, 0x1E81}, {
492 0x57, 0x27, 0x1E82}, {
493 0x77, 0x27, 0x1E83}, {
494 0x57, 0x22, 0x1E84}, {
495 0x77, 0x22, 0x1E85}, {
496 0x58, 0x22, 0x1E8C}, {
497 0x78, 0x22, 0x1E8D}, {
498 0x5A, 0x5E, 0x1E90}, {
499 0x7A, 0x5E, 0x1E91}, {
500 0x74, 0x22, 0x1E97}, {
501 0x77, 0x2A, 0x1E98}, {
502 0x79, 0x2A, 0x1E99}, {
503 0x45, 0x7E, 0x1EBC}, {
504 0x65, 0x7E, 0x1EBD}, {
505 0x59, 0x60, 0x1EF2}, {
506 0x79, 0x60, 0x1EF3}, {
507 0x59, 0x7E, 0x1EF8}, {
508 0x79, 0x7E, 0x1EF9},
509 /* Compatible/possibles from UCS */
510 {
511 0x49, 0x4A, 0x0132}, {
512 0x69, 0x6A, 0x0133}, {
513 0x4C, 0x4A, 0x01C7}, {
514 0x4C, 0x6A, 0x01C8}, {
515 0x6C, 0x6A, 0x01C9}, {
516 0x4E, 0x4A, 0x01CA}, {
517 0x4E, 0x6A, 0x01CB}, {
518 0x6E, 0x6A, 0x01CC}, {
519 0x44, 0x5A, 0x01F1}, {
520 0x44, 0x7A, 0x01F2}, {
521 0x64, 0x7A, 0x01F3}, {
522 0x2E, 0x2E, 0x2025}, {
523 0x21, 0x21, 0x203C}, {
524 0x3F, 0x21, 0x2048}, {
525 0x21, 0x3F, 0x2049}, {
526 0x52, 0x73, 0x20A8}, {
527 0x4E, 0x6F, 0x2116}, {
528 0x53, 0x4D, 0x2120}, {
529 0x54, 0x4D, 0x2122}, {
530 0x49, 0x49, 0x2161}, {
531 0x49, 0x56, 0x2163}, {
532 0x56, 0x49, 0x2165}, {
533 0x49, 0x58, 0x2168}, {
534 0x58, 0x49, 0x216A}, {
535 0x69, 0x69, 0x2171}, {
536 0x69, 0x76, 0x2173}, {
537 0x76, 0x69, 0x2175}, {
538 0x69, 0x78, 0x2178}, {
539 0x78, 0x69, 0x217A}, {
540 0x31, 0x30, 0x2469}, {
541 0x31, 0x31, 0x246A}, {
542 0x31, 0x32, 0x246B}, {
543 0x31, 0x33, 0x246C}, {
544 0x31, 0x34, 0x246D}, {
545 0x31, 0x35, 0x246E}, {
546 0x31, 0x36, 0x246F}, {
547 0x31, 0x37, 0x2470}, {
548 0x31, 0x38, 0x2471}, {
549 0x31, 0x39, 0x2472}, {
550 0x32, 0x30, 0x2473}, {
551 0x31, 0x2E, 0x2488}, {
552 0x32, 0x2E, 0x2489}, {
553 0x33, 0x2E, 0x248A}, {
554 0x34, 0x2E, 0x248B}, {
555 0x35, 0x2E, 0x248C}, {
556 0x36, 0x2E, 0x248D}, {
557 0x37, 0x2E, 0x248E}, {
558 0x38, 0x2E, 0x248F}, {
559 0x39, 0x2E, 0x2490}, {
560 0x64, 0x61, 0x3372}, {
561 0x41, 0x55, 0x3373}, {
562 0x6F, 0x56, 0x3375}, {
563 0x70, 0x63, 0x3376}, {
564 0x70, 0x41, 0x3380}, {
565 0x6E, 0x41, 0x3381}, {
566 0x6D, 0x41, 0x3383}, {
567 0x6B, 0x41, 0x3384}, {
568 0x4B, 0x42, 0x3385}, {
569 0x4D, 0x42, 0x3386}, {
570 0x47, 0x42, 0x3387}, {
571 0x70, 0x46, 0x338A}, {
572 0x6E, 0x46, 0x338B}, {
573 0x6D, 0x67, 0x338E}, {
574 0x6B, 0x67, 0x338F}, {
575 0x48, 0x7A, 0x3390}, {
576 0x66, 0x6D, 0x3399}, {
577 0x6E, 0x6D, 0x339A}, {
578 0x6D, 0x6D, 0x339C}, {
579 0x63, 0x6D, 0x339D}, {
580 0x6B, 0x6D, 0x339E}, {
581 0x50, 0x61, 0x33A9}, {
582 0x70, 0x73, 0x33B0}, {
583 0x6E, 0x73, 0x33B1}, {
584 0x6D, 0x73, 0x33B3}, {
585 0x70, 0x56, 0x33B4}, {
586 0x6E, 0x56, 0x33B5}, {
587 0x6D, 0x56, 0x33B7}, {
588 0x6B, 0x56, 0x33B8}, {
589 0x4D, 0x56, 0x33B9}, {
590 0x70, 0x57, 0x33BA}, {
591 0x6E, 0x57, 0x33BB}, {
592 0x6D, 0x57, 0x33BD}, {
593 0x6B, 0x57, 0x33BE}, {
594 0x4D, 0x57, 0x33BF}, {
595 0x42, 0x71, 0x33C3}, {
596 0x63, 0x63, 0x33C4}, {
597 0x63, 0x64, 0x33C5}, {
598 0x64, 0x42, 0x33C8}, {
599 0x47, 0x79, 0x33C9}, {
600 0x68, 0x61, 0x33CA}, {
601 0x48, 0x50, 0x33CB}, {
602 0x69, 0x6E, 0x33CC}, {
603 0x4B, 0x4B, 0x33CD}, {
604 0x4B, 0x4D, 0x33CE}, {
605 0x6B, 0x74, 0x33CF}, {
606 0x6C, 0x6D, 0x33D0}, {
607 0x6C, 0x6E, 0x33D1}, {
608 0x6C, 0x78, 0x33D3}, {
609 0x6D, 0x62, 0x33D4}, {
610 0x50, 0x48, 0x33D7}, {
611 0x50, 0x52, 0x33DA}, {
612 0x73, 0x72, 0x33DB}, {
613 0x53, 0x76, 0x33DC}, {
614 0x57, 0x62, 0x33DD}, {
615 0x66, 0x66, 0xFB00}, {
616 0x66, 0x69, 0xFB01}, {
617 0x66, 0x6C, 0xFB02}, {
618 0x73, 0x74, 0xFB06}, {
619 0, 0, 0}
620 }, *c;
621
622 static int recurse = 0;
623 int nc = -1;
624
625 for (c = composetbl; c->first; c++) {
626 if (c->first == first && c->second == second)
627 return c->composed;
628 }
629
630 if (recurse == 0) {
631 recurse = 1;
632 nc = check_compose(second, first);
633 if (nc == -1)
634 nc = check_compose(toupper(first), toupper(second));
635 if (nc == -1)
636 nc = check_compose(toupper(second), toupper(first));
637 recurse = 0;
638 }
639 return nc;
640}
641
642int decode_codepage(char *cp_name)
643{
644 char *s, *d;
645 struct cp_list_item *cpi;
646 int codepage = -1;
4eeb7d09 647 CPINFO cpinfo;
648
649 if (cp_name && *cp_name)
650 for (cpi = cp_list; cpi->name; cpi++) {
651 s = cp_name;
652 d = cpi->name;
653 for (;;) {
654 while (*s && !isalnum(*s) && *s != ':')
655 s++;
656 while (*d && !isalnum(*d) && *d != ':')
657 d++;
658 if (*s == 0) {
659 codepage = cpi->codepage;
660 if (codepage == CP_UTF8)
661 goto break_break;
662 if (codepage == 0) {
663 codepage = 65536 + (cpi - cp_list);
664 goto break_break;
665 }
666
667 if (GetCPInfo(codepage, &cpinfo) != 0)
668 goto break_break;
669 }
274a5b41 670 if (tolower(*s++) != tolower(*d++))
4eeb7d09 671 break;
672 }
673 }
674
675 if (cp_name && *cp_name) {
676 d = cp_name;
2d466ffd 677 if (tolower(d[0]) == 'c' && tolower(d[1]) == 'p')
4eeb7d09 678 d += 2;
2d466ffd 679 if (tolower(d[0]) == 'i' && tolower(d[1]) == 'b'
680 && tolower(d[1]) == 'm')
4eeb7d09 681 d += 3;
682 for (s = d; *s >= '0' && *s <= '9'; s++);
683 if (*s == 0 && s != d)
684 codepage = atoi(d); /* CP999 or IBM999 */
685
686 if (codepage == CP_ACP)
687 codepage = GetACP();
688 if (codepage == CP_OEMCP)
689 codepage = GetOEMCP();
690 if (codepage > 65535)
691 codepage = -2;
692 }
693
694 break_break:;
695 if (codepage != -1) {
696 if (codepage != CP_UTF8 && codepage < 65536) {
697 if (GetCPInfo(codepage, &cpinfo) == 0) {
698 codepage = -2;
699 } else if (cpinfo.MaxCharSize > 1)
700 codepage = -3;
701 }
702 }
703 if (codepage == -1 && *cp_name)
704 codepage = -2;
705 return codepage;
706}
707
708char *cp_name(int codepage)
709{
710 struct cp_list_item *cpi, *cpno;
711 static char buf[32];
712 if (codepage > 0 && codepage < 65536)
713 sprintf(buf, "CP%03d", codepage);
714 else
715 *buf = 0;
716
717 if (codepage >= 65536) {
718 cpno = 0;
719 for (cpi = cp_list; cpi->name; cpi++)
720 if (cpi == cp_list + (codepage - 65536)) {
721 cpno = cpi;
722 break;
723 }
724 if (cpno)
725 for (cpi = cp_list; cpi->name; cpi++) {
726 if (cpno->cp_table == cpi->cp_table)
727 return cpi->name;
728 }
729 } else {
730 for (cpi = cp_list; cpi->name; cpi++) {
731 if (codepage == cpi->codepage)
732 return cpi->name;
733 }
734 }
735 return buf;
736}
737
738static void get_unitab(int codepage, wchar_t * unitab, int ftype)
739{
740 char tbuf[4];
741 int i, max = 256, flg = MB_ERR_INVALID_CHARS;
742
743 if (ftype)
744 flg |= MB_USEGLYPHCHARS;
745 if (ftype == 2)
746 max = 128;
747
748 if (codepage == CP_UTF8)
749 codepage = 28591;
750 else if (codepage == CP_ACP)
751 codepage = GetACP();
752 else if (codepage == CP_OEMCP)
753 codepage = GetOEMCP();
754
755 if (codepage > 0 && codepage < 65536) {
756 for (i = 0; i < max; i++) {
757 tbuf[0] = i;
758
759 if (MultiByteToWideChar(codepage, flg, tbuf, 1, unitab + i, 1)
760 != 1)
761 unitab[i] = 0xFFFD;
762 }
763 } else {
764 int j = 256 - cp_list[codepage & 0xFFFF].cp_size;
765 for (i = 0; i < max; i++)
766 unitab[i] = i;
767 for (i = j; i < max; i++)
768 unitab[i] = cp_list[codepage & 0xFFFF].cp_table[i - j];
769 }
770}
771
772/*
773 * From here down is the codepage data, if you want to add your own line
774 * codepage do it here.
775 *
776 * If the codepage is non-zero it's a window codepage, zero means use a
777 * local codepage. The name is always converted to the first of any
778 * duplicate definitions.
779 */
780extern wchar_t iso_8859_10[];
781extern wchar_t iso_8859_11[];
782extern wchar_t iso_8859_12[];
783extern wchar_t iso_8859_14[];
784extern wchar_t iso_8859_15[];
785extern wchar_t roman8[];
786extern wchar_t koi8_u[];
787extern wchar_t vscii[];
788extern wchar_t dec_mcs[];
789
790static struct cp_list_item cp_list[] = {
791 {"UTF-8", CP_UTF8},
792
793 {"ISO-8859-1:1987", 28591},
794 {"ISO-8859-2:1987", 28592},
795 {"ISO-8859-3:1988", 28593},
796 {"ISO-8859-4:1988", 28594},
797 {"ISO-8859-5:1988", 28595},
798 {"ISO-8859-6:1987", 28596},
799 {"ISO-8859-7:1987", 28597},
800 {"ISO-8859-8:1988", 28598},
801 {"ISO-8859-9:1989", 28599},
802 {"ISO-8859-10:1993", 0, 96, iso_8859_10},
803 {"ISO-8859-11", 0, 96, iso_8859_11},
804 {"ISO-8859-12", 0, 96, iso_8859_12},
805 {"ISO-8859-14", 0, 96, iso_8859_14},
806 {"ISO-8859-15:1998", 0, 96, iso_8859_15},
807
808 {"KOI8-U", 0, 128, koi8_u},
809 {"KOI8-R", 20866},
810 {"HP-ROMAN8", 0, 96, roman8},
811 {"VSCII", 0, 256, vscii},
812 {"DEC-MCS", 0, 96, dec_mcs},
813
274a5b41 814 {"Win1250 (Central European)", 1250},
815 {"Win1251 (Cyrillic)", 1251},
816 {"Win1252 (Western)", 1252},
817 {"Win1253 (Greek)", 1253},
818 {"Win1254 (Turkish)", 1254},
819 {"Win1255 (Hebrew)", 1255},
820 {"Win1256 (Arabic)", 1256},
821 {"Win1257 (Baltic)", 1257},
822 {"Win1258 (Vietnamese)", 1258},
823
824 /* All below here are aliases - First the windows ones. */
825 {"Central European (Win1250)", 1250},
826 {"Cyrillic (Win1251)", 1251},
827 {"Western (Win1252)", 1252},
828 {"Greek (Win1253)", 1253},
829 {"Turkish (Win1254)", 1254},
830 {"Hebrew (Win1255)", 1255},
831 {"Arabic (Win1256)", 1256},
832 {"Baltic (Win1257)", 1257},
833 {"Vietnamese (Win1258)", 1258},
834
4eeb7d09 835 {"ROMAN8", 0, 96, roman8},
836 {"R8", 0, 96, roman8},
837
838 /* Note this is Latin ->> */
839 {"LATIN0", 0, 96, iso_8859_15},
840 {"L0", 0, 96, iso_8859_15},
841
842 {"CP819", 28591},
843 {"CP878", 20866},
844 {"L1", 28591},
845 {"L2", 28592},
846 {"L3", 28593},
847 {"L4", 28594},
848 {"L5", 28599},
849 {"LATIN1", 28591},
850 {"LATIN2", 28592},
851 {"LATIN3", 28593},
852 {"LATIN4", 28594},
853 {"LATIN5", 28599},
854 {0, 0}
855};
856
857static wchar_t iso_8859_10[] = {
858 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7,
859 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A,
860 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7,
861 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2014, 0x016B, 0x014B,
862 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
863 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF,
864 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168,
865 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
866 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
867 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF,
868 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169,
869 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138
870};
871
872static wchar_t iso_8859_11[] = {
873 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
874 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
875 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
876 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
877 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
878 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
879 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
880 0x0E38, 0x0E39, 0x0E3A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0E3F,
881 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
882 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
883 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
884 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD
885};
886
887static wchar_t iso_8859_12[] = {
888 0x00A0, 0x201D, 0x00A2, 0x00A3, 0x00A4, 0x201E, 0x00A6, 0x00A7,
889 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6,
890 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x201C, 0x00B5, 0x00B6, 0x00B7,
891 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
892 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
893 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
894 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
895 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
896 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
897 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
898 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
899 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x2019
900};
901
902static wchar_t iso_8859_14[] = {
903 0x00A0, 0x1E02, 0x1E03, 0x00A3, 0x010A, 0x010B, 0x1E0A, 0x00A7,
904 0x1E80, 0x00A9, 0x1E82, 0x1E0B, 0x1EF2, 0x00AD, 0x00AE, 0x0178,
905 0x1E1E, 0x1E1F, 0x0120, 0x0121, 0x1E40, 0x1E41, 0x00B6, 0x1E56,
906 0x1E81, 0x1E57, 0x1E83, 0x1E60, 0x1EF3, 0x1E84, 0x1E85, 0x1E61,
907 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
908 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
909 0x0174, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x1E6A,
910 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x0176, 0x00DF,
911 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
912 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
913 0x0175, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x1E6B,
914 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x0177, 0x00FF
915};
916
917static wchar_t iso_8859_15[] = {
918 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7,
919 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
920 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7,
921 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf,
922 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
923 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
924 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
925 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
926 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
927 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
928 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
929 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
930};
931
932static wchar_t roman8[] = {
933 0x00A0, 0x00C0, 0x00C2, 0x00C8, 0x00CA, 0x00CB, 0x00CE, 0x00CF,
934 0x00B4, 0x02CB, 0x02C6, 0x00A8, 0x02DC, 0x00D9, 0x00DB, 0x20A4,
935 0x00AF, 0x00DD, 0x00FD, 0x00B0, 0x00C7, 0x00E7, 0x00D1, 0x00F1,
936 0x00A1, 0x00BF, 0x00A4, 0x00A3, 0x00A5, 0x00A7, 0x0192, 0x00A2,
937 0x00E2, 0x00EA, 0x00F4, 0x00FB, 0x00E1, 0x00E9, 0x00F3, 0x00FA,
938 0x00E0, 0x00E8, 0x00F2, 0x00F9, 0x00E4, 0x00EB, 0x00F6, 0x00FC,
939 0x00C5, 0x00EE, 0x00D8, 0x00C6, 0x00E5, 0x00ED, 0x00F8, 0x00E6,
940 0x00C4, 0x00EC, 0x00D6, 0x00DC, 0x00C9, 0x00EF, 0x00DF, 0x00D4,
941 0x00C1, 0x00C3, 0x00E3, 0x00D0, 0x00F0, 0x00CD, 0x00CC, 0x00D3,
942 0x00D2, 0x00D5, 0x00F5, 0x0160, 0x0161, 0x00DA, 0x0178, 0x00FF,
943 0x00DE, 0x00FE, 0x00B7, 0x00B5, 0x00B6, 0x00BE, 0x2014, 0x00BC,
944 0x00BD, 0x00AA, 0x00BA, 0x00AB, 0x25A0, 0x00BB, 0x00B1, 0xFFFD
945};
946
947static wchar_t koi8_u[] = {
948 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
949 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
950 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2022, 0x221A, 0x2248,
951 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
952 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457,
953 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x0491, 0x255D, 0x255E,
954 0x255F, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407,
955 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x0490, 0x256C, 0x00A9,
956 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
957 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
958 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
959 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
960 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
961 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
962 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
963 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A
964};
965
966static wchar_t vscii[] = {
967 0x0000, 0x0001, 0x1EB2, 0x0003, 0x0004, 0x1EB4, 0x1EAA, 0x0007,
968 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
969 0x0010, 0x0011, 0x0012, 0x0013, 0x1EF6, 0x0015, 0x0016, 0x0017,
970 0x0018, 0x1EF8, 0x001a, 0x001b, 0x001c, 0x001d, 0x1EF4, 0x001f,
971 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
972 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
973 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
974 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
975 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
976 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
977 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
978 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
979 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
980 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
981 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
982 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007f,
983 0x1EA0, 0x1EAE, 0x1EB0, 0x1EB6, 0x1EA4, 0x1EA6, 0x1EA8, 0x1EAC,
984 0x1EBC, 0x1EB8, 0x1EBE, 0x1EC0, 0x1EC2, 0x1EC4, 0x1EC6, 0x1ED0,
985 0x1ED2, 0x1ED4, 0x1ED6, 0x1ED8, 0x1EE2, 0x1EDA, 0x1EDC, 0x1EDE,
986 0x1ECA, 0x1ECE, 0x1ECC, 0x1EC8, 0x1EE6, 0x0168, 0x1EE4, 0x1EF2,
987 0x00D5, 0x1EAF, 0x1EB1, 0x1EB7, 0x1EA5, 0x1EA7, 0x1EA8, 0x1EAD,
988 0x1EBD, 0x1EB9, 0x1EBF, 0x1EC1, 0x1EC3, 0x1EC5, 0x1EC7, 0x1ED1,
989 0x1ED3, 0x1ED5, 0x1ED7, 0x1EE0, 0x01A0, 0x1ED9, 0x1EDD, 0x1EDF,
990 0x1ECB, 0x1EF0, 0x1EE8, 0x1EEA, 0x1EEC, 0x01A1, 0x1EDB, 0x01AF,
991 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x1EA2, 0x0102, 0x1EB3, 0x1EB5,
992 0x00C8, 0x00C9, 0x00CA, 0x1EBA, 0x00CC, 0x00CD, 0x0128, 0x1EF3,
993 0x0110, 0x1EE9, 0x00D2, 0x00D3, 0x00D4, 0x1EA1, 0x1EF7, 0x1EEB,
994 0x1EED, 0x00D9, 0x00DA, 0x1EF9, 0x1EF5, 0x00DD, 0x1EE1, 0x01B0,
995 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x1EA3, 0x0103, 0x1EEF, 0x1EAB,
996 0x00E8, 0x00E9, 0x00EA, 0x1EBB, 0x00EC, 0x00ED, 0x0129, 0x1EC9,
997 0x0111, 0x1EF1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x1ECF, 0x1ECD,
998 0x1EE5, 0x00F9, 0x00FA, 0x0169, 0x1EE7, 0x00FD, 0x1EE3, 0x1EEE
999};
1000
1001static wchar_t dec_mcs[] = {
1002 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0xFFFD, 0x00A5, 0xFFFD, 0x00A7,
1003 0x00A4, 0x00A9, 0x00AA, 0x00AB, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
1004 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0xFFFD, 0x00B5, 0x00B6, 0x00B7,
1005 0xFFFD, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0xFFFD, 0x00BF,
1006 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
1007 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
1008 0xFFFD, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0152,
1009 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0178, 0xFFFD, 0x00DF,
1010 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
1011 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
1012 0xFFFD, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0153,
1013 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FF, 0xFFFD, 0xFFFD
1014};