Coverage Report

Created: 2026-01-13 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libidn2/gl/c-ctype.h
Line
Count
Source
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-2025 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 C_CTYPE_H
24
#define C_CTYPE_H
25
26
/* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE.  */
27
#if !_GL_CONFIG_H_INCLUDED
28
 #error "Please include config.h first."
29
#endif
30
31
_GL_INLINE_HEADER_BEGIN
32
#ifndef C_CTYPE_INLINE
33
# define C_CTYPE_INLINE _GL_INLINE
34
#endif
35
36
#ifdef __cplusplus
37
extern "C" {
38
#endif
39
40
41
/* The functions defined in this file assume the "C" locale and a character
42
   set without diacritics (ASCII-US or EBCDIC-US or something like that).
43
   Even if the "C" locale on a particular system is an extension of the ASCII
44
   character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it
45
   is ISO-8859-1), the functions in this file recognize only the ASCII
46
   characters.  */
47
48
49
#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
50
    && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
51
    && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
52
    && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
53
    && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
54
    && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
55
    && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
56
    && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
57
    && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
58
    && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
59
    && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
60
    && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
61
    && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
62
    && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
63
    && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
64
    && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
65
    && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
66
    && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
67
    && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
68
    && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
69
    && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
70
    && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
71
    && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
72
/* The character set is ASCII or one of its variants or extensions, not EBCDIC.
73
   Testing the value of '\n' and '\r' is not relevant.  */
74
# define C_CTYPE_ASCII 1
75
#elif ! (' ' == '\x40' && '0' == '\xf0'                     \
76
         && 'A' == '\xc1' && 'J' == '\xd1' && 'S' == '\xe2' \
77
         && 'a' == '\x81' && 'j' == '\x91' && 's' == '\xa2')
78
# error "Only ASCII and EBCDIC are supported"
79
#endif
80
81
#if 'A' < 0
82
# error "EBCDIC and char is signed -- not supported"
83
#endif
84
85
/* Cases for control characters.  */
86
87
#define _C_CTYPE_CNTRL \
88
0
   case '\a': case '\b': case '\f': case '\n': \
89
0
   case '\r': case '\t': case '\v': \
90
0
   _C_CTYPE_OTHER_CNTRL
91
92
/* ASCII control characters other than those with \-letter escapes.  */
93
94
#if C_CTYPE_ASCII
95
# define _C_CTYPE_OTHER_CNTRL \
96
0
    case '\x00': case '\x01': case '\x02': case '\x03': \
97
0
    case '\x04': case '\x05': case '\x06': case '\x0e': \
98
0
    case '\x0f': case '\x10': case '\x11': case '\x12': \
99
0
    case '\x13': case '\x14': case '\x15': case '\x16': \
100
0
    case '\x17': case '\x18': case '\x19': case '\x1a': \
101
0
    case '\x1b': case '\x1c': case '\x1d': case '\x1e': \
102
0
    case '\x1f': case '\x7f'
103
#else
104
   /* Use EBCDIC code page 1047's assignments for ASCII control chars;
105
      assume all EBCDIC code pages agree about these assignments.  */
106
# define _C_CTYPE_OTHER_CNTRL \
107
    case '\x00': case '\x01': case '\x02': case '\x03': \
108
    case '\x07': case '\x0e': case '\x0f': case '\x10': \
109
    case '\x11': case '\x12': case '\x13': case '\x18': \
110
    case '\x19': case '\x1c': case '\x1d': case '\x1e': \
111
    case '\x1f': case '\x26': case '\x27': case '\x2d': \
112
    case '\x2e': case '\x32': case '\x37': case '\x3c': \
113
    case '\x3d': case '\x3f'
114
#endif
115
116
/* Cases for lowercase hex letters, and lowercase letters, all offset by N.  */
117
118
#define _C_CTYPE_LOWER_A_THRU_F_N(N) \
119
60.3k
   case 'a' + (N): case 'b' + (N): case 'c' + (N): case 'd' + (N): \
