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