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
check_character(const char * s,size_t n)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
main(int argc,char * argv[])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