120
120k
   case 'e' + (N): case 'f' + (N)
121
#define _C_CTYPE_LOWER_N(N) \
122
120k
   _C_CTYPE_LOWER_A_THRU_F_N(N): \
123
159k
   case 'g' + (N): case 'h' + (N): case 'i' + (N): case 'j' + (N): \
124
238k
   case 'k' + (N): case 'l' + (N): case 'm' + (N): case 'n' + (N): \
125
278k
   case 'o' + (N): case 'p' + (N): case 'q' + (N): case 'r' + (N): \
126
578k
   case 's' + (N): case 't' + (N): case 'u' + (N): case 'v' + (N): \
127
578k
   case 'w' + (N): case 'x' + (N): case 'y' + (N): case 'z' + (N)
128
129
/* Cases for hex letters, digits, lower, punct, and upper.  */
130
131
#define _C_CTYPE_A_THRU_F \
132
0
   _C_CTYPE_LOWER_A_THRU_F_N (0): \
133
0
   _C_CTYPE_LOWER_A_THRU_F_N ('A' - 'a')
134
#define _C_CTYPE_DIGIT                     \
135
0
   case '0': case '1': case '2': case '3': \
136
0
   case '4': case '5': case '6': case '7': \
137
0
   case '8': case '9'
138
0
#define _C_CTYPE_LOWER _C_CTYPE_LOWER_N (0)
139
#define _C_CTYPE_PUNCT \
140
0
   case '!': case '"': case '#': case '$':  \
141
0
   case '%': case '&': case '\'': case '(': \
142
0
   case ')': case '*': case '+': case ',':  \
143
0
   case '-': case '.': case '/': case ':':  \
144
0
   case ';': case '<': case '=': case '>':  \
145
0
   case '?': case '@': case '[': case '\\': \
146
0
   case ']': case '^': case '_': case '`':  \
147
0
   case '{': case '|': case '}': case '~'
148
0
#define _C_CTYPE_UPPER _C_CTYPE_LOWER_N ('A' - 'a')
149
150
151
/* Function definitions.  */
152
153
/* Unlike the functions in <ctype.h>, which require an argument in the range
154
   of the 'unsigned char' type, the functions here operate on values that are
155
   in the 'unsigned char' range or in the 'char' range.  In other words,
156
   when you have a 'char' value, you need to cast it before using it as
157
   argument to a <ctype.h> function:
158
159
         const char *s = ...;
160
         if (isalpha ((unsigned char) *s)) ...
161
162
   but you don't need to cast it for the functions defined in this file:
163
164
         const char *s = ...;
165
         if (c_isalpha (*s)) ...
166
 */
167
168
C_CTYPE_INLINE bool
169
c_isalnum (int c)
170
0
{
171
0
  switch (c)
172
0
    {
173
0
    _C_CTYPE_DIGIT:
174
0
    _C_CTYPE_LOWER:
175
0
    _C_CTYPE_UPPER:
176
0
      return true;
177
0
    default:
178
0
      return false;
179
0
    }
180
0
}
181
182
C_CTYPE_INLINE bool
183
c_isalpha (int c)
184
0
{
185
0
  switch (c)
186
0
    {
187
0
    _C_CTYPE_LOWER:
188
0
    _C_CTYPE_UPPER:
189
0
      return true;
190
0
    default:
191
0
      return false;
192
0
    }
193
0
}
194
195
/* The function isascii is not locale dependent.
196
   Its use in EBCDIC is questionable. */
