a8f3cee407528c9e4b28f63016952246e9fe2c0f
[gedcom-parse.git] / ansel / ANSI_Z39.47.c
1 /* $Id$ */
2 /* $Name$ */
3
4 /* Generic conversion to and from ANSI Z39.47 (also known as ANSEL)
5    Based on the ansi_x3.110.c file from the glibc sources
6    Data coming from:
7    http://lcweb.loc.gov/marc/specifications/speccharlatin.html
8
9    Note: in ANSEL, diacritical marks come *before* the base character;
10    in Unicode, they come *after*...
11 */
12
13 #include <dlfcn.h>
14 #include <gconv.h>
15 #include <stdint.h>
16 #include <string.h>
17
18 static const uint32_t to_ucs4[256] =
19 {
20   /* 0x00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
21   /* 0x08 */ 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
22   /* 0x10 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
23   /* 0x18 */ 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
24   /* 0x20 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
25   /* 0x28 */ 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
26   /* 0x30 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
27   /* 0x38 */ 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
28   /* 0x40 */ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
29   /* 0x48 */ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
30   /* 0x50 */ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
31   /* 0x58 */ 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
32   /* 0x60 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
33   /* 0x68 */ 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
34   /* 0x70 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
35   /* 0x78 */ 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
36   
37   /* 0x80 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
38   /* 0x88 */ 0x0088, 0x0089, 0x0000, 0x0000, 0x0000, 0x200d, 0x200c, 0x0000,
39   /* 0x90 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
40   /* 0x98 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
41   /* 0xa0 */ 0x0000, 0x0141, 0x00d8, 0x0110, 0x00de, 0x00c6, 0x0152, 0x02b9,
42   /* 0xa8 */ 0x00b7, 0x266d, 0x00ae, 0x00b1, 0x01a0, 0x01af, 0x02be, 0x0000,
43   /* 0xb0 */ 0x02bb, 0x0142, 0x00f8, 0x0111, 0x00fe, 0x00e6, 0x0153, 0x02ba,
44   /* 0xb8 */ 0x0131, 0x00a3, 0x00f0, 0x0000, 0x01a1, 0x01b0, 0x0000, 0x0000,
45   /* 0xc0 */ 0x00b0, 0x2113, 0x2117, 0x00a9, 0x266f, 0x00bf, 0x00a1, 0x0000,
46   /* 0xc8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00df,
47   /* 0xd0 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
48   /* 0xd8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
49   /* 0xe0 */ 0x0309, 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0306, 0x0307,
50   /* 0xe8 */ 0x0308, 0x030c, 0x030a, 0xfe20, 0xfe21, 0x0315, 0x030b, 0x0310,
51   /* 0xf0 */ 0x0327, 0x0328, 0x0323, 0x0324, 0x0325, 0x0333, 0x0332, 0x0326,
52   /* 0xf8 */ 0x031c, 0x032e, 0xfe22, 0xfe23, 0x0000, 0x0000, 0x0313, 0x0000
53 };
54
55 /* The outer array range runs from 0xe0 to 0xfe, the inner range from 0x20
56    to 0x7f.  */
57 static const uint32_t to_ucs4_comb[31][96] =
58 {
59   /* 0xe0 (hook above) */
60   {
61     /* 0x20 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
62     /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
63     /* 0x30 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
64     /* 0x38 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
65     /* 0x40 */ 0x0000, 0x1ea2, 0x0000, 0x0000, 0x0000, 0x1eba, 0x0000, 0x0000,
66     /* 0x48 */ 0x0000, 0x1ec8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1ece,
67     /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1ee6, 0x0000, 0x0000,
68     /* 0x58 */ 0x0000, 0x1ef6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
69     /* 0x60 */ 0x0000, 0x1ea3, 0x0000, 0x0000, 0x0000, 0x1ebb, 0x0000, 0x0000,
70     /* 0x68 */ 0x0000, 0x1ec9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1ecf,
71     /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1ee7, 0x0000, 0x0000,
72     /* 0x78 */ 0x0000, 0x1ef7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
73   },
74   /* 0xe1 (grave) */
75   {
76     /* 0x20 */ 0x0060, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
77     /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
78     /* 0x30 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
79     /* 0x38 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
80     /* 0x40 */ 0x0000, 0x00c0, 0x0000, 0x0000, 0x0000, 0x00c8, 0x0000, 0x0000,
81     /* 0x48 */ 0x0000, 0x00cc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d2,
82     /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d9, 0x0000, 0x0000,
83     /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
84     /* 0x60 */ 0x0000, 0x00e0, 0x0000, 0x0000, 0x0000, 0x00e8, 0x0000, 0x0000,
85     /* 0x68 */ 0x0000, 0x00ec, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f2,
86     /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f9, 0x0000, 0x0000,
87     /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
88   },
89   /* 0xe2 (acute) */
90   {
91     /* 0x20 */ 0x00b4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
92     /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
93     /* 0x30 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
94     /* 0x38 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
95     /* 0x40 */ 0x0000, 0x00c1, 0x0000, 0x0106, 0x0000, 0x00c9, 0x0000, 0x0000,
96     /* 0x48 */ 0x0000, 0x00cd, 0x0000, 0x0000, 0x0139, 0x0000, 0x0143, 0x00d3,
97     /* 0x50 */ 0x0000, 0x0000, 0x0154, 0x015a, 0x0000, 0x00da, 0x0000, 0x0000,
98     /* 0x58 */ 0x0000, 0x00dd, 0x0179, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
99     /* 0x60 */ 0x0000, 0x00e1, 0x0000, 0x0107, 0x0000, 0x00e9, 0x0000, 0x0000,
100     /* 0x68 */ 0x0000, 0x00ed, 0x0000, 0x0000, 0x013a, 0x0000, 0x0144, 0x00f3,
101     /* 0x70 */ 0x0000, 0x0000, 0x0155, 0x015b, 0x0000, 0x00fa, 0x0000, 0x0000,
102     /* 0x78 */ 0x0000, 0x00fd, 0x017a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
103   },
104   /* 0xe3 (circumflex) */
105   {
106     /* 0x20 */ 0x005e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
107     /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
108     /* 0x30 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
109     /* 0x38 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
110     /* 0x40 */ 0x0000, 0x00c2, 0x0000, 0x0108, 0x0000, 0x00ca, 0x0000, 0x011c,
111     /* 0x48 */ 0x0124, 0x00ce, 0x0134, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d4,
112     /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x015c, 0x0000, 0x00db, 0x0000, 0x0174,
113     /* 0x58 */ 0x0000, 0x0176, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
114     /* 0x60 */ 0x0000, 0x00e2, 0x0000, 0x0109, 0x0000, 0x00ea, 0x0000, 0x011d,
115     /* 0x68 */ 0x0125, 0x00ee, 0x0135, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f4,
116     /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x015d, 0x0000, 0x00fb, 0x0000, 0x0175,
117     /* 0x78 */ 0x0000, 0x0177, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
118   },
119   /* 0xe4 (tilde) */
120   {
121     /* 0x20 */ 0x007e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
122     /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
123     /* 0x30 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
124     /* 0x38 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
125     /* 0x40 */ 0x0000, 0x00c3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
126     /* 0x48 */ 0x0000, 0x0128, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d1, 0x00d5,
127     /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0168, 0x0000, 0x0000,
128     /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
129     /* 0x60 */ 0x0000, 0x00e3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
130     /* 0x68 */ 0x0000, 0x0129, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f1, 0x00f5,
131     /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0169, 0x0000, 0x0000,
132     /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
133   },
134   /* 0xe5 (macron) */
135   {
136     /* 0x20 */ 0x00af, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
137     /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
138     /* 0x30 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
139     /* 0x38 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
140     /* 0x40 */ 0x0000, 0x0100, 0x0000, 0x0000, 0x0000, 0x0112, 0x0000, 0x0000,
141     /* 0x48 */ 0x0000, 0x012a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x014c,
142     /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016a, 0x0000, 0x0000,
143     /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
144     /* 0x60 */ 0x0000, 0x0101, 0x0000, 0x0000, 0x0000, 0x0113, 0x0000, 0x0000,
145     /* 0x68 */ 0x0000, 0x012b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x014d,
146     /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016b, 0x0000, 0x0000,
147     /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
148   },
149   /* 0xe6 (breve) */
150   {
151     /* 0x20 */ 0x02d8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
152     /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
153     /* 0x30 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
154     /* 0x38 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
155     /* 0x40 */ 0x0000, 0x0102, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x011e,
156     /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
157     /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x0000, 0x0000,
158     /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
159     /* 0x60 */ 0x0000, 0x0103, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x011f,
160     /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
161     /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016d, 0x0000, 0x0000,
162     /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
163   },
164   /* 0xe7 (dot above) */
165   {
166     /* 0x20 */ 0x02d9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
167     /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
168     /* 0x30 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
169     /* 0x38 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
170     /* 0x40 */ 0x0000, 0x0226, 0x0000, 0x010a, 0x0000, 0x0116, 0x0000, 0x0120,
171     /* 0x48 */ 0x0000, 0x0130, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x022e,
172     /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
173     /* 0x58 */ 0x0000, 0x0000, 0x017b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
174     /* 0x60 */ 0x0000, 0x0227, 0x0000, 0x010b, 0x0000, 0x0117, 0x0000, 0x0121,
175     /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x022f,
176     /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
177     /* 0x78 */ 0x0000, 0x0000, 0x017c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
178   },
179   /* 0xe8 (umlaut, diaeresis) */
180   {
181     /* 0x20 */ 0x00a8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
182     /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
183     /* 0x30 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
184     /* 0x38 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
185     /* 0x40 */ 0x0000, 0x00c4, 0x0000, 0x0000, 0x0000, 0x00cb, 0x0000, 0x0000,
186     /* 0x48 */ 0x0000, 0x00cf, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d6,
187     /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00dc, 0x0000, 0x0000,
188     /* 0x58 */ 0x0000, 0x0178, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
189     /* 0x60 */ 0x0000, 0x00e4, 0x0000, 0x0000, 0x0000, 0x00eb, 0x0000, 0x0000,
190     /* 0x68 */ 0x0000, 0x00ef, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f6,
191     /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00fc, 0x0000, 0x0000,
192     /* 0x78 */ 0x0000, 0x00ff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
193   },
194   /* 0xe9 (caron, hacek) */
195   {
196     /* 0x20 */ 0x02c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
197     /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
198     /* 0x30 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
199     /* 0x38 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
200     /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x010c, 0x010e, 0x011a, 0x0000, 0x0000,
201     /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x013d, 0x0000, 0x0147, 0x0000,
202     /* 0x50 */ 0x0000, 0x0000, 0x0158, 0x0160, 0x0164, 0x0000, 0x0000, 0x0000,
203     /* 0x58 */ 0x0000, 0x0000, 0x017d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
204     /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x010d, 0x010f, 0x011b, 0x0000, 0x0000,
205     /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x013e, 0x0000, 0x0148, 0x0000,
206     /* 0x70 */ 0x0000, 0x0000, 0x0159, 0x0161, 0x0165, 0x0000, 0x0000, 0x0000,
207     /* 0x78 */ 0x0000, 0x0000, 0x017e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
208   },
209   /* 0xea (ring above) */
210   {
211     /* 0x20 */ 0x02da, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
212     /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
213     /* 0x30 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
214     /* 0x38 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
215     /* 0x40 */ 0x0000, 0x00c5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
216     /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
217     /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016e, 0x0000, 0x0000,
218     /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
219     /* 0x60 */ 0x0000, 0x00e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
220     /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
221     /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016f, 0x0000, 0x0000,
222     /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
223   },
224   /* 0xeb (ligature, left half) */
225   {
226     0x0000,
227   },
228   /* 0xec (ligature, right half) */
229   {
230     0x0000,
231   },
232   /* 0xed (comma above right) */
233   {
234     0x0000,
235   },
236   /* 0xee (double acute) */
237   {
238     /* 0x20 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
239     /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
240     /* 0x30 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
241     /* 0x38 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
242     /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
243     /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0150,
244     /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0170, 0x0000, 0x0000,
245     /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
246     /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
247     /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0151,
248     /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0171, 0x0000, 0x0000,
249     /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
250   },
251   /* 0xef (candrabindu) */      
252   {
253     0x0000,
254   },
255   /* 0xf0 (cedilla) */
256   {
257     /* 0x20 */ 0x00b8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
258     /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
259     /* 0x30 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
260     /* 0x38 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
261     /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x00c7, 0x0000, 0x0000, 0x0000, 0x0122,
262     /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0136, 0x013b, 0x0000, 0x0145, 0x0000,
263     /* 0x50 */ 0x0000, 0x0000, 0x0156, 0x015e, 0x0162, 0x0000, 0x0000, 0x0000,
264     /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
265     /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x00e7, 0x0000, 0x0000, 0x0000, 0x0123,
266     /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0137, 0x013c, 0x0000, 0x0146, 0x0000,
267     /* 0x70 */ 0x0000, 0x0000, 0x0157, 0x015f, 0x0163, 0x0000, 0x0000, 0x0000,
268     /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
269   },
270   /* 0xf1 (ogonek, right hook) */
271   {
272     /* 0x20 */ 0x02db, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
273     /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
274     /* 0x30 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
275     /* 0x38 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
276     /* 0x40 */ 0x0000, 0x0104, 0x0000, 0x0000, 0x0000, 0x0118, 0x0000, 0x0000,
277     /* 0x48 */ 0x0000, 0x012e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
278     /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0172, 0x0000, 0x0000,
279     /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
280     /* 0x60 */ 0x0000, 0x0105, 0x0000, 0x0000, 0x0000, 0x0119, 0x0000, 0x0000,
281     /* 0x68 */ 0x0000, 0x012f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
282     /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0173, 0x0000, 0x0000,
283     /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
284   },
285   /* 0xf2 (dot below) */
286   {
287     0x0000,
288   },
289   /* 0xf3 (double dot below) */
290   {
291     0x0000,
292   },
293   /* 0xf4 (ring below) */
294   {
295     0x0000,
296   },
297   /* 0xf5 (double low line) */
298   {
299     0x0000,
300   },
301   /* 0xf6 (line below) */
302   {
303     0x0000,
304   },
305   /* 0xf7 (comma below, left hook) */
306   {
307     0x0000,
308   },
309   /* 0xf8 (left half ring below, right cedilla) */
310   {
311     0x0000,
312   },
313   /* 0xf9 (breve below, half circle below) */
314   {
315     0x0000,
316   },
317   /* 0xfa (double tilde, left half) */
318   {
319     0x0000,
320   },
321   /* 0xfb (double tilde, right half) */
322   {
323     0x0000,
324   },
325   /* 0xfc */
326   {
327     0x0000,
328   },
329   /* 0xfd */
330   {
331     0x0000,
332   },
333   /* 0xfe (comma above, high centered comma) */
334   {
335     0x0000,
336   },
337 };
338
339
340 static const char from_ucs4[][2] =
341 {
342   /* 0x0000 */ "\x00\x00", "\x01\x00", "\x02\x00", "\x03\x00", "\x04\x00",
343   /* 0x0005 */ "\x05\x00", "\x06\x00", "\x07\x00", "\x08\x00", "\x09\x00",
344   /* 0x000a */ "\x0a\x00", "\x0b\x00", "\x0c\x00", "\x0d\x00", "\x0e\x00",
345   /* 0x000f */ "\x0f\x00", "\x10\x00", "\x11\x00", "\x12\x00", "\x13\x00",
346   /* 0x0014 */ "\x14\x00", "\x15\x00", "\x16\x00", "\x17\x00", "\x18\x00",
347   /* 0x0019 */ "\x19\x00", "\x1a\x00", "\x1b\x00", "\x1c\x00", "\x1d\x00",
348   /* 0x001e */ "\x1e\x00", "\x1f\x00", "\x20\x00", "\x21\x00", "\x22\x00",
349   /* 0x0023 */ "\xa6\x00", "\xa4\x00", "\x25\x00", "\x26\x00", "\x27\x00",
350   /* 0x0028 */ "\x28\x00", "\x29\x00", "\x2a\x00", "\x2b\x00", "\x2c\x00",
351   /* 0x002d */ "\x2d\x00", "\x2e\x00", "\x2f\x00", "\x30\x00", "\x31\x00",
352   /* 0x0032 */ "\x32\x00", "\x33\x00", "\x34\x00", "\x35\x00", "\x36\x00",
353   /* 0x0037 */ "\x37\x00", "\x38\x00", "\x39\x00", "\x3a\x00", "\x3b\x00",
354   /* 0x003c */ "\x3c\x00", "\x3d\x00", "\x3e\x00", "\x3f\x00", "\x40\x00",
355   /* 0x0041 */ "\x41\x00", "\x42\x00", "\x43\x00", "\x44\x00", "\x45\x00",
356   /* 0x0046 */ "\x46\x00", "\x47\x00", "\x48\x00", "\x49\x00", "\x4a\x00",
357   /* 0x004b */ "\x4b\x00", "\x4c\x00", "\x4d\x00", "\x4e\x00", "\x4f\x00",
358   /* 0x0050 */ "\x50\x00", "\x51\x00", "\x52\x00", "\x53\x00", "\x54\x00",
359   /* 0x0055 */ "\x55\x00", "\x56\x00", "\x57\x00", "\x58\x00", "\x59\x00",
360   /* 0x005a */ "\x5a\x00", "\x5b\x00", "\x5c\x00", "\x5d\x00", "\x5e\x00",
361   /* 0x005f */ "\x5f\x00", "\x60\x00", "\x61\x00", "\x62\x00", "\x63\x00",
362   /* 0x0064 */ "\x64\x00", "\x65\x00", "\x66\x00", "\x67\x00", "\x68\x00",
363   /* 0x0069 */ "\x69\x00", "\x6a\x00", "\x6b\x00", "\x6c\x00", "\x6d\x00",
364   /* 0x006e */ "\x6e\x00", "\x6f\x00", "\x70\x00", "\x71\x00", "\x72\x00",
365   /* 0x0073 */ "\x73\x00", "\x74\x00", "\x75\x00", "\x76\x00", "\x77\x00",
366   /* 0x0078 */ "\x78\x00", "\x79\x00", "\x7a\x00", "\x7b\x00", "\x7c\x00",
367   /* 0x007d */ "\x7d\x00", "\x7e\x00", "\x7f\x00", "\x00\x00", "\x00\x00",
368   /* 0x0082 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00",
369   /* 0x0087 */ "\x00\x00", "\x88\x00", "\x89\x00", "\x00\x00", "\x00\x00",
370   /* 0x008c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00",
371   /* 0x0091 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00",
372   /* 0x0096 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00",
373   /* 0x009b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00",
374   /* 0x00a0 */ "\x00\x00", "\xc6\x00", "\x00\x00", "\xb9\x00", "\x00\x00",
375   /* 0x00a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x20", "\xc3\x00",
376   /* 0x00aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xaa\x00",
377   /* 0x00af */ "\x00\x20", "\xc0\x00", "\xab\x00", "\x00\x00", "\x00\x00",
378   /* 0x00b4 */ "\x00\x20", "\x00\x00", "\x00\x00", "\xa8\x00", "\x00\x00",
379   /* 0x00b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00",
380   /* 0x00be */ "\x00\x00", "\xc5\x00", "\xe1\x41", "\xe2\x41", "\xe3\x41",
381   /* 0x00c3 */ "\xe4\x41", "\xe8\x41", "\xea\x41", "\xa5\x00", "\xf0\x43",
382   /* 0x00c8 */ "\xe1\x45", "\xe2\x45", "\xe3\x45", "\xe8\x45", "\xe1\x49",
383   /* 0x00cd */ "\xe2\x49", "\xe3\x49", "\xe8\x49", "\xa3\x00", "\xe4\x4e",
384   /* 0x00d2 */ "\xe1\x4f", "\xe2\x4f", "\xce\x4f", "\xe4\x4f", "\xe8\x4f",
385   /* 0x00d7 */ "\x00\x00", "\xa2\x00", "\xe1\x55", "\xe2\x55", "\xe3\x55",
386   /* 0x00dc */ "\xe8\x55", "\xe2\x59", "\xa4\x00", "\xc8\x00", "\xe1\x61",
387   /* 0x00e1 */ "\xe2\x61", "\xe3\x61", "\xe4\x61", "\xe8\x61", "\xea\x61",
388   /* 0x00e6 */ "\xb5\x00", "\xf0\x63", "\xe1\x65", "\xe2\x65", "\xe3\x65",
389   /* 0x00eb */ "\xe8\x65", "\xe1\x69", "\xe2\x69", "\xe3\x69", "\xe8\x69",
390   /* 0x00f0 */ "\xba\x00", "\xe4\x6e", "\xe1\x6f", "\xe2\x6f", "\xe3\x6f",
391   /* 0x00f5 */ "\xe4\x6f", "\xe8\x6f", "\x00\x00", "\xb2\x00", "\xe1\x75",
392   /* 0x00fa */ "\xe2\x75", "\xe3\x75", "\xe8\x75", "\xe2\x79", "\xb4\x00",
393   /* 0x00ff */ "\xe8\x79", "\xe5\x41", "\xe5\x61", "\xe6\x41", "\xe6\x61",
394   /* 0x0104 */ "\xe1\x41", "\xe1\x61", "\xe2\x43", "\xe2\x63", "\xe3\x43",
395   /* 0x0109 */ "\xe3\x63", "\xe7\x43", "\xe7\x63", "\xe9\x43", "\xe9\x63",
396   /* 0x010e */ "\xe9\x44", "\xe9\x64", "\xa3\x00", "\xb3\x00", "\xe5\x45",
397   /* 0x0113 */ "\xe5\x65", "\xe6\x65", "\xe6\x65", "\xe7\x45", "\xe7\x65",
398   /* 0x0118 */ "\xf1\x45", "\xf1\x65", "\xe9\x45", "\xe9\x65", "\xe3\x47",
399   /* 0x011d */ "\xe3\x67", "\xe6\x47", "\xe6\x67", "\xe7\x47", "\xe7\x67",
400   /* 0x0122 */ "\xf0\x47", "\xf0\x67", "\xe3\x48", "\x00\x00", "\x00\x00",
401   /* 0x0127 */ "\xe5\x68", "\xe4\x49", "\xe4\x69", "\xe5\x49", "\xe5\x69",
402   /* 0x012c */ "\xe6\x49", "\xe6\x69", "\xf1\x49", "\xf1\x69", "\xe7\x49",
403   /* 0x0131 */ "\xb8\x00", "\x00\x00", "\x00\x00", "\xe3\x4a", "\xe3\x6a",
404   /* 0x0136 */ "\xf0\x4b", "\xf0\x6b", "\x00\x00", "\xe2\x4c", "\xe2\x6c",
405   /* 0x013b */ "\xf0\x4c", "\xf0\x6c", "\xe9\x4c", "\xe9\x6c", "\xe7\x4c",
406   /* 0x0140 */ "\xe7\x6c", "\xa1\x00", "\xb1\x00", "\xe2\x4e", "\xe2\x6e",
407   /* 0x0145 */ "\xf0\x4e", "\xf0\x6e", "\xe9\x4e", "\xe9\x6e", "\x00\x00",
408   /* 0x014a */ "\x00\x00", "\x00\x00", "\xe5\x4f", "\xe5\x6f", "\xe6\x4f",
409   /* 0x014f */ "\xe6\x6f", "\xee\x4f", "\xee\x6f", "\xa6\x00", "\xb6\x00",
410   /* 0x0154 */ "\xe2\x52", "\xe2\x72", "\xf0\x52", "\xf0\x72", "\xe9\x52",
411   /* 0x0159 */ "\xe9\x72", "\xe2\x53", "\xe2\x73", "\xe3\x53", "\xe3\x73",
412   /* 0x015e */ "\xf0\x53", "\xf0\x73", "\xe9\x53", "\xe9\x73", "\xf0\x54",
413   /* 0x0163 */ "\xf0\x74", "\xe9\x54", "\xe9\x74", "\x00\x00", "\x00\x00",
414   /* 0x0168 */ "\xe4\x55", "\xe4\x75", "\xe5\x55", "\xe5\x75", "\xe6\x55",
415   /* 0x016d */ "\xe6\x75", "\xea\x55", "\xea\x75", "\xee\x55", "\xee\x75",
416   /* 0x0172 */ "\xf1\x55", "\xf1\x75", "\xe3\x57", "\xe3\x77", "\xe3\x59",
417   /* 0x0177 */ "\xe3\x79", "\xe8\x59", "\xe2\x5a", "\xe2\x7a", "\xe7\x5a",
418   /* 0x017c */ "\xe7\x7a", "\xe9\x5a", "\xe9\x7a"
419 /*
420    This table does not cover the following positions:
421
422      0x01a0    "\xac\x00", "\xbc\x00"
423      ...
424      0x01af    "\xad\x00", "\xbd\x00"
425      ...
426      0x0226    "\xe7\x41", "\xe7\x61"
427      ...
428      0x022e    "\xe7\x4f", "\xe7\x6f"
429      ...
430      0x02ba    "\xb7\x00"
431      ...
432      0x02be    "\xae\x00", "\xb0\x00"
433      ...
434      0x02c7    "\xe9\x20",
435      ...
436      0x02d8    "\xe6\x20", "\xe7\x20", "\xea\x20", "\xf1\x20", "\xe4\x20",
437      0x02dd    "\xee\x20",
438      ...
439      0x200C    "\x8e\x00", "\x8d\x00"
440      ...
441      0x2113    "\xc1\x00"
442      ...
443      0x2117    "\xc2\x00"
444      ...
445      0x266d    "\xa9\x00", "\x00\x00", "\xc4\x00"
446      ...
447      0xfe20    "\xeb\x00", "\xec\x00", "\xfa\x00", "\xfb\x00"
448
449    These would blow up the table and are therefore handled specially in
450    the code.
451 */
452 };
453
454
455 /* Definitions used in the body of the `gconv' function.  */
456 #define CHARSET_NAME            "ANSI_Z39.47//"
457 #define FROM_LOOP               from_ansi_z39_47
458 #define TO_LOOP                 to_ansi_z39_47
459 #define DEFINE_INIT             1
460 #define DEFINE_FINI             1
461 #define MIN_NEEDED_FROM         1
462 #define MAX_NEEDED_FROM         2
463 #define MIN_NEEDED_TO           4
464
465 /* First define the conversion function from ANSI_Z39.47 to UCS4.  */
466 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
467 #define MAX_NEEDED_INPUT        MAX_NEEDED_FROM
468 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
469 #define LOOPFCT                 FROM_LOOP
470 #define BODY \
471   {                                                                           \
472     uint32_t ch = *inptr;                                                     \
473     int incr;                                                                 \
474                                                                               \
475     if (__builtin_expect (ch >= 0xe0, 0) && ch <= 0xfe)                       \
476       {                                                                       \
477         /* Composed character.  First test whether the next character         \
478            is also available.  */                                             \
479         uint32_t ch2;                                                         \
480                                                                               \
481         if (inptr + 1 >= inend)                                               \
482           {                                                                   \
483             /* The second character is not available.  */                     \
484             result = __GCONV_INCOMPLETE_INPUT;                                \
485             break;                                                            \
486           }                                                                   \
487                                                                               \
488         ch2 = inptr[1];                                                       \
489                                                                               \
490         if (__builtin_expect (ch2 < 0x20, 0)                                  \
491             || __builtin_expect (ch2 >= 0x80, 0))                             \
492           {                                                                   \
493             /* This is illegal.  */                                           \
494             if (! ignore_errors_p ())                                         \
495               {                                                               \
496                 result = __GCONV_ILLEGAL_INPUT;                               \
497                 break;                                                        \
498               }                                                               \
499                                                                               \
500             ++*irreversible;                                                  \
501             incr = 1;                                                         \
502           }                                                                   \
503         else                                                                  \
504           {                                                                   \
505             uint32_t ch3 = to_ucs4_comb[ch - 0xe0][ch2 - 0x20];               \
506             if (ch3 != 0) {                                                   \
507               ch = ch3;                                                       \
508               incr = 2;                                                       \
509             }                                                                 \
510             else {                                                            \
511               ch2 = to_ucs4[ch2];                                             \
512               put32 (outptr, ch2);                                            \
513               outptr += 4;                                                    \
514               ch = to_ucs4[ch];                                               \
515               incr = 2;                                                       \
516             }                                                                 \
517           }                                                                   \
518       }                                                                       \
519     else                                                                      \
520       {                                                                       \
521         ch = to_ucs4[ch];                                                     \
522         incr = 1;                                                             \
523       }                                                                       \
524                                                                               \
525     if (__builtin_expect (ch, 1) == 0 && *inptr != '\0')                      \
526       {                                                                       \
527         /* This is an illegal character.  */                                  \
528         if (! ignore_errors_p ())                                             \
529           {                                                                   \
530             result = __GCONV_ILLEGAL_INPUT;                                   \
531             break;                                                            \
532           }                                                                   \
533       }                                                                       \
534     else                                                                      \
535       {                                                                       \
536         put32 (outptr, ch);                                                   \
537         outptr += 4;                                                          \
538       }                                                                       \
539                                                                               \
540     inptr += incr;                                                            \
541   }
542 #define LOOP_NEED_FLAGS
543 #include "loop.c"
544
545
546 /* Next, define the other direction.  */
547 #define MIN_NEEDED_INPUT        MIN_NEEDED_TO
548 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_FROM
549 #define MAX_NEEDED_OUTPUT       MAX_NEEDED_FROM
550 #define LOOPFCT                 TO_LOOP
551 #define BODY \
552   {                                                                           \
553     char tmp[2];                                                              \
554     uint32_t ch = get32 (inptr);                                              \
555     const char *cp;                                                           \
556                                                                               \
557     if (__builtin_expect (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]),   \
558         0))                                                                   \
559       {                                                                       \
560         if (ch >= 0x1a0 && ch <= 0x1a1)                                       \
561           {                                                                   \
562             static const char map[2] = "\xac\xbc";                            \
563             tmp[0] = map[ch - 0x1a0];                                         \
564             tmp[1] = '\0';                                                    \
565             cp = tmp;                                                         \
566           }                                                                   \
567         else if (ch >= 0x1af && ch <= 0x1b0)                                  \
568           {                                                                   \
569             static const char map[2] = "\xad\xbd";                            \
570             tmp[0] = map[ch - 0x1af];                                         \
571             tmp[1] = '\0';                                                    \
572             cp = tmp;                                                         \
573           }                                                                   \
574         else if (ch >= 0x226 && ch <= 0x227)                                  \
575           {                                                                   \
576             static const char map[2] = "\x41\x61";                            \
577             tmp[0] = '\xe7';                                                  \
578             tmp[1] = map[ch - 0x226];                                         \
579             cp = tmp;                                                         \
580           }                                                                   \
581         else if (ch >= 0x22e && ch <= 0x22f)                                  \
582           {                                                                   \
583             static const char map[2] = "\x4f\x6f";                            \
584             tmp[0] = '\xe7';                                                  \
585             tmp[1] = map[ch - 0x22e];                                         \
586             cp = tmp;                                                         \
587           }                                                                   \
588         else if (ch = 0x2ba)                                                  \
589             cp = "\xb7";                                                      \
590         else if (ch >= 0x2be && ch <= 0x2bf)                                  \
591           {                                                                   \
592             static const char map[2] = "\xae\xb0";                            \
593             tmp[0] = map[ch - 0x2be];                                         \
594             tmp[1] = '\0';                                                    \
595             cp = tmp;                                                         \
596           }                                                                   \
597         else if (ch = 0x2c7)                                                  \
598             cp = "\xe9 ";                                                     \
599         else if (ch >= 0x2d8 && ch <= 0x2dd && ch != 0x2dc)                   \
600           {                                                                   \
601             static const char map[6] = "\xe6\xe7\xea\xf1\xe4\xee";            \
602                                                                               \
603             tmp[0] = map[ch - 0x2d8];                                         \
604             tmp[1] = ' ';                                                     \
605             cp = tmp;                                                         \
606           }                                                                   \
607         else if (ch = 0x200c)                                                 \
608             cp = "\x8e";                                                      \
609         else if (ch = 0x200d)                                                 \
610             cp = "\x8d";                                                      \
611         else if (ch = 0x2113)                                                 \
612             cp = "\xc1";                                                      \
613         else if (ch = 0x2117)                                                 \
614             cp = "\xc2";                                                      \
615         else if (ch = 0x266d)                                                 \
616             cp = "\xa9";                                                      \
617         else if (ch = 0x266f)                                                 \
618             cp = "\xc4";                                                      \
619         else if (ch >= 0xfe20 && ch <= 0xfe23)                                \
620           {                                                                   \
621             static const char map[4] = "\xeb\xec\xfa\xfb";                    \
622                                                                               \
623             tmp[0] = map[ch - 0xfe20];                                        \
624             tmp[1] = '\0';                                                    \
625             cp = tmp;                                                         \
626           }                                                                   \
627         else                                                                  \
628           {                                                                   \
629             UNICODE_TAG_HANDLER (ch, 4);                                      \
630                                                                               \
631             /* Illegal characters.  */                                        \
632             STANDARD_ERR_HANDLER (4);                                         \
633           }                                                                   \
634       }                                                                       \
635     else                                                                      \
636       {                                                                       \
637         cp = from_ucs4[ch];                                                   \
638                                                                               \
639         if (__builtin_expect (cp[0], '\1') == '\0' && ch != 0)                \
640           {                                                                   \
641             /* Illegal characters.  */                                        \
642             STANDARD_ERR_HANDLER (4);                                         \
643           }                                                                   \
644       }                                                                       \
645                                                                               \
646     *outptr++ = cp[0];                                                        \
647     /* Now test for a possible second byte and write this if possible.  */    \
648     if (cp[1] != '\0')                                                        \
649       {                                                                       \
650         if (__builtin_expect (outptr >= outend, 0))                           \
651           {                                                                   \
652             /* The result does not fit into the buffer.  */                   \
653             --outptr;                                                         \
654             result = __GCONV_FULL_OUTPUT;                                     \
655             break;                                                            \
656           }                                                                   \
657                                                                               \
658         *outptr++ = cp[1];                                                    \
659       }                                                                       \
660                                                                               \
661     inptr += 4;                                                               \
662   }
663 #define LOOP_NEED_FLAGS
664 #include "loop.c"
665
666
667 /* Now define the toplevel functions.  */
668 #include "skeleton.c"