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