Fix problems caught with --enable-gcc-warnings
[emacs.git] / lib / c-ctype.h
blob50ebbb582930722a8158ec9b4d26fa137f3b3552
1 /* Character handling in C locale.
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.
8 Copyright (C) 2000-2003, 2006, 2008-2015 Free Software Foundation, Inc.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program 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 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, see <http://www.gnu.org/licenses/>. */
23 #ifndef C_CTYPE_H
24 #define C_CTYPE_H
26 #include <stdbool.h>
28 #ifndef _GL_INLINE_HEADER_BEGIN
29 #error "Please include config.h first."
30 #endif
31 _GL_INLINE_HEADER_BEGIN
32 #ifndef C_CTYPE_INLINE
33 # define C_CTYPE_INLINE _GL_INLINE
34 #endif
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
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. */
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
81 #define _C_CTYPE_SIGNED_EBCDIC ('A' < 0)
83 #if C_CTYPE_ASCII
84 # define _C_CTYPE_CNTRL \
85 case '\x00': case '\x01': case '\x02': case '\x03': \
86 case '\x04': case '\x05': case '\x06': case '\x07': \
87 case '\x08': case '\x09': case '\x0a': case '\x0b': \
88 case '\x0c': case '\x0d': case '\x0e': case '\x0f': \
89 case '\x10': case '\x11': case '\x12': case '\x13': \
90 case '\x14': case '\x15': case '\x16': case '\x17': \
91 case '\x18': case '\x19': case '\x1a': case '\x1b': \
92 case '\x1c': case '\x1d': case '\x1e': case '\x1f': \
93 case '\x7f'
94 #else
95 /* Use EBCDIC code page 1047's assignments for ASCII control chars;
96 assume all EBCDIC code pages agree about these assignments. */
97 # define _C_CTYPE_CNTRL \
98 case '\x00': case '\x01': case '\x02': case '\x03': \
99 case '\x05': case '\x07': case '\x0b': case '\x0c': \
100 case '\x0d': case '\x0e': case '\x0f': case '\x10': \
101 case '\x11': case '\x12': case '\x13': case '\x16': \
102 case '\x18': case '\x19': case '\x1c': case '\x1d': \
103 case '\x1e': case '\x1f': case '\x25': case '\x26': \
104 case '\x27': case '\x2d': case '\x2e': case '\x2f': \
105 case '\x32': case '\x37': case '\x3c': case '\x3d': \
106 case '\x3f'
107 #endif
109 /* Cases for hex letter digits, digits, lower, and upper, offset by N. */
111 #define _C_CTYPE_A_THRU_F_N(n) \
112 case 'a' + (n): case 'b' + (n): case 'c' + (n): case 'd' + (n): \
113 case 'e' + (n): case 'f' + (n): \
114 case 'A' + (n): case 'B' + (n): case 'C' + (n): case 'D' + (n): \
115 case 'E' + (n): case 'F' + (n)
116 #define _C_CTYPE_DIGIT_N(n) \
117 case '0' + (n): case '1' + (n): case '2' + (n): case '3' + (n): \
118 case '4' + (n): case '5' + (n): case '6' + (n): case '7' + (n): \
119 case '8' + (n): case '9' + (n)
120 #define _C_CTYPE_LOWER_N(n) \
121 case 'a' + (n): case 'b' + (n): case 'c' + (n): case 'd' + (n): \
122 case 'e' + (n): case 'f' + (n): case 'g' + (n): case 'h' + (n): \
123 case 'i' + (n): case 'j' + (n): case 'k' + (n): case 'l' + (n): \
124 case 'm' + (n): case 'n' + (n): case 'o' + (n): case 'p' + (n): \
125 case 'q' + (n): case 'r' + (n): case 's' + (n): case 't' + (n): \
126 case 'u' + (n): case 'v' + (n): case 'w' + (n): case 'x' + (n): \
127 case 'y' + (n): case 'z' + (n)
128 #define _C_CTYPE_UPPER_N(n) \
129 case 'A' + (n): case 'B' + (n): case 'C' + (n): case 'D' + (n): \
130 case 'E' + (n): case 'F' + (n): case 'G' + (n): case 'H' + (n): \
131 case 'I' + (n): case 'J' + (n): case 'K' + (n): case 'L' + (n): \
132 case 'M' + (n): case 'N' + (n): case 'O' + (n): case 'P' + (n): \
133 case 'Q' + (n): case 'R' + (n): case 'S' + (n): case 'T' + (n): \
134 case 'U' + (n): case 'V' + (n): case 'W' + (n): case 'X' + (n): \
135 case 'Y' + (n): case 'Z' + (n)
137 /* Given MACRO_N, expand to all the cases for the corresponding class. */
138 #if _C_CTYPE_SIGNED_EBCDIC
139 # define _C_CTYPE_CASES(macro_n) macro_n (0): macro_n (256)
140 #else
141 # define _C_CTYPE_CASES(macro_n) macro_n (0)
142 #endif
144 /* Cases for hex letter digits, digits, lower, and upper, with another
145 case for unsigned char if the original char is negative. */
147 #define _C_CTYPE_A_THRU_F _C_CTYPE_CASES (_C_CTYPE_A_THRU_F_N)
148 #define _C_CTYPE_DIGIT _C_CTYPE_CASES (_C_CTYPE_DIGIT_N)
149 #define _C_CTYPE_LOWER _C_CTYPE_CASES (_C_CTYPE_LOWER_N)
150 #define _C_CTYPE_UPPER _C_CTYPE_CASES (_C_CTYPE_UPPER_N)
152 /* The punct class differs because some punctuation characters may be
153 negative while others are nonnegative. Instead of attempting to
154 define _C_CTYPE_PUNCT, define just the plain chars here, and do any
155 cases-plus-256 by hand after using this macro. */
156 #define _C_CTYPE_PUNCT_PLAIN \
157 case '!': case '"': case '#': case '$': \
158 case '%': case '&': case '\'': case '(': \
159 case ')': case '*': case '+': case ',': \
160 case '-': case '.': case '/': case ':': \
161 case ';': case '<': case '=': case '>': \
162 case '?': case '@': case '[': case '\\': \
163 case ']': case '^': case '_': case '`': \
164 case '{': case '|': case '}': case '~'
166 /* Function definitions. */
168 /* Unlike the functions in <ctype.h>, which require an argument in the range
169 of the 'unsigned char' type, the functions here operate on values that are
170 in the 'unsigned char' range or in the 'char' range. In other words,
171 when you have a 'char' value, you need to cast it before using it as
172 argument to a <ctype.h> function:
174 const char *s = ...;
175 if (isalpha ((unsigned char) *s)) ...
177 but you don't need to cast it for the functions defined in this file:
179 const char *s = ...;
180 if (c_isalpha (*s)) ...
183 C_CTYPE_INLINE bool
184 c_isalnum (int c)
186 switch (c)
188 _C_CTYPE_DIGIT:
189 _C_CTYPE_LOWER:
190 _C_CTYPE_UPPER:
191 return true;
193 default:
194 return false;
198 C_CTYPE_INLINE bool
199 c_isalpha (int c)
201 switch (c)
203 _C_CTYPE_LOWER:
204 _C_CTYPE_UPPER:
205 return true;
207 default:
208 return false;
212 /* The function isascii is not locale dependent.
213 Its use in EBCDIC is questionable. */
214 C_CTYPE_INLINE bool
215 c_isascii (int c)
217 switch (c)
219 case ' ':
220 _C_CTYPE_CNTRL:
221 _C_CTYPE_DIGIT:
222 _C_CTYPE_LOWER:
223 _C_CTYPE_UPPER:
225 _C_CTYPE_PUNCT_PLAIN:
226 #if '!' < 0
227 case '!' + 256:
228 #endif
229 #if '"' < 0
230 case '"' + 256:
231 #endif
232 #if '#' < 0
233 case '#' + 256:
234 #endif
235 #if '$' < 0
236 case '$' + 256:
237 #endif
238 #if '%' < 0
239 case '%' + 256:
240 #endif
241 #if '&' < 0
242 case '&' + 256:
243 #endif
244 #if '\'' < 0
245 case '\'' + 256:
246 #endif
247 #if '(' < 0
248 case '(' + 256:
249 #endif
250 #if ')' < 0
251 case ')' + 256:
252 #endif
253 #if '*' < 0
254 case '*' + 256:
255 #endif
256 #if '+' < 0
257 case '+' + 256:
258 #endif
259 #if ',' < 0
260 case ',' + 256:
261 #endif
262 #if '-' < 0
263 case '-' + 256:
264 #endif
265 #if '.' < 0
266 case '.' + 256:
267 #endif
268 #if '/' < 0
269 case '/' + 256:
270 #endif
271 #if ':' < 0
272 case ':' + 256:
273 #endif
274 #if ';' < 0
275 case ';' + 256:
276 #endif
277 #if '<' < 0
278 case '<' + 256:
279 #endif
280 #if '=' < 0
281 case '=' + 256:
282 #endif
283 #if '>' < 0
284 case '>' + 256:
285 #endif
286 #if '?' < 0
287 case '?' + 256:
288 #endif
289 #if '@' < 0
290 case '@' + 256:
291 #endif
292 #if '[' < 0
293 case '[' + 256:
294 #endif
295 #if '\\' < 0
296 case '\\' + 256:
297 #endif
298 #if ']' < 0
299 case ']' + 256:
300 #endif
301 #if '^' < 0
302 case '^' + 256:
303 #endif
304 #if '_' < 0
305 case '_' + 256:
306 #endif
307 #if '`' < 0
308 case '`' + 256:
309 #endif
310 #if '{' < 0
311 case '{' + 256:
312 #endif
313 #if '|' < 0
314 case '|' + 256:
315 #endif
316 #if '}' < 0
317 case '}' + 256:
318 #endif
319 #if '~' < 0
320 case '~' + 256:
321 #endif
322 return true;
324 default:
325 return false;
329 C_CTYPE_INLINE bool
330 c_isblank (int c)
332 return c == ' ' || c == '\t';
335 C_CTYPE_INLINE bool
336 c_iscntrl (int c)
338 switch (c)
340 _C_CTYPE_CNTRL:
341 return true;
342 default:
343 return false;
347 C_CTYPE_INLINE bool
348 c_isdigit (int c)
350 switch (c)
352 _C_CTYPE_DIGIT:
353 return true;
354 default:
355 return false;
359 C_CTYPE_INLINE bool
360 c_isgraph (int c)
362 switch (c)
364 _C_CTYPE_DIGIT:
365 _C_CTYPE_LOWER:
366 _C_CTYPE_UPPER:
368 _C_CTYPE_PUNCT_PLAIN:
369 #if '!' < 0
370 case '!' + 256:
371 #endif
372 #if '"' < 0
373 case '"' + 256:
374 #endif
375 #if '#' < 0
376 case '#' + 256:
377 #endif
378 #if '$' < 0
379 case '$' + 256:
380 #endif
381 #if '%' < 0
382 case '%' + 256:
383 #endif
384 #if '&' < 0
385 case '&' + 256:
386 #endif
387 #if '\'' < 0
388 case '\'' + 256:
389 #endif
390 #if '(' < 0
391 case '(' + 256:
392 #endif
393 #if ')' < 0
394 case ')' + 256:
395 #endif
396 #if '*' < 0
397 case '*' + 256:
398 #endif
399 #if '+' < 0
400 case '+' + 256:
401 #endif
402 #if ',' < 0
403 case ',' + 256:
404 #endif
405 #if '-' < 0
406 case '-' + 256:
407 #endif
408 #if '.' < 0
409 case '.' + 256:
410 #endif
411 #if '/' < 0
412 case '/' + 256:
413 #endif
414 #if ':' < 0
415 case ':' + 256:
416 #endif
417 #if ';' < 0
418 case ';' + 256:
419 #endif
420 #if '<' < 0
421 case '<' + 256:
422 #endif
423 #if '=' < 0
424 case '=' + 256:
425 #endif
426 #if '>' < 0
427 case '>' + 256:
428 #endif
429 #if '?' < 0
430 case '?' + 256:
431 #endif
432 #if '@' < 0
433 case '@' + 256:
434 #endif
435 #if '[' < 0
436 case '[' + 256:
437 #endif
438 #if '\\' < 0
439 case '\\' + 256:
440 #endif
441 #if ']' < 0
442 case ']' + 256:
443 #endif
444 #if '^' < 0
445 case '^' + 256:
446 #endif
447 #if '_' < 0
448 case '_' + 256:
449 #endif
450 #if '`' < 0
451 case '`' + 256:
452 #endif
453 #if '{' < 0
454 case '{' + 256:
455 #endif
456 #if '|' < 0
457 case '|' + 256:
458 #endif
459 #if '}' < 0
460 case '}' + 256:
461 #endif
462 #if '~' < 0
463 case '~' + 256:
464 #endif
465 return true;
467 default:
468 return false;
472 C_CTYPE_INLINE bool
473 c_islower (int c)
475 switch (c)
477 _C_CTYPE_LOWER:
478 return true;
479 default:
480 return false;
484 C_CTYPE_INLINE bool
485 c_isprint (int c)
487 switch (c)
489 case ' ':
490 _C_CTYPE_DIGIT:
491 _C_CTYPE_LOWER:
492 _C_CTYPE_UPPER:
494 _C_CTYPE_PUNCT_PLAIN:
495 #if '!' < 0
496 case '!' + 256:
497 #endif
498 #if '"' < 0
499 case '"' + 256:
500 #endif
501 #if '#' < 0
502 case '#' + 256:
503 #endif
504 #if '$' < 0
505 case '$' + 256:
506 #endif
507 #if '%' < 0
508 case '%' + 256:
509 #endif
510 #if '&' < 0
511 case '&' + 256:
512 #endif
513 #if '\'' < 0
514 case '\'' + 256:
515 #endif
516 #if '(' < 0
517 case '(' + 256:
518 #endif
519 #if ')' < 0
520 case ')' + 256:
521 #endif
522 #if '*' < 0
523 case '*' + 256:
524 #endif
525 #if '+' < 0
526 case '+' + 256:
527 #endif
528 #if ',' < 0
529 case ',' + 256:
530 #endif
531 #if '-' < 0
532 case '-' + 256:
533 #endif
534 #if '.' < 0
535 case '.' + 256:
536 #endif
537 #if '/' < 0
538 case '/' + 256:
539 #endif
540 #if ':' < 0
541 case ':' + 256:
542 #endif
543 #if ';' < 0
544 case ';' + 256:
545 #endif
546 #if '<' < 0
547 case '<' + 256:
548 #endif
549 #if '=' < 0
550 case '=' + 256:
551 #endif
552 #if '>' < 0
553 case '>' + 256:
554 #endif
555 #if '?' < 0
556 case '?' + 256:
557 #endif
558 #if '@' < 0
559 case '@' + 256:
560 #endif
561 #if '[' < 0
562 case '[' + 256:
563 #endif
564 #if '\\' < 0
565 case '\\' + 256:
566 #endif
567 #if ']' < 0
568 case ']' + 256:
569 #endif
570 #if '^' < 0
571 case '^' + 256:
572 #endif
573 #if '_' < 0
574 case '_' + 256:
575 #endif
576 #if '`' < 0
577 case '`' + 256:
578 #endif
579 #if '{' < 0
580 case '{' + 256:
581 #endif
582 #if '|' < 0
583 case '|' + 256:
584 #endif
585 #if '}' < 0
586 case '}' + 256:
587 #endif
588 #if '~' < 0
589 case '~' + 256:
590 #endif
591 return true;
593 default:
594 return false;
598 C_CTYPE_INLINE bool
599 c_ispunct (int c)
601 switch (c)
603 _C_CTYPE_PUNCT_PLAIN:
604 #if '!' < 0
605 case '!' + 256:
606 #endif
607 #if '"' < 0
608 case '"' + 256:
609 #endif
610 #if '#' < 0
611 case '#' + 256:
612 #endif
613 #if '$' < 0
614 case '$' + 256:
615 #endif
616 #if '%' < 0
617 case '%' + 256:
618 #endif
619 #if '&' < 0
620 case '&' + 256:
621 #endif
622 #if '\'' < 0
623 case '\'' + 256:
624 #endif
625 #if '(' < 0
626 case '(' + 256:
627 #endif
628 #if ')' < 0
629 case ')' + 256:
630 #endif
631 #if '*' < 0
632 case '*' + 256:
633 #endif
634 #if '+' < 0
635 case '+' + 256:
636 #endif
637 #if ',' < 0
638 case ',' + 256:
639 #endif
640 #if '-' < 0
641 case '-' + 256:
642 #endif
643 #if '.' < 0
644 case '.' + 256:
645 #endif
646 #if '/' < 0
647 case '/' + 256:
648 #endif
649 #if ':' < 0
650 case ':' + 256:
651 #endif
652 #if ';' < 0
653 case ';' + 256:
654 #endif
655 #if '<' < 0
656 case '<' + 256:
657 #endif
658 #if '=' < 0
659 case '=' + 256:
660 #endif
661 #if '>' < 0
662 case '>' + 256:
663 #endif
664 #if '?' < 0
665 case '?' + 256:
666 #endif
667 #if '@' < 0
668 case '@' + 256:
669 #endif
670 #if '[' < 0
671 case '[' + 256:
672 #endif
673 #if '\\' < 0
674 case '\\' + 256:
675 #endif
676 #if ']' < 0
677 case ']' + 256:
678 #endif
679 #if '^' < 0
680 case '^' + 256:
681 #endif
682 #if '_' < 0
683 case '_' + 256:
684 #endif
685 #if '`' < 0
686 case '`' + 256:
687 #endif
688 #if '{' < 0
689 case '{' + 256:
690 #endif
691 #if '|' < 0
692 case '|' + 256:
693 #endif
694 #if '}' < 0
695 case '}' + 256:
696 #endif
697 #if '~' < 0
698 case '~' + 256:
699 #endif
700 return true;
702 default:
703 return false;
707 C_CTYPE_INLINE bool
708 c_isspace (int c)
710 switch (c)
712 case ' ': case '\t': case '\n': case '\v': case '\f': case '\r':
713 return true;
714 default:
715 return false;
719 C_CTYPE_INLINE bool
720 c_isupper (int c)
722 switch (c)
724 _C_CTYPE_UPPER:
725 return true;
726 default:
727 return false;
731 C_CTYPE_INLINE bool
732 c_isxdigit (int c)
734 switch (c)
736 _C_CTYPE_DIGIT:
737 _C_CTYPE_A_THRU_F:
738 return true;
740 default:
741 return false;
745 C_CTYPE_INLINE int
746 c_tolower (int c)
748 switch (c)
750 _C_CTYPE_UPPER_N (0):
751 #if _C_CTYPE_SIGNED_EBCDIC
752 c += 256;
753 /* Fall through. */
754 _C_CTYPE_UPPER_N (256):
755 #endif
756 return c - 'A' + 'a';
758 default:
759 return c;
763 C_CTYPE_INLINE int
764 c_toupper (int c)
766 switch (c)
768 _C_CTYPE_LOWER_N (0):
769 #if _C_CTYPE_SIGNED_EBCDIC
770 c += 256;
771 /* Fall through. */
772 _C_CTYPE_LOWER_N (256):
773 #endif
774 return c - 'a' + 'A';
776 default:
777 return c;
781 #ifdef __cplusplus
783 #endif
785 _GL_INLINE_HEADER_END
787 #endif /* C_CTYPE_H */