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-2014 Free Software Foundation, Inc. 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU Lesser General Public License as published by 12 the Free Software Foundation; either version 2.1 of the License, or 13 (at your option) any later version. 14 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 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 <http://www.gnu.org/licenses/>. */ 22 23 #ifndef C_CTYPE_H 24 #define C_CTYPE_H 25 26 #include <stdbool.h> 27 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 34 /* The functions defined in this file assume the "C" locale and a character 35 set without diacritics (ASCII-US or EBCDIC-US or something like that). 36 Even if the "C" locale on a particular system is an extension of the ASCII 37 character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it 38 is ISO-8859-1), the functions in this file recognize only the ASCII 39 characters. */ 40 41 42 /* Check whether the ASCII optimizations apply. */ 43 44 /* ANSI C89 (and ISO C99 5.2.1.3 too) already guarantees that 45 '0', '1', ..., '9' have consecutive integer values. */ 46 #define C_CTYPE_CONSECUTIVE_DIGITS 1 47 48 #if ('A' <= 'Z') \ 49 && ('A' + 1 == 'B') && ('B' + 1 == 'C') && ('C' + 1 == 'D') \ 50 && ('D' + 1 == 'E') && ('E' + 1 == 'F') && ('F' + 1 == 'G') \ 51 && ('G' + 1 == 'H') && ('H' + 1 == 'I') && ('I' + 1 == 'J') \ 52 && ('J' + 1 == 'K') && ('K' + 1 == 'L') && ('L' + 1 == 'M') \ 53 && ('M' + 1 == 'N') && ('N' + 1 == 'O') && ('O' + 1 == 'P') \ 54 && ('P' + 1 == 'Q') && ('Q' + 1 == 'R') && ('R' + 1 == 'S') \ 55 && ('S' + 1 == 'T') && ('T' + 1 == 'U') && ('U' + 1 == 'V') \ 56 && ('V' + 1 == 'W') && ('W' + 1 == 'X') && ('X' + 1 == 'Y') \ 57 && ('Y' + 1 == 'Z') 58 #define C_CTYPE_CONSECUTIVE_UPPERCASE 1 59 #endif 60 61 #if ('a' <= 'z') \ 62 && ('a' + 1 == 'b') && ('b' + 1 == 'c') && ('c' + 1 == 'd') \ 63 && ('d' + 1 == 'e') && ('e' + 1 == 'f') && ('f' + 1 == 'g') \ 64 && ('g' + 1 == 'h') && ('h' + 1 == 'i') && ('i' + 1 == 'j') \ 65 && ('j' + 1 == 'k') && ('k' + 1 == 'l') && ('l' + 1 == 'm') \ 66 && ('m' + 1 == 'n') && ('n' + 1 == 'o') && ('o' + 1 == 'p') \ 67 && ('p' + 1 == 'q') && ('q' + 1 == 'r') && ('r' + 1 == 's') \ 68 && ('s' + 1 == 't') && ('t' + 1 == 'u') && ('u' + 1 == 'v') \ 69 && ('v' + 1 == 'w') && ('w' + 1 == 'x') && ('x' + 1 == 'y') \ 70 && ('y' + 1 == 'z') 71 #define C_CTYPE_CONSECUTIVE_LOWERCASE 1 72 #endif 73 74 #if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ 75 && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ 76 && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ 77 && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ 78 && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ 79 && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ 80 && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ 81 && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ 82 && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ 83 && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ 84 && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ 85 && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ 86 && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ 87 && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ 88 && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ 89 && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ 90 && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ 91 && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ 92 && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ 93 && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ 94 && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ 95 && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ 96 && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126) 97 /* The character set is ASCII or one of its variants or extensions, not EBCDIC. 98 Testing the value of '\n' and '\r' is not relevant. */ 99 #define C_CTYPE_ASCII 1 100 #endif 101 102 103 /* Function declarations. */ 104 105 /* Unlike the functions in <ctype.h>, which require an argument in the range 106 of the 'unsigned char' type, the functions here operate on values that are 107 in the 'unsigned char' range or in the 'char' range. In other words, 108 when you have a 'char' value, you need to cast it before using it as 109 argument to a <ctype.h> function: 110 111 const char *s = ...; 112 if (isalpha ((unsigned char) *s)) ... 113 114 but you don't need to cast it for the functions defined in this file: 115 116 const char *s = ...; 117 if (c_isalpha (*s)) ... 118 */ 119 120 extern bool c_isascii (int c) _GL_ATTRIBUTE_CONST; /* not locale dependent */ 121 122 extern bool c_isalnum (int c) _GL_ATTRIBUTE_CONST; 123 extern bool c_isalpha (int c) _GL_ATTRIBUTE_CONST; 124 extern bool c_isblank (int c) _GL_ATTRIBUTE_CONST; 125 extern bool c_iscntrl (int c) _GL_ATTRIBUTE_CONST; 126 extern bool c_isdigit (int c) _GL_ATTRIBUTE_CONST; 127 extern bool c_islower (int c) _GL_ATTRIBUTE_CONST; 128 extern bool c_isgraph (int c) _GL_ATTRIBUTE_CONST; 129 extern bool c_isprint (int c) _GL_ATTRIBUTE_CONST; 130 extern bool c_ispunct (int c) _GL_ATTRIBUTE_CONST; 131 extern bool c_isspace (int c) _GL_ATTRIBUTE_CONST; 132 extern bool c_isupper (int c) _GL_ATTRIBUTE_CONST; 133 extern bool c_isxdigit (int c) _GL_ATTRIBUTE_CONST; 134 135 extern int c_tolower (int c) _GL_ATTRIBUTE_CONST; 136 extern int c_toupper (int c) _GL_ATTRIBUTE_CONST; 137 138 139 #if (defined __GNUC__ && !defined __STRICT_ANSI__ && defined __OPTIMIZE__ \ 140 && !defined __OPTIMIZE_SIZE__ && !defined NO_C_CTYPE_MACROS) 141 142 /* ASCII optimizations. */ 143 144 #undef c_isascii 145 #define c_isascii(c) \ 146 ({ int __c = (c); \ 147 (__c >= 0x00 && __c <= 0x7f); \ 148 }) 149 150 #if C_CTYPE_CONSECUTIVE_DIGITS \ 151 && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE 152 #if C_CTYPE_ASCII 153 #undef c_isalnum 154 #define c_isalnum(c) \ 155 ({ int __c = (c); \ 156 ((__c >= '0' && __c <= '9') \ 157 || ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z')); \ 158 }) 159 #else 160 #undef c_isalnum 161 #define c_isalnum(c) \ 162 ({ int __c = (c); \ 163 ((__c >= '0' && __c <= '9') \ 164 || (__c >= 'A' && __c <= 'Z') \ 165 || (__c >= 'a' && __c <= 'z')); \ 166 }) 167 #endif 168 #endif 169 170 #if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE 171 #if C_CTYPE_ASCII 172 #undef c_isalpha 173 #define c_isalpha(c) \ 174 ({ int __c = (c); \ 175 ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z'); \ 176 }) 177 #else 178 #undef c_isalpha 179 #define c_isalpha(c) \ 180 ({ int __c = (c); \ 181 ((__c >= 'A' && __c <= 'Z') || (__c >= 'a' && __c <= 'z')); \ 182 }) 183 #endif 184 #endif 185 186 #undef c_isblank 187 #define c_isblank(c) \ 188 ({ int __c = (c); \ 189 (__c == ' ' || __c == '\t'); \ 190 }) 191 192 #if C_CTYPE_ASCII 193 #undef c_iscntrl 194 #define c_iscntrl(c) \ 195 ({ int __c = (c); \ 196 ((__c & ~0x1f) == 0 || __c == 0x7f); \ 197 }) 198 #endif 199 200 #if C_CTYPE_CONSECUTIVE_DIGITS 201 #undef c_isdigit 202 #define c_isdigit(c) \ 203 ({ int __c = (c); \ 204 (__c >= '0' && __c <= '9'); \ 205 }) 206 #endif 207 208 #if C_CTYPE_CONSECUTIVE_LOWERCASE 209 #undef c_islower 210 #define c_islower(c) \ 211 ({ int __c = (c); \ 212 (__c >= 'a' && __c <= 'z'); \ 213 }) 214 #endif 215 216 #if C_CTYPE_ASCII 217 #undef c_isgraph 218 #define c_isgraph(c) \ 219 ({ int __c = (c); \ 220 (__c >= '!' && __c <= '~'); \ 221 }) 222 #endif 223 224 #if C_CTYPE_ASCII 225 #undef c_isprint 226 #define c_isprint(c) \ 227 ({ int __c = (c); \ 228 (__c >= ' ' && __c <= '~'); \ 229 }) 230 #endif 231 232 #if C_CTYPE_ASCII 233 #undef c_ispunct 234 #define c_ispunct(c) \ 235 ({ int _c = (c); \ 236 (c_isgraph (_c) && ! c_isalnum (_c)); \ 237 }) 238 #endif 239 240 #undef c_isspace 241 #define c_isspace(c) \ 242 ({ int __c = (c); \ 243 (__c == ' ' || __c == '\t' \ 244 || __c == '\n' || __c == '\v' || __c == '\f' || __c == '\r'); \ 245 }) 246 247 #if C_CTYPE_CONSECUTIVE_UPPERCASE 248 #undef c_isupper 249 #define c_isupper(c) \ 250 ({ int __c = (c); \ 251 (__c >= 'A' && __c <= 'Z'); \ 252 }) 253 #endif 254 255 #if C_CTYPE_CONSECUTIVE_DIGITS \ 256 && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE 257 #if C_CTYPE_ASCII 258 #undef c_isxdigit 259 #define c_isxdigit(c) \ 260 ({ int __c = (c); \ 261 ((__c >= '0' && __c <= '9') \ 262 || ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'F')); \ 263 }) 264 #else 265 #undef c_isxdigit 266 #define c_isxdigit(c) \ 267 ({ int __c = (c); \ 268 ((__c >= '0' && __c <= '9') \ 269 || (__c >= 'A' && __c <= 'F') \ 270 || (__c >= 'a' && __c <= 'f')); \ 271 }) 272 #endif 273 #endif 274 275 #if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE 276 #undef c_tolower 277 #define c_tolower(c) \ 278 ({ int __c = (c); \ 279 (__c >= 'A' && __c <= 'Z' ? __c - 'A' + 'a' : __c); \ 280 }) 281 #undef c_toupper 282 #define c_toupper(c) \ 283 ({ int __c = (c); \ 284 (__c >= 'a' && __c <= 'z' ? __c - 'a' + 'A' : __c); \ 285 }) 286 #endif 287 288 #endif /* optimizing for speed */ 289 290 291 #ifdef __cplusplus 292 } 293 #endif 294 295 #endif /* C_CTYPE_H */ 296