OSDN Git Service

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