root/maint/gnulib/lib/iconv_open.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rpl_iconv_open

   1 /* Character set conversion.
   2    Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
   3 
   4    This file is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU Lesser General Public License as
   6    published by the Free Software Foundation; either version 2.1 of the
   7    License, or (at your option) any later version.
   8 
   9    This file is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU Lesser General Public License for more details.
  13 
  14    You should have received a copy of the GNU Lesser General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 #include <config.h>
  18 
  19 /* Specification.  */
  20 #include <iconv.h>
  21 
  22 #include <errno.h>
  23 #include <string.h>
  24 #include "c-ctype.h"
  25 #include "c-strcase.h"
  26 
  27 #define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
  28 
  29 /* Namespace cleanliness.  */
  30 #define mapping_lookup rpl_iconv_open_mapping_lookup
  31 
  32 /* The macro ICONV_FLAVOR is defined to one of these or undefined.  */
  33 
  34 #define ICONV_FLAVOR_AIX "iconv_open-aix.h"
  35 #define ICONV_FLAVOR_HPUX "iconv_open-hpux.h"
  36 #define ICONV_FLAVOR_IRIX "iconv_open-irix.h"
  37 #define ICONV_FLAVOR_OSF "iconv_open-osf.h"
  38 #define ICONV_FLAVOR_SOLARIS "iconv_open-solaris.h"
  39 #define ICONV_FLAVOR_ZOS "iconv_open-zos.h"
  40 
  41 #ifdef ICONV_FLAVOR
  42 # include ICONV_FLAVOR
  43 #endif
  44 
  45 iconv_t
  46 rpl_iconv_open (const char *tocode, const char *fromcode)
     /* [previous][next][first][last][top][bottom][index][help] */
  47 #undef iconv_open
  48 {
  49   char fromcode_upper[32];
  50   char tocode_upper[32];
  51   char *fromcode_upper_end;
  52   char *tocode_upper_end;
  53 
  54 #if REPLACE_ICONV_UTF
  55   /* Special handling of conversion between UTF-8 and UTF-{16,32}{BE,LE}.
  56      Do this here, before calling the real iconv_open(), because  OSF/1 5.1
  57      iconv() to these encoding inserts a BOM, which is wrong.
  58      We do not need to handle conversion between arbitrary encodings and
  59      UTF-{16,32}{BE,LE}, because the 'striconveh' module implements two-step
  60      conversion through UTF-8.
  61      The _ICONV_* constants are chosen to be disjoint from any iconv_t
  62      returned by the system's iconv_open() functions.  Recall that iconv_t
  63      is a scalar type.  */
  64   if (c_toupper (fromcode[0]) == 'U'
  65       && c_toupper (fromcode[1]) == 'T'
  66       && c_toupper (fromcode[2]) == 'F'
  67       && fromcode[3] == '-')
  68     {
  69       if (c_toupper (tocode[0]) == 'U'
  70           && c_toupper (tocode[1]) == 'T'
  71           && c_toupper (tocode[2]) == 'F'
  72           && tocode[3] == '-')
  73         {
  74           if (strcmp (fromcode + 4, "8") == 0)
  75             {
  76               if (c_strcasecmp (tocode + 4, "16BE") == 0)
  77                 return _ICONV_UTF8_UTF16BE;
  78               if (c_strcasecmp (tocode + 4, "16LE") == 0)
  79                 return _ICONV_UTF8_UTF16LE;
  80               if (c_strcasecmp (tocode + 4, "32BE") == 0)
  81                 return _ICONV_UTF8_UTF32BE;
  82               if (c_strcasecmp (tocode + 4, "32LE") == 0)
  83                 return _ICONV_UTF8_UTF32LE;
  84             }
  85           else if (strcmp (tocode + 4, "8") == 0)
  86             {
  87               if (c_strcasecmp (fromcode + 4, "16BE") == 0)
  88                 return _ICONV_UTF16BE_UTF8;
  89               if (c_strcasecmp (fromcode + 4, "16LE") == 0)
  90                 return _ICONV_UTF16LE_UTF8;
  91               if (c_strcasecmp (fromcode + 4, "32BE") == 0)
  92                 return _ICONV_UTF32BE_UTF8;
  93               if (c_strcasecmp (fromcode + 4, "32LE") == 0)
  94                 return _ICONV_UTF32LE_UTF8;
  95             }
  96         }
  97     }
  98 #endif
  99 
 100   /* Do *not* add special support for 8-bit encodings like ASCII or ISO-8859-1
 101      here.  This would lead to programs that work in some locales (such as the
 102      "C" or "en_US" locales) but do not work in East Asian locales.  It is
 103      better if programmers make their programs depend on GNU libiconv (except
 104      on glibc systems), e.g. by using the AM_ICONV macro and documenting the
 105      dependency in an INSTALL or DEPENDENCIES file.  */
 106 
 107   /* Try with the original names first.
 108      This covers the case when fromcode or tocode is a lowercase encoding name
 109      that is understood by the system's iconv_open but not listed in our
 110      mappings table.  */
 111   {
 112     iconv_t cd = iconv_open (tocode, fromcode);
 113     if (cd != (iconv_t)(-1))
 114       return cd;
 115   }
 116 
 117   /* Convert the encodings to upper case, because
 118        1. in the arguments of iconv_open() on AIX, HP-UX, and OSF/1 the case
 119           matters,
 120        2. it makes searching in the table faster.  */
 121   {
 122     const char *p = fromcode;
 123     char *q = fromcode_upper;
 124     while ((*q = c_toupper (*p)) != '\0')
 125       {
 126         p++;
 127         q++;
 128         if (q == &fromcode_upper[SIZEOF (fromcode_upper)])
 129           {
 130             errno = EINVAL;
 131             return (iconv_t)(-1);
 132           }
 133       }
 134     fromcode_upper_end = q;
 135   }
 136 
 137   {
 138     const char *p = tocode;
 139     char *q = tocode_upper;
 140     while ((*q = c_toupper (*p)) != '\0')
 141       {
 142         p++;
 143         q++;
 144         if (q == &tocode_upper[SIZEOF (tocode_upper)])
 145           {
 146             errno = EINVAL;
 147             return (iconv_t)(-1);
 148           }
 149       }
 150     tocode_upper_end = q;
 151   }
 152 
 153 #ifdef ICONV_FLAVOR
 154   /* Apply the mappings.  */
 155   {
 156     const struct mapping *m =
 157       mapping_lookup (fromcode_upper, fromcode_upper_end - fromcode_upper);
 158 
 159     fromcode = (m != NULL ? m->vendor_name : fromcode_upper);
 160   }
 161   {
 162     const struct mapping *m =
 163       mapping_lookup (tocode_upper, tocode_upper_end - tocode_upper);
 164 
 165     tocode = (m != NULL ? m->vendor_name : tocode_upper);
 166   }
 167 #else
 168   fromcode = fromcode_upper;
 169   tocode = tocode_upper;
 170 #endif
 171 
 172   return iconv_open (tocode, fromcode);
 173 }

/* [previous][next][first][last][top][bottom][index][help] */