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