2003-04-22 Roland McGrath <roland@redhat.com>
[glibc.git] / localedata / tst-ctype.c
blobfb2e78cbb2cb291175bcfa4ba78e048ad66d2daa
1 /* Copyright (C) 2000,02 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, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #include <ctype.h>
21 #include <locale.h>
22 #include <langinfo.h>
23 #include <stdio.h>
24 #include <string.h>
27 static const char lower[] = "abcdefghijklmnopqrstuvwxyz";
28 static const char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
29 static const char digits[] = "0123456789";
30 static const char cntrl[] = "\
31 \x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\
32 \x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ";
35 static struct classes
37 const char *name;
38 int mask;
39 } classes[] =
41 #define ENTRY(name) { #name, _IS##name }
42 ENTRY (upper),
43 ENTRY (lower),
44 ENTRY (alpha),
45 ENTRY (digit),
46 ENTRY (xdigit),
47 ENTRY (space),
48 ENTRY (print),
49 ENTRY (graph),
50 ENTRY (blank),
51 ENTRY (cntrl),
52 ENTRY (punct),
53 ENTRY (alnum)
55 #define nclasses (sizeof (classes) / sizeof (classes[0]))
58 #define FAIL(str, args...) \
59 { \
60 printf (" " str "\n", ##args); \
61 ++errors; \
65 int
66 main (void)
68 const char *cp;
69 const char *cp2;
70 int errors = 0;
71 char *inpline = NULL;
72 size_t inplinelen = 0;
73 char *resline = NULL;
74 size_t reslinelen = 0;
75 size_t n;
76 const unsigned short int *__ctype_b;
78 setlocale (LC_ALL, "");
80 printf ("Testing the ctype data of the `%s' locale\n",
81 setlocale (LC_CTYPE, NULL));
83 __ctype_b = ((const unsigned short *) nl_langinfo (_NL_CTYPE_CLASS)) + 128;
85 #if 0
86 /* Just for debugging. */
88 /* Contents of the class array. */
89 printf ("\
90 upper = %04x lower = %04x alpha = %04x digit = %04x xdigit = %04x\n\
91 space = %04x print = %04x graph = %04x blank = %04x cntrl = %04x\n\
92 punct = %04x alnum = %04x\n",
93 _ISupper, _ISlower, _ISalpha, _ISdigit, _ISxdigit,
94 _ISspace, _ISprint, _ISgraph, _ISblank, _IScntrl,
95 _ISpunct, _ISalnum);
97 while (n < 256)
99 if (n % 8 == 0)
100 printf ("%02x: ", n);
101 printf ("%04x%s", __ctype_b[n], (n + 1) % 8 == 0 ? "\n" : " ");
102 ++n;
104 #endif
106 puts (" Test of ASCII character range\n special NUL byte handling");
107 if (isupper ('\0'))
108 FAIL ("isupper ('\\0') is true");
109 if (islower ('\0'))
110 FAIL ("islower ('\\0') is true");
111 if (isalpha ('\0'))
112 FAIL ("isalpha ('\\0') is true");
113 if (isdigit ('\0'))
114 FAIL ("isdigit ('\\0') is true");
115 if (isxdigit ('\0'))
116 FAIL ("isxdigit ('\\0') is true");
117 if (isspace ('\0'))
118 FAIL ("isspace ('\\0') is true");
119 if (isprint ('\0'))
120 FAIL ("isprint ('\\0') is true");
121 if (isgraph ('\0'))
122 FAIL ("isgraph ('\\0') is true");
123 if (isblank ('\0'))
124 FAIL ("isblank ('\\0') is true");
125 if (! iscntrl ('\0'))
126 FAIL ("iscntrl ('\\0') not true");
127 if (ispunct ('\0'))
128 FAIL ("ispunct ('\\0') is true");
129 if (isalnum ('\0'))
130 FAIL ("isalnum ('\\0') is true");
132 puts (" islower()");
133 for (cp = lower; *cp != '\0'; ++cp)
134 if (! islower (*cp))
135 FAIL ("islower ('%c') not true", *cp);
136 for (cp = upper; *cp != '\0'; ++cp)
137 if (islower (*cp))
138 FAIL ("islower ('%c') is true", *cp);
139 for (cp = digits; *cp != '\0'; ++cp)
140 if (islower (*cp))
141 FAIL ("islower ('%c') is true", *cp);
142 for (cp = cntrl; *cp != '\0'; ++cp)
143 if (islower (*cp))
144 FAIL ("islower ('\\x%02x') is true", *cp);
146 puts (" isupper()");
147 for (cp = lower; *cp != '\0'; ++cp)
148 if (isupper (*cp))
149 FAIL ("isupper ('%c') is true", *cp);
150 for (cp = upper; *cp != '\0'; ++cp)
151 if (! isupper (*cp))
152 FAIL ("isupper ('%c') not true", *cp);
153 for (cp = digits; *cp != '\0'; ++cp)
154 if (isupper (*cp))
155 FAIL ("isupper ('%c') is true", *cp);
156 for (cp = cntrl; *cp != '\0'; ++cp)
157 if (isupper (*cp))
158 FAIL ("isupper ('\\x%02x') is true", *cp);
160 puts (" isalpha()");
161 for (cp = lower; *cp != '\0'; ++cp)
162 if (! isalpha (*cp))
163 FAIL ("isalpha ('%c') not true", *cp);
164 for (cp = upper; *cp != '\0'; ++cp)
165 if (! isalpha (*cp))
166 FAIL ("isalpha ('%c') not true", *cp);
167 for (cp = digits; *cp != '\0'; ++cp)
168 if (isalpha (*cp))
169 FAIL ("isalpha ('%c') is true", *cp);
170 for (cp = cntrl; *cp != '\0'; ++cp)
171 if (isalpha (*cp))
172 FAIL ("isalpha ('\\x%02x') is true", *cp);
174 puts (" isdigit()");
175 for (cp = lower; *cp != '\0'; ++cp)
176 if (isdigit (*cp))
177 FAIL ("isdigit ('%c') is true", *cp);
178 for (cp = upper; *cp != '\0'; ++cp)
179 if (isdigit (*cp))
180 FAIL ("isdigit ('%c') is true", *cp);
181 for (cp = digits; *cp != '\0'; ++cp)
182 if (! isdigit (*cp))
183 FAIL ("isdigit ('%c') not true", *cp);
184 for (cp = cntrl; *cp != '\0'; ++cp)
185 if (isdigit (*cp))
186 FAIL ("isdigit ('\\x%02x') is true", *cp);
188 puts (" isxdigit()");
189 for (cp = lower; *cp != '\0'; ++cp)
190 if ((! isxdigit (*cp) && cp - lower < 6)
191 || (isxdigit (*cp) && cp - lower >= 6))
192 FAIL ("isxdigit ('%c') %s true", *cp, cp - upper < 6 ? "not" : "is");
193 for (cp = upper; *cp != '\0'; ++cp)
194 if ((! isxdigit (*cp) && cp - upper < 6)
195 || (isxdigit (*cp) && cp - upper >= 6))
196 FAIL ("isxdigit ('%c') %s true", *cp, cp - upper < 6 ? "not" : "is");
197 for (cp = digits; *cp != '\0'; ++cp)
198 if (! isxdigit (*cp))
199 FAIL ("isxdigit ('%c') not true", *cp);
200 for (cp = cntrl; *cp != '\0'; ++cp)
201 if (isxdigit (*cp))
202 FAIL ("isxdigit ('\\x%02x') is true", *cp);
204 puts (" isspace()");
205 for (cp = lower; *cp != '\0'; ++cp)
206 if (isspace (*cp))
207 FAIL ("isspace ('%c') is true", *cp);
208 for (cp = upper; *cp != '\0'; ++cp)
209 if (isspace (*cp))
210 FAIL ("isspace ('%c') is true", *cp);
211 for (cp = digits; *cp != '\0'; ++cp)
212 if (isspace (*cp))
213 FAIL ("isspace ('%c') is true", *cp);
214 for (cp = cntrl; *cp != '\0'; ++cp)
215 if ((isspace (*cp) && ((*cp < '\x09' || *cp > '\x0d') && *cp != ' '))
216 || (! isspace (*cp)
217 && ((*cp >= '\x09' && *cp <= '\x0d') || *cp == ' ')))
218 FAIL ("isspace ('\\x%02x') %s true", *cp,
219 (*cp < '\x09' || *cp > '\x0d') ? "is" : "not");
221 puts (" isprint()");
222 for (cp = lower; *cp != '\0'; ++cp)
223 if (! isprint (*cp))
224 FAIL ("isprint ('%c') not true", *cp);
225 for (cp = upper; *cp != '\0'; ++cp)
226 if (! isprint (*cp))
227 FAIL ("isprint ('%c') not true", *cp);
228 for (cp = digits; *cp != '\0'; ++cp)
229 if (! isprint (*cp))
230 FAIL ("isprint ('%c') not true", *cp);
231 for (cp = cntrl; *cp != '\0'; ++cp)
232 if ((isprint (*cp) && *cp != ' ')
233 || (! isprint (*cp) && *cp == ' '))
234 FAIL ("isprint ('\\x%02x') is true", *cp);
236 puts (" isgraph()");
237 for (cp = lower; *cp != '\0'; ++cp)
238 if (! isgraph (*cp))
239 FAIL ("isgraph ('%c') not true", *cp);
240 for (cp = upper; *cp != '\0'; ++cp)
241 if (! isgraph (*cp))
242 FAIL ("isgraph ('%c') not true", *cp);
243 for (cp = digits; *cp != '\0'; ++cp)
244 if (! isgraph (*cp))
245 FAIL ("isgraph ('%c') not true", *cp);
246 for (cp = cntrl; *cp != '\0'; ++cp)
247 if (isgraph (*cp))
248 FAIL ("isgraph ('\\x%02x') is true", *cp);
250 puts (" isblank()");
251 for (cp = lower; *cp != '\0'; ++cp)
252 if (isblank (*cp))
253 FAIL ("isblank ('%c') is true", *cp);
254 for (cp = upper; *cp != '\0'; ++cp)
255 if (isblank (*cp))
256 FAIL ("isblank ('%c') is true", *cp);
257 for (cp = digits; *cp != '\0'; ++cp)
258 if (isblank (*cp))
259 FAIL ("isblank ('%c') is true", *cp);
260 for (cp = cntrl; *cp != '\0'; ++cp)
261 if ((isblank (*cp) && *cp != '\x09' && *cp != ' ')
262 || (! isblank (*cp) && (*cp == '\x09' || *cp == ' ')))
263 FAIL ("isblank ('\\x%02x') %s true", *cp, *cp != '\x09' ? "is" : "not");
265 puts (" iscntrl()");
266 for (cp = lower; *cp != '\0'; ++cp)
267 if (iscntrl (*cp))
268 FAIL ("iscntrl ('%c') is true", *cp);
269 for (cp = upper; *cp != '\0'; ++cp)
270 if (iscntrl (*cp))
271 FAIL ("iscntrl ('%c') is true", *cp);
272 for (cp = digits; *cp != '\0'; ++cp)
273 if (iscntrl (*cp))
274 FAIL ("iscntrl ('%c') is true", *cp);
275 for (cp = cntrl; *cp != '\0'; ++cp)
276 if ((iscntrl (*cp) && *cp == ' ')
277 || (! iscntrl (*cp) && *cp != ' '))
278 FAIL ("iscntrl ('\\x%02x') not true", *cp);
280 puts (" ispunct()");
281 for (cp = lower; *cp != '\0'; ++cp)
282 if (ispunct (*cp))
283 FAIL ("ispunct ('%c') is true", *cp);
284 for (cp = upper; *cp != '\0'; ++cp)
285 if (ispunct (*cp))
286 FAIL ("ispunct ('%c') is true", *cp);
287 for (cp = digits; *cp != '\0'; ++cp)
288 if (ispunct (*cp))
289 FAIL ("ispunct ('%c') is true", *cp);
290 for (cp = cntrl; *cp != '\0'; ++cp)
291 if (ispunct (*cp))
292 FAIL ("ispunct ('\\x%02x') is true", *cp);
294 puts (" isalnum()");
295 for (cp = lower; *cp != '\0'; ++cp)
296 if (! isalnum (*cp))
297 FAIL ("isalnum ('%c') not true", *cp);
298 for (cp = upper; *cp != '\0'; ++cp)
299 if (! isalnum (*cp))
300 FAIL ("isalnum ('%c') not true", *cp);
301 for (cp = digits; *cp != '\0'; ++cp)
302 if (! isalnum (*cp))
303 FAIL ("isalnum ('%c') not true", *cp);
304 for (cp = cntrl; *cp != '\0'; ++cp)
305 if (isalnum (*cp))
306 FAIL ("isalnum ('\\x%02x') is true", *cp);
309 puts (" tolower()");
310 for (cp = lower; *cp != '\0'; ++cp)
311 if (tolower (*cp) != *cp)
312 FAIL ("tolower ('%c') != '%c'", *cp, *cp);
313 for (cp = upper, cp2 = lower; *cp != '\0'; ++cp, ++cp2)
314 if (tolower (*cp) != *cp2)
315 FAIL ("tolower ('%c') != '%c'", *cp, *cp2);
316 for (cp = digits; *cp != '\0'; ++cp)
317 if (tolower (*cp) != *cp)
318 FAIL ("tolower ('%c') != '%c'", *cp, *cp);
319 for (cp = cntrl; *cp != '\0'; ++cp)
320 if (tolower (*cp) != *cp)
321 FAIL ("tolower ('\\x%02x') != '\\x%02x'", *cp, *cp);
323 puts (" toupper()");
324 for (cp = lower, cp2 = upper; *cp != '\0'; ++cp, ++cp2)
325 if (toupper (*cp) != *cp2)
326 FAIL ("toupper ('%c') != '%c'", *cp, *cp2);
327 for (cp = upper; *cp != '\0'; ++cp)
328 if (toupper (*cp) != *cp)
329 FAIL ("toupper ('%c') != '%c'", *cp, *cp);
330 for (cp = digits; *cp != '\0'; ++cp)
331 if (toupper (*cp) != *cp)
332 FAIL ("toupper ('%c') != '%c'", *cp, *cp);
333 for (cp = cntrl; *cp != '\0'; ++cp)
334 if (toupper (*cp) != *cp)
335 FAIL ("toupper ('\\x%02x') != '\\x%02x'", *cp, *cp);
338 /* Now some locale specific tests. */
339 while (! feof (stdin))
341 unsigned char *inp;
342 unsigned char *resp;
344 if (getline (&inpline, &inplinelen, stdin) <= 0
345 || getline (&resline, &reslinelen, stdin) <= 0)
346 break;
348 inp = strchr (inpline, '\n');
349 if (inp != NULL)
350 *inp = '\0';
351 resp = strchr (resline, '\n');
352 if (resp != NULL)
353 *resp = '\0';
355 inp = inpline;
356 while (*inp != ' ' && *inp != '\t' && *inp && *inp != '\n'
357 && *inp != '\0')
358 ++inp;
360 if (*inp == '\0')
362 printf ("line \"%s\" is without content\n", inpline);
363 continue;
365 *inp++ = '\0';
366 while (*inp == ' ' || *inp == '\t')
367 ++inp;
369 /* Try all classes. */
370 for (n = 0; n < nclasses; ++n)
371 if (strcmp (inpline, classes[n].name) == 0)
372 break;
374 resp = resline;
375 while (*resp == ' ' || *resp == '\t')
376 ++resp;
378 if (strlen (inp) != strlen (resp))
380 printf ("lines \"%.20s\"... and \"%.20s\" have not the same length\n",
381 inp, resp);
382 continue;
385 if (n < nclasses)
387 if (strspn (resp, "01") != strlen (resp))
389 printf ("result string \"%s\" malformed\n", resp);
390 continue;
393 printf (" Locale-specific tests for `%s'\n", inpline);
395 while (*inp != '\0' && *inp != '\n')
397 if (((__ctype_b[(unsigned int) *inp] & classes[n].mask) != 0)
398 != (*resp != '0'))
400 printf (" is%s('%c' = '\\x%02x') %s true\n", inpline,
401 *inp, *inp, *resp == '1' ? "not" : "is");
402 ++errors;
404 ++inp;
405 ++resp;
408 else if (strcmp (inpline, "tolower") == 0)
410 while (*inp != '\0')
412 if (tolower (*inp) != *resp)
414 printf (" tolower('%c' = '\\x%02x') != '%c'\n",
415 *inp, *inp, *resp);
416 ++errors;
418 ++inp;
419 ++resp;
422 else if (strcmp (inpline, "toupper") == 0)
424 while (*inp != '\0')
426 if (toupper (*inp) != *resp)
428 printf (" toupper('%c' = '\\x%02x') != '%c'\n",
429 *inp, *inp, *resp);
430 ++errors;
432 ++inp;
433 ++resp;
436 else
437 printf ("\"%s\": unknown class or map\n", inpline);
441 if (errors != 0)
443 printf (" %d error%s for `%s' locale\n\n\n", errors,
444 errors == 1 ? "" : "s", setlocale (LC_ALL, NULL));
445 return 1;
448 printf (" No errors for `%s' locale\n\n\n", setlocale (LC_ALL, NULL));
449 return 0;