1/* Test of conversion of wide string to string.
2   Copyright (C) 2008-2011 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#undef NDEBUG
20#include <assert.h>
21#include <locale.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <wchar.h>
26
27
28#define BUFSIZE 20
29
30
31int
32main (int argc, char *argv[])
33{
34  int mode;
35
36  for (mode = '0'; mode <= '4'; ++mode)
37    {
38      wchar_t input[10];
39      size_t n;
40      const wchar_t *src;
41      char buf[BUFSIZE];
42      size_t ret;
43
44      {
45        size_t i;
46        for (i = 0; i < BUFSIZE; i++)
47          buf[i] = '_';
48      }
49
50      switch (mode)
51        {
52        case '0':
53          /* Locale encoding is POSIX  */
54          printf("POSIX ...\n");
55          {
56            const char original[] = "Buesser";
57
58            ret = mbstowcs (input, original, 10);
59            assert(ret == 7);
60
61            for (n = 0; n < 10; n++)
62              {
63                src = input;
64                ret = wcsrtombs (NULL, &src, n, NULL);
65                assert(ret == 7);
66                assert(src == input);
67
68                src = input;
69                ret = wcsrtombs (buf, &src, n, NULL);
70                assert(ret == (n <= 7 ? n : 7));
71                assert(src == (n <= 7 ? input + n : NULL));
72                assert(memcmp (buf, original, ret) == 0);
73                if (src == NULL)
74                  assert(buf[ret] == '\0');
75                assert(buf[ret + (src == NULL) + 0] == '_');
76                assert(buf[ret + (src == NULL) + 1] == '_');
77                assert(buf[ret + (src == NULL) + 2] == '_');
78              }
79
80            input[2] = 0xDEADBEEFul;
81			src = input;
82			ret = wcsrtombs(buf, &src, BUFSIZE, NULL);
83			assert(ret == (size_t)-1);
84			assert(src == input + 2);
85          }
86          break;
87
88        case '1':
89          /* Locale encoding is ISO-8859-1 or ISO-8859-15.  */
90          printf("ISO8859-1 ...\n");
91          {
92            const char original[] = "B\374\337er"; /* "B����er" */
93
94       	    if (setlocale (LC_ALL, "en_US.ISO8859-1") == NULL)
95       	      {
96       		    fprintf(stderr, "unable to set ISO8859-1 locale, skipping\n");
97       		    break;
98       	      }
99
100            ret = mbstowcs (input, original, 10);
101            assert(ret == 5);
102
103            for (n = 0; n < 10; n++)
104              {
105                src = input;
106                ret = wcsrtombs (NULL, &src, n, NULL);
107                assert(ret == 5);
108                assert(src == input);
109
110                src = input;
111                ret = wcsrtombs (buf, &src, n, NULL);
112                assert(ret == (n <= 5 ? n : 5));
113                assert(src == (n <= 5 ? input + n : NULL));
114                assert(memcmp (buf, original, ret) == 0);
115                if (src == NULL)
116                  assert(buf[ret] == '\0');
117                assert(buf[ret + (src == NULL) + 0] == '_');
118                assert(buf[ret + (src == NULL) + 1] == '_');
119                assert(buf[ret + (src == NULL) + 2] == '_');
120              }
121          }
122          break;
123
124        case '2':
125          /* Locale encoding is UTF-8.  */
126          printf("UTF-8 ... \n");
127          {
128            const char original[] = "B\303\274\303\237er"; /* "B����er" */
129
130       	    if (setlocale (LC_ALL, "en_US.UTF-8") == NULL)
131       	      {
132       		    fprintf(stderr, "unable to set UTF-8 locale, skipping\n");
133       		    break;
134       	      }
135
136            ret = mbstowcs (input, original, 10);
137            assert(ret == 5);
138
139            for (n = 0; n < 10; n++)
140              {
141                src = input;
142                ret = wcsrtombs (NULL, &src, n, NULL);
143                assert(ret == 7);
144                assert(src == input);
145
146                src = input;
147                ret = wcsrtombs (buf, &src, n, NULL);
148                assert(ret == (n < 1 ? n :
149                                n < 3 ? 1 :
150                                n < 5 ? 3 :
151                                n <= 7 ? n : 7));
152                assert(src == (n < 1 ? input + n :
153                                n < 3 ? input + 1 :
154                                n < 5 ? input + 2 :
155                                n <= 7 ? input + (n - 2) : NULL));
156                assert(memcmp (buf, original, ret) == 0);
157                if (src == NULL)
158                  assert(buf[ret] == '\0');
159                assert(buf[ret + (src == NULL) + 0] == '_');
160                assert(buf[ret + (src == NULL) + 1] == '_');
161                assert(buf[ret + (src == NULL) + 2] == '_');
162              }
163
164            input[2] = 0xDEADBEEFul;
165			src = input;
166			ret = wcsrtombs(buf, &src, BUFSIZE, NULL);
167			assert(ret == (size_t)-1);
168			assert(src == input + 2);
169          }
170          break;
171
172        case '3':
173          /* Locale encoding is EUC-JP.  */
174          printf("EUC-JP ... \n");
175          {
176            const char original[] = "<\306\374\313\334\270\354>"; /* "<���������>" */
177
178       	    if (setlocale (LC_ALL, "en_US.EUC-JP") == NULL)
179       	      {
180       		    fprintf(stderr, "unable to set EUC-JP locale, skipping\n");
181       		    break;
182       	      }
183
184            ret = mbstowcs (input, original, 10);
185            assert(ret == 5);
186
187            for (n = 0; n < 10; n++)
188              {
189                src = input;
190                ret = wcsrtombs (NULL, &src, n, NULL);
191                assert(ret == 8);
192                assert(src == input);
193
194                src = input;
195                ret = wcsrtombs (buf, &src, n, NULL);
196                assert(ret == (n < 1 ? n :
197                                n < 3 ? 1 :
198                                n < 5 ? 3 :
199                                n < 7 ? 5 :
200                                n <= 8 ? n : 8));
201                assert(src == (n < 1 ? input + n :
202                                n < 3 ? input + 1 :
203                                n < 5 ? input + 2 :
204                                n < 7 ? input + 3 :
205                                n <= 8 ? input + (n - 3) : NULL));
206                assert(memcmp (buf, original, ret) == 0);
207                if (src == NULL)
208                  assert(buf[ret] == '\0');
209                assert(buf[ret + (src == NULL) + 0] == '_');
210                assert(buf[ret + (src == NULL) + 1] == '_');
211                assert(buf[ret + (src == NULL) + 2] == '_');
212              }
213          }
214          break;
215
216
217        case '4':
218          printf("GB18030 ... \n");
219          /* Locale encoding is GB18030.  */
220          {
221            const char original[] = "B\250\271\201\060\211\070er"; /* "B����er" */
222
223       	    if (setlocale (LC_ALL, "en_US.GB18030") == NULL)
224       	      {
225       		    fprintf(stderr, "unable to set GB18030 locale, skipping\n");
226       		    break;
227       	      }
228
229            ret = mbstowcs (input, original, 10);
230            assert(ret == 5);
231
232            for (n = 0; n < 10; n++)
233              {
234                src = input;
235                ret = wcsrtombs (NULL, &src, n, NULL);
236                assert(ret == 9);
237                assert(src == input);
238
239                src = input;
240                ret = wcsrtombs (buf, &src, n, NULL);
241                assert(ret == (n < 1 ? n :
242                                n < 3 ? 1 :
243                                n < 7 ? 3 :
244                                n <= 9 ? n : 9));
245                assert(src == (n < 1 ? input + n :
246                                n < 3 ? input + 1 :
247                                n < 7 ? input + 2 :
248                                n <= 9 ? input + (n - 4) : NULL));
249                assert(memcmp (buf, original, ret) == 0);
250                if (src == NULL)
251                  assert(buf[ret] == '\0');
252                assert(buf[ret + (src == NULL) + 0] == '_');
253                assert(buf[ret + (src == NULL) + 1] == '_');
254                assert(buf[ret + (src == NULL) + 2] == '_');
255              }
256          }
257          break;
258
259        default:
260          return 1;
261        }
262    }
263
264  return 0;
265}
266