Update.
[glibc.git] / iconvdata / tst-table-from.c
blob92a562d884d2dd4c1fb8a2ef56eaad0e2ba839cd
1 /* Copyright (C) 2000 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Bruno Haible <haible@clisp.cons.org>, 2000.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
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
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
20 /* Create a table from CHARSET to Unicode.
21 This is a good test for CHARSET's iconv() module, in particular the
22 FROM_LOOP BODY macro. */
24 #include <stddef.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <iconv.h>
29 #include <errno.h>
31 /* Converts a byte buffer to a hexadecimal string. */
32 static const char*
33 hexbuf (unsigned char buf[], unsigned int buflen)
35 static char msg[50];
37 switch (buflen)
39 case 1:
40 sprintf (msg, "0x%02X", buf[0]);
41 break;
42 case 2:
43 sprintf (msg, "0x%02X%02X", buf[0], buf[1]);
44 break;
45 case 3:
46 sprintf (msg, "0x%02X%02X%02X", buf[0], buf[1], buf[2]);
47 break;
48 case 4:
49 sprintf (msg, "0x%02X%02X%02X%02X", buf[0], buf[1], buf[2], buf[3]);
50 break;
51 default:
52 abort ();
54 return msg;
57 /* Attempts to convert a byte buffer BUF (BUFLEN bytes) to OUT (6 bytes)
58 using the conversion descriptor CD. Returns the number of written bytes,
59 or 0 if ambiguous, or -1 if invalid. */
60 static int
61 try (iconv_t cd, unsigned char buf[], unsigned int buflen, unsigned char *out)
63 const char *inbuf = (const char *) buf;
64 size_t inbytesleft = buflen;
65 char *outbuf = (char *) out;
66 size_t outbytesleft = 6;
67 size_t result = iconv (cd,
68 (char **) &inbuf, &inbytesleft,
69 &outbuf, &outbytesleft);
70 if (result == (size_t)(-1))
72 if (errno == EILSEQ)
74 return -1;
76 else if (errno == EINVAL)
78 return 0;
80 else
82 int saved_errno = errno;
83 fprintf (stderr, "%s: iconv error: ", hexbuf (buf, buflen));
84 errno = saved_errno;
85 perror ("");
86 exit (1);
89 else
91 if (inbytesleft != 0)
93 fprintf (stderr, "%s: inbytes = %ld, outbytes = %ld\n",
94 hexbuf (buf, buflen),
95 (long) (buflen - inbytesleft),
96 (long) (6 - outbytesleft));
97 exit (1);
99 return 6 - outbytesleft;
103 /* Returns the out[] buffer as a Unicode value. */
104 static unsigned int
105 utf8_decode (const unsigned char *out, unsigned int outlen)
107 return (outlen==1 ? out[0] :
108 outlen==2 ? ((out[0] & 0x1f) << 6) + (out[1] & 0x3f) :
109 outlen==3 ? ((out[0] & 0x0f) << 12) + ((out[1] & 0x3f) << 6) + (out[2] & 0x3f) :
110 outlen==4 ? ((out[0] & 0x07) << 18) + ((out[1] & 0x3f) << 12) + ((out[2] & 0x3f) << 6) + (out[3] & 0x3f) :
111 outlen==5 ? ((out[0] & 0x03) << 24) + ((out[1] & 0x3f) << 18) + ((out[2] & 0x3f) << 12) + ((out[3] & 0x3f) << 6) + (out[4] & 0x3f) :
112 outlen==6 ? ((out[0] & 0x01) << 30) + ((out[1] & 0x3f) << 24) + ((out[2] & 0x3f) << 18) + ((out[3] & 0x3f) << 12) + ((out[4] & 0x3f) << 6) + (out[5] & 0x3f) :
113 0xfffd);
117 main (int argc, char *argv[])
119 const char *charset;
120 iconv_t cd;
122 if (argc != 2)
124 fprintf (stderr, "Usage: tst-table-to charset\n");
125 exit (1);
127 charset = argv[1];
129 cd = iconv_open ("UTF-8", charset);
130 if (cd == (iconv_t)(-1))
132 perror ("iconv_open");
133 exit (1);
137 unsigned char out[6];
138 unsigned char buf[4];
139 unsigned int i0, i1, i2, i3;
140 int result;
142 for (i0 = 0; i0 < 0x100; i0++)
144 buf[0] = i0;
145 result = try (cd, buf, 1, out);
146 if (result < 0)
149 else if (result > 0)
151 printf ("0x%02X\t0x%04X\n",
152 i0, utf8_decode (out, result));
154 else
156 for (i1 = 0; i1 < 0x100; i1++)
158 buf[1] = i1;
159 result = try (cd, buf, 2, out);
160 if (result < 0)
163 else if (result > 0)
165 printf ("0x%02X%02X\t0x%04X\n",
166 i0, i1, utf8_decode (out, result));
168 else
170 for (i2 = 0; i2 < 0x100; i2++)
172 buf[2] = i2;
173 result = try (cd, buf, 3, out);
174 if (result < 0)
177 else if (result > 0)
179 printf ("0x%02X%02X%02X\t0x%04X\n",
180 i0, i1, i2, utf8_decode (out, result));
182 else if (strcmp (charset, "UTF-8"))
184 for (i3 = 0; i3 < 0x100; i3++)
186 buf[3] = i3;
187 result = try (cd, buf, 4, out);
188 if (result < 0)
191 else if (result > 0)
193 printf ("0x%02X%02X%02X%02X\t0x%04X\n",
194 i0, i1, i2, i3,
195 utf8_decode (out, result));
197 else
199 fprintf (stderr,
200 "%s: incomplete byte sequence\n",
201 hexbuf (buf, 4));
202 exit (1);
213 if (iconv_close (cd) < 0)
215 perror ("iconv_close");
216 exit (1);
219 if (ferror (stdin) || ferror (stdout))
221 fprintf (stderr, "I/O error\n");
222 exit (1);
225 exit (0);