]> git.ipfire.org Git - thirdparty/util-linux.git/blob - include/cctype.h
Merge branch 'lsfd--bpf-name#in-flight' of https://github.com/masatake/util-linux
[thirdparty/util-linux.git] / include / cctype.h
1 /* Character handling in C locale.
2
3 These functions work like the corresponding functions in <ctype.h>,
4 except that they have the C (POSIX) locale hardwired, whereas the
5 <ctype.h> functions' behaviour depends on the current locale set via
6 setlocale.
7
8 Copyright (C) 2000-2003, 2006, 2008-2023 Free Software Foundation, Inc.
9
10 This file is free software: you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as
12 published by the Free Software Foundation; either version 2.1 of the
13 License, or (at your option) any later version.
14
15 This file is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public License
21 along with this program. If not, see <https://www.gnu.org/licenses/>. */
22
23 #ifndef UTIL_LINUX_CCTYPE_H
24 #define UTIL_LINUX_CCTYPE_H
25
26 /**
27 * The functions defined in this file assume the "C" locale and a character
28 * set without diacritics (ASCII-US or EBCDIC-US or something like that).
29 * Even if the "C" locale on a particular system is an extension of the ASCII
30 * character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it
31 * is ISO-8859-1), the functions in this file recognize only the ASCII
32 * characters.
33 */
34
35 #if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
36 && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
37 && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
38 && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
39 && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
40 && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
41 && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
42 && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
43 && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
44 && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
45 && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
46 && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
47 && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
48 && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
49 && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
50 && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
51 && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
52 && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
53 && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
54 && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
55 && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
56 && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
57 && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
58
59 /*
60 * The character set is ASCII or one of its variants or extensions, not EBCDIC.
61 * Testing the value of '\n' and '\r' is not relevant.
62 */
63 # define C_CTYPE_ASCII 1
64 #elif ! (' ' == '\x40' && '0' == '\xf0' \
65 && 'A' == '\xc1' && 'J' == '\xd1' && 'S' == '\xe2' \
66 && 'a' == '\x81' && 'j' == '\x91' && 's' == '\xa2')
67 # error "Only ASCII and EBCDIC are supported"
68 #endif
69
70 #if 'A' < 0
71 # error "EBCDIC and char is signed -- not supported"
72 #endif
73
74 /* Cases for control characters. */
75 #define _C_CTYPE_CNTRL \
76 case '\a': case '\b': case '\f': case '\n': \
77 case '\r': case '\t': case '\v': \
78 _C_CTYPE_OTHER_CNTRL
79
80 /* ASCII control characters other than those with \-letter escapes. */
81 #if C_CTYPE_ASCII
82 # define _C_CTYPE_OTHER_CNTRL \
83 case '\x00': case '\x01': case '\x02': case '\x03': \
84 case '\x04': case '\x05': case '\x06': case '\x0e': \
85 case '\x0f': case '\x10': case '\x11': case '\x12': \
86 case '\x13': case '\x14': case '\x15': case '\x16': \
87 case '\x17': case '\x18': case '\x19': case '\x1a': \
88 case '\x1b': case '\x1c': case '\x1d': case '\x1e': \
89 case '\x1f': case '\x7f'
90 #else
91
92 /*
93 * Use EBCDIC code page 1047's assignments for ASCII control chars;
94 * assume all EBCDIC code pages agree about these assignments.
95 */
96 # define _C_CTYPE_OTHER_CNTRL \
97 case '\x00': case '\x01': case '\x02': case '\x03': \
98 case '\x07': case '\x0e': case '\x0f': case '\x10': \
99 case '\x11': case '\x12': case '\x13': case '\x18': \
100 case '\x19': case '\x1c': case '\x1d': case '\x1e': \
101 case '\x1f': case '\x26': case '\x27': case '\x2d': \
102 case '\x2e': case '\x32': case '\x37': case '\x3c': \
103 case '\x3d': case '\x3f'
104 #endif
105
106 /* Cases for lowercase hex letters, and lowercase letters, all offset by N. */
107 #define _C_CTYPE_LOWER_A_THRU_F_N(N) \
108 case 'a' + (N): case 'b' + (N): case 'c' + (N): case 'd' + (N): \
109 case 'e' + (N): case 'f' + (N)
110 #define _C_CTYPE_LOWER_N(N) \
111 _C_CTYPE_LOWER_A_THRU_F_N(N): \
112 case 'g' + (N): case 'h' + (N): case 'i' + (N): case 'j' + (N): \
113 case 'k' + (N): case 'l' + (N): case 'm' + (N): case 'n' + (N): \
114 case 'o' + (N): case 'p' + (N): case 'q' + (N): case 'r' + (N): \
115 case 's' + (N): case 't' + (N): case 'u' + (N): case 'v' + (N): \
116 case 'w' + (N): case 'x' + (N): case 'y' + (N): case 'z' + (N)
117
118 /* Cases for hex letters, digits, lower, punct, and upper. */
119 #define _C_CTYPE_A_THRU_F \
120 _C_CTYPE_LOWER_A_THRU_F_N (0): \
121 _C_CTYPE_LOWER_A_THRU_F_N ('A' - 'a')
122 #define _C_CTYPE_DIGIT \
123 case '0': case '1': case '2': case '3': \
124 case '4': case '5': case '6': case '7': \
125 case '8': case '9'
126 #define _C_CTYPE_LOWER _C_CTYPE_LOWER_N (0)
127 #define _C_CTYPE_PUNCT \
128 case '!': case '"': case '#': case '$': \
129 case '%': case '&': case '\'': case '(': \
130 case ')': case '*': case '+': case ',': \
131 case '-': case '.': case '/': case ':': \
132 case ';': case '<': case '=': case '>': \
133 case '?': case '@': case '[': case '\\': \
134 case ']': case '^': case '_': case '`': \
135 case '{': case '|': case '}': case '~'
136 #define _C_CTYPE_UPPER _C_CTYPE_LOWER_N ('A' - 'a')
137
138 /**
139 * Function definitions.
140 *
141 * Unlike the functions in <ctype.h>, which require an argument in the range
142 * of the 'unsigned char' type, the functions here operate on values that are
143 * in the 'unsigned char' range or in the 'char' range. In other words,
144 * when you have a 'char' value, you need to cast it before using it as
145 * argument to a <ctype.h> function:
146 *
147 * const char *s = ...;
148 * if (isalpha ((unsigned char) *s)) ...
149 *
150 * but you don't need to cast it for the functions defined in this file:
151 *
152 * const char *s = ...;
153 * if (c_isalpha (*s)) ...
154 */
155
156 static inline int c_isalnum (int c)
157 {
158 switch (c) {
159 _C_CTYPE_DIGIT:
160 _C_CTYPE_LOWER:
161 _C_CTYPE_UPPER:
162 return 1;
163 default:
164 return 0;
165 }
166 }
167
168 static inline int c_isalpha (int c)
169 {
170 switch (c) {
171 _C_CTYPE_LOWER:
172 _C_CTYPE_UPPER:
173 return 1;
174 default:
175 return 0;
176 }
177 }
178
179 /* The function isascii is not locale dependent.
180 * Its use in EBCDIC is questionable.
181 */
182 static inline int c_isascii (int c)
183 {
184 switch (c) {
185 case ' ':
186 _C_CTYPE_CNTRL:
187 _C_CTYPE_DIGIT:
188 _C_CTYPE_LOWER:
189 _C_CTYPE_PUNCT:
190 _C_CTYPE_UPPER:
191 return 1;
192 default:
193 return 0;
194 }
195 }
196
197 static inline int c_isblank (int c)
198 {
199 return c == ' ' || c == '\t';
200 }
201
202 static inline int c_iscntrl (int c)
203 {
204 switch (c) {
205 _C_CTYPE_CNTRL:
206 return 1;
207 default:
208 return 0;
209 }
210 }
211
212 static inline int c_isdigit (int c)
213 {
214 switch (c) {
215 _C_CTYPE_DIGIT:
216 return 1;
217 default:
218 return 0;
219 }
220 }
221
222 static inline int c_isgraph (int c)
223 {
224 switch (c) {
225 _C_CTYPE_DIGIT:
226 _C_CTYPE_LOWER:
227 _C_CTYPE_PUNCT:
228 _C_CTYPE_UPPER:
229 return 1;
230 default:
231 return 0;
232 }
233 }
234
235 static inline int c_islower (int c)
236 {
237 switch (c) {
238 _C_CTYPE_LOWER:
239 return 1;
240 default:
241 return 0;
242 }
243 }
244
245 static inline int c_isprint (int c)
246 {
247 switch (c) {
248 case ' ':
249 _C_CTYPE_DIGIT:
250 _C_CTYPE_LOWER:
251 _C_CTYPE_PUNCT:
252 _C_CTYPE_UPPER:
253 return 1;
254 default:
255 return 0;
256 }
257 }
258
259 static inline int c_ispunct (int c)
260 {
261 switch (c) {
262 _C_CTYPE_PUNCT:
263 return 1;
264 default:
265 return 0;
266 }
267 }
268
269 static inline int c_isspace (int c)
270 {
271 switch (c) {
272 case ' ': case '\t': case '\n': case '\v': case '\f': case '\r':
273 return 1;
274 default:
275 return 0;
276 }
277 }
278
279 static inline int c_isupper (int c)
280 {
281 switch (c) {
282 _C_CTYPE_UPPER:
283 return 1;
284 default:
285 return 0;
286 }
287 }
288
289 static inline int c_isxdigit (int c)
290 {
291 switch (c) {
292 _C_CTYPE_DIGIT:
293 _C_CTYPE_A_THRU_F:
294 return 1;
295 default:
296 return 0;
297 }
298 }
299
300 static inline int c_tolower (int c)
301 {
302 switch (c) {
303 _C_CTYPE_UPPER:
304 return c - 'A' + 'a';
305 default:
306 return c;
307 }
308 }
309
310 static inline int c_toupper (int c)
311 {
312 switch (c) {
313 _C_CTYPE_LOWER:
314 return c - 'a' + 'A';
315 default:
316 return c;
317 }
318 }
319
320 static inline int c_strncasecmp(const char *a, const char *b, size_t n)
321 {
322 int res = 0;
323
324 for (; n > 0; a++, b++, n--) {
325 unsigned int x = (unsigned int) *a;
326 unsigned int y = (unsigned int) *b;
327
328 res = c_tolower(x) - c_tolower(y);
329 if (res)
330 break;
331 }
332 return res;
333 }
334
335 static inline int c_strcasecmp(const char *a, const char *b)
336 {
337 int res = 0;
338
339 if (a == b)
340 return 0;
341
342 for (; *a != '\0'; a++, b++) {
343 unsigned int x = (unsigned int) *a;
344 unsigned int y = (unsigned int) *b;
345
346 res = c_tolower(x) - c_tolower(y);
347 if (res)
348 break;
349 }
350
351 return res;
352 }
353
354 #endif /* UTIL_LINUX_CCTYPE_H */