xref: /haiku/src/tests/system/libroot/posix/gnulib-test-wcsnrtombs.c (revision 220d04022750f40f8bac8f01fa551211e28d04f2)
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 
30 int
31 main (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