Back to index

glibc  2.9
iso646.c
Go to the documentation of this file.
00001 /* Conversion to and from the various ISO 646 CCS.
00002    Copyright (C) 1998, 1999, 2000-2002 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 /* The implementation of the conversion which can be performed by this
00022    module are not very sophisticated and not tuned at all.  There are
00023    zillions of ISO 646 derivates and supporting them all in a separate
00024    module is overkill since these coded character sets are hardly ever
00025    used anymore (except ANSI_X3.4-1968 == ASCII, which is compatible
00026    with ISO 8859-1).  The European variants are superceded by the
00027    various ISO 8859-? standards and the Asian variants are embedded in
00028    larger character sets.  Therefore this implementation is simply
00029    here to make it possible to do the conversion if it is necessary.
00030    The cost in the gconv-modules file is set to `2' and therefore
00031    allows one to easily provide a tuned implementation in case this
00032    proofs to be necessary.  */
00033 
00034 #include <dlfcn.h>
00035 #include <gconv.h>
00036 #include <stdint.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 
00040 /* Definitions used in the body of the `gconv' function.  */
00041 #define FROM_LOOP           from_ascii
00042 #define TO_LOOP                    to_ascii
00043 #define DEFINE_INIT         0
00044 #define DEFINE_FINI         0
00045 #define MIN_NEEDED_FROM            1
00046 #define MIN_NEEDED_TO              4
00047 #define FROM_DIRECTION             (dir == from_iso646)
00048 #define PREPARE_LOOP \
00049   enum direction dir = ((struct iso646_data *) step->__data)->dir;          \
00050   enum variant var = ((struct iso646_data *) step->__data)->var;
00051 #define EXTRA_LOOP_ARGS            , var
00052 
00053 
00054 /* Direction of the transformation.  */
00055 enum direction
00056 {
00057   illegal_dir,
00058   to_iso646,
00059   from_iso646
00060 };
00061 
00062 enum variant
00063 {
00064   illegal_var,
00065   GB,         /* BS_4730 */
00066   CA,         /* CSA_Z243.4-1985-1 */
00067   CA2,        /* CSA_Z243.4-1985-2 */
00068   DE,         /* DIN_66003 */
00069   DK,         /* DS_2089 */
00070   ES,         /* ES */
00071   ES2,        /* ES2 */
00072   CN,         /* GB_1988-80 */
00073   IT,         /* IT */
00074   JP,         /* JIS_C6220-1969-RO */
00075   JP_OCR_B,   /* JIS_C6229-1984-B */
00076   YU,         /* JUS_I.B1.002 */
00077   KR,         /* KSC5636 */
00078   HU,         /* MSZ_7795.3 */
00079   CU,         /* NC_NC00-10 */
00080   FR,         /* NF_Z_62-010 */
00081   FR1,        /* NF_Z_62-010_(1973) */
00082   NO,         /* NS_4551-1 */
00083   NO2,        /* NS_4551-2 */
00084   PT,         /* PT */
00085   PT2,        /* PT2 */
00086   SE,         /* SEN_850200_B */
00087   SE2         /* SEN_850200_C */
00088 };
00089 
00090 static const char *names[] =
00091 {
00092   [GB] = "BS_4730//",
00093   [CA] = "CSA_Z243.4-1985-1//",
00094   [CA2] = "CSA_Z243.4-1985-2//",
00095   [DE] = "DIN_66003//",
00096   [DK] = "DS_2089//",
00097   [ES] = "ES//",
00098   [ES2] = "ES2//",
00099   [CN] = "GB_1988-80//",
00100   [IT] = "IT//",
00101   [JP] = "JIS_C6220-1969-RO//",
00102   [JP_OCR_B] = "JIS_C6229-1984-B//",
00103   [YU] = "JUS_I.B1.002//",
00104   [KR] = "KSC5636//",
00105   [HU] = "MSZ_7795.3//",
00106   [CU] = "NC_NC00-10//",
00107   [FR] = "NF_Z_62-010//",
00108   [FR1] = "NF_Z_62-010_1973//",    /* Note that we don't have the parenthesis
00109                                in the name.  */
00110   [NO] = "NS_4551-1//",
00111   [NO2] = "NS_4551-2//",
00112   [PT] = "PT//",
00113   [PT2] = "PT2//",
00114   [SE] = "SEN_850200_B//",
00115   [SE2] = "SEN_850200_C//"
00116 };
00117 
00118 struct iso646_data
00119 {
00120   enum direction dir;
00121   enum variant var;
00122 };
00123 
00124 
00125 extern int gconv_init (struct __gconv_step *step);
00126 int
00127 gconv_init (struct __gconv_step *step)
00128 {
00129   /* Determine which direction.  */
00130   struct iso646_data *new_data;
00131   enum direction dir = illegal_dir;
00132   enum variant var;
00133   int result;
00134 
00135   for (var = sizeof (names) / sizeof (names[0]) - 1; var > illegal_var; --var)
00136     if (__strcasecmp (step->__from_name, names[var]) == 0)
00137       {
00138        dir = from_iso646;
00139        break;
00140       }
00141     else if (__strcasecmp (step->__to_name, names[var]) == 0)
00142       {
00143        dir = to_iso646;
00144        break;
00145       }
00146 
00147   result = __GCONV_NOCONV;
00148   if (__builtin_expect (dir, from_iso646) != illegal_dir)
00149     {
00150       new_data = (struct iso646_data *) malloc (sizeof (struct iso646_data));
00151 
00152       result = __GCONV_NOMEM;
00153       if (new_data != NULL)
00154        {
00155          new_data->dir = dir;
00156          new_data->var = var;
00157          step->__data = new_data;
00158 
00159          if (var == from_iso646)
00160            {
00161              step->__min_needed_from = MIN_NEEDED_FROM;
00162              step->__max_needed_from = MIN_NEEDED_FROM;
00163              step->__min_needed_to = MIN_NEEDED_TO;
00164              step->__max_needed_to = MIN_NEEDED_TO;
00165            }
00166          else
00167            {
00168              step->__min_needed_from = MIN_NEEDED_TO;
00169              step->__max_needed_from = MIN_NEEDED_TO;
00170              step->__min_needed_to = MIN_NEEDED_FROM;
00171              step->__max_needed_to = MIN_NEEDED_FROM;
00172            }
00173 
00174          step->__stateful = 0;
00175 
00176          result = __GCONV_OK;
00177        }
00178     }
00179 
00180   return result;
00181 }
00182 
00183 
00184 extern void gconv_end (struct __gconv_step *data);
00185 void
00186 gconv_end (struct __gconv_step *data)
00187 {
00188   free (data->__data);
00189 }
00190 
00191 
00192 /* First define the conversion function from ASCII to UCS4.  */
00193 #define MIN_NEEDED_INPUT    MIN_NEEDED_FROM
00194 #define MIN_NEEDED_OUTPUT   MIN_NEEDED_TO
00195 #define LOOPFCT                    FROM_LOOP
00196 #define BODY \
00197   {                                                                  \
00198     uint32_t ch;                                                     \
00199     int failure = __GCONV_OK;                                               \
00200                                                                      \
00201     ch = *inptr;                                                     \
00202     switch (ch)                                                             \
00203       {                                                                     \
00204       case 0x23:                                                     \
00205        if (var == GB || var == ES || var == IT || var == FR || var == FR1)   \
00206          ch = 0xa3;                                                  \
00207        else if (var == NO2)                                          \
00208          ch = 0xa7;                                                  \
00209        break;                                                        \
00210       case 0x24:                                                     \
00211        if (var == CN)                                                       \
00212          ch = 0xa5;                                                  \
00213        else if (var == HU || var == CU || var == SE || var == SE2)          \
00214          ch = 0xa4;                                                  \
00215        break;                                                        \
00216       case 0x40:                                                     \
00217        if (var == CA || var == CA2 || var == FR || var == FR1)              \
00218          ch = 0xe0;                                                  \
00219        else if (var == DE || var == ES || var == IT || var == PT)           \
00220          ch = 0xa7;                                                  \
00221        else if (var == ES2)                                          \
00222          ch = 0x2022;                                                       \
00223        else if (var == YU)                                           \
00224          ch = 0x17d;                                                 \
00225        else if (var == HU)                                           \
00226          ch = 0xc1;                                                  \
00227        else if (var == PT2)                                          \
00228          ch = 0xb4;                                                  \
00229        else if (var == SE2)                                          \
00230          ch = 0xc9;                                                  \
00231        break;                                                        \
00232       case 0x5b:                                                     \
00233        if (var == CA || var == CA2)                                         \
00234          ch = 0xe2;                                                  \
00235        else if (var == DE || var == SE || var == SE2)                       \
00236          ch = 0xc4;                                                  \
00237        else if (var == DK || var == NO || var == NO2)                       \
00238          ch = 0xc6;                                                  \
00239        else if (var == ES || var == ES2 || var == CU)                       \
00240          ch = 0xa1;                                                  \
00241        else if (var == IT || var == FR || var == FR1)                       \
00242          ch = 0xb0;                                                  \
00243        else if (var == JP_OCR_B)                                     \
00244          ch = 0x2329;                                                       \
00245        else if (var == YU)                                           \
00246          ch = 0x160;                                                 \
00247        else if (var == HU)                                           \
00248          ch = 0xc9;                                                  \
00249        else if (var == PT || var == PT2)                             \
00250          ch = 0xc3;                                                  \
00251        break;                                                        \
00252       case 0x5c:                                                     \
00253        if (var == CA || var == CA2 || var == IT || var == FR || var == FR1)  \
00254          ch = 0xe7;                                                  \
00255        else if (var == DE || var == HU || var == SE || var == SE2)          \
00256          ch = 0xd6;                                                  \
00257        else if (var == DK || var == NO || var == NO2)                       \
00258          ch = 0xd8;                                                  \
00259        else if (var == ES || var == ES2 || var == CU)                       \
00260          ch = 0xd1;                                                  \
00261        else if (var == JP || var == JP_OCR_B)                               \
00262          ch = 0xa5;                                                  \
00263        else if (var == YU)                                           \
00264          ch = 0x110;                                                 \
00265        else if (var == KR)                                           \
00266          ch = 0x20a9;                                                       \
00267        else if (var == PT || var == PT2)                             \
00268          ch = 0xc7;                                                  \
00269        break;                                                        \
00270       case 0x5d:                                                     \
00271        if (var == CA || var == CA2)                                         \
00272          ch = 0xea;                                                  \
00273        else if (var == DE || var == HU)                              \
00274          ch = 0xdc;                                                  \
00275        else if (var == DK || var == NO || var == NO2 || var == SE           \
00276                || var == SE2)                                               \
00277          ch = 0xc5;                                                  \
00278        else if (var == ES)                                           \
00279          ch = 0xbf;                                                  \
00280        else if (var == ES2)                                          \
00281          ch = 0xc7;                                                  \
00282        else if (var == IT)                                           \
00283          ch = 0xe9;                                                  \
00284        else if (var == JP_OCR_B)                                     \
00285          ch = 0x232a;                                                       \
00286        else if (var == YU)                                           \
00287          ch = 0x106;                                                 \
00288        else if (var == FR || var == FR1)                             \
00289          ch = 0xa7;                                                  \
00290        else if (var == PT || var == PT2)                             \
00291          ch = 0xd5;                                                  \
00292        break;                                                        \
00293       case 0x5e:                                                     \
00294        if (var == CA)                                                       \
00295          ch = 0xee;                                                  \
00296        else if (var == CA2)                                          \
00297          ch = 0xc9;                                                  \
00298        else if (var == ES2 || var == CU)                             \
00299          ch = 0xbf;                                                  \
00300        else if (var == YU)                                           \
00301          ch = 0x10c;                                                 \
00302        else if (var == SE2)                                          \
00303          ch = 0xdc;                                                  \
00304        break;                                                        \
00305       case 0x60:                                                     \
00306        if (var == CA || var == CA2)                                         \
00307          ch = 0xf4;                                                  \
00308        else if (var == IT)                                           \
00309          ch = 0xf9;                                                  \
00310        else if (var == JP_OCR_B)                                     \
00311          /* Illegal character.  */                                   \
00312          failure = __GCONV_ILLEGAL_INPUT;                            \
00313        else if (var == YU)                                           \
00314          ch = 0x17e;                                                 \
00315        else if (var == HU)                                           \
00316          ch = 0xe1;                                                  \
00317        else if (var == FR)                                           \
00318          ch = 0xb5;                                                  \
00319        else if (var == SE2)                                          \
00320          ch = 0xe9;                                                  \
00321        break;                                                        \
00322       case 0x7b:                                                     \
00323        if (var == CA || var == CA2 || var == HU || var == FR || var == FR1)  \
00324          ch = 0xe9;                                                  \
00325        else if (var == DE || var == SE || var == SE2)                       \
00326          ch = 0xe4;                                                  \
00327        else if (var == DK || var == NO || var == NO2)                       \
00328          ch = 0xe6;                                                  \
00329        else if (var == ES)                                           \
00330          ch = 0xb0;                                                  \
00331        else if (var == ES2 || var == CU)                             \
00332          ch = 0xb4;                                                  \
00333        else if (var == IT)                                           \
00334          ch = 0xe0;                                                  \
00335        else if (var == YU)                                           \
00336          ch = 0x161;                                                 \
00337        else if (var == PT || var == PT2)                             \
00338          ch = 0xe3;                                                  \
00339        break;                                                        \
00340       case 0x7c:                                                     \
00341        if (var == CA || var == CA2 || var == FR || var == FR1)              \
00342          ch = 0xf9;                                                  \
00343        else if (var == DE || var == HU || var == SE || var == SE2)          \
00344          ch = 0xf6;                                                  \
00345        else if (var == DK || var == NO || var == NO2)                       \
00346          ch = 0xf8;                                                  \
00347        else if (var == ES || var == ES2 || var == CU)                       \
00348          ch = 0xf1;                                                  \
00349        else if (var == IT)                                           \
00350          ch = 0xf2;                                                  \
00351        else if (var == YU)                                           \
00352          ch = 0x111;                                                 \
00353        else if (var == PT || var == PT2)                             \
00354          ch = 0xe7;                                                  \
00355        break;                                                        \
00356       case 0x7d:                                                     \
00357        if (var == CA || var == CA2 || var == IT || var == FR || var == FR1)  \
00358          ch = 0xe8;                                                  \
00359        else if (var == DE || var == HU)                              \
00360          ch = 0xfc;                                                  \
00361        else if (var == DK || var == NO || var == NO2 || var == SE           \
00362                || var == SE2)                                               \
00363          ch = 0xe5;                                                  \
00364        else if (var == ES || var == ES2)                             \
00365          ch = 0xe7;                                                  \
00366        else if (var == YU)                                           \
00367          ch = 0x107;                                                 \
00368        else if (var == CU)                                           \
00369          ch = 0x5b;                                                  \
00370        else if (var == PT || var == PT2)                             \
00371          ch = 0xf5;                                                  \
00372        break;                                                        \
00373       case 0x7e:                                                     \
00374        if (var == GB || var == CN || var == JP || var == NO || var == SE)    \
00375          ch = 0x203e;                                                       \
00376        else if (var == CA || var == CA2)                             \
00377          ch = 0xfb;                                                  \
00378        else if (var == DE)                                           \
00379          ch = 0xdf;                                                  \
00380        else if (var == ES2 || var == CU || var == FR || var == FR1)         \
00381          ch = 0xa8;                                                  \
00382        else if (var == IT)                                           \
00383          ch = 0xec;                                                  \
00384        else if (var == JP_OCR_B)                                     \
00385          /* Illegal character.  */                                   \
00386          failure = __GCONV_ILLEGAL_INPUT;                            \
00387        else if (var == YU)                                           \
00388          ch = 0x10d;                                                 \
00389        else if (var == HU)                                           \
00390          ch = 0x2dd;                                                 \
00391        else if (var == NO2)                                          \
00392          ch = 0x7c;                                                  \
00393        else if (var == PT)                                           \
00394          ch = 0xb0;                                                  \
00395        else if (var == SE2)                                          \
00396          ch = 0xfc;                                                  \
00397        break;                                                        \
00398       default:                                                              \
00399        break;                                                        \
00400       case 0x80 ... 0xff:                                            \
00401        /* Illegal character.  */                                     \
00402        failure = __GCONV_ILLEGAL_INPUT;                              \
00403        break;                                                        \
00404       }                                                                     \
00405                                                                      \
00406     /* Hopefully gcc can recognize that the following `if' is only true            \
00407        when we reach the default case in the `switch' statement.  */        \
00408     if (__builtin_expect (failure, __GCONV_OK) == __GCONV_ILLEGAL_INPUT)      \
00409       {                                                                     \
00410        STANDARD_FROM_LOOP_ERR_HANDLER (1);                                  \
00411       }                                                                     \
00412     else                                                             \
00413       {                                                                     \
00414        put32 (outptr, ch);                                           \
00415        outptr += 4;                                                  \
00416       }                                                                     \
00417     ++inptr;                                                         \
00418   }
00419 #define LOOP_NEED_FLAGS
00420 #define EXTRA_LOOP_DECLS    , enum variant var
00421 #include <iconv/loop.c>
00422 
00423 
00424 /* Next, define the other direction.  */
00425 #define MIN_NEEDED_INPUT    MIN_NEEDED_TO
00426 #define MIN_NEEDED_OUTPUT   MIN_NEEDED_FROM
00427 #define LOOPFCT                    TO_LOOP
00428 #define BODY \
00429   {                                                                  \
00430     unsigned int ch;                                                 \
00431     int failure = __GCONV_OK;                                               \
00432                                                                      \
00433     ch = get32 (inptr);                                                     \
00434     switch (ch)                                                             \
00435       {                                                                     \
00436       case 0x23:                                                     \
00437        if (var == GB || var == ES || var == IT || var == FR || var == FR1    \
00438            || var == NO2)                                            \
00439          failure = __GCONV_ILLEGAL_INPUT;                            \
00440        break;                                                        \
00441       case 0x24:                                                     \
00442        if (var == CN || var == HU || var == CU || var == SE || var == SE2)   \
00443          failure = __GCONV_ILLEGAL_INPUT;                            \
00444        break;                                                        \
00445       case 0x40:                                                     \
00446        if (var == CA || var == CA2 || var == DE || var == ES || var == ES2   \
00447            || var == IT || var == YU || var == HU || var == FR || var == FR1 \
00448            || var == PT || var == PT2 || var == SE2)                        \
00449          failure = __GCONV_ILLEGAL_INPUT;                            \
00450        break;                                                        \
00451       case 0x5b:                                                     \
00452        if (var == CA || var == CA2 || var == DE || var == DK || var == ES    \
00453            || var == ES2 || var == IT || var == JP_OCR_B || var == YU       \
00454            || var == HU || var == FR || var == FR1 || var == NO             \
00455            || var == NO2 || var == PT || var == PT2 || var == SE            \
00456            || var == SE2)                                            \
00457          failure = __GCONV_ILLEGAL_INPUT;                            \
00458        else if (var == CU)                                           \
00459          ch = 0x7d;                                                  \
00460        break;                                                        \
00461       case 0x5c:                                                     \
00462        if (var == CA || var == CA2 || var == DE || var == DK || var == ES    \
00463            || var == ES2 || var == IT || var == JP || var == JP_OCR_B       \
00464            || var == YU || var == KR || var == HU || var == CU || var == FR  \
00465            || var == FR1 || var == NO || var == NO2 || var == PT            \
00466            || var == PT2 || var == SE || var == SE2)                        \
00467          failure = __GCONV_ILLEGAL_INPUT;                            \
00468        break;                                                        \
00469       case 0x5d:                                                     \
00470        if (var == CA || var == CA2 || var == DE || var == DK || var == ES    \
00471            || var == ES2 || var == IT || var == JP_OCR_B || var == YU       \
00472            || var == HU || var == FR || var == FR1 || var == NO             \
00473            || var == NO2 || var == PT || var == PT2 || var == SE            \
00474            || var == SE2)                                            \
00475          failure = __GCONV_ILLEGAL_INPUT;                            \
00476        break;                                                        \
00477       case 0x5e:                                                     \
00478        if (var == CA || var == CA2 || var == ES2 || var == YU || var == CU   \
00479            || var == SE2)                                            \
00480          failure = __GCONV_ILLEGAL_INPUT;                            \
00481        break;                                                        \
00482       case 0x60:                                                     \
00483        if (var == CA || var == CA2 || var == IT || var == JP_OCR_B          \
00484            || var == YU || var == HU || var == FR || var == SE2)            \
00485          failure = __GCONV_ILLEGAL_INPUT;                            \
00486        break;                                                        \
00487       case 0x7b:                                                     \
00488        if (var == CA || var == CA2 || var == DE || var == DK || var == ES    \
00489            || var == ES2 || var == IT || var == YU || var == HU             \
00490            || var == CU || var == FR || var == FR1 || var == NO             \
00491            || var == NO2 || var == PT || var == PT2 || var == SE            \
00492            || var == SE2)                                            \
00493          failure = __GCONV_ILLEGAL_INPUT;                            \
00494        break;                                                        \
00495       case 0x7c:                                                     \
00496        if (var == CA || var == CA2 || var == DE || var == DK || var == ES    \
00497            || var == ES2 || var == IT || var == YU || var == HU || var == CU \
00498            || var == FR || var == FR1 || var == NO || var == PT             \
00499            || var == PT2 || var == SE || var == SE2)                        \
00500          failure = __GCONV_ILLEGAL_INPUT;                            \
00501        else if (var == NO2)                                          \
00502          ch = 0x7e;                                                  \
00503        break;                                                        \
00504       case 0x7d:                                                     \
00505        if (var == CA || var == CA2 || var == DE || var == DK || var == ES    \
00506            || var == ES2 || var == IT || var == YU || var == HU || var == CU \
00507            || var == FR || var == FR1 || var == NO || var == NO2            \
00508            || var == PT || var == PT2 || var == SE || var == SE2)           \
00509          failure = __GCONV_ILLEGAL_INPUT;                            \
00510        break;                                                        \
00511       case 0x7e:                                                     \
00512        if (var == GB || var == CA || var == CA2 || var == DE || var == ES2   \
00513            || var == CN || var == IT || var == JP || var == JP_OCR_B        \
00514            || var == YU || var == HU || var == CU || var == FR || var == FR1 \
00515            || var == NO || var == NO2 || var == PT || var == SE             \
00516            || var == SE2)                                            \
00517          failure = __GCONV_ILLEGAL_INPUT;                            \
00518        break;                                                        \
00519       case 0xa1:                                                     \
00520        if (var != ES && var != ES2 && var != CU)                     \
00521          failure = __GCONV_ILLEGAL_INPUT;                            \
00522        ch = 0x5b;                                                    \
00523        break;                                                        \
00524       case 0xa3:                                                     \
00525        if (var != GB && var != ES && var != IT && var != FR && var != FR1)   \
00526          failure = __GCONV_ILLEGAL_INPUT;                            \
00527        ch = 0x23;                                                    \
00528        break;                                                        \
00529       case 0xa4:                                                     \
00530        if (var != HU && var != CU && var != SE && var != SE2)               \
00531          failure = __GCONV_ILLEGAL_INPUT;                            \
00532        ch = 0x24;                                                    \
00533        break;                                                        \
00534       case 0xa5:                                                     \
00535        if (var == CN)                                                       \
00536          ch = 0x24;                                                  \
00537        else if (var == JP || var == JP_OCR_B)                               \
00538          ch = 0x5c;                                                  \
00539        else                                                          \
00540          failure = __GCONV_ILLEGAL_INPUT;                            \
00541        break;                                                        \
00542       case 0xa7:                                                     \
00543        if (var == DE || var == ES || var == IT || var == PT)                \
00544          ch = 0x40;                                                  \
00545        else if (var == FR || var == FR1)                             \
00546          ch = 0x5d;                                                  \
00547        else if (var == NO2)                                          \
00548          ch = 0x23;                                                  \
00549        else                                                          \
00550          failure = __GCONV_ILLEGAL_INPUT;                            \
00551        break;                                                        \
00552       case 0xa8:                                                     \
00553        if (var != ES2 && var != CU && var != FR && var != FR1)              \
00554          failure = __GCONV_ILLEGAL_INPUT;                            \
00555        ch = 0x7e;                                                    \
00556        break;                                                        \
00557       case 0xb0:                                                     \
00558        if (var == ES)                                                       \
00559          ch = 0x7b;                                                  \
00560        else if (var == IT || var == FR || var == FR1)                       \
00561          ch = 0x5b;                                                  \
00562        else if (var == PT)                                           \
00563          ch = 0x7e;                                                  \
00564        else                                                          \
00565          failure = __GCONV_ILLEGAL_INPUT;                            \
00566        break;                                                        \
00567       case 0xb4:                                                     \
00568        if (var == ES2 || var == CU)                                         \
00569          ch = 0x7b;                                                  \
00570        else if (var == PT2)                                          \
00571          ch = 0x40;                                                  \
00572        else                                                          \
00573          failure = __GCONV_ILLEGAL_INPUT;                            \
00574        break;                                                        \
00575       case 0xb5:                                                     \
00576        if (var != FR)                                                       \
00577          failure = __GCONV_ILLEGAL_INPUT;                            \
00578        ch = 0x60;                                                    \
00579        break;                                                        \
00580       case 0xbf:                                                     \
00581        if (var == ES)                                                       \
00582          ch = 0x5d;                                                  \
00583        else if (var == ES2 || var == CU)                             \
00584          ch = 0x5e;                                                  \
00585        else                                                          \
00586          failure = __GCONV_ILLEGAL_INPUT;                            \
00587        break;                                                        \
00588       case 0xc1:                                                     \
00589        if (var != HU)                                                       \
00590          failure = __GCONV_ILLEGAL_INPUT;                            \
00591        ch = 0x40;                                                    \
00592        break;                                                        \
00593       case 0xc3:                                                     \
00594        if (var != PT && var != PT2)                                         \
00595          failure = __GCONV_ILLEGAL_INPUT;                            \
00596        ch = 0x5b;                                                    \
00597        break;                                                        \
00598       case 0xc4:                                                     \
00599        if (var != DE && var != SE && var != SE2)                     \
00600          failure = __GCONV_ILLEGAL_INPUT;                            \
00601        ch = 0x5b;                                                    \
00602        break;                                                        \
00603       case 0xc5:                                                     \
00604        if (var != DK && var != NO && var != NO2 && var != SE && var != SE2)  \
00605          failure = __GCONV_ILLEGAL_INPUT;                            \
00606        ch = 0x5d;                                                    \
00607        break;                                                        \
00608       case 0xc6:                                                     \
00609        if (var != DK && var != NO && var != NO2)                     \
00610          failure = __GCONV_ILLEGAL_INPUT;                            \
00611        ch = 0x5b;                                                    \
00612        break;                                                        \
00613       case 0xc7:                                                     \
00614        if (var == ES2)                                                      \
00615          ch = 0x5d;                                                  \
00616        else if (var == PT || var == PT2)                             \
00617          ch = 0x5c;                                                  \
00618        else                                                          \
00619          failure = __GCONV_ILLEGAL_INPUT;                            \
00620        break;                                                        \
00621       case 0xc9:                                                     \
00622        if (var == CA2)                                                      \
00623          ch = 0x5e;                                                  \
00624        else if (var == HU)                                           \
00625          ch = 0x5b;                                                  \
00626        else if (var == SE2)                                          \
00627          ch = 0x40;                                                  \
00628        else                                                          \
00629          failure = __GCONV_ILLEGAL_INPUT;                            \
00630        break;                                                        \
00631       case 0xd1:                                                     \
00632        if (var != ES && var != ES2 && var != CU)                     \
00633          failure = __GCONV_ILLEGAL_INPUT;                            \
00634        ch = 0x5c;                                                    \
00635        break;                                                        \
00636       case 0xd5:                                                     \
00637        if (var != PT && var != PT2)                                         \
00638          failure = __GCONV_ILLEGAL_INPUT;                            \
00639        ch = 0x5d;                                                    \
00640        break;                                                        \
00641       case 0xd6:                                                     \
00642        if (var != DE && var != HU && var != SE && var != SE2)               \
00643          failure = __GCONV_ILLEGAL_INPUT;                            \
00644        ch = 0x5c;                                                    \
00645        break;                                                        \
00646       case 0xd8:                                                     \
00647        if (var != DK && var != NO && var != NO2)                     \
00648          failure = __GCONV_ILLEGAL_INPUT;                            \
00649        ch = 0x5c;                                                    \
00650        break;                                                        \
00651       case 0xdc:                                                     \
00652        if (var == DE || var == HU)                                   \
00653          ch = 0x5d;                                                  \
00654        else if (var == SE2)                                          \
00655          ch = 0x5e;                                                  \
00656        else                                                          \
00657          failure = __GCONV_ILLEGAL_INPUT;                            \
00658        break;                                                        \
00659       case 0xdf:                                                     \
00660        if (var != DE)                                                       \
00661          failure = __GCONV_ILLEGAL_INPUT;                            \
00662        ch = 0x7e;                                                    \
00663        break;                                                        \
00664       case 0xe0:                                                     \
00665        if (var == CA || var == CA2 || var == FR || var == FR1)              \
00666          ch = 0x40;                                                  \
00667        else if (var == IT)                                           \
00668          ch = 0x7b;                                                  \
00669        else                                                          \
00670          failure = __GCONV_ILLEGAL_INPUT;                            \
00671        break;                                                        \
00672       case 0xe1:                                                     \
00673        if (var != HU)                                                       \
00674          failure = __GCONV_ILLEGAL_INPUT;                            \
00675        ch = 0x60;                                                    \
00676        break;                                                        \
00677       case 0xe2:                                                     \
00678        if (var != CA && var != CA2)                                         \
00679          failure = __GCONV_ILLEGAL_INPUT;                            \
00680        ch = 0x5b;                                                    \
00681        break;                                                        \
00682       case 0xe3:                                                     \
00683        if (var != PT && var != PT2)                                         \
00684          failure = __GCONV_ILLEGAL_INPUT;                            \
00685        ch = 0x7b;                                                    \
00686        break;                                                        \
00687       case 0xe4:                                                     \
00688        if (var != DE && var != SE && var != SE2)                     \
00689          failure = __GCONV_ILLEGAL_INPUT;                            \
00690        ch = 0x7b;                                                    \
00691        break;                                                        \
00692       case 0xe5:                                                     \
00693        if (var != DK && var != NO && var != NO2 && var != SE && var != SE2)  \
00694          failure = __GCONV_ILLEGAL_INPUT;                            \
00695        ch = 0x7d;                                                    \
00696        break;                                                        \
00697       case 0xe6:                                                     \
00698        if (var != DK && var != NO && var != NO2)                     \
00699          failure = __GCONV_ILLEGAL_INPUT;                            \
00700        ch = 0x7b;                                                    \
00701        break;                                                        \
00702       case 0xe7:                                                     \
00703        if (var == CA || var == CA2 || var == IT || var == FR || var == FR1)  \
00704          ch = 0x5c;                                                  \
00705        else if (var == ES || var == ES2)                             \
00706          ch = 0x7d;                                                  \
00707        else if (var == PT || var == PT2)                             \
00708          ch = 0x7c;                                                  \
00709        else                                                          \
00710          failure = __GCONV_ILLEGAL_INPUT;                            \
00711        break;                                                        \
00712       case 0xe8:                                                     \
00713        if (var != CA && var != CA2 && var != IT && var != FR && var != FR1)  \
00714          failure = __GCONV_ILLEGAL_INPUT;                            \
00715        ch = 0x7d;                                                    \
00716        break;                                                        \
00717       case 0xe9:                                                     \
00718        if (var == CA || var == CA2 || var == HU || var == FR || var == FR1)  \
00719          ch = 0x7b;                                                  \
00720        else if (var == IT)                                           \
00721          ch = 0x5d;                                                  \
00722        else if (var == SE2)                                          \
00723          ch = 0x60;                                                  \
00724        else                                                          \
00725          failure = __GCONV_ILLEGAL_INPUT;                            \
00726        break;                                                        \
00727       case 0xea:                                                     \
00728        if (var != CA && var != CA2)                                         \
00729          failure = __GCONV_ILLEGAL_INPUT;                            \
00730        ch = 0x5d;                                                    \
00731        break;                                                        \
00732       case 0xec:                                                     \
00733        if (var != IT)                                                       \
00734          failure = __GCONV_ILLEGAL_INPUT;                            \
00735        ch = 0x7e;                                                    \
00736        break;                                                        \
00737       case 0xee:                                                     \
00738        if (var != CA)                                                       \
00739          failure = __GCONV_ILLEGAL_INPUT;                            \
00740        ch = 0x5e;                                                    \
00741        break;                                                        \
00742       case 0xf1:                                                     \
00743        if (var != ES && var != ES2 && var != CU)                     \
00744          failure = __GCONV_ILLEGAL_INPUT;                            \
00745        ch = 0x7c;                                                    \
00746        break;                                                        \
00747       case 0xf2:                                                     \
00748        if (var != IT)                                                       \
00749          failure = __GCONV_ILLEGAL_INPUT;                            \
00750        ch = 0x7c;                                                    \
00751        break;                                                        \
00752       case 0xf4:                                                     \
00753        if (var != CA && var != CA2)                                         \
00754          failure = __GCONV_ILLEGAL_INPUT;                            \
00755        ch = 0x60;                                                    \
00756        break;                                                        \
00757       case 0xf5:                                                     \
00758        if (var != PT && var != PT2)                                         \
00759          failure = __GCONV_ILLEGAL_INPUT;                            \
00760        ch = 0x7d;                                                    \
00761        break;                                                        \
00762       case 0xf6:                                                     \
00763        if (var != DE && var != HU && var != SE && var != SE2)               \
00764          failure = __GCONV_ILLEGAL_INPUT;                            \
00765        ch = 0x7c;                                                    \
00766        break;                                                        \
00767       case 0xf8:                                                     \
00768        if (var != DK && var != NO && var != NO2)                     \
00769          failure = __GCONV_ILLEGAL_INPUT;                            \
00770        ch = 0x7c;                                                    \
00771        break;                                                        \
00772       case 0xf9:                                                     \
00773        if (var == CA || var == CA2 || var == FR || var == FR1)              \
00774          ch = 0x7c;                                                  \
00775        else if (var == IT)                                           \
00776          ch = 0x60;                                                  \
00777        else                                                          \
00778          failure = __GCONV_ILLEGAL_INPUT;                            \
00779        break;                                                        \
00780       case 0xfb:                                                     \
00781        if (var != CA && var != CA2)                                         \
00782          failure = __GCONV_ILLEGAL_INPUT;                            \
00783        ch = 0x7e;                                                    \
00784        break;                                                        \
00785       case 0xfc:                                                     \
00786        if (var == DE || var == HU)                                   \
00787          ch = 0x7d;                                                  \
00788        else if (var == SE2)                                          \
00789          ch = 0x7e;                                                  \
00790        else                                                          \
00791          failure = __GCONV_ILLEGAL_INPUT;                            \
00792        break;                                                        \
00793       case 0x160:                                                    \
00794        if (var != YU)                                                       \
00795          failure = __GCONV_ILLEGAL_INPUT;                            \
00796        ch = 0x5b;                                                    \
00797        break;                                                        \
00798       case 0x106:                                                    \
00799        if (var != YU)                                                       \
00800          failure = __GCONV_ILLEGAL_INPUT;                            \
00801        ch = 0x5d;                                                    \
00802        break;                                                        \
00803       case 0x107:                                                    \
00804        if (var != YU)                                                       \
00805          failure = __GCONV_ILLEGAL_INPUT;                            \
00806        ch = 0x7d;                                                    \
00807        break;                                                        \
00808       case 0x10c:                                                    \
00809        if (var != YU)                                                       \
00810          failure = __GCONV_ILLEGAL_INPUT;                            \
00811        ch = 0x5e;                                                    \
00812        break;                                                        \
00813       case 0x10d:                                                    \
00814        if (var != YU)                                                       \
00815          failure = __GCONV_ILLEGAL_INPUT;                            \
00816        ch = 0x7e;                                                    \
00817        break;                                                        \
00818       case 0x110:                                                    \
00819        if (var != YU)                                                       \
00820          failure = __GCONV_ILLEGAL_INPUT;                            \
00821        ch = 0x5c;                                                    \
00822        break;                                                        \
00823       case 0x111:                                                    \
00824        if (var != YU)                                                       \
00825          failure = __GCONV_ILLEGAL_INPUT;                            \
00826        ch = 0x7c;                                                    \
00827        break;                                                        \
00828       case 0x161:                                                    \
00829        if (var != YU)                                                       \
00830          failure = __GCONV_ILLEGAL_INPUT;                            \
00831        ch = 0x7b;                                                    \
00832        break;                                                        \
00833       case 0x17d:                                                    \
00834        if (var != YU)                                                       \
00835          failure = __GCONV_ILLEGAL_INPUT;                            \
00836        ch = 0x40;                                                    \
00837        break;                                                        \
00838       case 0x17e:                                                    \
00839        if (var != YU)                                                       \
00840          failure = __GCONV_ILLEGAL_INPUT;                            \
00841        ch = 0x60;                                                    \
00842        break;                                                        \
00843       case 0x2dd:                                                    \
00844        if (var != HU)                                                       \
00845          failure = __GCONV_ILLEGAL_INPUT;                            \
00846        ch = 0x7e;                                                    \
00847        break;                                                        \
00848       case 0x2022:                                                   \
00849        if (var != ES2)                                                      \
00850          failure = __GCONV_ILLEGAL_INPUT;                            \
00851        ch = 0x40;                                                    \
00852        break;                                                        \
00853       case 0x203e:                                                   \
00854        if (var != GB && var != CN && var != JP && var != NO && var != SE)    \
00855          failure = __GCONV_ILLEGAL_INPUT;                            \
00856        ch = 0x7e;                                                    \
00857        break;                                                        \
00858       case 0x20a9:                                                   \
00859        if (var != KR)                                                       \
00860          failure = __GCONV_ILLEGAL_INPUT;                            \
00861        ch = 0x5c;                                                    \
00862        break;                                                        \
00863       case 0x2329:                                                   \
00864        if (var != JP_OCR_B)                                          \
00865          failure = __GCONV_ILLEGAL_INPUT;                            \
00866        ch = 0x5b;                                                    \
00867        break;                                                        \
00868       case 0x232a:                                                   \
00869        if (var != JP_OCR_B)                                          \
00870          failure = __GCONV_ILLEGAL_INPUT;                            \
00871        ch = 0x5d;                                                    \
00872        break;                                                        \
00873       default:                                                              \
00874        if (__builtin_expect (ch > 0x7f, 0))                                 \
00875          {                                                           \
00876            UNICODE_TAG_HANDLER (ch, 4);                              \
00877            failure = __GCONV_ILLEGAL_INPUT;                                 \
00878          }                                                           \
00879        break;                                                        \
00880       }                                                                     \
00881                                                                      \
00882     if (__builtin_expect (failure, __GCONV_OK) == __GCONV_ILLEGAL_INPUT)      \
00883       {                                                                     \
00884        STANDARD_TO_LOOP_ERR_HANDLER (4);                             \
00885       }                                                                     \
00886                                                                      \
00887     *outptr++ = (unsigned char) ch;                                         \
00888     inptr += 4;                                                             \
00889   }
00890 #define LOOP_NEED_FLAGS
00891 #define EXTRA_LOOP_DECLS    , enum variant var
00892 #include <iconv/loop.c>
00893 
00894 
00895 /* Now define the toplevel functions.  */
00896 #include <iconv/skeleton.c>