annotate lib/striconveha.c @ 40057:b06060465f09

maint: Run 'make update-copyright'
author Paul Eggert <eggert@cs.ucla.edu>
date Tue, 01 Jan 2019 00:25:11 +0100
parents 10eb9086bea0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Character set conversion with error handling and autodetection.
40057
b06060465f09 maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
2 Copyright (C) 2002, 2005, 2007, 2009-2019 Free Software Foundation, Inc.
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3 Written by Bruno Haible.
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 8948
diff changeset
5 This program is free software: you can redistribute it and/or modify
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 8948
diff changeset
7 the Free Software Foundation; either version 3 of the License, or
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 8948
diff changeset
8 (at your option) any later version.
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 GNU General Public License for more details.
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
19190
9759915b2aca all: prefer https: URLs
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18 #include <config.h>
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 /* Specification. */
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 #include "striconveha.h"
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23 #include <errno.h>
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24 #include <stdlib.h>
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 #include <string.h>
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26
8948
a162347a0232 Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents: 7944
diff changeset
27 #include "malloca.h"
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
28 #include "c-strcase.h"
11477
63b291ae83b6 Add include that is no longer done by striconveha.h.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
29 #include "striconveh.h"
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
30
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 #define SIZEOF(a) (sizeof(a)/sizeof(a[0]))
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34 /* Autodetection list. */
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
35
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
36 struct autodetect_alias
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
37 {
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
38 struct autodetect_alias *next;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39 const char *name;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 const char * const *encodings_to_try;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41 };
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
42
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
43 static const char * const autodetect_utf8_try[] =
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
44 {
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
45 /* Try UTF-8 first. There are very few ISO-8859-1 inputs that would
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46 be valid UTF-8, but many UTF-8 inputs are valid ISO-8859-1. */
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
47 "UTF-8", "ISO-8859-1",
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
48 NULL
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
49 };
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
50 static const char * const autodetect_jp_try[] =
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
51 {
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
52 /* Try 7-bit encoding first. If the input contains bytes >= 0x80,
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
53 it will fail.
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
54 Try EUC-JP next. Short SHIFT_JIS inputs may come out wrong. This
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
55 is unavoidable. People will condemn SHIFT_JIS.
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
56 If we tried SHIFT_JIS first, then some short EUC-JP inputs would
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
57 come out wrong, and people would condemn EUC-JP and Unix, which
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
58 would not be good.
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
59 Finally try SHIFT_JIS. */
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
60 "ISO-2022-JP-2", "EUC-JP", "SHIFT_JIS",
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
61 NULL
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
62 };
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
63 static const char * const autodetect_kr_try[] =
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
64 {
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
65 /* Try 7-bit encoding first. If the input contains bytes >= 0x80,
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
66 it will fail.
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
67 Finally try EUC-KR. */
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 "ISO-2022-KR", "EUC-KR",
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
69 NULL
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
70 };
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
71
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
72 static struct autodetect_alias autodetect_predefined[] =
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73 {
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
74 { &autodetect_predefined[1], "autodetect_utf8", autodetect_utf8_try },
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75 { &autodetect_predefined[2], "autodetect_jp", autodetect_jp_try },
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
76 { NULL, "autodetect_kr", autodetect_kr_try }
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
77 };
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
78
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
79 static struct autodetect_alias *autodetect_list = &autodetect_predefined[0];
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
80 static struct autodetect_alias **autodetect_list_end =
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
81 &autodetect_predefined[SIZEOF(autodetect_predefined)-1].next;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
82
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
83 int
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
84 uniconv_register_autodetect (const char *name,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
85 const char * const *try_in_order)
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
86 {
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
87 size_t namelen;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
88 size_t listlen;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
89 size_t memneed;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
90 size_t i;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
91 char *memory;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
92 struct autodetect_alias *new_alias;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
93 char *new_name;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
94 const char **new_try_in_order;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
95
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
96 /* The TRY_IN_ORDER list must not be empty. */
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
97 if (try_in_order[0] == NULL)
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
98 {
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
99 errno = EINVAL;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100 return -1;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101 }
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
102
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
103 /* We must deep-copy NAME and TRY_IN_ORDER, because they may be allocated
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
104 with dynamic extent. */
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
105 namelen = strlen (name) + 1;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
106 memneed = sizeof (struct autodetect_alias) + namelen + sizeof (char *);
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
107 for (i = 0; try_in_order[i] != NULL; i++)
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
108 memneed += sizeof (char *) + strlen (try_in_order[i]) + 1;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
109 listlen = i;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
110
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
111 memory = (char *) malloc (memneed);
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
112 if (memory != NULL)
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
113 {
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
114 new_alias = (struct autodetect_alias *) memory;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
115 memory += sizeof (struct autodetect_alias);
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
116
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
117 new_try_in_order = (const char **) memory;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
118 memory += (listlen + 1) * sizeof (char *);
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
119
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
120 new_name = (char *) memory;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
121 memcpy (new_name, name, namelen);
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
122 memory += namelen;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
123
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
124 for (i = 0; i < listlen; i++)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
125 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
126 size_t len = strlen (try_in_order[i]) + 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
127 memcpy (memory, try_in_order[i], len);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
128 new_try_in_order[i] = (const char *) memory;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
129 memory += len;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
130 }
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
131 new_try_in_order[i] = NULL;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
132
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
133 /* Now insert the new alias. */
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
134 new_alias->name = new_name;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
135 new_alias->encodings_to_try = new_try_in_order;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
136 new_alias->next = NULL;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
137 /* FIXME: Not multithread-safe. */
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
138 *autodetect_list_end = new_alias;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
139 autodetect_list_end = &new_alias->next;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
140 return 0;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
141 }
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
142 else
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
143 {
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
144 errno = ENOMEM;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
145 return -1;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
146 }
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
147 }
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
148
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
149 /* Like mem_iconveha, except no handling of transliteration. */
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
150 static int
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
151 mem_iconveha_notranslit (const char *src, size_t srclen,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
152 const char *from_codeset, const char *to_codeset,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
153 enum iconv_ilseq_handler handler,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
154 size_t *offsets,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
155 char **resultp, size_t *lengthp)
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
156 {
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
157 int retval = mem_iconveh (src, srclen, from_codeset, to_codeset, handler,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
158 offsets, resultp, lengthp);
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
159 if (retval >= 0 || errno != EINVAL)
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
160 return retval;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
161 else
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
162 {
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
163 struct autodetect_alias *alias;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
164
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
165 /* Unsupported from_codeset or to_codeset. Check whether the caller
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
166 requested autodetection. */
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
167 for (alias = autodetect_list; alias != NULL; alias = alias->next)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
168 if (strcmp (from_codeset, alias->name) == 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
169 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
170 const char * const *encodings;
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
171
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
172 if (handler != iconveh_error)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
173 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
174 /* First try all encodings without any forgiving. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
175 encodings = alias->encodings_to_try;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
176 do
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
177 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
178 retval = mem_iconveha_notranslit (src, srclen,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
179 *encodings, to_codeset,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
180 iconveh_error, offsets,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
181 resultp, lengthp);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
182 if (!(retval < 0 && errno == EILSEQ))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
183 return retval;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
184 encodings++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
185 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
186 while (*encodings != NULL);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
187 }
7930
8929067c3772 Make the striconveha module actually work.
Bruno Haible <bruno@clisp.org>
parents: 7927
diff changeset
188
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
189 encodings = alias->encodings_to_try;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
190 do
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
191 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
192 retval = mem_iconveha_notranslit (src, srclen,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
193 *encodings, to_codeset,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
194 handler, offsets,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
195 resultp, lengthp);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
196 if (!(retval < 0 && errno == EILSEQ))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
197 return retval;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
198 encodings++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
199 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
200 while (*encodings != NULL);
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
201
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
202 /* Return the last call's result. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
203 return -1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
204 }
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
205
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
206 /* It wasn't an autodetection name. */
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
207 errno = EINVAL;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
208 return -1;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
209 }
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
210 }
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
211
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
212 int
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
213 mem_iconveha (const char *src, size_t srclen,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
214 const char *from_codeset, const char *to_codeset,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
215 bool transliterate,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
216 enum iconv_ilseq_handler handler,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
217 size_t *offsets,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
218 char **resultp, size_t *lengthp)
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
219 {
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
220 if (srclen == 0)
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
221 {
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
222 /* Nothing to convert. */
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
223 *lengthp = 0;
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
224 return 0;
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
225 }
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
226
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
227 /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
228 we want to use transliteration. */
13885
87a95303747f Port to uClibc.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
229 #if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) \
87a95303747f Port to uClibc.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
230 && !defined __UCLIBC__) \
87a95303747f Port to uClibc.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
231 || _LIBICONV_VERSION >= 0x0105
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
232 if (transliterate)
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
233 {
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
234 int retval;
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
235 size_t len = strlen (to_codeset);
8948
a162347a0232 Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents: 7944
diff changeset
236 char *to_codeset_suffixed = (char *) malloca (len + 10 + 1);
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
237 memcpy (to_codeset_suffixed, to_codeset, len);
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
238 memcpy (to_codeset_suffixed + len, "//TRANSLIT", 10 + 1);
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
239
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
240 retval = mem_iconveha_notranslit (src, srclen,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
241 from_codeset, to_codeset_suffixed,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
242 handler, offsets, resultp, lengthp);
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
243
8948
a162347a0232 Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents: 7944
diff changeset
244 freea (to_codeset_suffixed);
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
245
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
246 return retval;
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
247 }
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
248 else
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
249 #endif
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
250 return mem_iconveha_notranslit (src, srclen,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
251 from_codeset, to_codeset,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
252 handler, offsets, resultp, lengthp);
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
253 }
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
254
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
255 /* Like str_iconveha, except no handling of transliteration. */
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
256 static char *
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
257 str_iconveha_notranslit (const char *src,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
258 const char *from_codeset, const char *to_codeset,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
259 enum iconv_ilseq_handler handler)
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
260 {
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
261 char *result = str_iconveh (src, from_codeset, to_codeset, handler);
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
262
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
263 if (result != NULL || errno != EINVAL)
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
264 return result;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
265 else
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
266 {
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
267 struct autodetect_alias *alias;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
268
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
269 /* Unsupported from_codeset or to_codeset. Check whether the caller
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
270 requested autodetection. */
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
271 for (alias = autodetect_list; alias != NULL; alias = alias->next)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
272 if (strcmp (from_codeset, alias->name) == 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
273 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
274 const char * const *encodings;
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
275
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
276 if (handler != iconveh_error)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
277 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
278 /* First try all encodings without any forgiving. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
279 encodings = alias->encodings_to_try;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
280 do
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
281 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
282 result = str_iconveha_notranslit (src,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
283 *encodings, to_codeset,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
284 iconveh_error);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
285 if (!(result == NULL && errno == EILSEQ))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
286 return result;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
287 encodings++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
288 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
289 while (*encodings != NULL);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
290 }
7930
8929067c3772 Make the striconveha module actually work.
Bruno Haible <bruno@clisp.org>
parents: 7927
diff changeset
291
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
292 encodings = alias->encodings_to_try;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
293 do
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
294 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
295 result = str_iconveha_notranslit (src,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
296 *encodings, to_codeset,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
297 handler);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
298 if (!(result == NULL && errno == EILSEQ))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
299 return result;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
300 encodings++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
301 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
302 while (*encodings != NULL);
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
303
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
304 /* Return the last call's result. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
305 return NULL;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
306 }
7919
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
307
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
308 /* It wasn't an autodetection name. */
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
309 errno = EINVAL;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
310 return NULL;
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
311 }
b7b7885895a6 New module 'striconveha'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
312 }
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
313
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
314 char *
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
315 str_iconveha (const char *src,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
316 const char *from_codeset, const char *to_codeset,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
317 bool transliterate,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
318 enum iconv_ilseq_handler handler)
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
319 {
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
320 if (*src == '\0' || c_strcasecmp (from_codeset, to_codeset) == 0)
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
321 {
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
322 char *result = strdup (src);
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
323
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
324 if (result == NULL)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
325 errno = ENOMEM;
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
326 return result;
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
327 }
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
328
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
329 /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5,
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
330 we want to use transliteration. */
13885
87a95303747f Port to uClibc.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
331 #if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) \
87a95303747f Port to uClibc.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
332 && !defined __UCLIBC__) \
87a95303747f Port to uClibc.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
333 || _LIBICONV_VERSION >= 0x0105
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
334 if (transliterate)
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
335 {
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
336 char *result;
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
337 size_t len = strlen (to_codeset);
8948
a162347a0232 Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents: 7944
diff changeset
338 char *to_codeset_suffixed = (char *) malloca (len + 10 + 1);
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
339 memcpy (to_codeset_suffixed, to_codeset, len);
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
340 memcpy (to_codeset_suffixed + len, "//TRANSLIT", 10 + 1);
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
341
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
342 result = str_iconveha_notranslit (src, from_codeset, to_codeset_suffixed,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11477
diff changeset
343 handler);
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
344
8948
a162347a0232 Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents: 7944
diff changeset
345 freea (to_codeset_suffixed);
7931
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
346
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
347 return result;
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
348 }
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
349 else
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
350 #endif
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
351 return str_iconveha_notranslit (src, from_codeset, to_codeset, handler);
0a4679777f66 Add an optional argument specifying transliteration.
Bruno Haible <bruno@clisp.org>
parents: 7930
diff changeset
352 }