Tests for module 'wcsrtombs'.
[gnulib.git] / tests / test-wcsrtombs.c
1 /* Test of conversion of wide string to 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   /* configure should already have checked that the locale is supported.  */
44   if (setlocale (LC_ALL, "") == NULL)
45     return 1;
46
47   if (argc > 1)
48     {
49       wchar_t input[10];
50       size_t n;
51       const wchar_t *src;
52       #define BUFSIZE 20
53       char buf[BUFSIZE];
54       size_t ret;
55
56       {
57         size_t i;
58         for (i = 0; i < BUFSIZE; i++)
59           buf[i] = '_';
60       }
61
62       switch (argv[1][0])
63         {
64         case '1':
65           /* Locale encoding is ISO-8859-1 or ISO-8859-15.  */
66           {
67             const char original[] = "B\374\337er"; /* "Büßer" */
68
69             ret = mbstowcs (input, original, 10);
70             ASSERT (ret == 5);
71
72             for (n = 0; n < 10; n++)
73               {
74                 src = input;
75                 ret = wcsrtombs (NULL, &src, n, NULL);
76                 ASSERT (ret == 5);
77                 ASSERT (src == input);
78
79                 src = input;
80                 ret = wcsrtombs (buf, &src, n, NULL);
81                 ASSERT (ret == (n <= 5 ? n : 5));
82                 ASSERT (src == (n <= 5 ? input + n : NULL));
83                 ASSERT (memcmp (buf, original, ret) == 0);
84                 if (src == NULL)
85                   ASSERT (buf[ret] == '\0');
86                 ASSERT (buf[ret + (src == NULL) + 0] == '_');
87                 ASSERT (buf[ret + (src == NULL) + 1] == '_');
88                 ASSERT (buf[ret + (src == NULL) + 2] == '_');
89               }
90           }
91           break;
92
93         case '2':
94           /* Locale encoding is UTF-8.  */
95           {
96             const char original[] = "B\303\274\303\237er"; /* "Büßer" */
97
98             ret = mbstowcs (input, original, 10);
99             ASSERT (ret == 5);
100
101             for (n = 0; n < 10; n++)
102               {
103                 src = input;
104                 ret = wcsrtombs (NULL, &src, n, NULL);
105                 ASSERT (ret == 7);
106                 ASSERT (src == input);
107
108                 src = input;
109                 ret = wcsrtombs (buf, &src, n, NULL);
110                 ASSERT (ret == (n < 1 ? n :
111                                 n < 3 ? 1 :
112                                 n < 5 ? 3 :
113                                 n <= 7 ? n : 7));
114                 ASSERT (src == (n < 1 ? input + n :
115                                 n < 3 ? input + 1 :
116                                 n < 5 ? input + 2 :
117                                 n <= 7 ? input + (n - 2) : NULL));
118                 ASSERT (memcmp (buf, original, ret) == 0);
119                 if (src == NULL)
120                   ASSERT (buf[ret] == '\0');
121                 ASSERT (buf[ret + (src == NULL) + 0] == '_');
122                 ASSERT (buf[ret + (src == NULL) + 1] == '_');
123                 ASSERT (buf[ret + (src == NULL) + 2] == '_');
124               }
125           }
126           break;
127
128         case '3':
129           /* Locale encoding is EUC-JP.  */
130           {
131             const char original[] = "<\306\374\313\334\270\354>"; /* "<日本語>" */
132
133             ret = mbstowcs (input, original, 10);
134             ASSERT (ret == 5);
135
136             for (n = 0; n < 10; n++)
137               {
138                 src = input;
139                 ret = wcsrtombs (NULL, &src, n, NULL);
140                 ASSERT (ret == 8);
141                 ASSERT (src == input);
142
143                 src = input;
144                 ret = wcsrtombs (buf, &src, n, NULL);
145                 ASSERT (ret == (n < 1 ? n :
146                                 n < 3 ? 1 :
147                                 n < 5 ? 3 :
148                                 n < 7 ? 5 :
149                                 n <= 8 ? n : 8));
150                 ASSERT (src == (n < 1 ? input + n :
151                                 n < 3 ? input + 1 :
152                                 n < 5 ? input + 2 :
153                                 n < 7 ? input + 3 :
154                                 n <= 8 ? input + (n - 3) : NULL));
155                 ASSERT (memcmp (buf, original, ret) == 0);
156                 if (src == NULL)
157                   ASSERT (buf[ret] == '\0');
158                 ASSERT (buf[ret + (src == NULL) + 0] == '_');
159                 ASSERT (buf[ret + (src == NULL) + 1] == '_');
160                 ASSERT (buf[ret + (src == NULL) + 2] == '_');
161               }
162           }
163           break;
164
165
166         case '4':
167           /* Locale encoding is GB18030.  */
168           {
169             const char original[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
170
171             ret = mbstowcs (input, original, 10);
172             ASSERT (ret == 5);
173
174             for (n = 0; n < 10; n++)
175               {
176                 src = input;
177                 ret = wcsrtombs (NULL, &src, n, NULL);
178                 ASSERT (ret == 9);
179                 ASSERT (src == input);
180
181                 src = input;
182                 ret = wcsrtombs (buf, &src, n, NULL);
183                 ASSERT (ret == (n < 1 ? n :
184                                 n < 3 ? 1 :
185                                 n < 7 ? 3 :
186                                 n <= 9 ? n : 9));
187                 ASSERT (src == (n < 1 ? input + n :
188                                 n < 3 ? input + 1 :
189                                 n < 7 ? input + 2 :
190                                 n <= 9 ? input + (n - 4) : NULL));
191                 ASSERT (memcmp (buf, original, ret) == 0);
192                 if (src == NULL)
193                   ASSERT (buf[ret] == '\0');
194                 ASSERT (buf[ret + (src == NULL) + 0] == '_');
195                 ASSERT (buf[ret + (src == NULL) + 1] == '_');
196                 ASSERT (buf[ret + (src == NULL) + 2] == '_');
197               }
198           }
199           break;
200
201         default:
202           return 1;
203         }
204
205       return 0;
206     }
207
208   return 1;
209 }