1 /* Test of conversion of string to wide 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 <string.h> 24 #include <wchar.h> 25 26 27 #define BUFSIZE 10 28 29 30 int 31 main(int argc, char *argv[]) 32 { 33 mbstate_t state; 34 wchar_t wc; 35 size_t ret; 36 int mode; 37 38 /* configure should already have checked that the locale is supported. */ 39 if (setlocale(LC_ALL, "") == NULL) { 40 fprintf(stderr, "unable to set standard locale\n"); 41 return 1; 42 } 43 44 /* Test NUL byte input. */ 45 { 46 const char *src; 47 48 memset(&state, '\0', sizeof(mbstate_t)); 49 50 src = ""; 51 ret = mbsnrtowcs(NULL, &src, 1, 0, &state); 52 assert(ret == 0); 53 assert(mbsinit (&state)); 54 55 src = ""; 56 ret = mbsnrtowcs(NULL, &src, 1, 1, &state); 57 assert(ret == 0); 58 assert(mbsinit (&state)); 59 60 wc = (wchar_t) 0xBADFACE; 61 src = ""; 62 ret = mbsnrtowcs(&wc, &src, 1, 0, &state); 63 assert(ret == 0); 64 assert(wc == (wchar_t) 0xBADFACE); 65 assert(mbsinit (&state)); 66 67 wc = (wchar_t) 0xBADFACE; 68 src = ""; 69 ret = mbsnrtowcs(&wc, &src, 1, 1, &state); 70 assert(ret == 0); 71 assert(wc == 0); 72 assert(mbsinit (&state)); 73 } 74 75 for (mode = '1'; mode <= '4'; ++mode) { 76 int unlimited; 77 for (unlimited = 0; unlimited < 2; unlimited++) { 78 wchar_t buf[BUFSIZE]; 79 const char *src; 80 mbstate_t temp_state; 81 82 { 83 size_t i; 84 for (i = 0; i < BUFSIZE; i++) 85 buf[i] = (wchar_t) 0xBADFACE; 86 } 87 88 switch (mode) { 89 case '1': 90 /* Locale encoding is ISO-8859-1 or ISO-8859-15. */ 91 printf("ISO8859-1 ...\n"); 92 { 93 char input[] = "B\374\337er"; /* "Büßer" */ 94 memset(&state, '\0', sizeof(mbstate_t)); 95 96 if (setlocale (LC_ALL, "en_US.ISO8859-1") == NULL) { 97 fprintf(stderr, 98 "unable to set ISO8859-1 locale, skipping\n"); 99 break; 100 } 101 102 wc = (wchar_t) 0xBADFACE; 103 ret = mbrtowc(&wc, input, 1, &state); 104 assert(ret == 1); 105 assert(wc == 'B'); 106 assert(mbsinit (&state)); 107 input[0] = '\0'; 108 109 wc = (wchar_t) 0xBADFACE; 110 ret = mbrtowc(&wc, input + 1, 1, &state); 111 assert(ret == 1); 112 assert(wctob (wc) == (unsigned char) '\374'); 113 assert(mbsinit (&state)); 114 input[1] = '\0'; 115 116 src = input + 2; 117 temp_state = state; 118 ret = mbsnrtowcs(NULL, &src, 4, unlimited ? BUFSIZE : 1, 119 &temp_state); 120 assert(ret == 3); 121 assert(src == input + 2); 122 assert(mbsinit (&state)); 123 124 src = input + 2; 125 ret = mbsnrtowcs(buf, &src, 4, unlimited ? BUFSIZE : 1, 126 &state); 127 assert(ret == (unlimited ? 3 : 1)); 128 assert(src == (unlimited ? NULL : input + 3)); 129 assert(wctob (buf[0]) == (unsigned char) '\337'); 130 if (unlimited) { 131 assert(buf[1] == 'e'); 132 assert(buf[2] == 'r'); 133 assert(buf[3] == 0); 134 assert(buf[4] == (wchar_t) 0xBADFACE); 135 } else 136 assert(buf[1] == (wchar_t) 0xBADFACE); 137 assert(mbsinit (&state)); 138 } 139 break; 140 141 case '2': 142 /* Locale encoding is UTF-8. */ 143 printf("UTF-8 ...\n"); 144 { 145 char input[] = "B\303\274\303\237er"; /* "Büßer" */ 146 memset(&state, '\0', sizeof(mbstate_t)); 147 148 if (setlocale (LC_ALL, "en_US.UTF-8") == NULL) { 149 fprintf(stderr, 150 "unable to set UTF-8 locale, skipping\n"); 151 break; 152 } 153 154 wc = (wchar_t) 0xBADFACE; 155 ret = mbrtowc(&wc, input, 1, &state); 156 assert(ret == 1); 157 assert(wc == 'B'); 158 assert(mbsinit (&state)); 159 input[0] = '\0'; 160 161 wc = (wchar_t) 0xBADFACE; 162 ret = mbrtowc(&wc, input + 1, 1, &state); 163 assert(ret == (size_t)(-2)); 164 assert(wc == (wchar_t) 0xBADFACE); 165 assert(!mbsinit (&state)); 166 input[1] = '\0'; 167 168 // Copying mbstate_t doesn't really copy the ICU-converter's state, so this 169 // doesn't work on Haiku. 170 #ifndef __HAIKU__ 171 src = input + 2; 172 temp_state = state; 173 ret = mbsnrtowcs(NULL, &src, 6, unlimited ? BUFSIZE : 2, 174 &temp_state); 175 assert(ret == 4); 176 assert(src == input + 2); 177 assert(!mbsinit (&state)); 178 #endif 179 180 src = input + 2; 181 ret = mbsnrtowcs(buf, &src, 6, unlimited ? BUFSIZE : 2, 182 &state); 183 assert(ret == (unlimited ? 4 : 2)); 184 assert(src == (unlimited ? NULL : input + 5)); 185 assert(wctob (buf[0]) == EOF); 186 assert(wctob (buf[1]) == EOF); 187 if (unlimited) { 188 assert(buf[2] == 'e'); 189 assert(buf[3] == 'r'); 190 assert(buf[4] == 0); 191 assert(buf[5] == (wchar_t) 0xBADFACE); 192 } else 193 assert(buf[2] == (wchar_t) 0xBADFACE); 194 assert(mbsinit (&state)); 195 } 196 break; 197 198 case '3': 199 /* Locale encoding is EUC-JP. */ 200 printf("EUC-JP ...\n"); 201 { 202 char input[] = "<\306\374\313\334\270\354>"; /* "<日本語>" */ 203 memset(&state, '\0', sizeof(mbstate_t)); 204 205 if (setlocale (LC_ALL, "en_US.EUC-JP") == NULL) { 206 fprintf(stderr, 207 "unable to set EUC-JP locale, skipping\n"); 208 break; 209 } 210 211 wc = (wchar_t) 0xBADFACE; 212 ret = mbrtowc(&wc, input, 1, &state); 213 assert(ret == 1); 214 assert(wc == '<'); 215 assert(mbsinit (&state)); 216 input[0] = '\0'; 217 218 wc = (wchar_t) 0xBADFACE; 219 ret = mbrtowc(&wc, input + 1, 2, &state); 220 assert(ret == 2); 221 assert(wctob (wc) == EOF); 222 assert(mbsinit (&state)); 223 input[1] = '\0'; 224 input[2] = '\0'; 225 226 wc = (wchar_t) 0xBADFACE; 227 ret = mbrtowc(&wc, input + 3, 1, &state); 228 assert(ret == (size_t)(-2)); 229 assert(wc == (wchar_t) 0xBADFACE); 230 assert(!mbsinit (&state)); 231 input[3] = '\0'; 232 233 // Copying mbstate_t doesn't really copy the ICU-converter's state, so this 234 // doesn't work on Haiku. 235 #ifndef __HAIKU__ 236 src = input + 4; 237 temp_state = state; 238 ret = mbsnrtowcs(NULL, &src, 5, unlimited ? BUFSIZE : 2, 239 &temp_state); 240 assert(ret == 3); 241 assert(src == input + 4); 242 assert(!mbsinit (&state)); 243 #endif 244 245 src = input + 4; 246 ret = mbsnrtowcs(buf, &src, 5, unlimited ? BUFSIZE : 2, 247 &state); 248 assert(ret == (unlimited ? 3 : 2)); 249 assert(src == (unlimited ? NULL : input + 7)); 250 assert(wctob (buf[0]) == EOF); 251 assert(wctob (buf[1]) == EOF); 252 if (unlimited) { 253 assert(buf[2] == '>'); 254 assert(buf[3] == 0); 255 assert(buf[4] == (wchar_t) 0xBADFACE); 256 } else 257 assert(buf[2] == (wchar_t) 0xBADFACE); 258 assert(mbsinit (&state)); 259 } 260 break; 261 262 case '4': 263 /* Locale encoding is GB18030. */ 264 printf("GB18030 ...\n"); 265 { 266 char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */ 267 memset(&state, '\0', sizeof(mbstate_t)); 268 269 if (setlocale (LC_ALL, "en_US.GB18030") == NULL) { 270 fprintf(stderr, 271 "unable to set GB18030 locale, skipping\n"); 272 break; 273 } 274 275 wc = (wchar_t) 0xBADFACE; 276 ret = mbrtowc(&wc, input, 1, &state); 277 assert(ret == 1); 278 assert(wc == 'B'); 279 assert(mbsinit (&state)); 280 input[0] = '\0'; 281 282 wc = (wchar_t) 0xBADFACE; 283 ret = mbrtowc(&wc, input + 1, 1, &state); 284 assert(ret == (size_t)(-2)); 285 assert(wc == (wchar_t) 0xBADFACE); 286 assert(!mbsinit (&state)); 287 input[1] = '\0'; 288 289 // Copying mbstate_t doesn't really copy the ICU-converter's state, so this 290 // doesn't work on Haiku. 291 #ifndef __HAIKU__ 292 src = input + 2; 293 temp_state = state; 294 ret = mbsnrtowcs(NULL, &src, 8, unlimited ? BUFSIZE : 2, 295 &temp_state); 296 assert(ret == 4); 297 assert(src == input + 2); 298 assert(!mbsinit (&state)); 299 #endif 300 301 src = input + 2; 302 ret = mbsnrtowcs(buf, &src, 8, unlimited ? BUFSIZE : 2, 303 &state); 304 assert(ret == (unlimited ? 4 : 2)); 305 assert(src == (unlimited ? NULL : input + 7)); 306 assert(wctob (buf[0]) == EOF); 307 assert(wctob (buf[1]) == EOF); 308 if (unlimited) { 309 assert(buf[2] == 'e'); 310 assert(buf[3] == 'r'); 311 assert(buf[4] == 0); 312 assert(buf[5] == (wchar_t) 0xBADFACE); 313 } else 314 assert(buf[2] == (wchar_t) 0xBADFACE); 315 assert(mbsinit (&state)); 316 } 317 break; 318 319 default: 320 return 1; 321 } 322 } 323 } 324 325 return 0; 326 } 327