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