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