Sorting data for tr_TR.UTF-8 locale.
[kopensolaris-gnu/glibc.git] / localedata / tst-ctype.c
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.
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   const unsigned short int *__ctype_b;
77
78   setlocale (LC_ALL, "");
79
80   printf ("Testing the ctype data of the `%s' locale\n",
81           setlocale (LC_CTYPE, NULL));
82
83   __ctype_b = ((const unsigned short *) nl_langinfo (_NL_CTYPE_CLASS)) + 128;
84
85 #if 0
86   /* Just for debugging.  */
87
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);
96
97   while (n < 256)
98     {
99       if (n % 8 == 0)
100         printf ("%02x: ", n);
101       printf ("%04x%s", __ctype_b[n], (n + 1) % 8 == 0 ? "\n" : " ");
102       ++n;
103     }
104 #endif
105
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");
131
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);
145
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);
159
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);
173
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);
187
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);
203
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");
220
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);
235
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);
249
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");
264
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);
279
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);
293
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);
307
308
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);
322
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);
336
337
338   /* Now some locale specific tests.  */
339   while (! feof (stdin))
340     {
341       unsigned char *inp;
342       unsigned char *resp;
343
344       if (getline (&inpline, &inplinelen, stdin) <= 0
345           || getline (&resline, &reslinelen, stdin) <= 0)
346         break;
347
348       inp = strchr (inpline, '\n');
349       if (inp != NULL)
350         *inp = '\0';
351       resp = strchr (resline, '\n');
352       if (resp != NULL)
353         *resp = '\0';
354
355       inp = inpline;
356       while (*inp != ' ' && *inp != '\t' && *inp && *inp != '\n'
357              && *inp != '\0')
358         ++inp;
359
360       if (*inp == '\0')
361         {
362           printf ("line \"%s\" is without content\n", inpline);
363           continue;
364         }
365       *inp++ = '\0';
366       while (*inp == ' ' || *inp == '\t')
367         ++inp;
368
369       /* Try all classes.  */
370       for (n = 0; n < nclasses; ++n)
371         if (strcmp (inpline, classes[n].name) == 0)
372           break;
373
374       resp = resline;
375       while (*resp == ' ' || *resp == '\t')
376         ++resp;
377
378       if (strlen (inp) != strlen (resp))
379         {
380           printf ("lines \"%.20s\"... and \"%.20s\" have not the same length\n",
381                   inp, resp);
382           continue;
383         }
384
385       if (n < nclasses)
386         {
387           if (strspn (resp, "01") != strlen (resp))
388             {
389               printf ("result string \"%s\" malformed\n", resp);
390               continue;
391             }
392
393           printf ("  Locale-specific tests for `%s'\n", inpline);
394
395           while (*inp != '\0' && *inp != '\n')
396             {
397               if (((__ctype_b[(unsigned int) *inp] & classes[n].mask) != 0)
398                   != (*resp != '0'))
399                 {
400                   printf ("    is%s('%c' = '\\x%02x') %s true\n", inpline,
401                           *inp, *inp, *resp == '1' ? "not" : "is");
402                   ++errors;
403                 }
404               ++inp;
405               ++resp;
406             }
407         }
408       else if (strcmp (inpline, "tolower") == 0)
409         {
410           while (*inp != '\0')
411             {
412               if (tolower (*inp) != *resp)
413                 {
414                   printf ("    tolower('%c' = '\\x%02x') != '%c'\n",
415                           *inp, *inp, *resp);
416                   ++errors;
417                 }
418               ++inp;
419               ++resp;
420             }
421         }
422       else if (strcmp (inpline, "toupper") == 0)
423         {
424           while (*inp != '\0')
425             {
426               if (toupper (*inp) != *resp)
427                 {
428                   printf ("    toupper('%c' = '\\x%02x') != '%c'\n",
429                           *inp, *inp, *resp);
430                   ++errors;
431                 }
432               ++inp;
433               ++resp;
434             }
435         }
436       else
437         printf ("\"%s\": unknown class or map\n", inpline);
438     }
439
440
441   if (errors != 0)
442     {
443       printf ("  %d error%s for `%s' locale\n\n\n", errors,
444               errors == 1 ? "" : "s", setlocale (LC_ALL, NULL));
445       return 1;
446     }
447
448   printf ("  No errors for `%s' locale\n\n\n", setlocale (LC_ALL, NULL));
449   return 0;
450 }