1*acbd8998SOliver Tappe /* Test of conversion of wide character to multibyte character. 2*acbd8998SOliver Tappe Copyright (C) 2008-2011 Free Software Foundation, Inc. 3*acbd8998SOliver Tappe 4*acbd8998SOliver Tappe This program is free software: you can redistribute it and/or modify 5*acbd8998SOliver Tappe it under the terms of the GNU General Public License as published by 6*acbd8998SOliver Tappe the Free Software Foundation; either version 3 of the License, or 7*acbd8998SOliver Tappe (at your option) any later version. 8*acbd8998SOliver Tappe 9*acbd8998SOliver Tappe This program is distributed in the hope that it will be useful, 10*acbd8998SOliver Tappe but WITHOUT ANY WARRANTY; without even the implied warranty of 11*acbd8998SOliver Tappe MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12*acbd8998SOliver Tappe GNU General Public License for more details. 13*acbd8998SOliver Tappe 14*acbd8998SOliver Tappe You should have received a copy of the GNU General Public License 15*acbd8998SOliver Tappe along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16*acbd8998SOliver Tappe 17*acbd8998SOliver Tappe /* Written by Bruno Haible <bruno@clisp.org>, 2008. */ 18*acbd8998SOliver Tappe 19*acbd8998SOliver Tappe #include <assert.h> 20*acbd8998SOliver Tappe #include <locale.h> 21*acbd8998SOliver Tappe #include <stdlib.h> 22*acbd8998SOliver Tappe #include <string.h> 23*acbd8998SOliver Tappe #include <wchar.h> 24*acbd8998SOliver Tappe 25*acbd8998SOliver Tappe /* Check the multibyte character s[0..n-1]. */ 26*acbd8998SOliver Tappe static void 27*acbd8998SOliver Tappe check_character (const char *s, size_t n) 28*acbd8998SOliver Tappe { 29*acbd8998SOliver Tappe wchar_t wc; 30*acbd8998SOliver Tappe char buf[64]; 31*acbd8998SOliver Tappe int iret; 32*acbd8998SOliver Tappe size_t ret; 33*acbd8998SOliver Tappe 34*acbd8998SOliver Tappe wc = (wchar_t) 0xBADFACE; 35*acbd8998SOliver Tappe iret = mbtowc (&wc, s, n); 36*acbd8998SOliver Tappe assert (iret == (int)n); 37*acbd8998SOliver Tappe 38*acbd8998SOliver Tappe ret = wcrtomb (buf, wc, NULL); 39*acbd8998SOliver Tappe assert (ret == n); 40*acbd8998SOliver Tappe assert (memcmp (buf, s, n) == 0); 41*acbd8998SOliver Tappe 42*acbd8998SOliver Tappe /* Test special calling convention, passing a NULL pointer. */ 43*acbd8998SOliver Tappe ret = wcrtomb (NULL, wc, NULL); 44*acbd8998SOliver Tappe 45*acbd8998SOliver Tappe assert (ret == 1); 46*acbd8998SOliver Tappe } 47*acbd8998SOliver Tappe 48*acbd8998SOliver Tappe int 49*acbd8998SOliver Tappe main (int argc, char *argv[]) 50*acbd8998SOliver Tappe { 51*acbd8998SOliver Tappe char buf[64]; 52*acbd8998SOliver Tappe size_t ret; 53*acbd8998SOliver Tappe int i; 54*acbd8998SOliver Tappe 55*acbd8998SOliver Tappe /* configure should already have checked that the locale is supported. */ 56*acbd8998SOliver Tappe if (setlocale (LC_ALL, "") == NULL) { 57*acbd8998SOliver Tappe fprintf(stderr, "unable to set standard locale\n"); 58*acbd8998SOliver Tappe return 1; 59*acbd8998SOliver Tappe } 60*acbd8998SOliver Tappe 61*acbd8998SOliver Tappe /* Test NUL character. */ 62*acbd8998SOliver Tappe printf("NUL character ...\n"); 63*acbd8998SOliver Tappe { 64*acbd8998SOliver Tappe buf[0] = 'x'; 65*acbd8998SOliver Tappe ret = wcrtomb (buf, 0, NULL); 66*acbd8998SOliver Tappe assert (ret == 1); 67*acbd8998SOliver Tappe assert (buf[0] == '\0'); 68*acbd8998SOliver Tappe } 69*acbd8998SOliver Tappe 70*acbd8998SOliver Tappe /* Test single bytes. */ 71*acbd8998SOliver Tappe printf("single bytes ...\n"); 72*acbd8998SOliver Tappe { 73*acbd8998SOliver Tappe int c; 74*acbd8998SOliver Tappe 75*acbd8998SOliver Tappe for (c = 0; c < 0x100; c++) 76*acbd8998SOliver Tappe switch (c) 77*acbd8998SOliver Tappe { 78*acbd8998SOliver Tappe case '\t': case '\v': case '\f': 79*acbd8998SOliver Tappe case ' ': case '!': case '"': case '#': case '%': 80*acbd8998SOliver Tappe case '&': case '\'': case '(': case ')': case '*': 81*acbd8998SOliver Tappe case '+': case ',': case '-': case '.': case '/': 82*acbd8998SOliver Tappe case '0': case '1': case '2': case '3': case '4': 83*acbd8998SOliver Tappe case '5': case '6': case '7': case '8': case '9': 84*acbd8998SOliver Tappe case ':': case ';': case '<': case '=': case '>': 85*acbd8998SOliver Tappe case '?': 86*acbd8998SOliver Tappe case 'A': case 'B': case 'C': case 'D': case 'E': 87*acbd8998SOliver Tappe case 'F': case 'G': case 'H': case 'I': case 'J': 88*acbd8998SOliver Tappe case 'K': case 'L': case 'M': case 'N': case 'O': 89*acbd8998SOliver Tappe case 'P': case 'Q': case 'R': case 'S': case 'T': 90*acbd8998SOliver Tappe case 'U': case 'V': case 'W': case 'X': case 'Y': 91*acbd8998SOliver Tappe case 'Z': 92*acbd8998SOliver Tappe case '[': case '\\': case ']': case '^': case '_': 93*acbd8998SOliver Tappe case 'a': case 'b': case 'c': case 'd': case 'e': 94*acbd8998SOliver Tappe case 'f': case 'g': case 'h': case 'i': case 'j': 95*acbd8998SOliver Tappe case 'k': case 'l': case 'm': case 'n': case 'o': 96*acbd8998SOliver Tappe case 'p': case 'q': case 'r': case 's': case 't': 97*acbd8998SOliver Tappe case 'u': case 'v': case 'w': case 'x': case 'y': 98*acbd8998SOliver Tappe case 'z': case '{': case '|': case '}': case '~': 99*acbd8998SOliver Tappe /* c is in the ISO C "basic character set". */ 100*acbd8998SOliver Tappe ret = wcrtomb (buf, btowc (c), NULL); 101*acbd8998SOliver Tappe assert (ret == 1); 102*acbd8998SOliver Tappe assert (buf[0] == (char) c); 103*acbd8998SOliver Tappe break; 104*acbd8998SOliver Tappe } 105*acbd8998SOliver Tappe } 106*acbd8998SOliver Tappe 107*acbd8998SOliver Tappe /* Test special calling convention, passing a NULL pointer. */ 108*acbd8998SOliver Tappe printf("special calling convention with NULL pointer ...\n"); 109*acbd8998SOliver Tappe { 110*acbd8998SOliver Tappe ret = wcrtomb (NULL, '\0', NULL); 111*acbd8998SOliver Tappe assert (ret == 1); 112*acbd8998SOliver Tappe ret = wcrtomb (NULL, btowc ('x'), NULL); 113*acbd8998SOliver Tappe assert (ret == 1); 114*acbd8998SOliver Tappe } 115*acbd8998SOliver Tappe 116*acbd8998SOliver Tappe for (i = '1'; i <= '4'; ++i) { 117*acbd8998SOliver Tappe switch (i) 118*acbd8998SOliver Tappe { 119*acbd8998SOliver Tappe case '1': 120*acbd8998SOliver Tappe /* Locale encoding is ISO-8859-1 or ISO-8859-15. */ 121*acbd8998SOliver Tappe printf("ISO8859-1 ...\n"); 122*acbd8998SOliver Tappe { 123*acbd8998SOliver Tappe const char input[] = "B\374\337er"; /* "Büßer" */ 124*acbd8998SOliver Tappe 125*acbd8998SOliver Tappe if (setlocale (LC_ALL, "en_US.ISO8859-1") == NULL) { 126*acbd8998SOliver Tappe fprintf(stderr, "unable to set ISO8859-1 locale, skipping\n"); 127*acbd8998SOliver Tappe break; 128*acbd8998SOliver Tappe } 129*acbd8998SOliver Tappe 130*acbd8998SOliver Tappe check_character (input + 1, 1); 131*acbd8998SOliver Tappe check_character (input + 2, 1); 132*acbd8998SOliver Tappe } 133*acbd8998SOliver Tappe break; 134*acbd8998SOliver Tappe 135*acbd8998SOliver Tappe case '2': 136*acbd8998SOliver Tappe /* Locale encoding is UTF-8. */ 137*acbd8998SOliver Tappe printf("UTF-8 ...\n"); 138*acbd8998SOliver Tappe { 139*acbd8998SOliver Tappe const char input[] = "B\303\274\303\237er"; /* "Büßer" */ 140*acbd8998SOliver Tappe 141*acbd8998SOliver Tappe if (setlocale (LC_ALL, "en_US.UTF-8") == NULL) { 142*acbd8998SOliver Tappe fprintf(stderr, "unable to set UTF-8 locale, skipping\n"); 143*acbd8998SOliver Tappe break; 144*acbd8998SOliver Tappe } 145*acbd8998SOliver Tappe 146*acbd8998SOliver Tappe check_character (input + 1, 2); 147*acbd8998SOliver Tappe check_character (input + 3, 2); 148*acbd8998SOliver Tappe } 149*acbd8998SOliver Tappe break; 150*acbd8998SOliver Tappe 151*acbd8998SOliver Tappe case '3': 152*acbd8998SOliver Tappe /* Locale encoding is EUC-JP. */ 153*acbd8998SOliver Tappe printf("EUC-JP ...\n"); 154*acbd8998SOliver Tappe { 155*acbd8998SOliver Tappe const char input[] = "<\306\374\313\334\270\354>"; /* "<日本語>" */ 156*acbd8998SOliver Tappe 157*acbd8998SOliver Tappe if (setlocale (LC_ALL, "en_US.EUC-JP") == NULL) { 158*acbd8998SOliver Tappe fprintf(stderr, "unable to set EUC-JP locale, skipping\n"); 159*acbd8998SOliver Tappe break; 160*acbd8998SOliver Tappe } 161*acbd8998SOliver Tappe 162*acbd8998SOliver Tappe check_character (input + 1, 2); 163*acbd8998SOliver Tappe check_character (input + 3, 2); 164*acbd8998SOliver Tappe check_character (input + 5, 2); 165*acbd8998SOliver Tappe } 166*acbd8998SOliver Tappe break; 167*acbd8998SOliver Tappe 168*acbd8998SOliver Tappe case '4': 169*acbd8998SOliver Tappe /* Locale encoding is GB18030. */ 170*acbd8998SOliver Tappe printf("GB18030 ...\n"); 171*acbd8998SOliver Tappe { 172*acbd8998SOliver Tappe const char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */ 173*acbd8998SOliver Tappe 174*acbd8998SOliver Tappe if (setlocale (LC_ALL, "en_US.GB18030") == NULL) { 175*acbd8998SOliver Tappe fprintf(stderr, "unable to set GB18030 locale, skipping\n"); 176*acbd8998SOliver Tappe break; 177*acbd8998SOliver Tappe } 178*acbd8998SOliver Tappe 179*acbd8998SOliver Tappe check_character (input + 1, 2); 180*acbd8998SOliver Tappe check_character (input + 3, 4); 181*acbd8998SOliver Tappe } 182*acbd8998SOliver Tappe break; 183*acbd8998SOliver Tappe } 184*acbd8998SOliver Tappe } 185*acbd8998SOliver Tappe 186*acbd8998SOliver Tappe return 0; 187*acbd8998SOliver Tappe } 188