(ISSPACE): New #define. Use isspace or __isspace_l. Replace calls to isspace.
[kopensolaris-gnu/glibc.git] / localedata / tst-ctype.c
1 /* Copyright (C) 2000 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@gnu.org>, 2000.
4
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.
9
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.
14
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.  */
19
20 #include <ctype.h>
21 #include <locale.h>
22 #include <stdio.h>
23 #include <string.h>
24
25
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 ";
32
33
34 static struct classes
35 {
36   const char *name;
37   int mask;
38 } classes[] =
39 {
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)
53 };
54 #define nclasses (sizeof (classes) / sizeof (classes[0]))
55
56
57 #define FAIL(str, args...) \
58   {                                                                           \
59     printf ("      " str "\n", ##args);                                       \
60     ++errors;                                                                 \
61   }
62
63
64 int
65 main (void)
66 {
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   int n;
75
76   setlocale (LC_ALL, "");
77
78   printf ("Testing the ctype data of the `%s' locale\n",
79           setlocale (LC_CTYPE, NULL));
80
81 #if 0
82   /* Just for debugging.  */
83
84   /* Contents of the class array.  */
85   printf ("\
86 upper = %04x  lower = %04x  alpha = %04x  digit = %04x  xdigit = %04x\n\
87 space = %04x  print = %04x  graph = %04x  blank = %04x  cntrl  = %04x\n\
88 punct = %04x  alnum = %04x\n",
89           _ISupper, _ISlower, _ISalpha, _ISdigit, _ISxdigit,
90           _ISspace, _ISprint, _ISgraph, _ISblank, _IScntrl,
91           _ISpunct, _ISalnum);
92
93   while (n < 256)
94     {
95       if (n % 8 == 0)
96         printf ("%02x: ", n);
97       printf ("%04x%s", __ctype_b[n], (n + 1) % 8 == 0 ? "\n" : " ");
98       ++n;
99     }
100 #endif
101
102   puts ("  Test of ASCII character range\n    special NUL byte handling");
103   if (isupper ('\0'))
104     FAIL ("isupper ('\\0') is true");
105   if (islower ('\0'))
106     FAIL ("islower ('\\0') is true");
107   if (isalpha ('\0'))
108     FAIL ("isalpha ('\\0') is true");
109   if (isdigit ('\0'))
110     FAIL ("isdigit ('\\0') is true");
111   if (isxdigit ('\0'))
112     FAIL ("isxdigit ('\\0') is true");
113   if (isspace ('\0'))
114     FAIL ("isspace ('\\0') is true");
115   if (isprint ('\0'))
116     FAIL ("isprint ('\\0') is true");
117   if (isgraph ('\0'))
118     FAIL ("isgraph ('\\0') is true");
119   if (isblank ('\0'))
120     FAIL ("isblank ('\\0') is true");
121   if (! iscntrl ('\0'))
122     FAIL ("iscntrl ('\\0') not true");
123   if (ispunct ('\0'))
124     FAIL ("ispunct ('\\0') is true");
125   if (isalnum ('\0'))
126     FAIL ("isalnum ('\\0') is true");
127
128   puts ("    islower()");
129   for (cp = lower; *cp != '\0'; ++cp)
130     if (! islower (*cp))
131       FAIL ("islower ('%c') not true", *cp);
132   for (cp = upper; *cp != '\0'; ++cp)
133     if (islower (*cp))
134       FAIL ("islower ('%c') is true", *cp);
135   for (cp = digits; *cp != '\0'; ++cp)
136     if (islower (*cp))
137       FAIL ("islower ('%c') is true", *cp);
138   for (cp = cntrl; *cp != '\0'; ++cp)
139     if (islower (*cp))
140       FAIL ("islower ('\\x%02x') is true", *cp);
141
142   puts ("    isupper()");
143   for (cp = lower; *cp != '\0'; ++cp)
144     if (isupper (*cp))
145       FAIL ("isupper ('%c') is true", *cp);
146   for (cp = upper; *cp != '\0'; ++cp)
147     if (! isupper (*cp))
148       FAIL ("isupper ('%c') not true", *cp);
149   for (cp = digits; *cp != '\0'; ++cp)
150     if (isupper (*cp))
151       FAIL ("isupper ('%c') is true", *cp);
152   for (cp = cntrl; *cp != '\0'; ++cp)
153     if (isupper (*cp))
154       FAIL ("isupper ('\\x%02x') is true", *cp);
155
156   puts ("    isalpha()");
157   for (cp = lower; *cp != '\0'; ++cp)
158     if (! isalpha (*cp))
159       FAIL ("isalpha ('%c') not true", *cp);
160   for (cp = upper; *cp != '\0'; ++cp)
161     if (! isalpha (*cp))
162       FAIL ("isalpha ('%c') not true", *cp);
163   for (cp = digits; *cp != '\0'; ++cp)
164     if (isalpha (*cp))
165       FAIL ("isalpha ('%c') is true", *cp);
166   for (cp = cntrl; *cp != '\0'; ++cp)
167     if (isalpha (*cp))
168       FAIL ("isalpha ('\\x%02x') is true", *cp);
169
170   puts ("    isdigit()");
171   for (cp = lower; *cp != '\0'; ++cp)
172     if (isdigit (*cp))
173       FAIL ("isdigit ('%c') is true", *cp);
174   for (cp = upper; *cp != '\0'; ++cp)
175     if (isdigit (*cp))
176       FAIL ("isdigit ('%c') is true", *cp);
177   for (cp = digits; *cp != '\0'; ++cp)
178     if (! isdigit (*cp))
179       FAIL ("isdigit ('%c') not true", *cp);
180   for (cp = cntrl; *cp != '\0'; ++cp)
181     if (isdigit (*cp))
182       FAIL ("isdigit ('\\x%02x') is true", *cp);
183
184   puts ("    isxdigit()");
185   for (cp = lower; *cp != '\0'; ++cp)
186     if ((! isxdigit (*cp) && cp - lower < 6)
187         || (isxdigit (*cp) && cp - lower >= 6))
188       FAIL ("isxdigit ('%c') %s true", *cp, cp - upper < 6 ? "not" : "is");
189   for (cp = upper; *cp != '\0'; ++cp)
190     if ((! isxdigit (*cp) && cp - upper < 6)
191         || (isxdigit (*cp) && cp - upper >= 6))
192       FAIL ("isxdigit ('%c') %s true", *cp, cp - upper < 6 ? "not" : "is");
193   for (cp = digits; *cp != '\0'; ++cp)
194     if (! isxdigit (*cp))
195       FAIL ("isxdigit ('%c') not true", *cp);
196   for (cp = cntrl; *cp != '\0'; ++cp)
197     if (isxdigit (*cp))
198       FAIL ("isxdigit ('\\x%02x') is true", *cp);
199
200   puts ("    isspace()");
201   for (cp = lower; *cp != '\0'; ++cp)
202     if (isspace (*cp))
203       FAIL ("isspace ('%c') is true", *cp);
204   for (cp = upper; *cp != '\0'; ++cp)
205     if (isspace (*cp))
206       FAIL ("isspace ('%c') is true", *cp);
207   for (cp = digits; *cp != '\0'; ++cp)
208     if (isspace (*cp))
209       FAIL ("isspace ('%c') is true", *cp);
210   for (cp = cntrl; *cp != '\0'; ++cp)
211     if ((isspace (*cp) && ((*cp < '\x09' || *cp > '\x0d') && *cp != ' '))
212         || (! isspace (*cp)
213             && ((*cp >= '\x09' && *cp <= '\x0d') || *cp == ' ')))
214       FAIL ("isspace ('\\x%02x') %s true", *cp,
215             (*cp < '\x09' || *cp > '\x0d') ? "is" : "not");
216
217   puts ("    isprint()");
218   for (cp = lower; *cp != '\0'; ++cp)
219     if (! isprint (*cp))
220       FAIL ("isprint ('%c') not true", *cp);
221   for (cp = upper; *cp != '\0'; ++cp)
222     if (! isprint (*cp))
223       FAIL ("isprint ('%c') not true", *cp);
224   for (cp = digits; *cp != '\0'; ++cp)
225     if (! isprint (*cp))
226       FAIL ("isprint ('%c') not true", *cp);
227   for (cp = cntrl; *cp != '\0'; ++cp)
228     if ((isprint (*cp) && *cp != ' ')
229         || (! isprint (*cp) && *cp == ' '))
230       FAIL ("isprint ('\\x%02x') is true", *cp);
231
232   puts ("    isgraph()");
233   for (cp = lower; *cp != '\0'; ++cp)
234     if (! isgraph (*cp))
235       FAIL ("isgraph ('%c') not true", *cp);
236   for (cp = upper; *cp != '\0'; ++cp)
237     if (! isgraph (*cp))
238       FAIL ("isgraph ('%c') not true", *cp);
239   for (cp = digits; *cp != '\0'; ++cp)
240     if (! isgraph (*cp))
241       FAIL ("isgraph ('%c') not true", *cp);
242   for (cp = cntrl; *cp != '\0'; ++cp)
243     if (isgraph (*cp))
244       FAIL ("isgraph ('\\x%02x') is true", *cp);
245
246   puts ("    isblank()");
247   for (cp = lower; *cp != '\0'; ++cp)
248     if (isblank (*cp))
249       FAIL ("isblank ('%c') is true", *cp);
250   for (cp = upper; *cp != '\0'; ++cp)
251     if (isblank (*cp))
252       FAIL ("isblank ('%c') is true", *cp);
253   for (cp = digits; *cp != '\0'; ++cp)
254     if (isblank (*cp))
255       FAIL ("isblank ('%c') is true", *cp);
256   for (cp = cntrl; *cp != '\0'; ++cp)
257     if ((isblank (*cp) && *cp != '\x09' && *cp != ' ')
258         || (! isblank (*cp) && (*cp == '\x09' || *cp == ' ')))
259       FAIL ("isblank ('\\x%02x') %s true", *cp, *cp != '\x09' ? "is" : "not");
260
261   puts ("    iscntrl()");
262   for (cp = lower; *cp != '\0'; ++cp)
263     if (iscntrl (*cp))
264       FAIL ("iscntrl ('%c') is true", *cp);
265   for (cp = upper; *cp != '\0'; ++cp)
266     if (iscntrl (*cp))
267       FAIL ("iscntrl ('%c') is true", *cp);
268   for (cp = digits; *cp != '\0'; ++cp)
269     if (iscntrl (*cp))
270       FAIL ("iscntrl ('%c') is true", *cp);
271   for (cp = cntrl; *cp != '\0'; ++cp)
272     if ((iscntrl (*cp) && *cp == ' ')
273         || (! iscntrl (*cp) && *cp != ' '))
274       FAIL ("iscntrl ('\\x%02x') not true", *cp);
275
276   puts ("    ispunct()");
277   for (cp = lower; *cp != '\0'; ++cp)
278     if (ispunct (*cp))
279       FAIL ("ispunct ('%c') is true", *cp);
280   for (cp = upper; *cp != '\0'; ++cp)
281     if (ispunct (*cp))
282       FAIL ("ispunct ('%c') is true", *cp);
283   for (cp = digits; *cp != '\0'; ++cp)
284     if (ispunct (*cp))
285       FAIL ("ispunct ('%c') is true", *cp);
286   for (cp = cntrl; *cp != '\0'; ++cp)
287     if (ispunct (*cp))
288       FAIL ("ispunct ('\\x%02x') is true", *cp);
289
290   puts ("    isalnum()");
291   for (cp = lower; *cp != '\0'; ++cp)
292     if (! isalnum (*cp))
293       FAIL ("isalnum ('%c') not true", *cp);
294   for (cp = upper; *cp != '\0'; ++cp)
295     if (! isalnum (*cp))
296       FAIL ("isalnum ('%c') not true", *cp);
297   for (cp = digits; *cp != '\0'; ++cp)
298     if (! isalnum (*cp))
299       FAIL ("isalnum ('%c') not true", *cp);
300   for (cp = cntrl; *cp != '\0'; ++cp)
301     if (isalnum (*cp))
302       FAIL ("isalnum ('\\x%02x') is true", *cp);
303
304
305   puts ("    tolower()");
306   for (cp = lower; *cp != '\0'; ++cp)
307     if (tolower (*cp) != *cp)
308       FAIL ("tolower ('%c') != '%c'", *cp, *cp);
309   for (cp = upper, cp2 = lower; *cp != '\0'; ++cp, ++cp2)
310     if (tolower (*cp) != *cp2)
311       FAIL ("tolower ('%c') != '%c'", *cp, *cp2);
312   for (cp = digits; *cp != '\0'; ++cp)
313     if (tolower (*cp) != *cp)
314       FAIL ("tolower ('%c') != '%c'", *cp, *cp);
315   for (cp = cntrl; *cp != '\0'; ++cp)
316     if (tolower (*cp) != *cp)
317       FAIL ("tolower ('\\x%02x') != '\\x%02x'", *cp, *cp);
318
319   puts ("    toupper()");
320   for (cp = lower, cp2 = upper; *cp != '\0'; ++cp, ++cp2)
321     if (toupper (*cp) != *cp2)
322       FAIL ("toupper ('%c') != '%c'", *cp, *cp2);
323   for (cp = upper; *cp != '\0'; ++cp)
324     if (toupper (*cp) != *cp)
325       FAIL ("toupper ('%c') != '%c'", *cp, *cp);
326   for (cp = digits; *cp != '\0'; ++cp)
327     if (toupper (*cp) != *cp)
328       FAIL ("toupper ('%c') != '%c'", *cp, *cp);
329   for (cp = cntrl; *cp != '\0'; ++cp)
330     if (toupper (*cp) != *cp)
331       FAIL ("toupper ('\\x%02x') != '\\x%02x'", *cp, *cp);
332
333
334   /* Now some locale specific tests.  */
335   while (! feof (stdin))
336     {
337       unsigned char *inp;
338       unsigned char *resp;
339
340       if (getline (&inpline, &inplinelen, stdin) <= 0
341           || getline (&resline, &reslinelen, stdin) <= 0)
342         break;
343
344       inp = strchr (inpline, '\n');
345       if (inp != NULL)
346         *inp = '\0';
347       resp = strchr (resline, '\n');
348       if (resp != NULL)
349         *resp = '\0';
350
351       inp = inpline;
352       while (*inp != ' ' && *inp != '\t' && *inp && *inp != '\n'
353              && *inp != '\0')
354         ++inp;
355
356       if (*inp == '\0')
357         {
358           printf ("line \"%s\" is without content\n", inpline);
359           continue;
360         }
361       *inp++ = '\0';
362       while (*inp == ' ' || *inp == '\t')
363         ++inp;
364
365       /* Try all classes.  */
366       for (n = 0; n < nclasses; ++n)
367         if (strcmp (inpline, classes[n].name) == 0)
368           break;
369
370       resp = resline;
371       while (*resp == ' ' || *resp == '\t')
372         ++resp;
373
374       if (strlen (inp) != strlen (resp))
375         {
376           printf ("lines \"%.20s\"... and \"%.20s\" have not the same length\n",
377                   inp, resp);
378           continue;
379         }
380
381       if (n < nclasses)
382         {
383           if (strspn (resp, "01") != strlen (resp))
384             {
385               printf ("result string \"%s\" malformed\n", resp);
386               continue;
387             }
388
389           printf ("  Locale-specific tests for `%s'\n", inpline);
390
391           while (*inp != '\0' && *inp != '\n')
392             {
393               if (((__ctype_b[(unsigned int) *inp] & classes[n].mask) != 0)
394                   != (*resp != '0'))
395                 {
396                   printf ("    is%s('%c' = '\\x%02x') %s true\n", inpline,
397                           *inp, *inp, *resp == '1' ? "not" : "is");
398                   ++errors;
399                 }
400               ++inp;
401               ++resp;
402             }
403         }
404       else if (strcmp (inpline, "tolower") == 0)
405         {
406           while (*inp != '\0')
407             {
408               if (tolower (*inp) != *resp)
409                 {
410                   printf ("    tolower('%c' = '\\x%02x') != '%c'\n",
411                           *inp, *inp, *resp);
412                   ++errors;
413                 }
414               ++inp;
415               ++resp;
416             }
417         }
418       else if (strcmp (inpline, "toupper") == 0)
419         {
420           while (*inp != '\0')
421             {
422               if (toupper (*inp) != *resp)
423                 {
424                   printf ("    toupper('%c' = '\\x%02x') != '%c'\n",
425                           *inp, *inp, *resp);
426                   ++errors;
427                 }
428               ++inp;
429               ++resp;
430             }
431         }
432       else
433         printf ("\"%s\": unknown class or map\n", inpline);
434     }
435
436
437   if (errors != 0)
438     {
439       printf ("  %d error%s for `%s' locale\n\n\n", errors,
440               errors == 1 ? "" : "s", setlocale (LC_ALL, NULL));
441       return 1;
442     }
443
444   printf ("  No errors for `%s' locale\n\n\n", setlocale (LC_ALL, NULL));
445   return 0;
446 }