1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
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:
87:
88:
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:
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 = (unsigned char *) strchr (inpline, '\n');
349: if (inp != NULL)
350: *inp = '\0';
351: resp = (unsigned char *) strchr (resline, '\n');
352: if (resp != NULL)
353: *resp = '\0';
354:
355: inp = (unsigned char *) 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:
370: for (n = 0; n < nclasses; ++n)
371: if (strcmp (inpline, classes[n].name) == 0)
372: break;
373:
374: resp = (unsigned char *) resline;
375: while (*resp == ' ' || *resp == '\t')
376: ++resp;
377:
378: if (strlen ((char *) inp) != strlen ((char *) 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 ((char *) resp, "01") != strlen ((char *) 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: }