Update.
[platform/upstream/glibc.git] / iconvdata / iso646.c
1 /* Conversion to and from the various ISO 646 CCS.
2    Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15
16    You should have received a copy of the GNU Library General Public
17    License along with the GNU C Library; see the file COPYING.LIB.  If not,
18    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 /* The implementation of the conversion which can be performed by this
22    module are not very sophisticated and not tuned at all.  There are
23    zillions of ISO 646 derivates and supporting them all in a separate
24    module is overkill since these coded character sets are hardly ever
25    used anymore (except ANSI_X3.4-1968 == ASCII, which is compatible
26    with ISO 8859-1).  The European variants are superceded by the
27    various ISO 8859-? standards and the Asian variants are embedded in
28    larger character sets.  Therefore this implementation is simply
29    here to make it possible to do the conversion if it is necessary.
30    The cost in the gconv-modules file is set to `2' and therefore
31    allows one to easily provide a tuned implementation in case this
32    proofs to be necessary.  */
33
34 #include <dlfcn.h>
35 #include <gconv.h>
36 #include <stdint.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 /* Definitions used in the body of the `gconv' function.  */
41 #define FROM_LOOP               from_ascii
42 #define TO_LOOP                 to_ascii
43 #define DEFINE_INIT             0
44 #define DEFINE_FINI             0
45 #define MIN_NEEDED_FROM         1
46 #define MIN_NEEDED_TO           4
47 #define FROM_DIRECTION          (dir == from_iso646)
48 #define PREPARE_LOOP \
49   enum direction dir = ((struct iso646_data *) step->__data)->dir;            \
50   enum variant var = ((struct iso646_data *) step->__data)->var;
51 #define EXTRA_LOOP_ARGS         , var
52
53
54 /* Direction of the transformation.  */
55 enum direction
56 {
57   illegal_dir,
58   to_iso646,
59   from_iso646
60 };
61
62 enum variant
63 {
64   illegal_var,
65   US,           /* ANSI_X3.4-1968 */
66   GB,           /* BS_4730 */
67   CA,           /* CSA_Z243.4-1985-1 */
68   CA2,          /* CSA_Z243.4-1985-2 */
69   DE,           /* DIN_66003 */
70   DK,           /* DS_2089 */
71   ES,           /* ES */
72   ES2,          /* ES2 */
73   CN,           /* GB_1988-80 */
74   IT,           /* IT */
75   JP,           /* JIS_C6220-1969-RO */
76   JP_OCR_B,     /* JIS_C6229-1984-B */
77   YU,           /* JUS_I.B1.002 */
78   KR,           /* KSC5636 */
79   HU,           /* MSZ_7795.3 */
80   CU,           /* NC_NC00-10 */
81   FR,           /* NF_Z_62-010 */
82   FR1,          /* NF_Z_62-010_(1973) */
83   NO,           /* NS_4551-1 */
84   NO2,          /* NS_4551-2 */
85   PT,           /* PT */
86   PT2,          /* PT2 */
87   SE,           /* SEN_850200_B */
88   SE2           /* SEN_850200_C */
89 };
90
91 static const char *names[] =
92 {
93   [US] = "ANSI_X3.4-1968//",
94   [GB] = "BS_4730//",
95   [CA] = "CSA_Z243.4-1985-1//",
96   [CA2] = "CSA_Z243.4-1985-2//",
97   [DE] = "DIN_66003//",
98   [DK] = "DS_2089//",
99   [ES] = "ES//",
100   [ES2] = "ES2//",
101   [CN] = "GB_1988-80//",
102   [IT] = "IT//",
103   [JP] = "JIS_C6220-1969-RO//",
104   [JP_OCR_B] = "JIS_C6229-1984-B//",
105   [YU] = "JUS_I.B1.002//",
106   [KR] = "KSC5636//",
107   [HU] = "MSZ_7795.3//",
108   [CU] = "NC_NC00-10//",
109   [FR] = "NF_Z_62-010//",
110   [FR1] = "NF_Z_62-010_1973//", /* Note that we don't have the parenthesis
111                                    in the name.  */
112   [NO] = "NS_4551-1//",
113   [NO2] = "NS_4551-2//",
114   [PT] = "PT//",
115   [PT2] = "PT2//",
116   [SE] = "SEN_850200_B//",
117   [SE2] = "SEN_850200_C//"
118 };
119
120 struct iso646_data
121 {
122   enum direction dir;
123   enum variant var;
124 };
125
126
127 int
128 gconv_init (struct __gconv_step *step)
129 {
130   /* Determine which direction.  */
131   struct iso646_data *new_data;
132   enum direction dir = illegal_dir;
133   enum variant var;
134   int result;
135
136   for (var = sizeof (names) / sizeof (names[0]) - 1; var > illegal_var; --var)
137     if (__strcasecmp (step->__from_name, names[var]) == 0)
138       {
139         dir = from_iso646;
140         break;
141       }
142     else if (__strcasecmp (step->__to_name, names[var]) == 0)
143       {
144         dir = to_iso646;
145         break;
146       }
147
148   result = __GCONV_NOCONV;
149   if (__builtin_expect (dir, from_iso646) != illegal_dir)
150     {
151       new_data = (struct iso646_data *) malloc (sizeof (struct iso646_data));
152
153       result = __GCONV_NOMEM;
154       if (new_data != NULL)
155         {
156           new_data->dir = dir;
157           new_data->var = var;
158           step->__data = new_data;
159
160           if (var == from_iso646)
161             {
162               step->__min_needed_from = MIN_NEEDED_FROM;
163               step->__max_needed_from = MIN_NEEDED_FROM;
164               step->__min_needed_to = MIN_NEEDED_TO;
165               step->__max_needed_to = MIN_NEEDED_TO;
166             }
167           else
168             {
169               step->__min_needed_from = MIN_NEEDED_TO;
170               step->__max_needed_from = MIN_NEEDED_TO;
171               step->__min_needed_to = MIN_NEEDED_FROM;
172               step->__max_needed_to = MIN_NEEDED_FROM;
173             }
174
175           step->__stateful = 0;
176
177           result = __GCONV_OK;
178         }
179     }
180
181   return result;
182 }
183
184
185 void
186 gconv_end (struct __gconv_step *data)
187 {
188   free (data->__data);
189 }
190
191
192 /* First define the conversion function from ASCII to UCS4.  */
193 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
194 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
195 #define LOOPFCT                 FROM_LOOP
196 #define BODY \
197   {                                                                           \
198     uint32_t ch;                                                              \
199     int failure = __GCONV_OK;                                                 \
200                                                                               \
201     ch = *inptr;                                                              \
202     switch (ch)                                                               \
203       {                                                                       \
204       case 0x23:                                                              \
205         if (var == GB || var == ES || var == IT || var == FR || var == FR1)   \
206           ch = 0xa3;                                                          \
207         else if (var == NO2)                                                  \
208           ch = 0xa7;                                                          \
209         break;                                                                \
210       case 0x24:                                                              \
211         if (var == CN)                                                        \
212           ch = 0xa5;                                                          \
213         else if (var == HU || var == CU || var == SE || var == SE2)           \
214           ch = 0xa4;                                                          \
215         break;                                                                \
216       case 0x40:                                                              \
217         if (var == CA || var == CA2 || var == FR || var == FR1)               \
218           ch = 0xe0;                                                          \
219         else if (var == DE || var == ES || var == IT || var == PT)            \
220           ch = 0xa7;                                                          \
221         else if (var == ES2)                                                  \
222           ch = 0x2022;                                                        \
223         else if (var == YU)                                                   \
224           ch = 0x17d;                                                         \
225         else if (var == HU)                                                   \
226           ch = 0xc1;                                                          \
227         else if (var == PT2)                                                  \
228           ch = 0xb4;                                                          \
229         else if (var == SE2)                                                  \
230           ch = 0xc9;                                                          \
231         break;                                                                \
232       case 0x5b:                                                              \
233         if (var == CA || var == CA2)                                          \
234           ch = 0xe2;                                                          \
235         else if (var == DE || var == SE || var == SE2)                        \
236           ch = 0xc4;                                                          \
237         else if (var == DK || var == NO || var == NO2)                        \
238           ch = 0xc6;                                                          \
239         else if (var == ES || var == ES2 || var == CU)                        \
240           ch = 0xa1;                                                          \
241         else if (var == IT || var == FR || var == FR1)                        \
242           ch = 0xb0;                                                          \
243         else if (var == JP_OCR_B)                                             \
244           ch = 0x2329;                                                        \
245         else if (var == YU)                                                   \
246           ch = 0x160;                                                         \
247         else if (var == HU)                                                   \
248           ch = 0xc9;                                                          \
249         else if (var == PT || var == PT2)                                     \
250           ch = 0xc3;                                                          \
251         break;                                                                \
252       case 0x5c:                                                              \
253         if (var == CA || var == CA2 || var == IT || var == FR || var == FR1)  \
254           ch = 0xe7;                                                          \
255         else if (var == DE || var == HU || var == SE || var == SE2)           \
256           ch = 0xd6;                                                          \
257         else if (var == DK || var == NO || var == NO2)                        \
258           ch = 0xd8;                                                          \
259         else if (var == ES || var == ES2 || var == CU)                        \
260           ch = 0xd1;                                                          \
261         else if (var == JP || var == JP_OCR_B)                                \
262           ch = 0xa5;                                                          \
263         else if (var == YU)                                                   \
264           ch = 0x110;                                                         \
265         else if (var == KR)                                                   \
266           ch = 0x20a9;                                                        \
267         else if (var == PT || var == PT2)                                     \
268           ch = 0xc7;                                                          \
269         break;                                                                \
270       case 0x5d:                                                              \
271         if (var == CA || var == CA2)                                          \
272           ch = 0xea;                                                          \
273         else if (var == DE || var == HU)                                      \
274           ch = 0xdc;                                                          \
275         else if (var == DK || var == NO || var == NO2 || var == SE            \
276                  || var == SE2)                                               \
277           ch = 0xc5;                                                          \
278         else if (var == ES)                                                   \
279           ch = 0xbf;                                                          \
280         else if (var == ES2)                                                  \
281           ch = 0xc7;                                                          \
282         else if (var == IT)                                                   \
283           ch = 0xe9;                                                          \
284         else if (var == JP_OCR_B)                                             \
285           ch = 0x232a;                                                        \
286         else if (var == YU)                                                   \
287           ch = 0x106;                                                         \
288         else if (var == FR || var == FR1)                                     \
289           ch = 0xa7;                                                          \
290         else if (var == PT || var == PT2)                                     \
291           ch = 0xd5;                                                          \
292         break;                                                                \
293       case 0x5e:                                                              \
294         if (var == CA)                                                        \
295           ch = 0xee;                                                          \
296         else if (var == CA2)                                                  \
297           ch = 0xc9;                                                          \
298         else if (var == ES2 || var == CU)                                     \
299           ch = 0xbf;                                                          \
300         else if (var == YU)                                                   \
301           ch = 0x10c;                                                         \
302         else if (var == SE2)                                                  \
303           ch = 0xdc;                                                          \
304         break;                                                                \
305       case 0x60:                                                              \
306         if (var == CA || var == CA2)                                          \
307           ch = 0xf4;                                                          \
308         else if (var == IT)                                                   \
309           ch = 0xf9;                                                          \
310         else if (var == JP_OCR_B)                                             \
311           /* Illegal character.  */                                           \
312           failure = __GCONV_ILLEGAL_INPUT;                                    \
313         else if (var == YU)                                                   \
314           ch = 0x17e;                                                         \
315         else if (var == HU)                                                   \
316           ch = 0xe1;                                                          \
317         else if (var == FR)                                                   \
318           ch = 0xb5;                                                          \
319         else if (var == SE2)                                                  \
320           ch = 0xe9;                                                          \
321         break;                                                                \
322       case 0x7b:                                                              \
323         if (var == CA || var == CA2 || var == HU || var == FR || var == FR1)  \
324           ch = 0xe9;                                                          \
325         else if (var == DE || var == SE || var == SE2)                        \
326           ch = 0xe4;                                                          \
327         else if (var == DK || var == NO || var == NO2)                        \
328           ch = 0xe6;                                                          \
329         else if (var == ES)                                                   \
330           ch = 0xb0;                                                          \
331         else if (var == ES2 || var == CU)                                     \
332           ch = 0xb4;                                                          \
333         else if (var == IT)                                                   \
334           ch = 0xe0;                                                          \
335         else if (var == YU)                                                   \
336           ch = 0x161;                                                         \
337         else if (var == PT || var == PT2)                                     \
338           ch = 0xe3;                                                          \
339         break;                                                                \
340       case 0x7c:                                                              \
341         if (var == CA || var == CA2 || var == FR || var == FR1)               \
342           ch = 0xf9;                                                          \
343         else if (var == DE || var == HU || var == SE || var == SE2)           \
344           ch = 0xf6;                                                          \
345         else if (var == DK || var == NO || var == NO2)                        \
346           ch = 0xf8;                                                          \
347         else if (var == ES || var == ES2 || var == CU)                        \
348           ch = 0xf1;                                                          \
349         else if (var == IT)                                                   \
350           ch = 0xf2;                                                          \
351         else if (var == YU)                                                   \
352           ch = 0x111;                                                         \
353         else if (var == PT || var == PT2)                                     \
354           ch = 0xe7;                                                          \
355         break;                                                                \
356       case 0x7d:                                                              \
357         if (var == CA || var == CA2 || var == IT || var == FR || var == FR1)  \
358           ch = 0xe8;                                                          \
359         else if (var == DE || var == HU)                                      \
360           ch = 0xfc;                                                          \
361         else if (var == DK || var == NO || var == NO2 || var == SE            \
362                  || var == SE2)                                               \
363           ch = 0xe5;                                                          \
364         else if (var == ES || var == ES2)                                     \
365           ch = 0xe7;                                                          \
366         else if (var == YU)                                                   \
367           ch = 0x107;                                                         \
368         else if (var == CU)                                                   \
369           ch = 0x5b;                                                          \
370         else if (var == PT || var == PT2)                                     \
371           ch = 0xf5;                                                          \
372         break;                                                                \
373       case 0x7e:                                                              \
374         if (var == GB || var == CN || var == JP || var == NO || var == SE)    \
375           ch = 0x203e;                                                        \
376         else if (var == CA || var == CA2)                                     \
377           ch = 0xfb;                                                          \
378         else if (var == DE)                                                   \
379           ch = 0xdf;                                                          \
380         else if (var == ES2 || var == CU || var == FR || var == FR1)          \
381           ch = 0xa8;                                                          \
382         else if (var == IT)                                                   \
383           ch = 0xec;                                                          \
384         else if (var == JP_OCR_B)                                             \
385           /* Illegal character.  */                                           \
386           failure = __GCONV_ILLEGAL_INPUT;                                    \
387         else if (var == YU)                                                   \
388           ch = 0x10d;                                                         \
389         else if (var == HU)                                                   \
390           ch = 0x2dd;                                                         \
391         else if (var == NO2)                                                  \
392           ch = 0x7c;                                                          \
393         else if (var == PT)                                                   \
394           ch = 0xb0;                                                          \
395         else if (var == SE2)                                                  \
396           ch = 0xfc;                                                          \
397         break;                                                                \
398       default:                                                                \
399         break;                                                                \
400       case 0x80 ... 0xff:                                                     \
401         /* Illegal character.  */                                             \
402         failure = __GCONV_ILLEGAL_INPUT;                                      \
403         break;                                                                \
404       }                                                                       \
405                                                                               \
406     /* Hopefully gcc can recognize that the following `if' is only true       \
407        when we reach the default case in the `switch' statement.  */          \
408     if (__builtin_expect (failure, __GCONV_OK) == __GCONV_ILLEGAL_INPUT)      \
409       {                                                                       \
410         if (! ignore_errors_p ())                                             \
411           {                                                                   \
412             /* Exit the loop with an error.  */                               \
413             result = __GCONV_ILLEGAL_INPUT;                                   \
414             break;                                                            \
415           }                                                                   \
416                                                                               \
417         ++*irreversible;                                                      \
418       }                                                                       \
419     else                                                                      \
420       {                                                                       \
421         put32 (outptr, ch);                                                   \
422         outptr += 4;                                                          \
423       }                                                                       \
424     ++inptr;                                                                  \
425   }
426 #define LOOP_NEED_FLAGS
427 #define EXTRA_LOOP_DECLS        , enum variant var
428 #include <iconv/loop.c>
429
430
431 /* Next, define the other direction.  */
432 #define MIN_NEEDED_INPUT        MIN_NEEDED_TO
433 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_FROM
434 #define LOOPFCT                 TO_LOOP
435 #define BODY \
436   {                                                                           \
437     unsigned char ch;                                                         \
438     int failure = __GCONV_OK;                                                 \
439                                                                               \
440     ch = get32 (inptr);                                                       \
441     switch (*((uint32_t *) inptr))                                            \
442       {                                                                       \
443       case 0x23:                                                              \
444         if (var == GB || var == ES || var == IT || var == FR || var == FR1    \
445             || var == NO2)                                                    \
446           failure = __GCONV_ILLEGAL_INPUT;                                    \
447         break;                                                                \
448       case 0x24:                                                              \
449         if (var == CN || var == HU || var == CU || var == SE || var == SE2)   \
450           failure = __GCONV_ILLEGAL_INPUT;                                    \
451         break;                                                                \
452       case 0x40:                                                              \
453         if (var == CA || var == CA2 || var == DE || var == ES || var == ES2   \
454             || var == IT || var == YU || var == HU || var == FR || var == FR1 \
455             || var == PT || var == PT2 || var == SE2)                         \
456           failure = __GCONV_ILLEGAL_INPUT;                                    \
457         break;                                                                \
458       case 0x5b:                                                              \
459         if (var == CA || var == CA2 || var == DE || var == DK || var == ES    \
460             || var == ES2 || var == IT || var == JP_OCR_B || var == YU        \
461             || var == HU || var == FR || var == FR1 || var == NO              \
462             || var == NO2 || var == PT || var == PT2 || var == SE             \
463             || var == SE2)                                                    \
464           failure = __GCONV_ILLEGAL_INPUT;                                    \
465         else if (var == CU)                                                   \
466           ch = 0x7d;                                                          \
467         break;                                                                \
468       case 0x5c:                                                              \
469         if (var == CA || var == CA2 || var == DE || var == DK || var == ES    \
470             || var == ES2 || var == IT || var == JP || var == JP_OCR_B        \
471             || var == YU || var == KR || var == HU || var == CU || var == FR  \
472             || var == FR1 || var == NO || var == NO2 || var == PT             \
473             || var == PT2 || var == SE || var == SE2)                         \
474           failure = __GCONV_ILLEGAL_INPUT;                                    \
475         break;                                                                \
476       case 0x5d:                                                              \
477         if (var == CA || var == CA2 || var == DE || var == DK || var == ES    \
478             || var == ES2 || var == IT || var == JP_OCR_B || var == YU        \
479             || var == HU || var == FR || var == FR1 || var == NO              \
480             || var == NO2 || var == PT || var == PT2 || var == SE             \
481             || var == SE2)                                                    \
482           failure = __GCONV_ILLEGAL_INPUT;                                    \
483         break;                                                                \
484       case 0x5e:                                                              \
485         if (var == CA || var == CA2 || var == ES2 || var == YU || var == CU   \
486             || var == SE2)                                                    \
487           failure = __GCONV_ILLEGAL_INPUT;                                    \
488         break;                                                                \
489       case 0x60:                                                              \
490         if (var == CA || var == CA2 || var == IT || var == JP_OCR_B           \
491             || var == YU || var == HU || var == FR || var == SE2)             \
492           failure = __GCONV_ILLEGAL_INPUT;                                    \
493         break;                                                                \
494       case 0x7b:                                                              \
495         if (var == CA || var == CA2 || var == DE || var == DK || var == ES    \
496             || var == ES2 || var == IT || var == YU || var == HU              \
497             || var == CU || var == FR || var == FR1 || var == NO              \
498             || var == NO2 || var == PT || var == PT2 || var == SE             \
499             || var == SE2)                                                    \
500           failure = __GCONV_ILLEGAL_INPUT;                                    \
501         break;                                                                \
502       case 0x7c:                                                              \
503         if (var == CA || var == CA2 || var == DE || var == DK || var == ES    \
504             || var == ES2 || var == IT || var == YU || var == HU || var == CU \
505             || var == FR || var == FR1 || var == NO || var == PT              \
506             || var == PT2 || var == SE || var == SE2)                         \
507           failure = __GCONV_ILLEGAL_INPUT;                                    \
508         else if (var == NO2)                                                  \
509           ch = 0x7e;                                                          \
510         break;                                                                \
511       case 0x7d:                                                              \
512         if (var == CA || var == CA2 || var == DE || var == DK || var == ES    \
513             || var == ES2 || var == IT || var == YU || var == HU || var == CU \
514             || var == FR || var == FR1 || var == NO || var == NO2             \
515             || var == PT || var == PT2 || var == SE || var == SE2)            \
516           failure = __GCONV_ILLEGAL_INPUT;                                    \
517         break;                                                                \
518       case 0x7e:                                                              \
519         if (var == GB || var == CA || var == CA2 || var == DE || var == ES2   \
520             || var == CN || var == IT || var == JP || var == JP_OCR_B         \
521             || var == YU || var == HU || var == CU || var == FR || var == FR1 \
522             || var == NO || var == NO2 || var == PT || var == SE              \
523             || var == SE2)                                                    \
524           failure = __GCONV_ILLEGAL_INPUT;                                    \
525         break;                                                                \
526       case 0xa1:                                                              \
527         if (var != ES && var != ES2 && var != CU)                             \
528           failure = __GCONV_ILLEGAL_INPUT;                                    \
529         ch = 0x5b;                                                            \
530         break;                                                                \
531       case 0xa3:                                                              \
532         if (var != GB && var != ES && var != IT && var != FR && var != FR1)   \
533           failure = __GCONV_ILLEGAL_INPUT;                                    \
534         ch = 0x23;                                                            \
535         break;                                                                \
536       case 0xa4:                                                              \
537         if (var != HU && var != CU && var != SE && var != SE2)                \
538           failure = __GCONV_ILLEGAL_INPUT;                                    \
539         ch = 0x24;                                                            \
540         break;                                                                \
541       case 0xa5:                                                              \
542         if (var == CN)                                                        \
543           ch = 0x24;                                                          \
544         else if (var == JP || var == JP_OCR_B)                                \
545           ch = 0x5c;                                                          \
546         else                                                                  \
547           failure = __GCONV_ILLEGAL_INPUT;                                    \
548         break;                                                                \
549       case 0xa7:                                                              \
550         if (var == DE || var == ES || var == IT || var == PT)                 \
551           ch = 0x40;                                                          \
552         else if (var == FR || var == FR1)                                     \
553           ch = 0x5d;                                                          \
554         else if (var == NO2)                                                  \
555           ch = 0x23;                                                          \
556         else                                                                  \
557           failure = __GCONV_ILLEGAL_INPUT;                                    \
558         break;                                                                \
559       case 0xa8:                                                              \
560         if (var != ES2 && var != CU && var != FR && var != FR1)               \
561           failure = __GCONV_ILLEGAL_INPUT;                                    \
562         ch = 0x7e;                                                            \
563         break;                                                                \
564       case 0xb0:                                                              \
565         if (var == ES)                                                        \
566           ch = 0x7b;                                                          \
567         else if (var == IT || var == FR || var == FR1)                        \
568           ch = 0x5b;                                                          \
569         else if (var == PT)                                                   \
570           ch = 0x7e;                                                          \
571         else                                                                  \
572           failure = __GCONV_ILLEGAL_INPUT;                                    \
573         break;                                                                \
574       case 0xb4:                                                              \
575         if (var == ES2 || var == CU)                                          \
576           ch = 0x7b;                                                          \
577         else if (var == PT2)                                                  \
578           ch = 0x40;                                                          \
579         else                                                                  \
580           failure = __GCONV_ILLEGAL_INPUT;                                    \
581         break;                                                                \
582       case 0xb5:                                                              \
583         if (var != FR)                                                        \
584           failure = __GCONV_ILLEGAL_INPUT;                                    \
585         ch = 0x60;                                                            \
586         break;                                                                \
587       case 0xbf:                                                              \
588         if (var == ES)                                                        \
589           ch = 0x5d;                                                          \
590         else if (var == ES2 || var == CU)                                     \
591           ch = 0x5e;                                                          \
592         else                                                                  \
593           failure = __GCONV_ILLEGAL_INPUT;                                    \
594         break;                                                                \
595       case 0xc1:                                                              \
596         if (var != HU)                                                        \
597           failure = __GCONV_ILLEGAL_INPUT;                                    \
598         ch = 0x40;                                                            \
599         break;                                                                \
600       case 0xc3:                                                              \
601         if (var != PT && var != PT2)                                          \
602           failure = __GCONV_ILLEGAL_INPUT;                                    \
603         ch = 0x5b;                                                            \
604         break;                                                                \
605       case 0xc4:                                                              \
606         if (var != DE && var != SE && var != SE2)                             \
607           failure = __GCONV_ILLEGAL_INPUT;                                    \
608         ch = 0x5b;                                                            \
609         break;                                                                \
610       case 0xc5:                                                              \
611         if (var != DK && var != NO && var != NO2 && var != SE && var != SE2)  \
612           failure = __GCONV_ILLEGAL_INPUT;                                    \
613         ch = 0x5d;                                                            \
614         break;                                                                \
615       case 0xc6:                                                              \
616         if (var != DK && var != NO && var != NO2)                             \
617           failure = __GCONV_ILLEGAL_INPUT;                                    \
618         ch = 0x5b;                                                            \
619         break;                                                                \
620       case 0xc7:                                                              \
621         if (var == ES2)                                                       \
622           ch = 0x5d;                                                          \
623         else if (var == PT || var == PT2)                                     \
624           ch = 0x5c;                                                          \
625         else                                                                  \
626           failure = __GCONV_ILLEGAL_INPUT;                                    \
627         break;                                                                \
628       case 0xc9:                                                              \
629         if (var == CA2)                                                       \
630           ch = 0x5e;                                                          \
631         else if (var == HU)                                                   \
632           ch = 0x5b;                                                          \
633         else if (var == SE2)                                                  \
634           ch = 0x40;                                                          \
635         else                                                                  \
636           failure = __GCONV_ILLEGAL_INPUT;                                    \
637         break;                                                                \
638       case 0xd1:                                                              \
639         if (var != ES && var != ES2 && var != CU)                             \
640           failure = __GCONV_ILLEGAL_INPUT;                                    \
641         ch = 0x5c;                                                            \
642         break;                                                                \
643       case 0xd5:                                                              \
644         if (var != PT && var != PT2)                                          \
645           failure = __GCONV_ILLEGAL_INPUT;                                    \
646         ch = 0x5d;                                                            \
647         break;                                                                \
648       case 0xd6:                                                              \
649         if (var != DE && var != HU && var != SE && var != SE2)                \
650           failure = __GCONV_ILLEGAL_INPUT;                                    \
651         ch = 0x5c;                                                            \
652         break;                                                                \
653       case 0xd8:                                                              \
654         if (var != DK && var != NO && var != NO2)                             \
655           failure = __GCONV_ILLEGAL_INPUT;                                    \
656         ch = 0x5c;                                                            \
657         break;                                                                \
658       case 0xdc:                                                              \
659         if (var == DE || var == HU)                                           \
660           ch = 0x5d;                                                          \
661         else if (var == SE2)                                                  \
662           ch = 0x5e;                                                          \
663         else                                                                  \
664           failure = __GCONV_ILLEGAL_INPUT;                                    \
665         break;                                                                \
666       case 0xdf:                                                              \
667         if (var != DE)                                                        \
668           failure = __GCONV_ILLEGAL_INPUT;                                    \
669         ch = 0x7e;                                                            \
670         break;                                                                \
671       case 0xe0:                                                              \
672         if (var == CA || var == CA2 || var == FR || var == FR1)               \
673           ch = 0x40;                                                          \
674         else if (var == IT)                                                   \
675           ch = 0x7b;                                                          \
676         else                                                                  \
677           failure = __GCONV_ILLEGAL_INPUT;                                    \
678         break;                                                                \
679       case 0xe1:                                                              \
680         if (var != HU)                                                        \
681           failure = __GCONV_ILLEGAL_INPUT;                                    \
682         ch = 0x60;                                                            \
683         break;                                                                \
684       case 0xe2:                                                              \
685         if (var != CA && var != CA2)                                          \
686           failure = __GCONV_ILLEGAL_INPUT;                                    \
687         ch = 0x5b;                                                            \
688         break;                                                                \
689       case 0xe3:                                                              \
690         if (var != PT && var != PT2)                                          \
691           failure = __GCONV_ILLEGAL_INPUT;                                    \
692         ch = 0x7b;                                                            \
693         break;                                                                \
694       case 0xe4:                                                              \
695         if (var != DE && var != SE && var != SE2)                             \
696           failure = __GCONV_ILLEGAL_INPUT;                                    \
697         ch = 0x7b;                                                            \
698         break;                                                                \
699       case 0xe5:                                                              \
700         if (var != DK && var != NO && var != NO2 && var != SE && var != SE2)  \
701           failure = __GCONV_ILLEGAL_INPUT;                                    \
702         ch = 0x7d;                                                            \
703         break;                                                                \
704       case 0xe6:                                                              \
705         if (var != DK && var != NO && var != NO2)                             \
706           failure = __GCONV_ILLEGAL_INPUT;                                    \
707         ch = 0x7b;                                                            \
708         break;                                                                \
709       case 0xe7:                                                              \
710         if (var == CA || var == CA2 || var == IT || var == FR || var == FR1)  \
711           ch = 0x5c;                                                          \
712         else if (var == ES || var == ES2)                                     \
713           ch = 0x7d;                                                          \
714         else if (var == PT || var == PT2)                                     \
715           ch = 0x7c;                                                          \
716         else                                                                  \
717           failure = __GCONV_ILLEGAL_INPUT;                                    \
718         break;                                                                \
719       case 0xe8:                                                              \
720         if (var != CA && var != CA2 && var != IT && var != FR && var != FR1)  \
721           failure = __GCONV_ILLEGAL_INPUT;                                    \
722         ch = 0x7d;                                                            \
723         break;                                                                \
724       case 0xe9:                                                              \
725         if (var == CA || var == CA2 || var == HU || var == FR || var == FR1)  \
726           ch = 0x7b;                                                          \
727         else if (var == IT)                                                   \
728           ch = 0x5d;                                                          \
729         else if (var == SE2)                                                  \
730           ch = 0x60;                                                          \
731         else                                                                  \
732           failure = __GCONV_ILLEGAL_INPUT;                                    \
733         break;                                                                \
734       case 0xea:                                                              \
735         if (var != CA && var != CA2)                                          \
736           failure = __GCONV_ILLEGAL_INPUT;                                    \
737         ch = 0x5d;                                                            \
738         break;                                                                \
739       case 0xec:                                                              \
740         if (var != IT)                                                        \
741           failure = __GCONV_ILLEGAL_INPUT;                                    \
742         ch = 0x7e;                                                            \
743         break;                                                                \
744       case 0xee:                                                              \
745         if (var != CA)                                                        \
746           failure = __GCONV_ILLEGAL_INPUT;                                    \
747         ch = 0x5e;                                                            \
748         break;                                                                \
749       case 0xf1:                                                              \
750         if (var != ES && var != ES2 && var != CU)                             \
751           failure = __GCONV_ILLEGAL_INPUT;                                    \
752         ch = 0x7c;                                                            \
753         break;                                                                \
754       case 0xf2:                                                              \
755         if (var != IT)                                                        \
756           failure = __GCONV_ILLEGAL_INPUT;                                    \
757         ch = 0x7c;                                                            \
758         break;                                                                \
759       case 0xf4:                                                              \
760         if (var != CA && var != CA2)                                          \
761           failure = __GCONV_ILLEGAL_INPUT;                                    \
762         ch = 0x60;                                                            \
763         break;                                                                \
764       case 0xf5:                                                              \
765         if (var != PT && var != PT2)                                          \
766           failure = __GCONV_ILLEGAL_INPUT;                                    \
767         ch = 0x7d;                                                            \
768         break;                                                                \
769       case 0xf6:                                                              \
770         if (var != DE && var != HU && var != SE && var != SE2)                \
771           failure = __GCONV_ILLEGAL_INPUT;                                    \
772         ch = 0x7c;                                                            \
773         break;                                                                \
774       case 0xf8:                                                              \
775         if (var != DK && var != NO && var != NO2)                             \
776           failure = __GCONV_ILLEGAL_INPUT;                                    \
777         ch = 0x7c;                                                            \
778         break;                                                                \
779       case 0xf9:                                                              \
780         if (var == CA || var == CA2 || var == FR || var == FR1)               \
781           ch = 0x7c;                                                          \
782         else if (var == IT)                                                   \
783           ch = 0x60;                                                          \
784         else                                                                  \
785           failure = __GCONV_ILLEGAL_INPUT;                                    \
786         break;                                                                \
787       case 0xfb:                                                              \
788         if (var != CA && var != CA2)                                          \
789           failure = __GCONV_ILLEGAL_INPUT;                                    \
790         ch = 0x7e;                                                            \
791         break;                                                                \
792       case 0xfc:                                                              \
793         if (var == DE || var == HU)                                           \
794           ch = 0x7d;                                                          \
795         else if (var == SE2)                                                  \
796           ch = 0x7e;                                                          \
797         else                                                                  \
798           failure = __GCONV_ILLEGAL_INPUT;                                    \
799         break;                                                                \
800       case 0x160:                                                             \
801         if (var != YU)                                                        \
802           failure = __GCONV_ILLEGAL_INPUT;                                    \
803         ch = 0x5b;                                                            \
804         break;                                                                \
805       case 0x106:                                                             \
806         if (var != YU)                                                        \
807           failure = __GCONV_ILLEGAL_INPUT;                                    \
808         ch = 0x5d;                                                            \
809         break;                                                                \
810       case 0x107:                                                             \
811         if (var != YU)                                                        \
812           failure = __GCONV_ILLEGAL_INPUT;                                    \
813         ch = 0x7d;                                                            \
814         break;                                                                \
815       case 0x10c:                                                             \
816         if (var != YU)                                                        \
817           failure = __GCONV_ILLEGAL_INPUT;                                    \
818         ch = 0x5e;                                                            \
819         break;                                                                \
820       case 0x10d:                                                             \
821         if (var != YU)                                                        \
822           failure = __GCONV_ILLEGAL_INPUT;                                    \
823         ch = 0x7e;                                                            \
824         break;                                                                \
825       case 0x110:                                                             \
826         if (var != YU)                                                        \
827           failure = __GCONV_ILLEGAL_INPUT;                                    \
828         ch = 0x5c;                                                            \
829         break;                                                                \
830       case 0x111:                                                             \
831         if (var != YU)                                                        \
832           failure = __GCONV_ILLEGAL_INPUT;                                    \
833         ch = 0x7c;                                                            \
834         break;                                                                \
835       case 0x161:                                                             \
836         if (var != YU)                                                        \
837           failure = __GCONV_ILLEGAL_INPUT;                                    \
838         ch = 0x7b;                                                            \
839         break;                                                                \
840       case 0x17d:                                                             \
841         if (var != YU)                                                        \
842           failure = __GCONV_ILLEGAL_INPUT;                                    \
843         ch = 0x40;                                                            \
844         break;                                                                \
845       case 0x17e:                                                             \
846         if (var != YU)                                                        \
847           failure = __GCONV_ILLEGAL_INPUT;                                    \
848         ch = 0x60;                                                            \
849         break;                                                                \
850       case 0x2dd:                                                             \
851         if (var != HU)                                                        \
852           failure = __GCONV_ILLEGAL_INPUT;                                    \
853         ch = 0x7e;                                                            \
854         break;                                                                \
855       case 0x2022:                                                            \
856         if (var != ES2)                                                       \
857           failure = __GCONV_ILLEGAL_INPUT;                                    \
858         ch = 0x40;                                                            \
859         break;                                                                \
860       case 0x203e:                                                            \
861         if (var != GB && var != CN && var != JP && var != NO && var != SE)    \
862           failure = __GCONV_ILLEGAL_INPUT;                                    \
863         ch = 0x7e;                                                            \
864         break;                                                                \
865       case 0x20a9:                                                            \
866         if (var != KR)                                                        \
867           failure = __GCONV_ILLEGAL_INPUT;                                    \
868         ch = 0x5c;                                                            \
869         break;                                                                \
870       case 0x2329:                                                            \
871         if (var != JP_OCR_B)                                                  \
872           failure = __GCONV_ILLEGAL_INPUT;                                    \
873         ch = 0x5b;                                                            \
874         break;                                                                \
875       case 0x232a:                                                            \
876         if (var != JP_OCR_B)                                                  \
877           failure = __GCONV_ILLEGAL_INPUT;                                    \
878         ch = 0x5d;                                                            \
879         break;                                                                \
880       default:                                                                \
881         if (*((uint32_t *) inptr) > 0x7f)                                     \
882           failure = __GCONV_ILLEGAL_INPUT;                                    \
883         break;                                                                \
884       }                                                                       \
885                                                                               \
886     if (__builtin_expect (failure, __GCONV_OK) == __GCONV_ILLEGAL_INPUT)      \
887       {                                                                       \
888         if (step_data->__trans.__trans_fct != NULL)                           \
889           {                                                                   \
890             result = DL_CALL_FCT (step_data->__trans.__trans_fct,             \
891                                   (step, step_data, *inptrp, &inptr, inend,   \
892                                    *outptrp, &outptr, outend, irreversible)); \
893             if (result != __GCONV_OK)                                         \
894               break;                                                          \
895           }                                                                   \
896         else if (! ignore_errors_p ())                                        \
897           {                                                                   \
898             /* Exit the loop with an error.  */                               \
899             result = __GCONV_ILLEGAL_INPUT;                                   \
900             break;                                                            \
901           }                                                                   \
902         else                                                                  \
903           {                                                                   \
904             ++*irreversible;                                                  \
905             inptr += 4;                                                       \
906           }                                                                   \
907         continue;                                                             \
908       }                                                                       \
909     else                                                                      \
910       *outptr++ = (unsigned char) ch;                                         \
911     inptr += 4;                                                               \
912   }
913 #define LOOP_NEED_FLAGS
914 #define EXTRA_LOOP_DECLS        , enum variant var
915 #include <iconv/loop.c>
916
917
918 /* Now define the toplevel functions.  */
919 #include <iconv/skeleton.c>