Use spaces for indentation, not tabs.
[gnulib.git] / tests / test-mbsnrtowcs.c
1 /* Test of conversion of string to wide string.
2    Copyright (C) 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>, 2008.  */
18
19 #include <config.h>
20
21 #include <wchar.h>
22
23 #include <locale.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #define ASSERT(expr) \
29   do                                                                         \
30     {                                                                        \
31       if (!(expr))                                                           \
32         {                                                                    \
33           fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
34           fflush (stderr);                                                   \
35           abort ();                                                          \
36         }                                                                    \
37     }                                                                        \
38   while (0)
39
40 int
41 main (int argc, char *argv[])
42 {
43   mbstate_t state;
44   wchar_t wc;
45   size_t ret;
46
47   /* configure should already have checked that the locale is supported.  */
48   if (setlocale (LC_ALL, "") == NULL)
49     return 1;
50
51   /* Test NUL byte input.  */
52   {
53     const char *src;
54
55     memset (&state, '\0', sizeof (mbstate_t));
56
57     src = "";
58     ret = mbsnrtowcs (NULL, &src, 1, 0, &state);
59     ASSERT (ret == 0);
60     ASSERT (mbsinit (&state));
61
62     src = "";
63     ret = mbsnrtowcs (NULL, &src, 1, 1, &state);
64     ASSERT (ret == 0);
65     ASSERT (mbsinit (&state));
66
67     wc = (wchar_t) 0xBADFACE;
68     src = "";
69     ret = mbsnrtowcs (&wc, &src, 1, 0, &state);
70     ASSERT (ret == 0);
71     ASSERT (wc == (wchar_t) 0xBADFACE);
72     ASSERT (mbsinit (&state));
73
74     wc = (wchar_t) 0xBADFACE;
75     src = "";
76     ret = mbsnrtowcs (&wc, &src, 1, 1, &state);
77     ASSERT (ret == 0);
78     ASSERT (wc == 0);
79     ASSERT (mbsinit (&state));
80   }
81
82   if (argc > 1)
83     {
84       int unlimited;
85
86       for (unlimited = 0; unlimited < 2; unlimited++)
87         {
88           #define BUFSIZE 10
89           wchar_t buf[BUFSIZE];
90           const char *src;
91           mbstate_t temp_state;
92
93           {
94             size_t i;
95             for (i = 0; i < BUFSIZE; i++)
96               buf[i] = (wchar_t) 0xBADFACE;
97           }
98
99           switch (argv[1][0])
100             {
101             case '1':
102               /* Locale encoding is ISO-8859-1 or ISO-8859-15.  */
103               {
104                 char input[] = "B\374\337er"; /* "Büßer" */
105                 memset (&state, '\0', sizeof (mbstate_t));
106
107                 wc = (wchar_t) 0xBADFACE;
108                 ret = mbrtowc (&wc, input, 1, &state);
109                 ASSERT (ret == 1);
110                 ASSERT (wc == 'B');
111                 ASSERT (mbsinit (&state));
112                 input[0] = '\0';
113
114                 wc = (wchar_t) 0xBADFACE;
115                 ret = mbrtowc (&wc, input + 1, 1, &state);
116                 ASSERT (ret == 1);
117                 ASSERT (wctob (wc) == (unsigned char) '\374');
118                 ASSERT (mbsinit (&state));
119                 input[1] = '\0';
120
121                 src = input + 2;
122                 temp_state = state;
123                 ret = mbsnrtowcs (NULL, &src, 4, unlimited ? BUFSIZE : 1, &temp_state);
124                 ASSERT (ret == 3);
125                 ASSERT (src == input + 2);
126                 ASSERT (mbsinit (&state));
127
128                 src = input + 2;
129                 ret = mbsnrtowcs (buf, &src, 4, unlimited ? BUFSIZE : 1, &state);
130                 ASSERT (ret == (unlimited ? 3 : 1));
131                 ASSERT (src == (unlimited ? NULL : input + 3));
132                 ASSERT (wctob (buf[0]) == (unsigned char) '\337');
133                 if (unlimited)
134                   {
135                     ASSERT (buf[1] == 'e');
136                     ASSERT (buf[2] == 'r');
137                     ASSERT (buf[3] == 0);
138                     ASSERT (buf[4] == (wchar_t) 0xBADFACE);
139                   }
140                 else
141                   ASSERT (buf[1] == (wchar_t) 0xBADFACE);
142                 ASSERT (mbsinit (&state));
143               }
144               break;
145
146             case '2':
147               /* Locale encoding is UTF-8.  */
148               {
149                 char input[] = "B\303\274\303\237er"; /* "Büßer" */
150                 memset (&state, '\0', sizeof (mbstate_t));
151
152                 wc = (wchar_t) 0xBADFACE;
153                 ret = mbrtowc (&wc, input, 1, &state);
154                 ASSERT (ret == 1);
155                 ASSERT (wc == 'B');
156                 ASSERT (mbsinit (&state));
157                 input[0] = '\0';
158
159                 wc = (wchar_t) 0xBADFACE;
160                 ret = mbrtowc (&wc, input + 1, 1, &state);
161                 ASSERT (ret == (size_t)(-2));
162                 ASSERT (wc == (wchar_t) 0xBADFACE);
163                 ASSERT (!mbsinit (&state));
164                 input[1] = '\0';
165
166                 src = input + 2;
167                 temp_state = state;
168                 ret = mbsnrtowcs (NULL, &src, 6, unlimited ? BUFSIZE : 2, &temp_state);
169                 ASSERT (ret == 4);
170                 ASSERT (src == input + 2);
171                 ASSERT (!mbsinit (&state));
172
173                 src = input + 2;
174                 ret = mbsnrtowcs (buf, &src, 6, unlimited ? BUFSIZE : 2, &state);
175                 ASSERT (ret == (unlimited ? 4 : 2));
176                 ASSERT (src == (unlimited ? NULL : input + 5));
177                 ASSERT (wctob (buf[0]) == EOF);
178                 ASSERT (wctob (buf[1]) == EOF);
179                 if (unlimited)
180                   {
181                     ASSERT (buf[2] == 'e');
182                     ASSERT (buf[3] == 'r');
183                     ASSERT (buf[4] == 0);
184                     ASSERT (buf[5] == (wchar_t) 0xBADFACE);
185                   }
186                 else
187                   ASSERT (buf[2] == (wchar_t) 0xBADFACE);
188                 ASSERT (mbsinit (&state));
189               }
190               break;
191
192             case '3':
193               /* Locale encoding is EUC-JP.  */
194               {
195                 char input[] = "<\306\374\313\334\270\354>"; /* "<日本語>" */
196                 memset (&state, '\0', sizeof (mbstate_t));
197
198                 wc = (wchar_t) 0xBADFACE;
199                 ret = mbrtowc (&wc, input, 1, &state);
200                 ASSERT (ret == 1);
201                 ASSERT (wc == '<');
202                 ASSERT (mbsinit (&state));
203                 input[0] = '\0';
204
205                 wc = (wchar_t) 0xBADFACE;
206                 ret = mbrtowc (&wc, input + 1, 2, &state);
207                 ASSERT (ret == 2);
208                 ASSERT (wctob (wc) == EOF);
209                 ASSERT (mbsinit (&state));
210                 input[1] = '\0';
211                 input[2] = '\0';
212
213                 wc = (wchar_t) 0xBADFACE;
214                 ret = mbrtowc (&wc, input + 3, 1, &state);
215                 ASSERT (ret == (size_t)(-2));
216                 ASSERT (wc == (wchar_t) 0xBADFACE);
217                 ASSERT (!mbsinit (&state));
218                 input[3] = '\0';
219
220                 src = input + 4;
221                 temp_state = state;
222                 ret = mbsnrtowcs (NULL, &src, 5, unlimited ? BUFSIZE : 2, &temp_state);
223                 ASSERT (ret == 3);
224                 ASSERT (src == input + 4);
225                 ASSERT (!mbsinit (&state));
226
227                 src = input + 4;
228                 ret = mbsnrtowcs (buf, &src, 5, unlimited ? BUFSIZE : 2, &state);
229                 ASSERT (ret == (unlimited ? 3 : 2));
230                 ASSERT (src == (unlimited ? NULL : input + 7));
231                 ASSERT (wctob (buf[0]) == EOF);
232                 ASSERT (wctob (buf[1]) == EOF);
233                 if (unlimited)
234                   {
235                     ASSERT (buf[2] == '>');
236                     ASSERT (buf[3] == 0);
237                     ASSERT (buf[4] == (wchar_t) 0xBADFACE);
238                   }
239                 else
240                   ASSERT (buf[2] == (wchar_t) 0xBADFACE);
241                 ASSERT (mbsinit (&state));
242               }
243               break;
244
245             case '4':
246               /* Locale encoding is GB18030.  */
247               {
248                 char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
249                 memset (&state, '\0', sizeof (mbstate_t));
250
251                 wc = (wchar_t) 0xBADFACE;
252                 ret = mbrtowc (&wc, input, 1, &state);
253                 ASSERT (ret == 1);
254                 ASSERT (wc == 'B');
255                 ASSERT (mbsinit (&state));
256                 input[0] = '\0';
257
258                 wc = (wchar_t) 0xBADFACE;
259                 ret = mbrtowc (&wc, input + 1, 1, &state);
260                 ASSERT (ret == (size_t)(-2));
261                 ASSERT (wc == (wchar_t) 0xBADFACE);
262                 ASSERT (!mbsinit (&state));
263                 input[1] = '\0';
264
265                 src = input + 2;
266                 temp_state = state;
267                 ret = mbsnrtowcs (NULL, &src, 8, unlimited ? BUFSIZE : 2, &temp_state);
268                 ASSERT (ret == 4);
269                 ASSERT (src == input + 2);
270                 ASSERT (!mbsinit (&state));
271
272                 src = input + 2;
273                 ret = mbsnrtowcs (buf, &src, 8, unlimited ? BUFSIZE : 2, &state);
274                 ASSERT (ret == (unlimited ? 4 : 2));
275                 ASSERT (src == (unlimited ? NULL : input + 7));
276                 ASSERT (wctob (buf[0]) == EOF);
277                 ASSERT (wctob (buf[1]) == EOF);
278                 if (unlimited)
279                   {
280                     ASSERT (buf[2] == 'e');
281                     ASSERT (buf[3] == 'r');
282                     ASSERT (buf[4] == 0);
283                     ASSERT (buf[5] == (wchar_t) 0xBADFACE);
284                   }
285                 else
286                   ASSERT (buf[2] == (wchar_t) 0xBADFACE);
287                 ASSERT (mbsinit (&state));
288               }
289               break;
290
291             default:
292               return 1;
293             }
294         }
295
296       return 0;
297     }
298
299   return 1;
300 }