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