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