Update.
[gsasl.git] / gl / iconv_open.c
blobf78cbb48d13794d147b55bc4f7bfd7ffdbdd886d
1 /* Character set conversion.
2 Copyright (C) 2007 Free Software Foundation, Inc.
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.
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.
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18 #include <config.h>
20 /* Specification. */
21 #include <iconv.h>
23 #include <errno.h>
24 #include <string.h>
25 #include "c-ctype.h"
27 #define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
29 /* Namespace cleanliness. */
30 #define mapping_lookup rpl_iconv_open_mapping_lookup
32 /* The macro ICONV_FLAVOR is defined to one of these. */
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"
39 #include ICONV_FLAVOR
41 iconv_t
42 rpl_iconv_open (const char *tocode, const char *fromcode)
43 #undef iconv_open
45 char fromcode_upper[32];
46 char tocode_upper[32];
47 char *fromcode_upper_end;
48 char *tocode_upper_end;
50 /* Try with the original names first.
51 This covers the case when fromcode or tocode is a lowercase encoding name
52 that is understood by the system's iconv_open but not listed in our
53 mappings table. */
55 iconv_t cd = iconv_open (tocode, fromcode);
56 if (cd != (iconv_t)(-1))
57 return cd;
60 /* Convert the encodings to upper case, because
61 1. in the arguments of iconv_open() on AIX, HP-UX, and OSF/1 the case
62 matters,
63 2. it makes searching in the table faster. */
65 const char *p = fromcode;
66 char *q = fromcode_upper;
67 while ((*q = c_toupper (*p)) != '\0')
69 p++;
70 q++;
71 if (q == &fromcode_upper[SIZEOF (fromcode_upper)])
73 errno = EINVAL;
74 return (iconv_t)(-1);
77 fromcode_upper_end = q;
81 const char *p = tocode;
82 char *q = tocode_upper;
83 while ((*q = c_toupper (*p)) != '\0')
85 p++;
86 q++;
87 if (q == &tocode_upper[SIZEOF (tocode_upper)])
89 errno = EINVAL;
90 return (iconv_t)(-1);
93 tocode_upper_end = q;
96 /* Apply the mappings. */
98 const struct mapping *m =
99 mapping_lookup (fromcode_upper, fromcode_upper_end - fromcode_upper);
101 fromcode = (m != NULL ? m->vendor_name : fromcode_upper);
104 const struct mapping *m =
105 mapping_lookup (tocode_upper, tocode_upper_end - tocode_upper);
107 tocode = (m != NULL ? m->vendor_name : tocode_upper);
110 return iconv_open (tocode, fromcode);