Better ASSERT macro.
[gnulib.git] / tests / test-striconv.c
1 /* Test of character set conversion.
2    Copyright (C) 2007 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 2, or (at your option)
7    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, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include "striconv.h"
25
26 #if HAVE_ICONV
27 # include <iconv.h>
28 #endif
29
30 #include <errno.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34
35 #define ASSERT(expr) \
36   do                                                                         \
37     {                                                                        \
38       if (!(expr))                                                           \
39         {                                                                    \
40           fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
41           abort ();                                                          \
42         }                                                                    \
43     }                                                                        \
44   while (0)
45
46 int
47 main ()
48 {
49 #if HAVE_ICONV
50   /* Assume that iconv() supports at least the encodings ASCII, ISO-8859-1,
51      and UTF-8.  */
52   iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
53   iconv_t cd_utf8_to_88591 = iconv_open ("ISO-8859-1", "UTF-8");
54
55   ASSERT (cd_88591_to_utf8 != (iconv_t)(-1));
56   ASSERT (cd_utf8_to_88591 != (iconv_t)(-1));
57
58   /* ------------------------- Test mem_cd_iconv() ------------------------- */
59
60   /* Test conversion from ISO-8859-1 to UTF-8 with no errors.  */
61   {
62     static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
63     static const char expected[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237";
64     char *result = NULL;
65     size_t length = 0;
66     int retval = mem_cd_iconv (input, strlen (input), cd_88591_to_utf8,
67                                &result, &length);
68     ASSERT (retval == 0);
69     ASSERT (length == strlen (expected));
70     ASSERT (result != NULL && memcmp (result, expected, strlen (expected)) == 0);
71     free (result);
72   }
73
74   /* Test conversion from UTF-8 to ISO-8859-1 with no errors.  */
75   {
76     static const char input[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237";
77     static const char expected[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
78     char *result = NULL;
79     size_t length = 0;
80     int retval = mem_cd_iconv (input, strlen (input), cd_utf8_to_88591,
81                                &result, &length);
82     ASSERT (retval == 0);
83     ASSERT (length == strlen (expected));
84     ASSERT (result != NULL && memcmp (result, expected, strlen (expected)) == 0);
85     free (result);
86   }
87
88   /* Test conversion from UTF-8 to ISO-8859-1 with EILSEQ.  */
89   {
90     static const char input[] = "\342\202\254"; /* EURO SIGN */
91     char *result = NULL;
92     size_t length = 0;
93     int retval = mem_cd_iconv (input, strlen (input), cd_utf8_to_88591,
94                                &result, &length);
95     ASSERT (retval == -1 && errno == EILSEQ);
96     ASSERT (result == NULL);
97   }
98
99   /* Test conversion from UTF-8 to ISO-8859-1 with EINVAL.  */
100   {
101     static const char input[] = "\342";
102     char *result = NULL;
103     size_t length = 0;
104     int retval = mem_cd_iconv (input, strlen (input), cd_utf8_to_88591,
105                                &result, &length);
106     ASSERT (retval == 0);
107     ASSERT (length == 0);
108     if (result != NULL)
109       free (result);
110   }
111
112   /* ------------------------- Test str_cd_iconv() ------------------------- */
113
114   /* Test conversion from ISO-8859-1 to UTF-8 with no errors.  */
115   {
116     static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
117     static const char expected[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237";
118     char *result = str_cd_iconv (input, cd_88591_to_utf8);
119     ASSERT (result != NULL);
120     ASSERT (strcmp (result, expected) == 0);
121     free (result);
122   }
123
124   /* Test conversion from UTF-8 to ISO-8859-1 with no errors.  */
125   {
126     static const char input[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237";
127     static const char expected[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
128     char *result = str_cd_iconv (input, cd_utf8_to_88591);
129     ASSERT (result != NULL);
130     ASSERT (strcmp (result, expected) == 0);
131     free (result);
132   }
133
134   /* Test conversion from UTF-8 to ISO-8859-1 with EILSEQ.  */
135   {
136     static const char input[] = "Costs: 27 \342\202\254"; /* EURO SIGN */
137     char *result = str_cd_iconv (input, cd_utf8_to_88591);
138     ASSERT (result == NULL && errno == EILSEQ);
139   }
140
141   /* Test conversion from UTF-8 to ISO-8859-1 with EINVAL.  */
142   {
143     static const char input[] = "\342";
144     char *result = str_cd_iconv (input, cd_utf8_to_88591);
145     ASSERT (result != NULL);
146     ASSERT (strcmp (result, "") == 0);
147     free (result);
148   }
149
150   iconv_close (cd_88591_to_utf8);
151   iconv_close (cd_utf8_to_88591);
152
153   /* -------------------------- Test str_iconv() -------------------------- */
154
155   /* Test conversion from ISO-8859-1 to UTF-8 with no errors.  */
156   {
157     static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
158     static const char expected[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237";
159     char *result = str_iconv (input, "ISO-8859-1", "UTF-8");
160     ASSERT (result != NULL);
161     ASSERT (strcmp (result, expected) == 0);
162     free (result);
163   }
164
165   /* Test conversion from UTF-8 to ISO-8859-1 with no errors.  */
166   {
167     static const char input[] = "\303\204rger mit b\303\266sen B\303\274bchen ohne Augenma\303\237";
168     static const char expected[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
169     char *result = str_iconv (input, "UTF-8", "ISO-8859-1");
170     ASSERT (result != NULL);
171     ASSERT (strcmp (result, expected) == 0);
172     free (result);
173   }
174
175   /* Test conversion from UTF-8 to ISO-8859-1 with EILSEQ.  */
176   {
177     static const char input[] = "Costs: 27 \342\202\254"; /* EURO SIGN */
178     char *result = str_iconv (input, "UTF-8", "ISO-8859-1");
179     ASSERT (result == NULL && errno == EILSEQ);
180   }
181
182   /* Test conversion from UTF-8 to ISO-8859-1 with EINVAL.  */
183   {
184     static const char input[] = "\342";
185     char *result = str_iconv (input, "UTF-8", "ISO-8859-1");
186     ASSERT (result != NULL);
187     ASSERT (strcmp (result, "") == 0);
188     free (result);
189   }
190
191 #endif
192
193   return 0;
194 }