]>
Commit | Line | Data |
---|---|---|
d614a753 | 1 | /* Copyright (C) 2000-2020 Free Software Foundation, Inc. |
b79f74cd UD |
2 | This file is part of the GNU C Library. |
3 | Contributed by Bruno Haible <haible@clisp.cons.org>, 2000. | |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
b79f74cd UD |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 13 | Lesser General Public License for more details. |
b79f74cd | 14 | |
41bdb6e2 | 15 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 | 16 | License along with the GNU C Library; if not, see |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
b79f74cd UD |
18 | |
19 | /* Create a table from Unicode to CHARSET. | |
20 | This is a good test for CHARSET's iconv() module, in particular the | |
21 | TO_LOOP BODY macro. */ | |
22 | ||
23 | #include <stddef.h> | |
24 | #include <stdio.h> | |
25 | #include <stdlib.h> | |
a29a3e1a | 26 | #include <string.h> |
b79f74cd UD |
27 | #include <iconv.h> |
28 | #include <errno.h> | |
29 | ||
30 | int | |
31 | main (int argc, char *argv[]) | |
32 | { | |
33 | const char *charset; | |
34 | iconv_t cd; | |
601d2942 | 35 | int bmp_only; |
b79f74cd UD |
36 | |
37 | if (argc != 2) | |
38 | { | |
39 | fprintf (stderr, "Usage: tst-table-to charset\n"); | |
4e6bc1f6 | 40 | return 1; |
b79f74cd UD |
41 | } |
42 | charset = argv[1]; | |
43 | ||
601d2942 | 44 | cd = iconv_open (charset, "UTF-8"); |
b79f74cd UD |
45 | if (cd == (iconv_t)(-1)) |
46 | { | |
47 | perror ("iconv_open"); | |
4e6bc1f6 | 48 | return 1; |
b79f74cd UD |
49 | } |
50 | ||
601d2942 UD |
51 | /* When testing UTF-8 or GB18030, stop at 0x10000, otherwise the output |
52 | file gets too big. */ | |
53 | bmp_only = (strcmp (charset, "UTF-8") == 0 | |
54 | || strcmp (charset, "GB18030") == 0); | |
55 | ||
b79f74cd UD |
56 | { |
57 | unsigned int i; | |
58 | unsigned char buf[10]; | |
59 | ||
601d2942 | 60 | for (i = 0; i < (bmp_only ? 0x10000 : 0x30000); i++) |
b79f74cd | 61 | { |
601d2942 UD |
62 | unsigned char in[6]; |
63 | unsigned int incount = | |
64 | (i < 0x80 ? (in[0] = i, 1) | |
65 | : i < 0x800 ? (in[0] = 0xc0 | (i >> 6), | |
66 | in[1] = 0x80 | (i & 0x3f), 2) | |
67 | : i < 0x10000 ? (in[0] = 0xe0 | (i >> 12), | |
68 | in[1] = 0x80 | ((i >> 6) & 0x3f), | |
69 | in[2] = 0x80 | (i & 0x3f), 3) | |
70 | : /* i < 0x200000 */ (in[0] = 0xf0 | (i >> 18), | |
71 | in[1] = 0x80 | ((i >> 12) & 0x3f), | |
72 | in[2] = 0x80 | ((i >> 6) & 0x3f), | |
73 | in[3] = 0x80 | (i & 0x3f), 4)); | |
74 | const char *inbuf = (const char *) in; | |
75 | size_t inbytesleft = incount; | |
b79f74cd UD |
76 | char *outbuf = (char *) buf; |
77 | size_t outbytesleft = sizeof (buf); | |
93a568aa | 78 | size_t result; |
faaa6f62 | 79 | size_t result2 = 0; |
93a568aa UD |
80 | |
81 | iconv (cd, NULL, NULL, NULL, NULL); | |
82 | result = iconv (cd, | |
83 | (char **) &inbuf, &inbytesleft, | |
84 | &outbuf, &outbytesleft); | |
85 | if (result != (size_t)(-1)) | |
faaa6f62 | 86 | result2 = iconv (cd, NULL, NULL, &outbuf, &outbytesleft); |
93a568aa | 87 | |
faaa6f62 | 88 | if (result == (size_t)(-1) || result2 == (size_t)(-1)) |
b79f74cd UD |
89 | { |
90 | if (errno != EILSEQ) | |
91 | { | |
92 | int saved_errno = errno; | |
93 | fprintf (stderr, "0x%02X: iconv error: ", i); | |
94 | errno = saved_errno; | |
95 | perror (""); | |
4e6bc1f6 | 96 | return 1; |
b79f74cd UD |
97 | } |
98 | } | |
99 | else if (result == 0) /* ignore conversions with transliteration */ | |
100 | { | |
101 | unsigned int j, jmax; | |
102 | if (inbytesleft != 0 || outbytesleft == sizeof (buf)) | |
103 | { | |
104 | fprintf (stderr, "0x%02X: inbytes = %ld, outbytes = %ld\n", i, | |
601d2942 | 105 | (long) (incount - inbytesleft), |
b79f74cd | 106 | (long) (sizeof (buf) - outbytesleft)); |
4e6bc1f6 | 107 | return 1; |
b79f74cd UD |
108 | } |
109 | jmax = sizeof (buf) - outbytesleft; | |
110 | printf ("0x"); | |
111 | for (j = 0; j < jmax; j++) | |
112 | printf ("%02X", buf[j]); | |
113 | printf ("\t0x%04X\n", i); | |
114 | } | |
115 | } | |
116 | } | |
117 | ||
118 | if (iconv_close (cd) < 0) | |
119 | { | |
120 | perror ("iconv_close"); | |
4e6bc1f6 | 121 | return 1; |
b79f74cd UD |
122 | } |
123 | ||
755104ed | 124 | if (ferror (stdin) || fflush (stdout) || ferror (stdout)) |
b79f74cd UD |
125 | { |
126 | fprintf (stderr, "I/O error\n"); | |
4e6bc1f6 | 127 | return 1; |
b79f74cd UD |
128 | } |
129 | ||
4e6bc1f6 | 130 | return 0; |
b79f74cd | 131 | } |