1 /*
2  * All the code below represent subset of the
3  * Bruno Haible's libiconv library, homepage
4  * http://clisp.cons.org/~haible/packages-libiconv.html
5  *
6  * Based on libiconv ver. 1.17
7  * See below for copyright notice.
8  */
9 
10 /*
11  * Copyright (C) 1999-2001 Free Software Foundation, Inc.
12  * This file is part of the GNU LIBICONV Library.
13  *
14  * The GNU LIBICONV Library is free software; you can redistribute it
15  * and/or modify it under the terms of the GNU Library General Public
16  * License as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * The GNU LIBICONV Library is distributed in the hope that it will be
20  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22  * Library General Public License for more details.
23  *
24  * You should have received a copy of the GNU Library General Public
25  * License along with the GNU LIBICONV Library; see the file COPYING.LIB.
26  * If not, write to the Free Software Foundation, Inc., 59 Temple Place -
27  * Suite 330, Boston, MA 02111-1307, USA.
28  */
29 
30 #ifdef _WIN32
31 #include "win32/config.h"
32 #else
33 #include "config.h"
34 #endif
35 
36 #define LOCAL_DEBUG
37 /*#define DO_CLOCKING*/
38 
39 #include <string.h>
40 #ifdef _WIN32
41 # include "win32/afterbase.h"
42 #else
43 # include "afterbase.h"
44 #endif
45 #include "char2uni.h"
46 
47 
48 /*
49  * ISO-8859-1
50  */
51 static const unsigned short _as_iso8859_1_2uni[128] = {
52 /* does not really require translation, but we'll stick it in
53    there for uniformity : */
54   /* 0x80 */
55   0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
56   0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
57   /* 0x90 */
58   0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
59   0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
60   /* 0xa0 */
61   0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
62   0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
63   /* 0xb0 */
64   0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
65   0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
66   /* 0xc0 */
67   0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
68   0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
69   /* 0xd0 */
70   0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
71   0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
72   /* 0xe0 */
73   0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
74   0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
75   /* 0xf0 */
76   0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
77   0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
78 };
79 
80 /*
81  * ISO-8859-2
82  */
83 
84 static const unsigned short _as_iso8859_2_2uni[128] = {
85   /* 0x80 */
86   0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
87   0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
88   /* 0x90 */
89   0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
90   0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
91   /* 0xa0 */
92   0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7,
93   0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b,
94   /* 0xb0 */
95   0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7,
96   0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c,
97   /* 0xc0 */
98   0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7,
99   0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
100   /* 0xd0 */
101   0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7,
102   0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
103   /* 0xe0 */
104   0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7,
105   0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
106   /* 0xf0 */
107   0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7,
108   0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9,
109 };
110 
111 /*
112  * ISO-8859-3
113  */
114 
115 static const unsigned short _as_iso8859_3_2uni[128] = {
116   /* 0x80 */
117   0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
118   0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
119   /* 0x90 */
120   0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
121   0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
122   /* 0xa0 */
123   0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, 0xfffd, 0x0124, 0x00a7,
124   0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, 0xfffd, 0x017b,
125   /* 0xb0 */
126   0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7,
127   0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, 0xfffd, 0x017c,
128   /* 0xc0 */
129   0x00c0, 0x00c1, 0x00c2, 0xfffd, 0x00c4, 0x010a, 0x0108, 0x00c7,
130   0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
131   /* 0xd0 */
132   0xfffd, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7,
133   0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df,
134   /* 0xe0 */
135   0x00e0, 0x00e1, 0x00e2, 0xfffd, 0x00e4, 0x010b, 0x0109, 0x00e7,
136   0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
137   /* 0xf0 */
138   0xfffd, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7,
139   0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9,
140 };
141 
142 
143 /*
144  * ISO-8859-4
145  */
146 
147 static const unsigned short _as_iso8859_4_2uni[128] = {
148   /* 0x80 */
149   0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
150   0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
151   /* 0x90 */
152   0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
153   0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
154   /* 0xa0 */
155   0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x0128, 0x013b, 0x00a7,
156   0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af,
157   /* 0xb0 */
158   0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7,
159   0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b,
160   /* 0xc0 */
161   0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e,
162   0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a,
163   /* 0xd0 */
164   0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
165   0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df,
166   /* 0xe0 */
167   0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f,
168   0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b,
169   /* 0xf0 */
170   0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
171   0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9,
172 };
173 
174 /*
175  * ISO-8859-5
176  */
177 
178 static const unsigned short _as_iso8859_5_2uni[128] = {
179   /* 0x80 */
180   0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
181   0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
182   /* 0x90 */
183   0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
184   0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
185   /* 0xa0 */
186   0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
187   0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f,
188   /* 0xb0 */
189   0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
190   0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
191   /* 0xc0 */
192   0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
193   0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
194   /* 0xd0 */
195   0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
196   0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
197   /* 0xe0 */
198   0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
199   0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
200   /* 0xf0 */
201   0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
202   0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f,
203 };
204 
205 /*
206  * ISO-8859-6
207  */
208 
209 static const unsigned short _as_iso8859_6_2uni[128] = {
210   /* 0x80 */
211   0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
212   0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
213   /* 0x90 */
214   0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
215   0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
216   /* 0xa0 */
217   0x00a0, 0xfffd, 0xfffd, 0xfffd, 0x00a4, 0xfffd, 0xfffd, 0xfffd,
218   0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x060c, 0x00ad, 0xfffd, 0xfffd,
219   /* 0xb0 */
220   0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
221   0xfffd, 0xfffd, 0xfffd, 0x061b, 0xfffd, 0xfffd, 0xfffd, 0x061f,
222   /* 0xc0 */
223   0xfffd, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
224   0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f,
225   /* 0xd0 */
226   0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637,
227   0x0638, 0x0639, 0x063a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
228   /* 0xe0 */
229   0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647,
230   0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f,
231   /* 0xf0 */
232   0x0650, 0x0651, 0x0652, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
233   0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
234 };
235 
236 /*
237  * ISO-8859-7
238  */
239 
240 static const unsigned short _as_iso8859_7_2uni[128] = {
241   /* 0x80 */
242   0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
243   0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
244   /* 0x90 */
245   0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
246   0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
247   /* 0xa0 */
248   0x00a0, 0x2018, 0x2019, 0x00a3, 0xfffd, 0xfffd, 0x00a6, 0x00a7,
249   0x00a8, 0x00a9, 0xfffd, 0x00ab, 0x00ac, 0x00ad, 0xfffd, 0x2015,
250   /* 0xb0 */
251   0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x0385, 0x0386, 0x00b7,
252   0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f,
253   /* 0xc0 */
254   0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
255   0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
256   /* 0xd0 */
257   0x03a0, 0x03a1, 0xfffd, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
258   0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af,
259   /* 0xe0 */
260   0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
261   0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
262   /* 0xf0 */
263   0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7,
264   0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0xfffd,
265 };
266 
267 /*
268  * ISO-8859-8
269  */
270 
271 static const unsigned short _as_iso8859_8_2uni[128] = {
272   /* 0x80 */
273   0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
274   0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
275   /* 0x90 */
276   0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
277   0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
278   /* 0xa0 */
279   0x00a0, 0xfffd, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
280   0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
281   /* 0xb0 */
282   0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
283   0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0xfffd,
284   /* 0xc0 */
285   0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
286   0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
287   /* 0xd0 */
288   0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
289   0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2017,
290   /* 0xe0 */
291   0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7,
292   0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df,
293   /* 0xf0 */
294   0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7,
295   0x05e8, 0x05e9, 0x05ea, 0xfffd, 0xfffd, 0x200e, 0x200f, 0xfffd,
296 };
297 
298 /*
299  * ISO-8859-9
300  */
301 
302 static const unsigned short _as_iso8859_9_2uni[128] = {
303   /* 0x80 */
304   0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
305   0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
306   /* 0x90 */
307   0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
308   0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
309   /* 0xa0 */
310   0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
311   0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
312   /* 0xb0 */
313   0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
314   0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
315   /* 0xc0 */
316   0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
317   0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
318   /* 0xd0 */
319   0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
320   0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df,
321   /* 0xe0 */
322   0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
323   0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
324   /* 0xf0 */
325   0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
326   0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff,
327 };
328 
329 /*
330  * ISO-8859-10
331  */
332 
333 static const unsigned short _as_iso8859_10_2uni[128] = {
334   /* 0x80 */
335   0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
336   0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
337   /* 0x90 */
338   0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
339   0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
340   /* 0xa0 */
341   0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x0128, 0x0136, 0x00a7,
342   0x013b, 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a,
343   /* 0xb0 */
344   0x00b0, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7,
345   0x013c, 0x0111, 0x0161, 0x0167, 0x017e, 0x2015, 0x016b, 0x014b,
346   /* 0xc0 */
347   0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e,
348   0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf,
349   /* 0xd0 */
350   0x00d0, 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168,
351   0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
352   /* 0xe0 */
353   0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f,
354   0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef,
355   /* 0xf0 */
356   0x00f0, 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169,
357   0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138,
358 };
359 
360 /*
361  * ISO-8859-13
362  */
363 
364 static const unsigned short _as_iso8859_13_2uni[128] = {
365   /* 0x80 */
366   0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
367   0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
368   /* 0x90 */
369   0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
370   0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
371   /* 0xa0 */
372   0x00a0, 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x201e, 0x00a6, 0x00a7,
373   0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6,
374   /* 0xb0 */
375   0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, 0x00b5, 0x00b6, 0x00b7,
376   0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6,
377   /* 0xc0 */
378   0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112,
379   0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b,
380   /* 0xd0 */
381   0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7,
382   0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df,
383   /* 0xe0 */
384   0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113,
385   0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c,
386   /* 0xf0 */
387   0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7,
388   0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x2019,
389 };
390 
391 /*
392  * ISO-8859-14
393  */
394 
395 static const unsigned short _as_iso8859_14_2uni[128] = {
396   /* 0x80 */
397   0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
398   0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
399   /* 0x90 */
400   0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
401   0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
402   /* 0xa0 */
403   0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7,
404   0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x0178,
405   /* 0xb0 */
406   0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56,
407   0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61,
408   /* 0xc0 */
409   0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
410   0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
411   /* 0xd0 */
412   0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a,
413   0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df,
414   /* 0xe0 */
415   0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
416   0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
417   /* 0xf0 */
418   0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b,
419   0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff,
420 };
421 
422 /*
423  * ISO-8859-15
424  */
425 
426 static const unsigned short _as_iso8859_15_2uni[128] = {
427   /* 0x80 */
428   0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
429   0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
430   /* 0x90 */
431   0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
432   0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
433   /* 0xa0 */
434   0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7,
435   0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
436   /* 0xb0 */
437   0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7,
438   0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf,
439   /* 0xc0 */
440   0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
441   0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
442   /* 0xd0 */
443   0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
444   0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
445   /* 0xe0 */
446   0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
447   0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
448   /* 0xf0 */
449   0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
450   0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
451 };
452 
453 /*
454  * ISO-8859-16
455  */
456 
457 static const unsigned short _as_iso8859_16_2uni[128] = {
458   /* 0x80 */
459   0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
460   0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
461   /* 0x90 */
462   0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
463   0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
464   /* 0xa0 */
465   0x00a0, 0x0104, 0x0105, 0x0141, 0x20ac, 0x00ab, 0x0160, 0x00a7,
466   0x0161, 0x00a9, 0x0218, 0x201e, 0x0179, 0x00ad, 0x017a, 0x017b,
467   /* 0xb0 */
468   0x00b0, 0x00b1, 0x010c, 0x0142, 0x017d, 0x201d, 0x00b6, 0x00b7,
469   0x017e, 0x010d, 0x0219, 0x00bb, 0x0152, 0x0153, 0x0178, 0x017c,
470   /* 0xc0 */
471   0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0106, 0x00c6, 0x00c7,
472   0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
473   /* 0xd0 */
474   0x0110, 0x0143, 0x00d2, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x015a,
475   0x0170, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0118, 0x021a, 0x00df,
476   /* 0xe0 */
477   0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x0107, 0x00e6, 0x00e7,
478   0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
479   /* 0xf0 */
480   0x0111, 0x0144, 0x00f2, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x015b,
481   0x0171, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0119, 0x021b, 0x00ff,
482 };
483 
484 /*
485  * KOI8-R
486  */
487 
488 /* Specification: RFC 1489 */
489 
490 static const unsigned short _as_koi8_r_2uni[128] = {
491   /* 0x80 */
492   0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524,
493   0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590,
494   /* 0x90 */
495   0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248,
496   0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7,
497   /* 0xa0 */
498   0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556,
499   0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e,
500   /* 0xb0 */
501   0x255f, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565,
502   0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x00a9,
503   /* 0xc0 */
504   0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
505   0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e,
506   /* 0xd0 */
507   0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
508   0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a,
509   /* 0xe0 */
510   0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
511   0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
512   /* 0xf0 */
513   0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
514   0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a,
515 };
516 
517 /*
518  * KOI8-RU
519  */
520 
521 static const unsigned short _as_koi8_ru_2uni[128] = {
522   /* 0x80 */
523   0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524,
524   0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590,
525   /* 0x90 */
526   0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248,
527   0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7,
528   /* 0xa0 */
529   0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457,
530   0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x0491, 0x045e, 0x255e,
531   /* 0xb0 */
532   0x255f, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407,
533   0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x0490, 0x040e, 0x00a9,
534   /* 0xc0 */
535   0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
536   0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e,
537   /* 0xd0 */
538   0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
539   0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a,
540   /* 0xe0 */
541   0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
542   0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
543   /* 0xf0 */
544   0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
545   0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a,
546 };
547 
548 /*
549  * KOI8-U
550  */
551 
552 /* Specification: RFC 2319 */
553 
554 static const unsigned short _as_koi8_u_2uni[128] = {
555   /* 0x80 */
556   0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524,
557   0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590,
558   /* 0x90 */
559   0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248,
560   0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7,
561   /* 0xa0 */
562   0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457,
563   0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x0491, 0x255d, 0x255e,
564   /* 0xb0 */
565   0x255f, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407,
566   0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x0490, 0x256c, 0x00a9,
567   /* 0xc0 */
568   0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
569   0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e,
570   /* 0xd0 */
571   0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
572   0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a,
573   /* 0xe0 */
574   0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
575   0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
576   /* 0xf0 */
577   0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
578   0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a,
579 };
580 
581 /*
582  * CP1250 Central European
583  */
584 
585 static const unsigned short _as_cp1250_2uni[128] = {
586   /* 0x80 */
587   0x20ac, 0xfffd, 0x201a, 0xfffd, 0x201e, 0x2026, 0x2020, 0x2021,
588   0xfffd, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179,
589   /* 0x90 */
590   0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
591   0xfffd, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a,
592   /* 0xa0 */
593   0x00a0, 0x02c7, 0x02d8, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7,
594   0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b,
595   /* 0xb0 */
596   0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
597   0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c,
598   /* 0xc0 */
599   0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7,
600   0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
601   /* 0xd0 */
602   0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7,
603   0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
604   /* 0xe0 */
605   0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7,
606   0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
607   /* 0xf0 */
608   0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7,
609   0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9,
610 };
611 
612 /*
613  * CP1251 Cyrillic
614  */
615 
616 static const unsigned short _as_cp1251_2uni[128] = {
617   /* 0x80 */
618   0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021,
619   0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f,
620   /* 0x90 */
621   0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
622   0xfffd, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f,
623   /* 0xa0 */
624   0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7,
625   0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407,
626   /* 0xb0 */
627   0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7,
628   0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457,
629   /* 0xc0 */
630   0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
631   0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
632   /* 0xd0 */
633   0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
634   0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
635   /* 0xe0 */
636   0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
637   0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
638   /* 0xf0 */
639   0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
640   0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
641 };
642 
643 /*
644  * CP1252 - Western European
645  */
646 
647 static const unsigned short _as_cp1252_2uni[128] = {
648   /* 0x80 */
649   0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021,
650   0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0xfffd, 0x017d, 0xfffd,
651   /* 0x90 */
652   0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
653   0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0xfffd, 0x017e, 0x0178,
654   /* 0xa0 */
655   0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
656   0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
657   /* 0xb0 */
658   0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
659   0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
660   /* 0xc0 */
661   0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
662   0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
663   /* 0xd0 */
664   0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
665   0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
666   /* 0xe0 */
667   0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
668   0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
669   /* 0xf0 */
670   0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
671   0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
672 };
673 
674 static const unsigned short *_as_supported_charsets[SUPPORTED_CHARSETS_NUM] = {
675  &_as_iso8859_1_2uni[0],
676  &_as_iso8859_2_2uni[0],
677  &_as_iso8859_3_2uni[0],
678  &_as_iso8859_4_2uni[0],
679  &_as_iso8859_5_2uni[0],
680  &_as_iso8859_6_2uni[0],
681  &_as_iso8859_7_2uni[0],
682  &_as_iso8859_8_2uni[0],
683  &_as_iso8859_9_2uni[0],
684  &_as_iso8859_10_2uni[0],
685  &_as_iso8859_13_2uni[0],
686  &_as_iso8859_14_2uni[0],
687  &_as_iso8859_15_2uni[0],
688  &_as_iso8859_16_2uni[0],
689  &_as_koi8_r_2uni[0],
690  &_as_koi8_ru_2uni[0],
691  &_as_koi8_u_2uni[0],
692  &_as_cp1250_2uni[0],
693  &_as_cp1251_2uni[0],
694  &_as_cp1252_2uni[0],
695  /* UTF-8 requires special processing : */
696  &_as_iso8859_1_2uni[0],
697 };
698 
699 #if 0
700 static unsigned short *_as_charset_names[SUPPORTED_CHARSETS_NUM][] = {
701 /* Standard 8-bit encodings */
702 {"ISO-8859-1", "ISO_8859-1", "ISO_8859-1:1987", "ISO-IR-100", "LATIN1", "L1", "csISOLatin1", 	"ISO8859-1", "ISO8859_1", "CP819", "IBM819", "" },
703 {"ISO-8859-2", "ISO_8859-2", "ISO_8859-2:1987", "ISO-IR-101", "LATIN2", "L2", "csISOLatin2", 	"ISO8859-2", "ISO8859_2", "" },
704 {"ISO-8859-3", "ISO_8859-3", "ISO_8859-3:1988", "ISO-IR-109", "LATIN3", "L3", "csISOLatin3", 	"ISO8859-3", "ISO8859_3", "" },
705 {"ISO-8859-4", "ISO_8859-4", "ISO_8859-4:1988", "ISO-IR-110", "LATIN4", "L4", "csISOLatin4", 	"ISO8859-4", "ISO8859_4", "" },
706 {"ISO-8859-5", "ISO_8859-5", "ISO_8859-5:1988", "ISO-IR-144", "CYRILLIC", "csISOLatinCyrillic","ISO8859-5", "ISO8859_5", "" },
707 {"ISO-8859-6", "ISO_8859-6", "ISO_8859-6:1987", "ISO-IR-127", "ARABIC",   "csISOLatinArabic", 	"ISO8859-6", "ISO8859_6", "ECMA-114", "ASMO-708", "" },
708 {"ISO-8859-7", "ISO_8859-7", "ISO_8859-7:1987", "ISO-IR-126", "GREEK",    "csISOLatinGreek", 	"ISO8859-7", "ISO8859_7", "ECMA-118", "ELOT_928", "GREEK8", "" },
709 {"ISO-8859-8", "ISO_8859-8", "ISO_8859-8:1988", "ISO-IR-138", "HEBREW",   "csISOLatinHebrew",   "ISO8859-8", "ISO8859_8", "" },
710 {"ISO-8859-9", "ISO_8859-9", "ISO_8859-9:1989", "ISO-IR-148", "LATIN5", "L5", "csISOLatin5",    "ISO8859-9", "ISO8859_9", "" },
711 {"ISO-8859-10","ISO_8859-10","ISO_8859-10:1992","ISO-IR-157", "LATIN6", "L6", "csISOLatin6",    "ISO8859-10", "" },
712 {"ISO-8859-13","ISO_8859-13",                   "ISO-IR-179", "LATIN7", "L7",                   "ISO8859-13", "" },
713 {"ISO-8859-14","ISO_8859-14","ISO_8859-14:1998","ISO-IR-199", "LATIN8", "L8", 	"ISO-CELTIC",   "ISO8859-14", "" },
714 {"ISO-8859-15","ISO_8859-15","ISO_8859-15:1998","ISO-IR-203",									"ISO8859-15", "" },
715 {"ISO-8859-16","ISO_8859-16","ISO_8859-16:2000","ISO-IR-226",					  				"ISO8859-16", "" },
716 /* Cyrillic 8-bit KOI encodings */
717 {"KOI8-R",  "csKOI8R", "" },
718 {"KOI8-U",  "" },
719 {"KOI8-RU", "" },
720 /* Windows 8-bit encodings */
721 {"CP1250", "WINDOWS-1250", "MS-EE",  "" },
722 {"CP1251", "WINDOWS-1251", "MS-CYRL","" },
723 {"CP1252", "WINDOWS-1252", "MS-ANSI","" }
724 };
725 
726 #endif
727 
728 static ASSupportedCharsets
parse_short_charset_name(const char * name)729 parse_short_charset_name( const char *name )
730 {
731 	/* fallbacks in case only language is specified : */
732 	if( name[0] == 'l' || name[0] == 'L' )
733 	{
734 		switch( name[1] )
735 		{
736 			case '1' : return CHARSET_ISO8859_1;
737 			case '2' : return CHARSET_ISO8859_2;
738 			case '3' : return CHARSET_ISO8859_3;
739 			case '4' : return CHARSET_ISO8859_4;
740 			case '5' : return CHARSET_ISO8859_9;
741 			case '6' : return CHARSET_ISO8859_10;
742 			case '7' : return CHARSET_ISO8859_13;
743 			case '8' : return CHARSET_ISO8859_14;
744 		}
745 	}
746 	if( mystrncasecmp( &name[0], "en", 2 ) == 0 )
747 		return CHARSET_ISO8859_1 ;     /* us */
748 	if( mystrncasecmp( &name[0], "el_GR", 5 ) == 0 )
749 		return CHARSET_ISO8859_7 ;     /* greece */
750 	else if( mystrncasecmp( &name[0], "he", 2 ) == 0 )
751 		return CHARSET_ISO8859_8 ;     /* Hebrew */
752 	else if( mystrncasecmp( &name[0], "hu", 2 ) == 0 )
753 		return CHARSET_ISO8859_2 ;     /* Hungary */
754 	else if( mystrncasecmp( &name[0], "lt", 2 ) == 0 )
755 	  	return CHARSET_ISO8859_4 ;     /* Lithuanian locale for Lithuania */
756 	else if( mystrncasecmp( &name[0], "pl", 2 ) == 0 )
757 		return CHARSET_ISO8859_2 ;     /* 2Polish locale for Poland */
758 	else if( mystrncasecmp( &name[0], "ru", 2 ) == 0 )
759 		return CHARSET_ISO8859_5 ;     /* Russian locale for Russia */
760 	else if( mystrncasecmp( &name[0], "sk", 2 ) == 0 )
761 		return CHARSET_ISO8859_2 ;     /* Slovak locale for Slovakia */
762 	else if( mystrncasecmp( &name[0], "sl", 2 ) == 0 )
763 		return CHARSET_ISO8859_2 ;     /* Slovene locale for Slovenia */
764 	else if( mystrncasecmp( &name[0], "tr", 2 ) == 0 )
765 		return CHARSET_ISO8859_9 ;     /* Turkish */
766 	else if( mystrncasecmp( &name[0], "cs", 2 ) == 0 )
767 		return CHARSET_ISO8859_2 ;     /* Czech */
768 	else
769 		return CHARSET_ISO8859_1 ;
770 }
771 
772 
773 ASSupportedCharsets
parse_charset_name(const char * name)774 parse_charset_name( const char *name )
775 {
776 	int i = 0;
777 	if( name == NULL || name[0] == '\0' || name[1] == '\0' ) /* that includes locale "C" */
778 		return CHARSET_ISO8859_1 ;
779 	/* if locale name came from LANG env var it may have formatof :
780 	 * 		language.charset@modifier
781 	 * we only need charset part of it here: */
782 	while(name[i] != '\0' && name[i] != '.' ) ++i ;
783 
784 	/* maybe LANG was set to some short thing such as just "RU" */
785 	if( name[i] == '\0' && (i == 2 || i == 5))
786 		return parse_short_charset_name( name );
787 
788 	if( name[i] == '.' )
789 	{
790 		if( name[i+1] == '\0' )
791 			return parse_short_charset_name( name );
792 		name = &name[i+1] ;
793 	}
794 	if( name[0] == 'L' || name[0] == 'l' ) /* L. or Latin... */
795 	{
796 		char latin_n = name[1] ;
797 		if( mystrncasecmp( &name[1], "ATIN", 4 ) == 0 )
798 			latin_n = name[5] ;
799 		switch( latin_n )
800 		{  /* L# latins : */
801 			case '1' : return CHARSET_ISO8859_1;
802 			case '2' : return CHARSET_ISO8859_2;
803 			case '3' : return CHARSET_ISO8859_3;
804 			case '4' : return CHARSET_ISO8859_4;
805 			case '5' : return CHARSET_ISO8859_9;
806 			case '6' : return CHARSET_ISO8859_10;
807 			case '7' : return CHARSET_ISO8859_13;
808 			case '8' : return CHARSET_ISO8859_14;
809 		}
810 		return CHARSET_ISO8859_1;
811 	}else if( name[0] == 'I' || name[0] == 'i' ) /* ISO... or IBM819*/
812 	{
813 		if( name[1] == 'S' && name[1] == 's' )
814 			if( name[2] == 'O' && name[2] == 'o' )
815 			{
816 				int pos = ( name[3] == '-' || name[3] == '_' )?4:3 ;
817 				if( name[pos] == '8' )
818 				{
819 					if( name[++pos] == '8' )
820 						if( name[++pos] == '5' )
821 							if( name[++pos] == '9' )
822 							{
823 								pos += 2 ;
824 								switch( name[pos] )
825 								{
826 									case '1' :
827 										{	switch(name[pos+1] )
828 											{	case '0' : return CHARSET_ISO8859_10;
829 												case '1' :
830 												case '2' : break;
831 												case '3' : return CHARSET_ISO8859_13;
832 												case '4' : return CHARSET_ISO8859_14;
833 												case '5' : return CHARSET_ISO8859_15;
834 												case '6' : return CHARSET_ISO8859_16;
835 											}
836 										}
837 										return CHARSET_ISO8859_1;
838 									case '2' : return CHARSET_ISO8859_2;
839 									case '3' : return CHARSET_ISO8859_3;
840 				  					case '4' : return CHARSET_ISO8859_4;
841 									case '5' : return CHARSET_ISO8859_5;
842 									case '6' : return CHARSET_ISO8859_6;
843 									case '7' : return CHARSET_ISO8859_7;
844 									case '8' : return CHARSET_ISO8859_8;
845 									case '9' : return CHARSET_ISO8859_9;
846 								}
847 							}
848 				}else if( mystrncasecmp( &name[pos], "IR-", 3 ) == 0 )
849 				{
850 					pos += 3 ;
851 					switch( name[pos+2] )
852 					{
853 						case '0' : if( name[pos+1] == '0' ) break;
854 							return CHARSET_ISO8859_4;
855 						case '1' : return CHARSET_ISO8859_2;
856 						case '2' : break;
857 						case '3' : return CHARSET_ISO8859_15;
858 	  					case '4' : return CHARSET_ISO8859_5;
859 						case '5' : break;
860 						case '6' : return (name[pos]  =='2')?CHARSET_ISO8859_16:CHARSET_ISO8859_7;
861 						case '7' : return (name[pos+1]=='2')?CHARSET_ISO8859_6:CHARSET_ISO8859_10;
862 						case '8' : return (name[pos+1]=='3')?CHARSET_ISO8859_8:CHARSET_ISO8859_9;
863 						case '9' : return (name[pos+1]=='0')?CHARSET_ISO8859_3:
864 						                  ((name[pos+1]=='7')?CHARSET_ISO8859_13:CHARSET_ISO8859_14);
865 					}
866 				}
867 			}
868 		return CHARSET_ISO8859_1;
869 	}else if( name[0] == 'C' || name[0] == 'c' ) /* cs or CP ... or CYRILLIC*/
870 	{
871 		if( name[1] == 'S' || name[1] == 's' )
872 		{/* cs* */
873 			if( mystrncasecmp( &name[2], "KOI8", 4 ) == 0 )
874 				return CHARSET_KOI8_R ;
875 			if( mystrncasecmp( &name[2], "ISOLatin", 8 ) == 0 )
876 			{
877 				switch( name[10] )
878 				{
879 					case '1' : return CHARSET_ISO8859_1;
880 					case '2' : return CHARSET_ISO8859_2;
881 					case '3' : return CHARSET_ISO8859_3;
882 					case '4' : return CHARSET_ISO8859_4;
883 					case '5' : return CHARSET_ISO8859_9;
884 					case '6' : return CHARSET_ISO8859_10;
885 					case '7' : return CHARSET_ISO8859_13;
886 					case '8' : return CHARSET_ISO8859_14;
887 				}
888 				if( name[10] == 'A' || name[10] == 'a' )
889 					return CHARSET_ISO8859_6;
890 				if( name[10] == 'C' || name[10] == 'c' )
891 					return CHARSET_ISO8859_5;
892 				if( name[10] == 'H' || name[10] == 'h' )
893 					return CHARSET_ISO8859_8;
894 				if( name[10] == 'G' || name[10] == 'g' )
895 					return CHARSET_ISO8859_7;
896 			}
897 			return CHARSET_ISO8859_1;
898 		}else if( name[1] == 'P' || name[1] == 'p' )
899 		{/* CP- */
900 			if( strncmp( &name[2], "125", 3 ) == 0 )
901 			{
902 				if( name[5] == '1')
903 					return CHARSET_CP1251;
904 				if( name[5] == '2')
905 					return CHARSET_CP1252;
906 				return CHARSET_CP1250;
907 			}
908 			return CHARSET_ISO8859_1;
909 		}
910 		return CHARSET_ISO8859_5 ; /* CYRILLIC */
911 	}else if( name[0] == 'K' || name[0] == 'k' ) /* KOI... */
912 	{
913 		if( mystrncasecmp( &name[1], "OI8-", 4) == 0 )
914 		{
915 			if( name[5] == 'U' || name[5] == 'u' )
916 				return CHARSET_KOI8_U;
917 			if( name[5] == 'R' || name[5] == 'r' )
918 			    if( name[6] == 'U' || name[6] == 'u' )
919 					return CHARSET_KOI8_RU;
920 		}
921 		return CHARSET_KOI8_R ;
922 	}else if( name[0] == 'E' || name[0] == 'e' ) /* ECMA... */
923 	{
924 		if( mystrncasecmp( &name[1], "CMA-11", 6 ) == 0 )
925 		{
926 			if( name[7] == '4' )
927 				return CHARSET_ISO8859_6 ;
928 		}
929 		/* ELOT_928 or ECMA-118 */
930 		return CHARSET_ISO8859_7 ;
931 	}else if( name[0] == 'M' || name[0] == 'm' ) /* MS-... */
932 	{
933 		if( name[1] == 'S' || name[1] == 's' ) /* MS-... */
934 			if( name[2] == '-' )
935 			{
936 				if( name[3] == 'C' || name[3] == 'c' )
937 					return CHARSET_CP1251 ;
938 				if( name[3] == 'A' || name[3] == 'a' )
939 					return CHARSET_CP1252 ;
940 			}
941 		return CHARSET_CP1250 ;
942 	}else if( name[0] == 'A' || name[0] == 'a' ) /* ARABIC or ASMO-708 */
943 	{
944 		return CHARSET_ISO8859_6 ;
945 	}else if( name[0] == 'G' || name[0] == 'g' ) /* GREEK or GREEK8 */
946 	{
947 		/* if( strncasecmp( &name[1], "REEK", 4 ) == 0 ) */
948 		return CHARSET_ISO8859_7 ;
949 	}else if( name[0] == 'H' || name[0] == 'h' ) /* HEBREW */
950 	{
951 		/* if( strncasecmp( &name[1], "EBREW", 5 ) == 0 ) */
952 		return CHARSET_ISO8859_8 ;
953 	}else if( name[0] == 'U' || name[0] == 'u' ) /* UTF8 ? */
954 	{
955 		return CHARSET_UTF8 ;
956 	}
957 
958 	return CHARSET_ISO8859_1 ;
959 }
960 
961 
962 const unsigned short *as_current_charset = &_as_iso8859_1_2uni[0];
963 ASSupportedCharsets as_current_charset_id = CHARSET_ISO8859_1;
964 
965 ASSupportedCharsets
as_set_charset(ASSupportedCharsets new_charset)966 as_set_charset( ASSupportedCharsets new_charset )
967 {
968 
969 	if( new_charset < 0 || new_charset >= SUPPORTED_CHARSETS_NUM )
970 		new_charset = CHARSET_ISO8859_1 ;
971 
972 	as_current_charset = _as_supported_charsets[new_charset] ;
973 	as_current_charset_id = new_charset ;
974 	return new_charset ;
975 }
976