Serenity Operating System
1/*
2 * Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <LibTest/TestCase.h>
8
9#include <ctype.h>
10
11// https://open-std.org/JTC1/SC22/WG14/www/docs/n2912.pdf
12// Section 7.4.1 Character classification functions
13
14// 7.4.1.1 The isalnum function
15// The isalnum function tests for any character for which isalpha or isdigit is true.
16TEST_CASE(test_isalnum)
17{
18 for (int i = 0; i < 256; ++i) {
19 if ((i >= '0' && i <= '9') || (i >= 'A' && i <= 'Z') || (i >= 'a' && i <= 'z'))
20 EXPECT_NE(isalnum(i), 0);
21 else
22 EXPECT_EQ(isalnum(i), 0);
23 }
24}
25
26// 7.4.1.2 The isalpha function
27// The isalpha function tests for any character for which isupper or islower is true, or any character
28// that is one of a locale-specific set of alphabetic characters for which none of iscntrl, isdigit,
29// ispunct, or isspace is true. In the "C" locale, isalpha returns true only for the characters for
30// which isupper or islower is true.
31TEST_CASE(test_isalpha)
32{
33 for (int i = 0; i < 256; ++i) {
34 if ((i >= 'A' && i <= 'Z') || (i >= 'a' && i <= 'z'))
35 EXPECT_NE(isalpha(i), 0);
36 else
37 EXPECT_EQ(isalpha(i), 0);
38 }
39}
40
41// 7.4.1.3 The isblank function
42// The isblank function tests for any character that is a standard blank character or is one of a locale-
43// specific set of characters for which isspace is true and that is used to separate words within a line
44// of text. The standard blank characters are the following: space (’ ’ ), and horizontal tab (’\t’ ). In
45// the "C" locale, isblank returns true only for the standard blank characters.
46TEST_CASE(test_isblank)
47{
48 for (int i = 0; i < 256; ++i) {
49 if ((i == ' ') || (i == '\t'))
50 EXPECT_NE(isblank(i), 0);
51 else
52 EXPECT_EQ(isblank(i), 0);
53 }
54}
55
56// 7.4.1.4 The iscntrl function
57// The iscntrl function tests for any control character
58TEST_CASE(test_iscntrl)
59{
60 for (int i = 0; i < 256; ++i) {
61 if ((i < ' ') || (i == '\x7F')) // 7F is DEL
62 EXPECT_NE(iscntrl(i), 0);
63 else
64 EXPECT_EQ(iscntrl(i), 0);
65 }
66}
67
68// 7.4.1.5 The isdigit function
69// The isdigit function tests for any decimal-digit character (as defined in 5.2.1)
70TEST_CASE(test_isdigit)
71{
72 for (int i = 0; i < 256; ++i) {
73 if ((i >= '0' && i <= '9'))
74 EXPECT_NE(isdigit(i), 0);
75 else
76 EXPECT_EQ(isdigit(i), 0);
77 }
78}
79
80// 7.4.1.6 The isgraph function
81// The isgraph function tests for any printing character except space (’ ’).
82TEST_CASE(test_isgraph)
83{
84 for (int i = 0; i < 256; ++i) {
85 if ((i > ' ' && i <= '~'))
86 EXPECT_NE(isgraph(i), 0);
87 else
88 EXPECT_EQ(isgraph(i), 0);
89 }
90}
91
92// 7.4.1.7 The islower function
93// The islower function tests for any character that is a lowercase letter or is one of a locale-specific set
94// of characters for which none of iscntrl, isdigit, ispunct, or isspace is true. In the "C" locale,
95// islower returns true only for the lowercase letters (as defined in 5.2.1
96TEST_CASE(test_islower)
97{
98 for (int i = 0; i < 256; ++i) {
99 if ((i >= 'a' && i <= 'z'))
100 EXPECT_NE(islower(i), 0);
101 else
102 EXPECT_EQ(islower(i), 0);
103 }
104}
105
106// 7.4.1.8 The isprint function
107// The isprint function tests for any printing character including space (’ ’).
108TEST_CASE(test_isprint)
109{
110 for (int i = 0; i < 256; ++i) {
111 if ((i >= ' ' && i <= '~'))
112 EXPECT_NE(isprint(i), 0);
113 else
114 EXPECT_EQ(isprint(i), 0);
115 }
116}
117
118// 7.4.1.9 The ispunct function
119// The ispunct function tests for any printing character that is one of a locale-specific set of punctuation
120// characters for which neither isspace nor isalnum is true. In the "C" locale, ispunct returns true
121// for every printing character for which neither isspace nor isalnum is true
122TEST_CASE(test_ispunct)
123{
124 for (int i = 0; i < 256; ++i) {
125 if ((i > ' ' && i < '0') || (i > '9' && i < 'A') || (i > 'Z' && i < 'a') || (i > 'z' && i < '\x7F'))
126 EXPECT_NE(ispunct(i), 0);
127 else
128 EXPECT_EQ(ispunct(i), 0);
129 }
130}
131
132// 7.4.1.10 The isspace function
133// The isspace function tests for any character that is a standard white-space character or is one of
134// a locale-specific set of characters for which isalnum is false. The standard white-space characters
135// are the following: space (’ ’ ), form feed (’\f’ ), new-line (’\n’ ), carriage return (’\r’ ), horizontal
136// tab (’\t’ ), and vertical tab (’\v’ ). In the "C" locale, isspace returns true only for the standard
137// white-space characters.
138TEST_CASE(test_isspace)
139{
140 for (int i = 0; i < 256; ++i) {
141 if ((i == ' ') || (i == '\f') || (i == '\n') || (i == '\r') || (i == '\t') || (i == '\v'))
142 EXPECT_NE(isspace(i), 0);
143 else
144 EXPECT_EQ(isspace(i), 0);
145 }
146}
147
148// 7.4.1.11 The isupper function
149// The isupper function tests for any character that is an uppercase letter or is one of a locale-specific
150// set of characters for which none of iscntrl, isdigit, ispunct, or isspace is true. In the "C" locale,
151// isupper returns true only for the uppercase letters (as defined in 5.2.1)
152TEST_CASE(test_isupper)
153{
154 for (int i = 0; i < 256; ++i) {
155 if ((i >= 'A' && i <= 'Z'))
156 EXPECT_NE(isupper(i), 0);
157 else
158 EXPECT_EQ(isupper(i), 0);
159 }
160}
161
162// 7.4.1.12 The isxdigit function
163// The isxdigit function tests for any hexadecimal-digit character (as defined in 6.4.4.1).
164TEST_CASE(test_isxdigit)
165{
166 for (int i = 0; i < 256; ++i) {
167 if ((i >= '0' && i <= '9') || (i >= 'A' && i <= 'F') || (i >= 'a' && i <= 'f'))
168 EXPECT_NE(isxdigit(i), 0);
169 else
170 EXPECT_EQ(isxdigit(i), 0);
171 }
172}
173
174// 7.4.2.1 The tolower function
175// The tolower function converts an uppercase letter to a corresponding lowercase letter
176TEST_CASE(test_tolower)
177{
178 for (int i = 0; i < 256; ++i) {
179 if ((i >= 'A' && i <= 'Z'))
180 EXPECT_EQ(tolower(i), i + 0x20);
181 else
182 EXPECT_EQ(tolower(i), i);
183 }
184}
185
186// 7.4.2.2 The toupper function
187// The toupper function converts an lowercase letter to a corresponding uppercase letter
188TEST_CASE(test_toupper)
189{
190 for (int i = 0; i < 256; ++i) {
191 if ((i >= 'a' && i <= 'z'))
192 EXPECT_EQ(toupper(i), i - 0x20);
193 else
194 EXPECT_EQ(toupper(i), i);
195 }
196}