Add test case for bug 18287
[glibc.git] / localedata / tst-ctype.c
blob62fb11fd2675bfdf86a05e60efc6740dbe3fbad0
1 /* Copyright (C) 2000-2015 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@gnu.org>, 2000.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 #include <ctype.h>
20 #include <locale.h>
21 #include <langinfo.h>
22 #include <stdio.h>
23 #include <string.h>
26 static const char lower[] = "abcdefghijklmnopqrstuvwxyz";
27 static const char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
28 static const char digits[] = "0123456789";
29 static const char cntrl[] = "\
30 \x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\
31 \x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ";
34 static struct classes
36 const char *name;
37 int mask;
38 } classes[] =
40 #define ENTRY(name) { #name, _IS##name }
41 ENTRY (upper),
42 ENTRY (lower),
43 ENTRY (alpha),
44 ENTRY (digit),
45 ENTRY (xdigit),
46 ENTRY (space),
47 ENTRY (print),
48 ENTRY (graph),
49 ENTRY (blank),
50 ENTRY (cntrl),
51 ENTRY (punct),
52 ENTRY (alnum)
54 #define nclasses (sizeof (classes) / sizeof (classes[0]))
57 #define FAIL(str, args...) \
58 { \
59 printf (" " str "\n", ##args); \
60 ++errors; \
64 static int
65 do_test (void)
67 const char *cp;
68 const char *cp2;
69 int errors = 0;
70 char *inpline = NULL;
71 size_t inplinelen = 0;
72 char *resline = NULL;
73 size_t reslinelen = 0;
74 size_t n;
75 const unsigned short int *__ctype_b;
77 setlocale (LC_ALL, "");
79 printf ("Testing the ctype data of the `%s' locale\n",
80 setlocale (LC_CTYPE, NULL));
82 __ctype_b = ((const unsigned short *) nl_langinfo (_NL_CTYPE_CLASS)) + 128;
84 #if 0
85 /* Just for debugging. */
87 /* Contents of the class array. */
88 printf ("\
89 upper = %04x lower = %04x alpha = %04x digit = %04x xdigit = %04x\n\
90 space = %04x print = %04x graph = %04x blank = %04x cntrl = %04x\n\
91 punct = %04x alnum = %04x\n",
92 _ISupper, _ISlower, _ISalpha, _ISdigit, _ISxdigit,
93 _ISspace, _ISprint, _ISgraph, _ISblank, _IScntrl,
94 _ISpunct, _ISalnum);
96 while (n < 256)
98 if (n % 8 == 0)
99 printf ("%02x: ", n);
100 printf ("%04x%s", __ctype_b[n], (n + 1) % 8 == 0 ? "\n" : " ");
101 ++n;
103 #endif
105 puts (" Test of ASCII character range\n special NUL byte handling");
106 if (isupper ('\0'))
107 FAIL ("isupper ('\\0') is true");
108 if (islower ('\0'))
109 FAIL ("islower ('\\0') is true");
110 if (isalpha ('\0'))
111 FAIL ("isalpha ('\\0') is true");
112 if (isdigit ('\0'))
113 FAIL ("isdigit ('\\0') is true");
114 if (isxdigit ('\0'))
115 FAIL ("isxdigit ('\\0') is true");
116 if (isspace ('\0'))
117 FAIL ("isspace ('\\0') is true");
118 if (isprint ('\0'))
119 FAIL ("isprint ('\\0') is true");
120 if (isgraph ('\0'))
121 FAIL ("isgraph ('\\0') is true");
122 if (isblank ('\0'))
123 FAIL ("isblank ('\\0') is true");
124 if (! iscntrl ('\0'))
125 FAIL ("iscntrl ('\\0') not true");
126 if (ispunct ('\0'))
127 FAIL ("ispunct ('\\0') is true");
128 if (isalnum ('\0'))
129 FAIL ("isalnum ('\\0') is true");
131 puts (" islower()");
132 for (cp = lower; *cp != '\0'; ++cp)
133 if (! islower (*cp))
134 FAIL ("islower ('%c') not true", *cp);
135 for (cp = upper; *cp != '\0'; ++cp)
136 if (islower (*cp))
137 FAIL ("islower ('%c') is true", *cp);
138 for (cp = digits; *cp != '\0'; ++cp)
139 if (islower (*cp))
140 FAIL ("islower ('%c') is true", *cp);
141 for (cp = cntrl; *cp != '\0'; ++cp)
142 if (islower (*cp))
143 FAIL ("islower ('\\x%02x') is true", *cp);
145 puts (" isupper()");
146 for (cp = lower; *cp != '\0'; ++cp)
147 if (isupper (*cp))
148 FAIL ("isupper ('%c') is true", *cp);
149 for (cp = upper; *cp != '\0'; ++cp)
150 if (! isupper (*cp))
151 FAIL ("isupper ('%c') not true", *cp);
152 for (cp = digits; *cp != '\0'; ++cp)
153 if (isupper (*cp))
154 FAIL ("isupper ('%c') is true", *cp);
155 for (cp = cntrl; *cp != '\0'; ++cp)
156 if (isupper (*cp))
157 FAIL ("isupper ('\\x%02x') is true", *cp);
159 puts (" isalpha()");
160 for (cp = lower; *cp != '\0'; ++cp)
161 if (! isalpha (*cp))
162 FAIL ("isalpha ('%c') not true", *cp);
163 for (cp = upper; *cp != '\0'; ++cp)
164 if (! isalpha (*cp))
165 FAIL ("isalpha ('%c') not true", *cp);
166 for (cp = digits; *cp != '\0'; ++cp)
167 if (isalpha (*cp))
168 FAIL ("isalpha ('%c') is true", *cp);
169 for (cp = cntrl; *cp != '\0'; ++cp)
170 if (isalpha (*cp))
171 FAIL ("isalpha ('\\x%02x') is true", *cp);
173 puts (" isdigit()");
174 for (cp = lower; *cp != '\0'; ++cp)
175 if (isdigit (*cp))
176 FAIL ("isdigit ('%c') is true", *cp);
177 for (cp = upper; *cp != '\0'; ++cp)
178 if (isdigit (*cp))
179 FAIL ("isdigit ('%c') is true", *cp);
180 for (cp = digits; *cp != '\0'; ++cp)
181 if (! isdigit (*cp))
182 FAIL ("isdigit ('%c') not true", *cp);
183 for (cp = cntrl; *cp != '\0'; ++cp)
184 if (isdigit (*cp))
185 FAIL ("isdigit ('\\x%02x') is true", *cp);
187 puts (" isxdigit()");
188 for (cp = lower; *cp != '\0'; ++cp)
189 if ((! isxdigit (*cp) && cp - lower < 6)
190 || (isxdigit (*cp) && cp - lower >= 6))
191 FAIL ("isxdigit ('%c') %s true", *cp, cp - upper < 6 ? "not" : "is");
192 for (cp = upper; *cp != '\0'; ++cp)
193 if ((! isxdigit (*cp) && cp - upper < 6)
194 || (isxdigit (*cp) && cp - upper >= 6))
195 FAIL ("isxdigit ('%c') %s true", *cp, cp - upper < 6 ? "not" : "is");
196 for (cp = digits; *cp != '\0'; ++cp)
197 if (! isxdigit (*cp))
198 FAIL ("isxdigit ('%c') not true", *cp);
199 for (cp = cntrl; *cp != '\0'; ++cp)
200 if (isxdigit (*cp))
201 FAIL ("isxdigit ('\\x%02x') is true", *cp);
203 puts (" isspace()");
204 for (cp = lower; *cp != '\0'; ++cp)
205 if (isspace (*cp))
206 FAIL ("isspace ('%c') is true", *cp);
207 for (cp = upper; *cp != '\0'; ++cp)
208 if (isspace (*cp))
209 FAIL ("isspace ('%c') is true", *cp);
210 for (cp = digits; *cp != '\0'; ++cp)
211 if (isspace (*cp))
212 FAIL ("isspace ('%c') is true", *cp);
213 for (cp = cntrl; *cp != '\0'; ++cp)
214 if ((isspace (*cp) && ((*cp < '\x09' || *cp > '\x0d') && *cp != ' '))
215 || (! isspace (*cp)
216 && ((*cp >= '\x09' && *cp <= '\x0d') || *cp == ' ')))
217 FAIL ("isspace ('\\x%02x') %s true", *cp,
218 (*cp < '\x09' || *cp > '\x0d') ? "is" : "not");
220 puts (" isprint()");
221 for (cp = lower; *cp != '\0'; ++cp)
222 if (! isprint (*cp))
223 FAIL ("isprint ('%c') not true", *cp);
224 for (cp = upper; *cp != '\0'; ++cp)
225 if (! isprint (*cp))
226 FAIL ("isprint ('%c') not true", *cp);
227 for (cp = digits; *cp != '\0'; ++cp)
228 if (! isprint (*cp))
229 FAIL ("isprint ('%c') not true", *cp);
230 for (cp = cntrl; *cp != '\0'; ++cp)
231 if ((isprint (*cp) && *cp != ' ')
232 || (! isprint (*cp) && *cp == ' '))
233 FAIL ("isprint ('\\x%02x') is true", *cp);
235 puts (" isgraph()");
236 for (cp = lower; *cp != '\0'; ++cp)
237 if (! isgraph (*cp))
238 FAIL ("isgraph ('%c') not true", *cp);
239 for (cp = upper; *cp != '\0'; ++cp)
240 if (! isgraph (*cp))
241 FAIL ("isgraph ('%c') not true", *cp);
242 for (cp = digits; *cp != '\0'; ++cp)
243 if (! isgraph (*cp))
244 FAIL ("isgraph ('%c') not true", *cp);
245 for (cp = cntrl; *cp != '\0'; ++cp)
246 if (isgraph (*cp))
247 FAIL ("isgraph ('\\x%02x') is true", *cp);
249 puts (" isblank()");
250 for (cp = lower; *cp != '\0'; ++cp)
251 if (isblank (*cp))
252 FAIL ("isblank ('%c') is true", *cp);
253 for (cp = upper; *cp != '\0'; ++cp)
254 if (isblank (*cp))
255 FAIL ("isblank ('%c') is true", *cp);
256 for (cp = digits; *cp != '\0'; ++cp)
257 if (isblank (*cp))
258 FAIL ("isblank ('%c') is true", *cp);
259 for (cp = cntrl; *cp != '\0'; ++cp)
260 if ((isblank (*cp) && *cp != '\x09' && *cp != ' ')
261 || (! isblank (*cp) && (*cp == '\x09' || *cp == ' ')))
262 FAIL ("isblank ('\\x%02x') %s true", *cp, *cp != '\x09' ? "is" : "not");
264 puts (" iscntrl()");
265 for (cp = lower; *cp != '\0'; ++cp)
266 if (iscntrl (*cp))
267 FAIL ("iscntrl ('%c') is true", *cp);
268 for (cp = upper; *cp != '\0'; ++cp)
269 if (iscntrl (*cp))
270 FAIL ("iscntrl ('%c') is true", *cp);
271 for (cp = digits; *cp != '\0'; ++cp)
272 if (iscntrl (*cp))
273 FAIL ("iscntrl ('%c') is true", *cp);
274 for (cp = cntrl; *cp != '\0'; ++cp)
275 if ((iscntrl (*cp) && *cp == ' ')
276 || (! iscntrl (*cp) && *cp != ' '))
277 FAIL ("iscntrl ('\\x%02x') not true", *cp);
279 puts (" ispunct()");
280 for (cp = lower; *cp != '\0'; ++cp)
281 if (ispunct (*cp))
282 FAIL ("ispunct ('%c') is true", *cp);
283 for (cp = upper; *cp != '\0'; ++cp)
284 if (ispunct (*cp))
285 FAIL ("ispunct ('%c') is true", *cp);
286 for (cp = digits; *cp != '\0'; ++cp)
287 if (ispunct (*cp))
288 FAIL ("ispunct ('%c') is true", *cp);
289 for (cp = cntrl; *cp != '\0'; ++cp)
290 if (ispunct (*cp))
291 FAIL ("ispunct ('\\x%02x') is true", *cp);
293 puts (" isalnum()");
294 for (cp = lower; *cp != '\0'; ++cp)
295 if (! isalnum (*cp))
296 FAIL ("isalnum ('%c') not true", *cp);
297 for (cp = upper; *cp != '\0'; ++cp)
298 if (! isalnum (*cp))
299 FAIL ("isalnum ('%c') not true", *cp);
300 for (cp = digits; *cp != '\0'; ++cp)
301 if (! isalnum (*cp))
302 FAIL ("isalnum ('%c') not true", *cp);
303 for (cp = cntrl; *cp != '\0'; ++cp)
304 if (isalnum (*cp))
305 FAIL ("isalnum ('\\x%02x') is true", *cp);
308 puts (" tolower()");
309 for (cp = lower; *cp != '\0'; ++cp)
310 if (tolower (*cp) != *cp)
311 FAIL ("tolower ('%c') != '%c'", *cp, *cp);
312 for (cp = upper, cp2 = lower; *cp != '\0'; ++cp, ++cp2)
313 if (tolower (*cp) != *cp2)
314 FAIL ("tolower ('%c') != '%c'", *cp, *cp2);
315 for (cp = digits; *cp != '\0'; ++cp)
316 if (tolower (*cp) != *cp)
317 FAIL ("tolower ('%c') != '%c'", *cp, *cp);
318 for (cp = cntrl; *cp != '\0'; ++cp)
319 if (tolower (*cp) != *cp)
320 FAIL ("tolower ('\\x%02x') != '\\x%02x'", *cp, *cp);
322 puts (" toupper()");
323 for (cp = lower, cp2 = upper; *cp != '\0'; ++cp, ++cp2)
324 if (toupper (*cp) != *cp2)
325 FAIL ("toupper ('%c') != '%c'", *cp, *cp2);
326 for (cp = upper; *cp != '\0'; ++cp)
327 if (toupper (*cp) != *cp)
328 FAIL ("toupper ('%c') != '%c'", *cp, *cp);
329 for (cp = digits; *cp != '\0'; ++cp)
330 if (toupper (*cp) != *cp)
331 FAIL ("toupper ('%c') != '%c'", *cp, *cp);
332 for (cp = cntrl; *cp != '\0'; ++cp)
333 if (toupper (*cp) != *cp)
334 FAIL ("toupper ('\\x%02x') != '\\x%02x'", *cp, *cp);
337 /* Now some locale specific tests. */
338 while (! feof (stdin))
340 unsigned char *inp;
341 unsigned char *resp;
343 if (getline (&inpline, &inplinelen, stdin) <= 0
344 || getline (&resline, &reslinelen, stdin) <= 0)
345 break;
347 inp = (unsigned char *) strchr (inpline, '\n');
348 if (inp != NULL)
349 *inp = '\0';
350 resp = (unsigned char *) strchr (resline, '\n');
351 if (resp != NULL)
352 *resp = '\0';
354 inp = (unsigned char *) inpline;
355 while (*inp != ' ' && *inp != '\t' && *inp && *inp != '\n'
356 && *inp != '\0')
357 ++inp;
359 if (*inp == '\0')
361 printf ("line \"%s\" is without content\n", inpline);
362 continue;
364 *inp++ = '\0';
365 while (*inp == ' ' || *inp == '\t')
366 ++inp;
368 /* Try all classes. */
369 for (n = 0; n < nclasses; ++n)
370 if (strcmp (inpline, classes[n].name) == 0)
371 break;
373 resp = (unsigned char *) resline;
374 while (*resp == ' ' || *resp == '\t')
375 ++resp;
377 if (strlen ((char *) inp) != strlen ((char *) resp))
379 printf ("lines \"%.20s\"... and \"%.20s\" have not the same length\n",
380 inp, resp);
381 continue;
384 if (n < nclasses)
386 if (strspn ((char *) resp, "01") != strlen ((char *) resp))
388 printf ("result string \"%s\" malformed\n", resp);
389 continue;
392 printf (" Locale-specific tests for `%s'\n", inpline);
394 while (*inp != '\0' && *inp != '\n')
396 if (((__ctype_b[(unsigned int) *inp] & classes[n].mask) != 0)
397 != (*resp != '0'))
399 printf (" is%s('%c' = '\\x%02x') %s true\n", inpline,
400 *inp, *inp, *resp == '1' ? "not" : "is");
401 ++errors;
403 ++inp;
404 ++resp;
407 else if (strcmp (inpline, "tolower") == 0)
409 while (*inp != '\0')
411 if (tolower (*inp) != *resp)
413 printf (" tolower('%c' = '\\x%02x') != '%c'\n",
414 *inp, *inp, *resp);
415 ++errors;
417 ++inp;
418 ++resp;
421 else if (strcmp (inpline, "toupper") == 0)
423 while (*inp != '\0')
425 if (toupper (*inp) != *resp)
427 printf (" toupper('%c' = '\\x%02x') != '%c'\n",
428 *inp, *inp, *resp);
429 ++errors;
431 ++inp;
432 ++resp;
435 else
436 printf ("\"%s\": unknown class or map\n", inpline);
440 if (errors != 0)
442 printf (" %d error%s for `%s' locale\n\n\n", errors,
443 errors == 1 ? "" : "s", setlocale (LC_ALL, NULL));
444 return 1;
447 printf (" No errors for `%s' locale\n\n\n", setlocale (LC_ALL, NULL));
448 return 0;
451 #define TEST_FUNCTION do_test ()
452 #include "../test-skeleton.c"