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