1 /*
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright © 2024 Keith Packard
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 *
18 * 3. Neither the name of the copyright holder nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33 * OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 #include <stdio.h>
37 #include <ctype.h>
38 #include <stdbool.h>
39
40 /* Validate C locale ctype data */
41
42 #define boolname(b) ((b) ? "true" : "false")
43 #define iscat(name) is ## name
44 #define TEST(name) do { \
45 if (!!iscat(name)(c) != !!name) { \
46 printf("character %#2x '%c' is%s is %s should be %s\n", \
47 c, c, #name, boolname(iscat(name)(c)), boolname(name)); \
48 error = 1; \
49 } \
50 } while(0)
51
main(void)52 int main(void) {
53
54 int c;
55 int error = 0;
56
57 for (c = 0; c < 128; c++) {
58 /* Direct values */
59 bool blank = c == ' ' || c == '\t';
60 bool cntrl = c < ' ' || c >= 127;
61 bool digit = '0' <= c && c <= '9';
62 bool graph = ' ' < c && c < 127;
63 bool lower = 'a' <= c && c <= 'z';
64 bool print = ' ' <= c && c < 127;
65 bool space = c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v';
66 bool upper = 'A' <= c && c <= 'Z';
67 bool xdigit = ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F');
68
69 /* Derived values */
70 bool alpha = upper || lower;
71 bool alnum = alpha || digit;
72
73 bool punct = print && !space && !alnum;
74
75 TEST(alnum);
76 TEST(alpha);
77 TEST(blank);
78 TEST(cntrl);
79 TEST(digit);
80 TEST(graph);
81 TEST(lower);
82 TEST(print);
83 TEST(punct);
84 TEST(space);
85 TEST(upper);
86 TEST(xdigit);
87 }
88 return error;
89 }
90