Flush the standard error stream before aborting.
[gnulib.git] / tests / test-iconv-utf.c
1 /* Test of character set conversion.
2    Copyright (C) 2007-2008 Free Software Foundation, Inc.
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 3 of the License, or
7    (at your option) 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
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17 /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
18
19 #include <config.h>
20
21 #if HAVE_ICONV
22 # include <iconv.h>
23 #endif
24
25 #include <errno.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #define ASSERT(expr) \
31   do                                                                         \
32     {                                                                        \
33       if (!(expr))                                                           \
34         {                                                                    \
35           fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
36           fflush (stderr);                                                   \
37           abort ();                                                          \
38         }                                                                    \
39     }                                                                        \
40   while (0)
41
42 int
43 main ()
44 {
45 #if HAVE_ICONV
46   /* Assume that iconv() supports at least the encoding UTF-8.  */
47
48   /* The text is "Japanese (日本語) [\U0001D50D\U0001D51E\U0001D52D]".  */
49
50   /* Test conversion from UTF-8 to UTF-16BE with no errors.  */
51   {
52     static const char input[] =
53       "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
54     static const char expected[] =
55       "\000J\000a\000p\000a\000n\000e\000s\000e\000 \000(\145\345\147\054\212\236\000)\000 \000[\330\065\335\015\330\065\335\036\330\065\335\055\000]";
56     iconv_t cd;
57     char buf[100];
58     const char *inptr;
59     size_t inbytesleft;
60     char *outptr;
61     size_t outbytesleft;
62     size_t res;
63
64     cd = iconv_open ("UTF-16BE", "UTF-8");
65     ASSERT (cd != (iconv_t)(-1));
66
67     inptr = input;
68     inbytesleft = sizeof (input) - 1;
69     outptr = buf;
70     outbytesleft = sizeof (buf);
71     res = iconv (cd,
72                  (ICONV_CONST char **) &inptr, &inbytesleft,
73                  &outptr, &outbytesleft);
74     ASSERT (res == 0 && inbytesleft == 0);
75     ASSERT (outptr == buf + (sizeof (expected) - 1));
76     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
77
78     ASSERT (iconv_close (cd) == 0);
79   }
80
81   /* Test conversion from UTF-8 to UTF-16LE with no errors.  */
82   {
83     static const char input[] =
84       "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
85     static const char expected[] =
86       "J\000a\000p\000a\000n\000e\000s\000e\000 \000(\000\345\145\054\147\236\212)\000 \000[\000\065\330\015\335\065\330\036\335\065\330\055\335]\000";
87     iconv_t cd;
88     char buf[100];
89     const char *inptr;
90     size_t inbytesleft;
91     char *outptr;
92     size_t outbytesleft;
93     size_t res;
94
95     cd = iconv_open ("UTF-16LE", "UTF-8");
96     ASSERT (cd != (iconv_t)(-1));
97
98     inptr = input;
99     inbytesleft = sizeof (input) - 1;
100     outptr = buf;
101     outbytesleft = sizeof (buf);
102     res = iconv (cd,
103                  (ICONV_CONST char **) &inptr, &inbytesleft,
104                  &outptr, &outbytesleft);
105     ASSERT (res == 0 && inbytesleft == 0);
106     ASSERT (outptr == buf + (sizeof (expected) - 1));
107     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
108
109     ASSERT (iconv_close (cd) == 0);
110   }
111
112   /* Test conversion from UTF-8 to UTF-32BE with no errors.  */
113   {
114     static const char input[] =
115       "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
116     static const char expected[] =
117       "\000\000\000J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\145\345\000\000\147\054\000\000\212\236\000\000\000)\000\000\000 \000\000\000[\000\001\325\015\000\001\325\036\000\001\325\055\000\000\000]";
118     iconv_t cd;
119     char buf[100];
120     const char *inptr;
121     size_t inbytesleft;
122     char *outptr;
123     size_t outbytesleft;
124     size_t res;
125
126     cd = iconv_open ("UTF-32BE", "UTF-8");
127     ASSERT (cd != (iconv_t)(-1));
128
129     inptr = input;
130     inbytesleft = sizeof (input) - 1;
131     outptr = buf;
132     outbytesleft = sizeof (buf);
133     res = iconv (cd,
134                  (ICONV_CONST char **) &inptr, &inbytesleft,
135                  &outptr, &outbytesleft);
136     ASSERT (res == 0 && inbytesleft == 0);
137     ASSERT (outptr == buf + (sizeof (expected) - 1));
138     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
139
140     ASSERT (iconv_close (cd) == 0);
141   }
142
143   /* Test conversion from UTF-8 to UTF-32LE with no errors.  */
144   {
145     static const char input[] =
146       "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
147     static const char expected[] =
148       "J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\000\345\145\000\000\054\147\000\000\236\212\000\000)\000\000\000 \000\000\000[\000\000\000\015\325\001\000\036\325\001\000\055\325\001\000]\000\000\000";
149     iconv_t cd;
150     char buf[100];
151     const char *inptr;
152     size_t inbytesleft;
153     char *outptr;
154     size_t outbytesleft;
155     size_t res;
156
157     cd = iconv_open ("UTF-32LE", "UTF-8");
158     ASSERT (cd != (iconv_t)(-1));
159
160     inptr = input;
161     inbytesleft = sizeof (input) - 1;
162     outptr = buf;
163     outbytesleft = sizeof (buf);
164     res = iconv (cd,
165                  (ICONV_CONST char **) &inptr, &inbytesleft,
166                  &outptr, &outbytesleft);
167     ASSERT (res == 0 && inbytesleft == 0);
168     ASSERT (outptr == buf + (sizeof (expected) - 1));
169     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
170
171     ASSERT (iconv_close (cd) == 0);
172   }
173
174   /* Test conversion from UTF-16BE to UTF-8 with no errors.  */
175   {
176     static const char input[] =
177       "\000J\000a\000p\000a\000n\000e\000s\000e\000 \000(\145\345\147\054\212\236\000)\000 \000[\330\065\335\015\330\065\335\036\330\065\335\055\000]";
178     static const char expected[] =
179       "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
180     iconv_t cd;
181     char buf[100];
182     const char *inptr;
183     size_t inbytesleft;
184     char *outptr;
185     size_t outbytesleft;
186     size_t res;
187
188     cd = iconv_open ("UTF-8", "UTF-16BE");
189     ASSERT (cd != (iconv_t)(-1));
190
191     inptr = input;
192     inbytesleft = sizeof (input) - 1;
193     outptr = buf;
194     outbytesleft = sizeof (buf);
195     res = iconv (cd,
196                  (ICONV_CONST char **) &inptr, &inbytesleft,
197                  &outptr, &outbytesleft);
198     ASSERT (res == 0 && inbytesleft == 0);
199     ASSERT (outptr == buf + (sizeof (expected) - 1));
200     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
201
202     ASSERT (iconv_close (cd) == 0);
203   }
204
205   /* Test conversion from UTF-16LE to UTF-8 with no errors.  */
206   {
207     static const char input[] =
208       "J\000a\000p\000a\000n\000e\000s\000e\000 \000(\000\345\145\054\147\236\212)\000 \000[\000\065\330\015\335\065\330\036\335\065\330\055\335]\000";
209     static const char expected[] =
210       "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
211     iconv_t cd;
212     char buf[100];
213     const char *inptr;
214     size_t inbytesleft;
215     char *outptr;
216     size_t outbytesleft;
217     size_t res;
218
219     cd = iconv_open ("UTF-8", "UTF-16LE");
220     ASSERT (cd != (iconv_t)(-1));
221
222     inptr = input;
223     inbytesleft = sizeof (input) - 1;
224     outptr = buf;
225     outbytesleft = sizeof (buf);
226     res = iconv (cd,
227                  (ICONV_CONST char **) &inptr, &inbytesleft,
228                  &outptr, &outbytesleft);
229     ASSERT (res == 0 && inbytesleft == 0);
230     ASSERT (outptr == buf + (sizeof (expected) - 1));
231     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
232
233     ASSERT (iconv_close (cd) == 0);
234   }
235
236   /* Test conversion from UTF-32BE to UTF-8 with no errors.  */
237   {
238     static const char input[] =
239       "\000\000\000J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\145\345\000\000\147\054\000\000\212\236\000\000\000)\000\000\000 \000\000\000[\000\001\325\015\000\001\325\036\000\001\325\055\000\000\000]";
240     static const char expected[] =
241       "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
242     iconv_t cd;
243     char buf[100];
244     const char *inptr;
245     size_t inbytesleft;
246     char *outptr;
247     size_t outbytesleft;
248     size_t res;
249
250     cd = iconv_open ("UTF-8", "UTF-32BE");
251     ASSERT (cd != (iconv_t)(-1));
252
253     inptr = input;
254     inbytesleft = sizeof (input) - 1;
255     outptr = buf;
256     outbytesleft = sizeof (buf);
257     res = iconv (cd,
258                  (ICONV_CONST char **) &inptr, &inbytesleft,
259                  &outptr, &outbytesleft);
260     ASSERT (res == 0 && inbytesleft == 0);
261     ASSERT (outptr == buf + (sizeof (expected) - 1));
262     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
263
264     ASSERT (iconv_close (cd) == 0);
265   }
266
267   /* Test conversion from UTF-32LE to UTF-8 with no errors.  */
268   {
269     static const char input[] =
270       "J\000\000\000a\000\000\000p\000\000\000a\000\000\000n\000\000\000e\000\000\000s\000\000\000e\000\000\000 \000\000\000(\000\000\000\345\145\000\000\054\147\000\000\236\212\000\000)\000\000\000 \000\000\000[\000\000\000\015\325\001\000\036\325\001\000\055\325\001\000]\000\000\000";
271     static const char expected[] =
272       "Japanese (\346\227\245\346\234\254\350\252\236) [\360\235\224\215\360\235\224\236\360\235\224\255]";
273     iconv_t cd;
274     char buf[100];
275     const char *inptr;
276     size_t inbytesleft;
277     char *outptr;
278     size_t outbytesleft;
279     size_t res;
280
281     cd = iconv_open ("UTF-8", "UTF-32LE");
282     ASSERT (cd != (iconv_t)(-1));
283
284     inptr = input;
285     inbytesleft = sizeof (input) - 1;
286     outptr = buf;
287     outbytesleft = sizeof (buf);
288     res = iconv (cd,
289                  (ICONV_CONST char **) &inptr, &inbytesleft,
290                  &outptr, &outbytesleft);
291     ASSERT (res == 0 && inbytesleft == 0);
292     ASSERT (outptr == buf + (sizeof (expected) - 1));
293     ASSERT (memcmp (buf, expected, sizeof (expected) - 1) == 0);
294
295     ASSERT (iconv_close (cd) == 0);
296   }
297 #endif
298
299   return 0;
300 }