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