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 31 int 32 main (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