Mercurial > hg > octave-nkf > gnulib-hg
annotate lib/iconv_open.c @ 17334:bb52d9cece01
unsetenv etc.: port to Solaris 11 + GNU Emacs
* lib/canonicalize-lgpl.c, lib/getaddrinfo.c, lib/getdelim.c:
* lib/glob.c, lib/random_r.c, lib/setenv.c, lib/tsearch.c:
* lib/unsetenv.c (_GL_ARG_NONNULL): Define before including <config.h>.
GNU Emacs's <config.h> includes <stdlib.h> (which is not a great
idea but is too painful to fix right now), and without this gnulib
change <stdlib.h> was defining _GL_ARG_NONNULL incorrectly when
compiling unsetenv.c on Solaris 11. Fix the problem for
unsetenv.c, and fix other similar occurrences.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Mon, 11 Feb 2013 14:58:56 -0800 |
parents | e542fd46ad6f |
children | 344018b6e5d7 |
rev | line source |
---|---|
8603 | 1 /* Character set conversion. |
17249
e542fd46ad6f
maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents:
16366
diff
changeset
|
2 Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. |
8603 | 3 |
4 This program is free software; you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 2, or (at your option) | |
7 any later version. | |
8 | |
9 This program 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 General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License along | |
16366
bb182ee4a09d
maint: replace FSF snail-mail addresses with URLs
Paul Eggert <eggert@cs.ucla.edu>
parents:
16358
diff
changeset
|
15 with this program; if not, see <http://www.gnu.org/licenses/>. */ |
8603 | 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" | |
9341
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
25 #include "c-strcase.h" |
8603 | 26 |
27 #define SIZEOF(a) (sizeof(a) / sizeof(a[0])) | |
28 | |
29 /* Namespace cleanliness. */ | |
30 #define mapping_lookup rpl_iconv_open_mapping_lookup | |
31 | |
9341
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
32 /* The macro ICONV_FLAVOR is defined to one of these or undefined. */ |
8603 | 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" | |
11915 | 38 #define ICONV_FLAVOR_SOLARIS "iconv_open-solaris.h" |
8603 | 39 |
9341
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
40 #ifdef ICONV_FLAVOR |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
41 # include ICONV_FLAVOR |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
42 #endif |
8603 | 43 |
44 iconv_t | |
45 rpl_iconv_open (const char *tocode, const char *fromcode) | |
46 #undef iconv_open | |
47 { | |
48 char fromcode_upper[32]; | |
49 char tocode_upper[32]; | |
50 char *fromcode_upper_end; | |
51 char *tocode_upper_end; | |
52 | |
9341
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
53 #if REPLACE_ICONV_UTF |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
54 /* Special handling of conversion between UTF-8 and UTF-{16,32}{BE,LE}. |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
55 Do this here, before calling the real iconv_open(), because OSF/1 5.1 |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
56 iconv() to these encoding inserts a BOM, which is wrong. |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
57 We do not need to handle conversion between arbitrary encodings and |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
58 UTF-{16,32}{BE,LE}, because the 'striconveh' module implements two-step |
16358 | 59 conversion through UTF-8. |
9341
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
60 The _ICONV_* constants are chosen to be disjoint from any iconv_t |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
61 returned by the system's iconv_open() functions. Recall that iconv_t |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
62 is a scalar type. */ |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
63 if (c_toupper (fromcode[0]) == 'U' |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
64 && c_toupper (fromcode[1]) == 'T' |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
65 && c_toupper (fromcode[2]) == 'F' |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
66 && fromcode[3] == '-') |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
67 { |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
68 if (c_toupper (tocode[0]) == 'U' |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
69 && c_toupper (tocode[1]) == 'T' |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
70 && c_toupper (tocode[2]) == 'F' |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
71 && tocode[3] == '-') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
72 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
73 if (strcmp (fromcode + 4, "8") == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
74 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
75 if (c_strcasecmp (tocode + 4, "16BE") == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
76 return _ICONV_UTF8_UTF16BE; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
77 if (c_strcasecmp (tocode + 4, "16LE") == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
78 return _ICONV_UTF8_UTF16LE; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
79 if (c_strcasecmp (tocode + 4, "32BE") == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
80 return _ICONV_UTF8_UTF32BE; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
81 if (c_strcasecmp (tocode + 4, "32LE") == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
82 return _ICONV_UTF8_UTF32LE; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
83 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
84 else if (strcmp (tocode + 4, "8") == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
85 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
86 if (c_strcasecmp (fromcode + 4, "16BE") == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
87 return _ICONV_UTF16BE_UTF8; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
88 if (c_strcasecmp (fromcode + 4, "16LE") == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
89 return _ICONV_UTF16LE_UTF8; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
90 if (c_strcasecmp (fromcode + 4, "32BE") == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
91 return _ICONV_UTF32BE_UTF8; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
92 if (c_strcasecmp (fromcode + 4, "32LE") == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
93 return _ICONV_UTF32LE_UTF8; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
94 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
95 } |
9341
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
96 } |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
97 #endif |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
98 |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
99 /* Do *not* add special support for 8-bit encodings like ASCII or ISO-8859-1 |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
100 here. This would lead to programs that work in some locales (such as the |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
101 "C" or "en_US" locales) but do not work in East Asian locales. It is |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
102 better if programmers make their programs depend on GNU libiconv (except |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
103 on glibc systems), e.g. by using the AM_ICONV macro and documenting the |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
104 dependency in an INSTALL or DEPENDENCIES file. */ |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
105 |
8603 | 106 /* Try with the original names first. |
107 This covers the case when fromcode or tocode is a lowercase encoding name | |
108 that is understood by the system's iconv_open but not listed in our | |
109 mappings table. */ | |
110 { | |
111 iconv_t cd = iconv_open (tocode, fromcode); | |
112 if (cd != (iconv_t)(-1)) | |
113 return cd; | |
114 } | |
115 | |
116 /* Convert the encodings to upper case, because | |
117 1. in the arguments of iconv_open() on AIX, HP-UX, and OSF/1 the case | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
118 matters, |
8603 | 119 2. it makes searching in the table faster. */ |
120 { | |
121 const char *p = fromcode; | |
122 char *q = fromcode_upper; | |
123 while ((*q = c_toupper (*p)) != '\0') | |
124 { | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
125 p++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
126 q++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
127 if (q == &fromcode_upper[SIZEOF (fromcode_upper)]) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
128 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
129 errno = EINVAL; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
130 return (iconv_t)(-1); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
131 } |
8603 | 132 } |
133 fromcode_upper_end = q; | |
134 } | |
135 | |
136 { | |
137 const char *p = tocode; | |
138 char *q = tocode_upper; | |
139 while ((*q = c_toupper (*p)) != '\0') | |
140 { | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
141 p++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
142 q++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
143 if (q == &tocode_upper[SIZEOF (tocode_upper)]) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
144 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
145 errno = EINVAL; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
146 return (iconv_t)(-1); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11915
diff
changeset
|
147 } |
8603 | 148 } |
149 tocode_upper_end = q; | |
150 } | |
151 | |
9341
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
152 #ifdef ICONV_FLAVOR |
8603 | 153 /* Apply the mappings. */ |
154 { | |
155 const struct mapping *m = | |
156 mapping_lookup (fromcode_upper, fromcode_upper_end - fromcode_upper); | |
157 | |
158 fromcode = (m != NULL ? m->vendor_name : fromcode_upper); | |
159 } | |
160 { | |
161 const struct mapping *m = | |
162 mapping_lookup (tocode_upper, tocode_upper_end - tocode_upper); | |
163 | |
164 tocode = (m != NULL ? m->vendor_name : tocode_upper); | |
165 } | |
9341
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
166 #else |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
167 fromcode = fromcode_upper; |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
168 tocode = tocode_upper; |
212d6f041290
New module 'iconv_open-utf': Enhance iconv_open to support UTF-{16,32}{BE,LE}.
Bruno Haible <bruno@clisp.org>
parents:
8603
diff
changeset
|
169 #endif |
8603 | 170 |
171 return iconv_open (tocode, fromcode); | |
172 } |