197
C_CTYPE_INLINE bool
198
c_isascii (int c)
199
0
{
200
0
  switch (c)
201
0
    {
202
0
    case ' ':
203
0
    _C_CTYPE_CNTRL:
204
0
    _C_CTYPE_DIGIT:
205
0
    _C_CTYPE_LOWER:
206
0
    _C_CTYPE_PUNCT:
207
0
    _C_CTYPE_UPPER:
208
0
      return true;
209
0
    default:
210
0
      return false;
211
0
    }
212
0
}
213
214
C_CTYPE_INLINE bool
215
c_isblank (int c)
216
0
{
217
0
  return c == ' ' || c == '\t';
218
0
}
219
220
C_CTYPE_INLINE bool
221
c_iscntrl (int c)
222
0
{
223
0
  switch (c)
224
0
    {
225
0
    _C_CTYPE_CNTRL:
226
0
      return true;
227
0
    default:
228
0
      return false;
229
0
    }
230
0
}
231
232
C_CTYPE_INLINE bool
233
c_isdigit (int c)
234
0
{
235
0
  switch (c)
236
0
    {
237
0
    _C_CTYPE_DIGIT:
238
0
      return true;
239
0
    default:
240
0
      return false;
241
0
    }
242
0
}
243
244
C_CTYPE_INLINE bool
245
c_isgraph (int c)
246
0
{
247
0
  switch (c)
248
0
    {
249
0
    _C_CTYPE_DIGIT:
250
0
    _C_CTYPE_LOWER:
251
0
    _C_CTYPE_PUNCT:
252
0
    _C_CTYPE_UPPER:
253
0
      return true;
254
0
    default:
255
0
      return false;
256
0
    }
257
0
}
258
259
C_CTYPE_INLINE bool
260
c_islower (int c)
261
0
{
262
0
  switch (c)
263
0
    {
264
0
    _C_CTYPE_LOWER:
265
0
      return true;
266
0
    default:
267
0
      return false;
268
0
    }
269
0
}
270
271
C_CTYPE_INLINE bool
272
c_isprint (int c)
273
0
{
274
0
  switch (c)
275
0
    {
276
0
    case ' ':
277
0
    _C_CTYPE_DIGIT:
278
0
    _C_CTYPE_LOWER:
279
0
    _C_CTYPE_PUNCT:
280
0
    _C_CTYPE_UPPER:
281
0
      return true;
282
0
    default:
283
0
      return false;
284
0
    }
285
0
}
286
287
C_CTYPE_INLINE bool
288
c_ispunct (int c)
289
0
{
290
0
  switch (c)
291
0
    {
292
0
    _C_CTYPE_PUNCT:
293
0
      return true;
294
0
    default:
295
0
      return false;
296
0
    }
297
0
}
298
299
C_CTYPE_INLINE bool
300
c_isspace (int c)
301
0
{
302
0
  switch (c)
303
0
    {
304
0
    case ' ': case '\t': case '\n': case '\v': case '\f': case '\r':
305
0
      return true;
306
0
    default:
307
0
      return false;
308
0
    }
309
0
}
310
311
C_CTYPE_INLINE bool
312
c_isupper (int c)
313
162k
{
314
162k
  switch (c)
315
162k
    {
316
101k
    _C_CTYPE_UPPER:
317
101k
      return true;
318
60.8k
    default:
319
60.8k
      return false;
320
162k
    }
321
162k
}
322
323
C_CTYPE_INLINE bool
324
c_isxdigit (int c)
325
0
{
326
0
  switch (c)
327
0
    {
328
0
    _C_CTYPE_DIGIT:
329
0
    _C_CTYPE_A_THRU_F:
330
0
      return true;
331
0
    default:
332
0
      return false;
333
0
    }
334
0
}
335
336
C_CTYPE_INLINE int
337
c_tolower (int c)
338
757k
{
339
757k
  switch (c)
340
757k
    {
341
476k
    _C_CTYPE_UPPER:
342
476k
      return c - 'A' + 'a';
343
280k
    default:
344
280k
      return c;
345
757k
    }
346
757k
}
347
348
C_CTYPE_INLINE int
349
c_toupper (int c)
350
0
{
351
0
  switch (c)
352
0
    {
353
0
    _C_CTYPE_LOWER:
354
0
      return c - 'a' + 'A';
355
0
    default:
356
0
      return c;
357
0
    }
358
0
}
359
360
#ifdef __cplusplus
361
}
362
#endif
363
364
_GL_INLINE_HEADER_END
365
366
#endif /* C_CTYPE_H */