Bump to m4 1.4.19
[platform/upstream/m4.git] / tests / test-mbrtowc-w32.c
1 /* Test of conversion of multibyte character to wide character.
2    Copyright (C) 2008-2021 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 <https://www.gnu.org/licenses/>.  */
16
17 #include <config.h>
18
19 #include <wchar.h>
20
21 #include <errno.h>
22 #include <locale.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "localcharset.h"
28 #include "macros.h"
29
30 #if defined _WIN32 && !defined __CYGWIN__
31
32 static int
33 test_one_locale (const char *name, int codepage)
34 {
35   mbstate_t state;
36   wchar_t wc;
37   size_t ret;
38
39 # if 1
40   /* Portable code to set the locale.  */
41   {
42     char name_with_codepage[1024];
43
44     sprintf (name_with_codepage, "%s.%d", name, codepage);
45
46     /* Set the locale.  */
47     if (setlocale (LC_ALL, name_with_codepage) == NULL)
48       return 77;
49   }
50 # else
51   /* Hacky way to set a locale.codepage combination that setlocale() refuses
52      to set.  */
53   {
54     /* Codepage of the current locale, set with setlocale().
55        Not necessarily the same as GetACP().  */
56     extern __declspec(dllimport) unsigned int __lc_codepage;
57
58     /* Set the locale.  */
59     if (setlocale (LC_ALL, name) == NULL)
60       return 77;
61
62     /* Clobber the codepage and MB_CUR_MAX, both set by setlocale().  */
63     __lc_codepage = codepage;
64     switch (codepage)
65       {
66       case 1252:
67       case 1256:
68         MB_CUR_MAX = 1;
69         break;
70       case 932:
71       case 950:
72       case 936:
73         MB_CUR_MAX = 2;
74         break;
75       case 54936:
76       case 65001:
77         MB_CUR_MAX = 4;
78         break;
79       }
80
81     /* Test whether the codepage is really available.  */
82     memset (&state, '\0', sizeof (mbstate_t));
83     if (mbrtowc (&wc, " ", 1, &state) == (size_t)(-1))
84       return 77;
85   }
86 # endif
87
88   /* Test zero-length input.  */
89   {
90     memset (&state, '\0', sizeof (mbstate_t));
91     wc = (wchar_t) 0xBADFACE;
92     ret = mbrtowc (&wc, "x", 0, &state);
93     /* gnulib's implementation returns (size_t)(-2).
94        The AIX 5.1 implementation returns (size_t)(-1).
95        glibc's implementation returns 0.  */
96     ASSERT (ret == (size_t)(-2) || ret == (size_t)(-1) || ret == 0);
97     ASSERT (mbsinit (&state));
98   }
99
100   /* Test NUL byte input.  */
101   {
102     memset (&state, '\0', sizeof (mbstate_t));
103     wc = (wchar_t) 0xBADFACE;
104     ret = mbrtowc (&wc, "", 1, &state);
105     ASSERT (ret == 0);
106     ASSERT (wc == 0);
107     ASSERT (mbsinit (&state));
108     ret = mbrtowc (NULL, "", 1, &state);
109     ASSERT (ret == 0);
110     ASSERT (mbsinit (&state));
111   }
112
113   /* Test single-byte input.  */
114   {
115     int c;
116     char buf[1];
117
118     memset (&state, '\0', sizeof (mbstate_t));
119     for (c = 0; c < 0x100; c++)
120       switch (c)
121         {
122         case '\t': case '\v': case '\f':
123         case ' ': case '!': case '"': case '#': case '%':
124         case '&': case '\'': case '(': case ')': case '*':
125         case '+': case ',': case '-': case '.': case '/':
126         case '0': case '1': case '2': case '3': case '4':
127         case '5': case '6': case '7': case '8': case '9':
128         case ':': case ';': case '<': case '=': case '>':
129         case '?':
130         case 'A': case 'B': case 'C': case 'D': case 'E':
131         case 'F': case 'G': case 'H': case 'I': case 'J':
132         case 'K': case 'L': case 'M': case 'N': case 'O':
133         case 'P': case 'Q': case 'R': case 'S': case 'T':
134         case 'U': case 'V': case 'W': case 'X': case 'Y':
135         case 'Z':
136         case '[': case '\\': case ']': case '^': case '_':
137         case 'a': case 'b': case 'c': case 'd': case 'e':
138         case 'f': case 'g': case 'h': case 'i': case 'j':
139         case 'k': case 'l': case 'm': case 'n': case 'o':
140         case 'p': case 'q': case 'r': case 's': case 't':
141         case 'u': case 'v': case 'w': case 'x': case 'y':
142         case 'z': case '{': case '|': case '}': case '~':
143           /* c is in the ISO C "basic character set".  */
144           buf[0] = c;
145           wc = (wchar_t) 0xBADFACE;
146           ret = mbrtowc (&wc, buf, 1, &state);
147           ASSERT (ret == 1);
148           ASSERT (wc == c);
149           ASSERT (mbsinit (&state));
150           ret = mbrtowc (NULL, buf, 1, &state);
151           ASSERT (ret == 1);
152           ASSERT (mbsinit (&state));
153           break;
154         }
155   }
156
157   /* Test special calling convention, passing a NULL pointer.  */
158   {
159     memset (&state, '\0', sizeof (mbstate_t));
160     wc = (wchar_t) 0xBADFACE;
161     ret = mbrtowc (&wc, NULL, 5, &state);
162     ASSERT (ret == 0);
163     ASSERT (wc == (wchar_t) 0xBADFACE);
164     ASSERT (mbsinit (&state));
165   }
166
167   switch (codepage)
168     {
169     case 1252:
170       /* Locale encoding is CP1252, an extension of ISO-8859-1.  */
171       {
172         char input[] = "B\374\337er"; /* "Büßer" */
173         memset (&state, '\0', sizeof (mbstate_t));
174
175         wc = (wchar_t) 0xBADFACE;
176         ret = mbrtowc (&wc, input, 1, &state);
177         ASSERT (ret == 1);
178         ASSERT (wc == 'B');
179         ASSERT (mbsinit (&state));
180         input[0] = '\0';
181
182         wc = (wchar_t) 0xBADFACE;
183         ret = mbrtowc (&wc, input + 1, 1, &state);
184         ASSERT (ret == 1);
185         ASSERT (wctob (wc) == (unsigned char) '\374');
186         ASSERT (wc == 0x00FC);
187         ASSERT (mbsinit (&state));
188         input[1] = '\0';
189
190         /* Test support of NULL first argument.  */
191         ret = mbrtowc (NULL, input + 2, 3, &state);
192         ASSERT (ret == 1);
193         ASSERT (mbsinit (&state));
194
195         wc = (wchar_t) 0xBADFACE;
196         ret = mbrtowc (&wc, input + 2, 3, &state);
197         ASSERT (ret == 1);
198         ASSERT (wctob (wc) == (unsigned char) '\337');
199         ASSERT (wc == 0x00DF);
200         ASSERT (mbsinit (&state));
201         input[2] = '\0';
202
203         wc = (wchar_t) 0xBADFACE;
204         ret = mbrtowc (&wc, input + 3, 2, &state);
205         ASSERT (ret == 1);
206         ASSERT (wc == 'e');
207         ASSERT (mbsinit (&state));
208         input[3] = '\0';
209
210         wc = (wchar_t) 0xBADFACE;
211         ret = mbrtowc (&wc, input + 4, 1, &state);
212         ASSERT (ret == 1);
213         ASSERT (wc == 'r');
214         ASSERT (mbsinit (&state));
215       }
216       return 0;
217
218     case 1256:
219       /* Locale encoding is CP1256, not the same as ISO-8859-6.  */
220       {
221         char input[] = "x\302\341\346y"; /* "xآلوy" */
222         memset (&state, '\0', sizeof (mbstate_t));
223
224         wc = (wchar_t) 0xBADFACE;
225         ret = mbrtowc (&wc, input, 1, &state);
226         ASSERT (ret == 1);
227         ASSERT (wc == 'x');
228         ASSERT (mbsinit (&state));
229         input[0] = '\0';
230
231         wc = (wchar_t) 0xBADFACE;
232         ret = mbrtowc (&wc, input + 1, 1, &state);
233         ASSERT (ret == 1);
234         ASSERT (wctob (wc) == (unsigned char) '\302');
235         ASSERT (wc == 0x0622);
236         ASSERT (mbsinit (&state));
237         input[1] = '\0';
238
239         /* Test support of NULL first argument.  */
240         ret = mbrtowc (NULL, input + 2, 3, &state);
241         ASSERT (ret == 1);
242         ASSERT (mbsinit (&state));
243
244         wc = (wchar_t) 0xBADFACE;
245         ret = mbrtowc (&wc, input + 2, 3, &state);
246         ASSERT (ret == 1);
247         ASSERT (wctob (wc) == (unsigned char) '\341');
248         ASSERT (wc == 0x0644);
249         ASSERT (mbsinit (&state));
250         input[2] = '\0';
251
252         wc = (wchar_t) 0xBADFACE;
253         ret = mbrtowc (&wc, input + 3, 2, &state);
254         ASSERT (ret == 1);
255         ASSERT (wctob (wc) == (unsigned char) '\346');
256         ASSERT (wc == 0x0648);
257         ASSERT (mbsinit (&state));
258         input[3] = '\0';
259
260         wc = (wchar_t) 0xBADFACE;
261         ret = mbrtowc (&wc, input + 4, 1, &state);
262         ASSERT (ret == 1);
263         ASSERT (wc == 'y');
264         ASSERT (mbsinit (&state));
265       }
266       return 0;
267
268     case 932:
269       /* Locale encoding is CP932, similar to Shift_JIS.  */
270       {
271         char input[] = "<\223\372\226\173\214\352>"; /* "<日本語>" */
272         memset (&state, '\0', sizeof (mbstate_t));
273
274         wc = (wchar_t) 0xBADFACE;
275         ret = mbrtowc (&wc, input, 1, &state);
276         ASSERT (ret == 1);
277         ASSERT (wc == '<');
278         ASSERT (mbsinit (&state));
279         input[0] = '\0';
280
281         wc = (wchar_t) 0xBADFACE;
282         ret = mbrtowc (&wc, input + 1, 2, &state);
283         ASSERT (ret == 2);
284         ASSERT (wctob (wc) == EOF);
285         ASSERT (wc == 0x65E5);
286         ASSERT (mbsinit (&state));
287         input[1] = '\0';
288         input[2] = '\0';
289
290         wc = (wchar_t) 0xBADFACE;
291         ret = mbrtowc (&wc, input + 3, 1, &state);
292         ASSERT (ret == (size_t)(-2));
293         ASSERT (wc == (wchar_t) 0xBADFACE);
294         ASSERT (!mbsinit (&state));
295         input[3] = '\0';
296
297         wc = (wchar_t) 0xBADFACE;
298         ret = mbrtowc (&wc, input + 4, 4, &state);
299         ASSERT (ret == 1);
300         ASSERT (wctob (wc) == EOF);
301         ASSERT (wc == 0x672C);
302         ASSERT (mbsinit (&state));
303         input[4] = '\0';
304
305         /* Test support of NULL first argument.  */
306         ret = mbrtowc (NULL, input + 5, 3, &state);
307         ASSERT (ret == 2);
308         ASSERT (mbsinit (&state));
309
310         wc = (wchar_t) 0xBADFACE;
311         ret = mbrtowc (&wc, input + 5, 3, &state);
312         ASSERT (ret == 2);
313         ASSERT (wctob (wc) == EOF);
314         ASSERT (wc == 0x8A9E);
315         ASSERT (mbsinit (&state));
316         input[5] = '\0';
317         input[6] = '\0';
318
319         wc = (wchar_t) 0xBADFACE;
320         ret = mbrtowc (&wc, input + 7, 1, &state);
321         ASSERT (ret == 1);
322         ASSERT (wc == '>');
323         ASSERT (mbsinit (&state));
324
325         /* Test some invalid input.  */
326         memset (&state, '\0', sizeof (mbstate_t));
327         wc = (wchar_t) 0xBADFACE;
328         ret = mbrtowc (&wc, "\377", 1, &state); /* 0xFF */
329         ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || ret == (size_t)-2);
330
331         memset (&state, '\0', sizeof (mbstate_t));
332         wc = (wchar_t) 0xBADFACE;
333         ret = mbrtowc (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
334         ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || (ret == 2 && wc == 0x30FB));
335       }
336       return 0;
337
338     case 950:
339       /* Locale encoding is CP950, similar to Big5.  */
340       {
341         char input[] = "<\244\351\245\273\273\171>"; /* "<日本語>" */
342         memset (&state, '\0', sizeof (mbstate_t));
343
344         wc = (wchar_t) 0xBADFACE;
345         ret = mbrtowc (&wc, input, 1, &state);
346         ASSERT (ret == 1);
347         ASSERT (wc == '<');
348         ASSERT (mbsinit (&state));
349         input[0] = '\0';
350
351         wc = (wchar_t) 0xBADFACE;
352         ret = mbrtowc (&wc, input + 1, 2, &state);
353         ASSERT (ret == 2);
354         ASSERT (wctob (wc) == EOF);
355         ASSERT (wc == 0x65E5);
356         ASSERT (mbsinit (&state));
357         input[1] = '\0';
358         input[2] = '\0';
359
360         wc = (wchar_t) 0xBADFACE;
361         ret = mbrtowc (&wc, input + 3, 1, &state);
362         ASSERT (ret == (size_t)(-2));
363         ASSERT (wc == (wchar_t) 0xBADFACE);
364         ASSERT (!mbsinit (&state));
365         input[3] = '\0';
366
367         wc = (wchar_t) 0xBADFACE;
368         ret = mbrtowc (&wc, input + 4, 4, &state);
369         ASSERT (ret == 1);
370         ASSERT (wctob (wc) == EOF);
371         ASSERT (wc == 0x672C);
372         ASSERT (mbsinit (&state));
373         input[4] = '\0';
374
375         /* Test support of NULL first argument.  */
376         ret = mbrtowc (NULL, input + 5, 3, &state);
377         ASSERT (ret == 2);
378         ASSERT (mbsinit (&state));
379
380         wc = (wchar_t) 0xBADFACE;
381         ret = mbrtowc (&wc, input + 5, 3, &state);
382         ASSERT (ret == 2);
383         ASSERT (wctob (wc) == EOF);
384         ASSERT (wc == 0x8A9E);
385         ASSERT (mbsinit (&state));
386         input[5] = '\0';
387         input[6] = '\0';
388
389         wc = (wchar_t) 0xBADFACE;
390         ret = mbrtowc (&wc, input + 7, 1, &state);
391         ASSERT (ret == 1);
392         ASSERT (wc == '>');
393         ASSERT (mbsinit (&state));
394
395         /* Test some invalid input.  */
396         memset (&state, '\0', sizeof (mbstate_t));
397         wc = (wchar_t) 0xBADFACE;
398         ret = mbrtowc (&wc, "\377", 1, &state); /* 0xFF */
399         ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || ret == (size_t)-2);
400
401         memset (&state, '\0', sizeof (mbstate_t));
402         wc = (wchar_t) 0xBADFACE;
403         ret = mbrtowc (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
404         ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || (ret == 2 && wc == '?'));
405       }
406       return 0;
407
408     case 936:
409       /* Locale encoding is CP936 = GBK, an extension of GB2312.  */
410       {
411         char input[] = "<\310\325\261\276\325\132>"; /* "<日本語>" */
412         memset (&state, '\0', sizeof (mbstate_t));
413
414         wc = (wchar_t) 0xBADFACE;
415         ret = mbrtowc (&wc, input, 1, &state);
416         ASSERT (ret == 1);
417         ASSERT (wc == '<');
418         ASSERT (mbsinit (&state));
419         input[0] = '\0';
420
421         wc = (wchar_t) 0xBADFACE;
422         ret = mbrtowc (&wc, input + 1, 2, &state);
423         ASSERT (ret == 2);
424         ASSERT (wctob (wc) == EOF);
425         ASSERT (wc == 0x65E5);
426         ASSERT (mbsinit (&state));
427         input[1] = '\0';
428         input[2] = '\0';
429
430         wc = (wchar_t) 0xBADFACE;
431         ret = mbrtowc (&wc, input + 3, 1, &state);
432         ASSERT (ret == (size_t)(-2));
433         ASSERT (wc == (wchar_t) 0xBADFACE);
434         ASSERT (!mbsinit (&state));
435         input[3] = '\0';
436
437         wc = (wchar_t) 0xBADFACE;
438         ret = mbrtowc (&wc, input + 4, 4, &state);
439         ASSERT (ret == 1);
440         ASSERT (wctob (wc) == EOF);
441         ASSERT (wc == 0x672C);
442         ASSERT (mbsinit (&state));
443         input[4] = '\0';
444
445         /* Test support of NULL first argument.  */
446         ret = mbrtowc (NULL, input + 5, 3, &state);
447         ASSERT (ret == 2);
448         ASSERT (mbsinit (&state));
449
450         wc = (wchar_t) 0xBADFACE;
451         ret = mbrtowc (&wc, input + 5, 3, &state);
452         ASSERT (ret == 2);
453         ASSERT (wctob (wc) == EOF);
454         ASSERT (wc == 0x8A9E);
455         ASSERT (mbsinit (&state));
456         input[5] = '\0';
457         input[6] = '\0';
458
459         wc = (wchar_t) 0xBADFACE;
460         ret = mbrtowc (&wc, input + 7, 1, &state);
461         ASSERT (ret == 1);
462         ASSERT (wc == '>');
463         ASSERT (mbsinit (&state));
464
465         /* Test some invalid input.  */
466         memset (&state, '\0', sizeof (mbstate_t));
467         wc = (wchar_t) 0xBADFACE;
468         ret = mbrtowc (&wc, "\377", 1, &state); /* 0xFF */
469         ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || ret == (size_t)-2);
470
471         memset (&state, '\0', sizeof (mbstate_t));
472         wc = (wchar_t) 0xBADFACE;
473         ret = mbrtowc (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
474         ASSERT ((ret == (size_t)-1 && errno == EILSEQ) || (ret == 2 && wc == '?'));
475       }
476       return 0;
477
478     case 54936:
479       /* Locale encoding is CP54936 = GB18030.  */
480       if (strcmp (locale_charset (), "GB18030") != 0)
481         return 77;
482       {
483         char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
484         memset (&state, '\0', sizeof (mbstate_t));
485
486         wc = (wchar_t) 0xBADFACE;
487         ret = mbrtowc (&wc, input, 1, &state);
488         ASSERT (ret == 1);
489         ASSERT (wc == 'B');
490         ASSERT (mbsinit (&state));
491         input[0] = '\0';
492
493         wc = (wchar_t) 0xBADFACE;
494         ret = mbrtowc (&wc, input + 1, 1, &state);
495         ASSERT (ret == (size_t)(-2));
496         ASSERT (wc == (wchar_t) 0xBADFACE);
497         ASSERT (!mbsinit (&state));
498         input[1] = '\0';
499
500         wc = (wchar_t) 0xBADFACE;
501         ret = mbrtowc (&wc, input + 2, 7, &state);
502         ASSERT (ret == 1);
503         ASSERT (wctob (wc) == EOF);
504         ASSERT (wc == 0x00FC);
505         ASSERT (mbsinit (&state));
506         input[2] = '\0';
507
508         /* Test support of NULL first argument.  */
509         ret = mbrtowc (NULL, input + 3, 6, &state);
510         ASSERT (ret == 4);
511         ASSERT (mbsinit (&state));
512
513         wc = (wchar_t) 0xBADFACE;
514         ret = mbrtowc (&wc, input + 3, 6, &state);
515         ASSERT (ret == 4);
516         ASSERT (wctob (wc) == EOF);
517         ASSERT (wc == 0x00DF);
518         ASSERT (mbsinit (&state));
519         input[3] = '\0';
520         input[4] = '\0';
521         input[5] = '\0';
522         input[6] = '\0';
523
524         wc = (wchar_t) 0xBADFACE;
525         ret = mbrtowc (&wc, input + 7, 2, &state);
526         ASSERT (ret == 1);
527         ASSERT (wc == 'e');
528         ASSERT (mbsinit (&state));
529         input[7] = '\0';
530
531         wc = (wchar_t) 0xBADFACE;
532         ret = mbrtowc (&wc, input + 8, 1, &state);
533         ASSERT (ret == 1);
534         ASSERT (wc == 'r');
535         ASSERT (mbsinit (&state));
536
537         /* Test some invalid input.  */
538         memset (&state, '\0', sizeof (mbstate_t));
539         wc = (wchar_t) 0xBADFACE;
540         ret = mbrtowc (&wc, "\377", 1, &state); /* 0xFF */
541         ASSERT (ret == (size_t)-1);
542         ASSERT (errno == EILSEQ);
543
544         memset (&state, '\0', sizeof (mbstate_t));
545         wc = (wchar_t) 0xBADFACE;
546         ret = mbrtowc (&wc, "\225\377", 2, &state); /* 0x95 0xFF */
547         ASSERT (ret == (size_t)-1);
548         ASSERT (errno == EILSEQ);
549
550         memset (&state, '\0', sizeof (mbstate_t));
551         wc = (wchar_t) 0xBADFACE;
552         ret = mbrtowc (&wc, "\201\045", 2, &state); /* 0x81 0x25 */
553         ASSERT (ret == (size_t)-1);
554         ASSERT (errno == EILSEQ);
555
556         memset (&state, '\0', sizeof (mbstate_t));
557         wc = (wchar_t) 0xBADFACE;
558         ret = mbrtowc (&wc, "\201\060\377", 3, &state); /* 0x81 0x30 0xFF */
559         ASSERT (ret == (size_t)-1);
560         ASSERT (errno == EILSEQ);
561
562         memset (&state, '\0', sizeof (mbstate_t));
563         wc = (wchar_t) 0xBADFACE;
564         ret = mbrtowc (&wc, "\201\060\377\064", 4, &state); /* 0x81 0x30 0xFF 0x34 */
565         ASSERT (ret == (size_t)-1);
566         ASSERT (errno == EILSEQ);
567
568         memset (&state, '\0', sizeof (mbstate_t));
569         wc = (wchar_t) 0xBADFACE;
570         ret = mbrtowc (&wc, "\201\060\211\072", 4, &state); /* 0x81 0x30 0x89 0x3A */
571         ASSERT (ret == (size_t)-1);
572         ASSERT (errno == EILSEQ);
573       }
574       return 0;
575
576     case 65001:
577       /* Locale encoding is CP65001 = UTF-8.  */
578       if (strcmp (locale_charset (), "UTF-8") != 0)
579         return 77;
580       {
581         char input[] = "B\303\274\303\237er"; /* "Büßer" */
582         memset (&state, '\0', sizeof (mbstate_t));
583
584         wc = (wchar_t) 0xBADFACE;
585         ret = mbrtowc (&wc, input, 1, &state);
586         ASSERT (ret == 1);
587         ASSERT (wc == 'B');
588         ASSERT (mbsinit (&state));
589         input[0] = '\0';
590
591         wc = (wchar_t) 0xBADFACE;
592         ret = mbrtowc (&wc, input + 1, 1, &state);
593         ASSERT (ret == (size_t)(-2));
594         ASSERT (wc == (wchar_t) 0xBADFACE);
595         ASSERT (!mbsinit (&state));
596         input[1] = '\0';
597
598         wc = (wchar_t) 0xBADFACE;
599         ret = mbrtowc (&wc, input + 2, 5, &state);
600         ASSERT (ret == 1);
601         ASSERT (wctob (wc) == EOF);
602         ASSERT (wc == 0x00FC);
603         ASSERT (mbsinit (&state));
604         input[2] = '\0';
605
606         /* Test support of NULL first argument.  */
607         ret = mbrtowc (NULL, input + 3, 4, &state);
608         ASSERT (ret == 2);
609         ASSERT (mbsinit (&state));
610
611         wc = (wchar_t) 0xBADFACE;
612         ret = mbrtowc (&wc, input + 3, 4, &state);
613         ASSERT (ret == 2);
614         ASSERT (wctob (wc) == EOF);
615         ASSERT (wc == 0x00DF);
616         ASSERT (mbsinit (&state));
617         input[3] = '\0';
618         input[4] = '\0';
619
620         wc = (wchar_t) 0xBADFACE;
621         ret = mbrtowc (&wc, input + 5, 2, &state);
622         ASSERT (ret == 1);
623         ASSERT (wc == 'e');
624         ASSERT (mbsinit (&state));
625         input[5] = '\0';
626
627         wc = (wchar_t) 0xBADFACE;
628         ret = mbrtowc (&wc, input + 6, 1, &state);
629         ASSERT (ret == 1);
630         ASSERT (wc == 'r');
631         ASSERT (mbsinit (&state));
632
633         /* Test some invalid input.  */
634         memset (&state, '\0', sizeof (mbstate_t));
635         wc = (wchar_t) 0xBADFACE;
636         ret = mbrtowc (&wc, "\377", 1, &state); /* 0xFF */
637         ASSERT (ret == (size_t)-1);
638         ASSERT (errno == EILSEQ);
639
640         memset (&state, '\0', sizeof (mbstate_t));
641         wc = (wchar_t) 0xBADFACE;
642         ret = mbrtowc (&wc, "\303\300", 2, &state); /* 0xC3 0xC0 */
643         ASSERT (ret == (size_t)-1);
644         ASSERT (errno == EILSEQ);
645
646         memset (&state, '\0', sizeof (mbstate_t));
647         wc = (wchar_t) 0xBADFACE;
648         ret = mbrtowc (&wc, "\343\300", 2, &state); /* 0xE3 0xC0 */
649         ASSERT (ret == (size_t)-1);
650         ASSERT (errno == EILSEQ);
651
652         memset (&state, '\0', sizeof (mbstate_t));
653         wc = (wchar_t) 0xBADFACE;
654         ret = mbrtowc (&wc, "\343\300\200", 3, &state); /* 0xE3 0xC0 0x80 */
655         ASSERT (ret == (size_t)-1);
656         ASSERT (errno == EILSEQ);
657
658         memset (&state, '\0', sizeof (mbstate_t));
659         wc = (wchar_t) 0xBADFACE;
660         ret = mbrtowc (&wc, "\343\200\300", 3, &state); /* 0xE3 0x80 0xC0 */
661         ASSERT (ret == (size_t)-1);
662         ASSERT (errno == EILSEQ);
663
664         memset (&state, '\0', sizeof (mbstate_t));
665         wc = (wchar_t) 0xBADFACE;
666         ret = mbrtowc (&wc, "\363\300", 2, &state); /* 0xF3 0xC0 */
667         ASSERT (ret == (size_t)-1);
668         ASSERT (errno == EILSEQ);
669
670         memset (&state, '\0', sizeof (mbstate_t));
671         wc = (wchar_t) 0xBADFACE;
672         ret = mbrtowc (&wc, "\363\300\200\200", 4, &state); /* 0xF3 0xC0 0x80 0x80 */
673         ASSERT (ret == (size_t)-1);
674         ASSERT (errno == EILSEQ);
675
676         memset (&state, '\0', sizeof (mbstate_t));
677         wc = (wchar_t) 0xBADFACE;
678         ret = mbrtowc (&wc, "\363\200\300", 3, &state); /* 0xF3 0x80 0xC0 */
679         ASSERT (ret == (size_t)-1);
680         ASSERT (errno == EILSEQ);
681
682         memset (&state, '\0', sizeof (mbstate_t));
683         wc = (wchar_t) 0xBADFACE;
684         ret = mbrtowc (&wc, "\363\200\300\200", 4, &state); /* 0xF3 0x80 0xC0 0x80 */
685         ASSERT (ret == (size_t)-1);
686         ASSERT (errno == EILSEQ);
687
688         memset (&state, '\0', sizeof (mbstate_t));
689         wc = (wchar_t) 0xBADFACE;
690         ret = mbrtowc (&wc, "\363\200\200\300", 4, &state); /* 0xF3 0x80 0x80 0xC0 */
691         ASSERT (ret == (size_t)-1);
692         ASSERT (errno == EILSEQ);
693       }
694       return 0;
695
696     default:
697       return 1;
698     }
699 }
700
701 int
702 main (int argc, char *argv[])
703 {
704   int codepage = atoi (argv[argc - 1]);
705   int result;
706   int i;
707
708   result = 77;
709   for (i = 1; i < argc - 1; i++)
710     {
711       int ret = test_one_locale (argv[i], codepage);
712
713       if (ret != 77)
714         result = ret;
715     }
716
717   if (result == 77)
718     {
719       fprintf (stderr, "Skipping test: found no locale with codepage %d\n",
720                codepage);
721     }
722   return result;
723 }
724
725 #else
726
727 int
728 main (int argc, char *argv[])
729 {
730   fputs ("Skipping test: not a native Windows system\n", stderr);
731   return 77;
732 }
733
734 #endif