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