195b7b453SJohn Marino /* Character handling in C locale.
295b7b453SJohn Marino
395b7b453SJohn Marino These functions work like the corresponding functions in <ctype.h>,
495b7b453SJohn Marino except that they have the C (POSIX) locale hardwired, whereas the
595b7b453SJohn Marino <ctype.h> functions' behaviour depends on the current locale set via
695b7b453SJohn Marino setlocale.
795b7b453SJohn Marino
8*09d4459fSDaniel Fojt Copyright (C) 2000-2003, 2006, 2008-2020 Free Software Foundation, Inc.
995b7b453SJohn Marino
1095b7b453SJohn Marino This program is free software; you can redistribute it and/or modify
1195b7b453SJohn Marino it under the terms of the GNU General Public License as published by
1295b7b453SJohn Marino the Free Software Foundation; either version 3 of the License, or
1395b7b453SJohn Marino (at your option) any later version.
1495b7b453SJohn Marino
1595b7b453SJohn Marino This program is distributed in the hope that it will be useful,
1695b7b453SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
1795b7b453SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1895b7b453SJohn Marino GNU General Public License for more details.
1995b7b453SJohn Marino
2095b7b453SJohn Marino You should have received a copy of the GNU General Public License
21*09d4459fSDaniel Fojt along with this program; if not, see <https://www.gnu.org/licenses/>. */
2295b7b453SJohn Marino
2395b7b453SJohn Marino #ifndef C_CTYPE_H
2495b7b453SJohn Marino #define C_CTYPE_H
2595b7b453SJohn Marino
2695b7b453SJohn Marino #include <stdbool.h>
2795b7b453SJohn Marino
28dc7c36e4SJohn Marino #ifndef _GL_INLINE_HEADER_BEGIN
29dc7c36e4SJohn Marino #error "Please include config.h first."
30dc7c36e4SJohn Marino #endif
31dc7c36e4SJohn Marino _GL_INLINE_HEADER_BEGIN
32dc7c36e4SJohn Marino #ifndef C_CTYPE_INLINE
33dc7c36e4SJohn Marino # define C_CTYPE_INLINE _GL_INLINE
34dc7c36e4SJohn Marino #endif
3595b7b453SJohn Marino
3695b7b453SJohn Marino #ifdef __cplusplus
3795b7b453SJohn Marino extern "C" {
3895b7b453SJohn Marino #endif
3995b7b453SJohn Marino
4095b7b453SJohn Marino
4195b7b453SJohn Marino /* The functions defined in this file assume the "C" locale and a character
4295b7b453SJohn Marino set without diacritics (ASCII-US or EBCDIC-US or something like that).
4395b7b453SJohn Marino Even if the "C" locale on a particular system is an extension of the ASCII
4495b7b453SJohn Marino character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it
4595b7b453SJohn Marino is ISO-8859-1), the functions in this file recognize only the ASCII
4695b7b453SJohn Marino characters. */
4795b7b453SJohn Marino
4895b7b453SJohn Marino
4995b7b453SJohn Marino #if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
5095b7b453SJohn Marino && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
5195b7b453SJohn Marino && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
5295b7b453SJohn Marino && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
5395b7b453SJohn Marino && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
5495b7b453SJohn Marino && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
5595b7b453SJohn Marino && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
5695b7b453SJohn Marino && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
5795b7b453SJohn Marino && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
5895b7b453SJohn Marino && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
5995b7b453SJohn Marino && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
6095b7b453SJohn Marino && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
6195b7b453SJohn Marino && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
6295b7b453SJohn Marino && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
6395b7b453SJohn Marino && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
6495b7b453SJohn Marino && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
6595b7b453SJohn Marino && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
6695b7b453SJohn Marino && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
6795b7b453SJohn Marino && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
6895b7b453SJohn Marino && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
6995b7b453SJohn Marino && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
7095b7b453SJohn Marino && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
7195b7b453SJohn Marino && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
7295b7b453SJohn Marino /* The character set is ASCII or one of its variants or extensions, not EBCDIC.
7395b7b453SJohn Marino Testing the value of '\n' and '\r' is not relevant. */
7495b7b453SJohn Marino # define C_CTYPE_ASCII 1
75dc7c36e4SJohn Marino #elif ! (' ' == '\x40' && '0' == '\xf0' \
76dc7c36e4SJohn Marino && 'A' == '\xc1' && 'J' == '\xd1' && 'S' == '\xe2' \
77dc7c36e4SJohn Marino && 'a' == '\x81' && 'j' == '\x91' && 's' == '\xa2')
78dc7c36e4SJohn Marino # error "Only ASCII and EBCDIC are supported"
7995b7b453SJohn Marino #endif
8095b7b453SJohn Marino
81dc7c36e4SJohn Marino #if 'A' < 0
82dc7c36e4SJohn Marino # error "EBCDIC and char is signed -- not supported"
83dc7c36e4SJohn Marino #endif
8495b7b453SJohn Marino
85dc7c36e4SJohn Marino /* Cases for control characters. */
86dc7c36e4SJohn Marino
87dc7c36e4SJohn Marino #define _C_CTYPE_CNTRL \
88dc7c36e4SJohn Marino case '\a': case '\b': case '\f': case '\n': \
89dc7c36e4SJohn Marino case '\r': case '\t': case '\v': \
90dc7c36e4SJohn Marino _C_CTYPE_OTHER_CNTRL
91dc7c36e4SJohn Marino
92dc7c36e4SJohn Marino /* ASCII control characters other than those with \-letter escapes. */
93dc7c36e4SJohn Marino
94dc7c36e4SJohn Marino #if C_CTYPE_ASCII
95dc7c36e4SJohn Marino # define _C_CTYPE_OTHER_CNTRL \
96dc7c36e4SJohn Marino case '\x00': case '\x01': case '\x02': case '\x03': \
97dc7c36e4SJohn Marino case '\x04': case '\x05': case '\x06': case '\x0e': \
98dc7c36e4SJohn Marino case '\x0f': case '\x10': case '\x11': case '\x12': \
99dc7c36e4SJohn Marino case '\x13': case '\x14': case '\x15': case '\x16': \
100dc7c36e4SJohn Marino case '\x17': case '\x18': case '\x19': case '\x1a': \
101dc7c36e4SJohn Marino case '\x1b': case '\x1c': case '\x1d': case '\x1e': \
102dc7c36e4SJohn Marino case '\x1f': case '\x7f'
103dc7c36e4SJohn Marino #else
104dc7c36e4SJohn Marino /* Use EBCDIC code page 1047's assignments for ASCII control chars;
105dc7c36e4SJohn Marino assume all EBCDIC code pages agree about these assignments. */
106dc7c36e4SJohn Marino # define _C_CTYPE_OTHER_CNTRL \
107dc7c36e4SJohn Marino case '\x00': case '\x01': case '\x02': case '\x03': \
108dc7c36e4SJohn Marino case '\x07': case '\x0e': case '\x0f': case '\x10': \
109dc7c36e4SJohn Marino case '\x11': case '\x12': case '\x13': case '\x18': \
110dc7c36e4SJohn Marino case '\x19': case '\x1c': case '\x1d': case '\x1e': \
111dc7c36e4SJohn Marino case '\x1f': case '\x26': case '\x27': case '\x2d': \
112dc7c36e4SJohn Marino case '\x2e': case '\x32': case '\x37': case '\x3c': \
113dc7c36e4SJohn Marino case '\x3d': case '\x3f'
114dc7c36e4SJohn Marino #endif
115dc7c36e4SJohn Marino
116dc7c36e4SJohn Marino /* Cases for lowercase hex letters, and lowercase letters, all offset by N. */
117dc7c36e4SJohn Marino
118*09d4459fSDaniel Fojt #define _C_CTYPE_LOWER_A_THRU_F_N(N) \
119*09d4459fSDaniel Fojt case 'a' + (N): case 'b' + (N): case 'c' + (N): case 'd' + (N): \
120*09d4459fSDaniel Fojt case 'e' + (N): case 'f' + (N)
121*09d4459fSDaniel Fojt #define _C_CTYPE_LOWER_N(N) \
122*09d4459fSDaniel Fojt _C_CTYPE_LOWER_A_THRU_F_N(N): \
123*09d4459fSDaniel Fojt case 'g' + (N): case 'h' + (N): case 'i' + (N): case 'j' + (N): \
124*09d4459fSDaniel Fojt case 'k' + (N): case 'l' + (N): case 'm' + (N): case 'n' + (N): \
125*09d4459fSDaniel Fojt case 'o' + (N): case 'p' + (N): case 'q' + (N): case 'r' + (N): \
126*09d4459fSDaniel Fojt case 's' + (N): case 't' + (N): case 'u' + (N): case 'v' + (N): \
127*09d4459fSDaniel Fojt case 'w' + (N): case 'x' + (N): case 'y' + (N): case 'z' + (N)
128dc7c36e4SJohn Marino
129dc7c36e4SJohn Marino /* Cases for hex letters, digits, lower, punct, and upper. */
130dc7c36e4SJohn Marino
131dc7c36e4SJohn Marino #define _C_CTYPE_A_THRU_F \
132dc7c36e4SJohn Marino _C_CTYPE_LOWER_A_THRU_F_N (0): \
133dc7c36e4SJohn Marino _C_CTYPE_LOWER_A_THRU_F_N ('A' - 'a')
134dc7c36e4SJohn Marino #define _C_CTYPE_DIGIT \
135dc7c36e4SJohn Marino case '0': case '1': case '2': case '3': \
136dc7c36e4SJohn Marino case '4': case '5': case '6': case '7': \
137dc7c36e4SJohn Marino case '8': case '9'
138dc7c36e4SJohn Marino #define _C_CTYPE_LOWER _C_CTYPE_LOWER_N (0)
139dc7c36e4SJohn Marino #define _C_CTYPE_PUNCT \
140dc7c36e4SJohn Marino case '!': case '"': case '#': case '$': \
141dc7c36e4SJohn Marino case '%': case '&': case '\'': case '(': \
142dc7c36e4SJohn Marino case ')': case '*': case '+': case ',': \
143dc7c36e4SJohn Marino case '-': case '.': case '/': case ':': \
144dc7c36e4SJohn Marino case ';': case '<': case '=': case '>': \
145dc7c36e4SJohn Marino case '?': case '@': case '[': case '\\': \
146dc7c36e4SJohn Marino case ']': case '^': case '_': case '`': \
147dc7c36e4SJohn Marino case '{': case '|': case '}': case '~'
148dc7c36e4SJohn Marino #define _C_CTYPE_UPPER _C_CTYPE_LOWER_N ('A' - 'a')
149dc7c36e4SJohn Marino
150dc7c36e4SJohn Marino
151dc7c36e4SJohn Marino /* Function definitions. */
15295b7b453SJohn Marino
15395b7b453SJohn Marino /* Unlike the functions in <ctype.h>, which require an argument in the range
15495b7b453SJohn Marino of the 'unsigned char' type, the functions here operate on values that are
15595b7b453SJohn Marino in the 'unsigned char' range or in the 'char' range. In other words,
15695b7b453SJohn Marino when you have a 'char' value, you need to cast it before using it as
15795b7b453SJohn Marino argument to a <ctype.h> function:
15895b7b453SJohn Marino
15995b7b453SJohn Marino const char *s = ...;
16095b7b453SJohn Marino if (isalpha ((unsigned char) *s)) ...
16195b7b453SJohn Marino
16295b7b453SJohn Marino but you don't need to cast it for the functions defined in this file:
16395b7b453SJohn Marino
16495b7b453SJohn Marino const char *s = ...;
16595b7b453SJohn Marino if (c_isalpha (*s)) ...
16695b7b453SJohn Marino */
16795b7b453SJohn Marino
168dc7c36e4SJohn Marino C_CTYPE_INLINE bool
c_isalnum(int c)169dc7c36e4SJohn Marino c_isalnum (int c)
170dc7c36e4SJohn Marino {
171dc7c36e4SJohn Marino switch (c)
172dc7c36e4SJohn Marino {
173dc7c36e4SJohn Marino _C_CTYPE_DIGIT:
174dc7c36e4SJohn Marino _C_CTYPE_LOWER:
175dc7c36e4SJohn Marino _C_CTYPE_UPPER:
176dc7c36e4SJohn Marino return true;
177dc7c36e4SJohn Marino default:
178dc7c36e4SJohn Marino return false;
179dc7c36e4SJohn Marino }
180dc7c36e4SJohn Marino }
18195b7b453SJohn Marino
182dc7c36e4SJohn Marino C_CTYPE_INLINE bool
c_isalpha(int c)183dc7c36e4SJohn Marino c_isalpha (int c)
184dc7c36e4SJohn Marino {
185dc7c36e4SJohn Marino switch (c)
186dc7c36e4SJohn Marino {
187dc7c36e4SJohn Marino _C_CTYPE_LOWER:
188dc7c36e4SJohn Marino _C_CTYPE_UPPER:
189dc7c36e4SJohn Marino return true;
190dc7c36e4SJohn Marino default:
191dc7c36e4SJohn Marino return false;
192dc7c36e4SJohn Marino }
193dc7c36e4SJohn Marino }
19495b7b453SJohn Marino
195dc7c36e4SJohn Marino /* The function isascii is not locale dependent.
196dc7c36e4SJohn Marino Its use in EBCDIC is questionable. */
197dc7c36e4SJohn Marino C_CTYPE_INLINE bool
c_isascii(int c)198dc7c36e4SJohn Marino c_isascii (int c)
199dc7c36e4SJohn Marino {
200dc7c36e4SJohn Marino switch (c)
201dc7c36e4SJohn Marino {
202dc7c36e4SJohn Marino case ' ':
203dc7c36e4SJohn Marino _C_CTYPE_CNTRL:
204dc7c36e4SJohn Marino _C_CTYPE_DIGIT:
205dc7c36e4SJohn Marino _C_CTYPE_LOWER:
206dc7c36e4SJohn Marino _C_CTYPE_PUNCT:
207dc7c36e4SJohn Marino _C_CTYPE_UPPER:
208dc7c36e4SJohn Marino return true;
209dc7c36e4SJohn Marino default:
210dc7c36e4SJohn Marino return false;
211dc7c36e4SJohn Marino }
212dc7c36e4SJohn Marino }
21395b7b453SJohn Marino
214dc7c36e4SJohn Marino C_CTYPE_INLINE bool
c_isblank(int c)215dc7c36e4SJohn Marino c_isblank (int c)
216dc7c36e4SJohn Marino {
217dc7c36e4SJohn Marino return c == ' ' || c == '\t';
218dc7c36e4SJohn Marino }
21995b7b453SJohn Marino
220dc7c36e4SJohn Marino C_CTYPE_INLINE bool
c_iscntrl(int c)221dc7c36e4SJohn Marino c_iscntrl (int c)
222dc7c36e4SJohn Marino {
223dc7c36e4SJohn Marino switch (c)
224dc7c36e4SJohn Marino {
225dc7c36e4SJohn Marino _C_CTYPE_CNTRL:
226dc7c36e4SJohn Marino return true;
227dc7c36e4SJohn Marino default:
228dc7c36e4SJohn Marino return false;
229dc7c36e4SJohn Marino }
230dc7c36e4SJohn Marino }
23195b7b453SJohn Marino
232dc7c36e4SJohn Marino C_CTYPE_INLINE bool
c_isdigit(int c)233dc7c36e4SJohn Marino c_isdigit (int c)
234dc7c36e4SJohn Marino {
235dc7c36e4SJohn Marino switch (c)
236dc7c36e4SJohn Marino {
237dc7c36e4SJohn Marino _C_CTYPE_DIGIT:
238dc7c36e4SJohn Marino return true;
239dc7c36e4SJohn Marino default:
240dc7c36e4SJohn Marino return false;
241dc7c36e4SJohn Marino }
242dc7c36e4SJohn Marino }
24395b7b453SJohn Marino
244dc7c36e4SJohn Marino C_CTYPE_INLINE bool
c_isgraph(int c)245dc7c36e4SJohn Marino c_isgraph (int c)
246dc7c36e4SJohn Marino {
247dc7c36e4SJohn Marino switch (c)
248dc7c36e4SJohn Marino {
249dc7c36e4SJohn Marino _C_CTYPE_DIGIT:
250dc7c36e4SJohn Marino _C_CTYPE_LOWER:
251dc7c36e4SJohn Marino _C_CTYPE_PUNCT:
252dc7c36e4SJohn Marino _C_CTYPE_UPPER:
253dc7c36e4SJohn Marino return true;
254dc7c36e4SJohn Marino default:
255dc7c36e4SJohn Marino return false;
256dc7c36e4SJohn Marino }
257dc7c36e4SJohn Marino }
25895b7b453SJohn Marino
259dc7c36e4SJohn Marino C_CTYPE_INLINE bool
c_islower(int c)260dc7c36e4SJohn Marino c_islower (int c)
261dc7c36e4SJohn Marino {
262dc7c36e4SJohn Marino switch (c)
263dc7c36e4SJohn Marino {
264dc7c36e4SJohn Marino _C_CTYPE_LOWER:
265dc7c36e4SJohn Marino return true;
266dc7c36e4SJohn Marino default:
267dc7c36e4SJohn Marino return false;
268dc7c36e4SJohn Marino }
269dc7c36e4SJohn Marino }
27095b7b453SJohn Marino
271dc7c36e4SJohn Marino C_CTYPE_INLINE bool
c_isprint(int c)272dc7c36e4SJohn Marino c_isprint (int c)
273dc7c36e4SJohn Marino {
274dc7c36e4SJohn Marino switch (c)
275dc7c36e4SJohn Marino {
276dc7c36e4SJohn Marino case ' ':
277dc7c36e4SJohn Marino _C_CTYPE_DIGIT:
278dc7c36e4SJohn Marino _C_CTYPE_LOWER:
279dc7c36e4SJohn Marino _C_CTYPE_PUNCT:
280dc7c36e4SJohn Marino _C_CTYPE_UPPER:
281dc7c36e4SJohn Marino return true;
282dc7c36e4SJohn Marino default:
283dc7c36e4SJohn Marino return false;
284dc7c36e4SJohn Marino }
285dc7c36e4SJohn Marino }
28695b7b453SJohn Marino
287dc7c36e4SJohn Marino C_CTYPE_INLINE bool
c_ispunct(int c)288dc7c36e4SJohn Marino c_ispunct (int c)
289dc7c36e4SJohn Marino {
290dc7c36e4SJohn Marino switch (c)
291dc7c36e4SJohn Marino {
292dc7c36e4SJohn Marino _C_CTYPE_PUNCT:
293dc7c36e4SJohn Marino return true;
294dc7c36e4SJohn Marino default:
295dc7c36e4SJohn Marino return false;
296dc7c36e4SJohn Marino }
297dc7c36e4SJohn Marino }
29895b7b453SJohn Marino
299dc7c36e4SJohn Marino C_CTYPE_INLINE bool
c_isspace(int c)300dc7c36e4SJohn Marino c_isspace (int c)
301dc7c36e4SJohn Marino {
302dc7c36e4SJohn Marino switch (c)
303dc7c36e4SJohn Marino {
304dc7c36e4SJohn Marino case ' ': case '\t': case '\n': case '\v': case '\f': case '\r':
305dc7c36e4SJohn Marino return true;
306dc7c36e4SJohn Marino default:
307dc7c36e4SJohn Marino return false;
308dc7c36e4SJohn Marino }
309dc7c36e4SJohn Marino }
31095b7b453SJohn Marino
311dc7c36e4SJohn Marino C_CTYPE_INLINE bool
c_isupper(int c)312dc7c36e4SJohn Marino c_isupper (int c)
313dc7c36e4SJohn Marino {
314dc7c36e4SJohn Marino switch (c)
315dc7c36e4SJohn Marino {
316dc7c36e4SJohn Marino _C_CTYPE_UPPER:
317dc7c36e4SJohn Marino return true;
318dc7c36e4SJohn Marino default:
319dc7c36e4SJohn Marino return false;
320dc7c36e4SJohn Marino }
321dc7c36e4SJohn Marino }
32295b7b453SJohn Marino
323dc7c36e4SJohn Marino C_CTYPE_INLINE bool
c_isxdigit(int c)324dc7c36e4SJohn Marino c_isxdigit (int c)
325dc7c36e4SJohn Marino {
326dc7c36e4SJohn Marino switch (c)
327dc7c36e4SJohn Marino {
328dc7c36e4SJohn Marino _C_CTYPE_DIGIT:
329dc7c36e4SJohn Marino _C_CTYPE_A_THRU_F:
330dc7c36e4SJohn Marino return true;
331dc7c36e4SJohn Marino default:
332dc7c36e4SJohn Marino return false;
333dc7c36e4SJohn Marino }
334dc7c36e4SJohn Marino }
33595b7b453SJohn Marino
336dc7c36e4SJohn Marino C_CTYPE_INLINE int
c_tolower(int c)337dc7c36e4SJohn Marino c_tolower (int c)
338dc7c36e4SJohn Marino {
339dc7c36e4SJohn Marino switch (c)
340dc7c36e4SJohn Marino {
341dc7c36e4SJohn Marino _C_CTYPE_UPPER:
342dc7c36e4SJohn Marino return c - 'A' + 'a';
343dc7c36e4SJohn Marino default:
344dc7c36e4SJohn Marino return c;
345dc7c36e4SJohn Marino }
346dc7c36e4SJohn Marino }
34795b7b453SJohn Marino
348dc7c36e4SJohn Marino C_CTYPE_INLINE int
c_toupper(int c)349dc7c36e4SJohn Marino c_toupper (int c)
350dc7c36e4SJohn Marino {
351dc7c36e4SJohn Marino switch (c)
352dc7c36e4SJohn Marino {
353dc7c36e4SJohn Marino _C_CTYPE_LOWER:
354dc7c36e4SJohn Marino return c - 'a' + 'A';
355dc7c36e4SJohn Marino default:
356dc7c36e4SJohn Marino return c;
357dc7c36e4SJohn Marino }
358dc7c36e4SJohn Marino }
35995b7b453SJohn Marino
36095b7b453SJohn Marino #ifdef __cplusplus
36195b7b453SJohn Marino }
36295b7b453SJohn Marino #endif
36395b7b453SJohn Marino
364dc7c36e4SJohn Marino _GL_INLINE_HEADER_END
365dc7c36e4SJohn Marino
36695b7b453SJohn Marino #endif /* C_CTYPE_H */
367