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-2011 Free Software Foundation, Inc. 9 10This program is free software; you can redistribute it and/or modify 11it under the terms of the GNU General Public License as published by 12the Free Software Foundation; either version 3 of the License, or 13(at your option) any later version. 14 15This program is distributed in the hope that it will be useful, 16but WITHOUT ANY WARRANTY; without even the implied warranty of 17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18GNU General Public License for more details. 19 20You should have received a copy of the GNU General Public License 21along with this program; if not, write to the Free Software Foundation, 22Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 23 24#ifndef C_CTYPE_H 25#define C_CTYPE_H 26 27#include <stdbool.h> 28 29 30#ifdef __cplusplus 31extern "C" { 32#endif 33 34 35/* The functions defined in this file assume the "C" locale and a character 36 set without diacritics (ASCII-US or EBCDIC-US or something like that). 37 Even if the "C" locale on a particular system is an extension of the ASCII 38 character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it 39 is ISO-8859-1), the functions in this file recognize only the ASCII 40 characters. */ 41 42 43/* Check whether the ASCII optimizations apply. */ 44 45/* ANSI C89 (and ISO C99 5.2.1.3 too) already guarantees that 46 '0', '1', ..., '9' have consecutive integer values. */ 47#define C_CTYPE_CONSECUTIVE_DIGITS 1 48 49#if ('A' <= 'Z') \ 50 && ('A' + 1 == 'B') && ('B' + 1 == 'C') && ('C' + 1 == 'D') \ 51 && ('D' + 1 == 'E') && ('E' + 1 == 'F') && ('F' + 1 == 'G') \ 52 && ('G' + 1 == 'H') && ('H' + 1 == 'I') && ('I' + 1 == 'J') \ 53 && ('J' + 1 == 'K') && ('K' + 1 == 'L') && ('L' + 1 == 'M') \ 54 && ('M' + 1 == 'N') && ('N' + 1 == 'O') && ('O' + 1 == 'P') \ 55 && ('P' + 1 == 'Q') && ('Q' + 1 == 'R') && ('R' + 1 == 'S') \ 56 && ('S' + 1 == 'T') && ('T' + 1 == 'U') && ('U' + 1 == 'V') \ 57 && ('V' + 1 == 'W') && ('W' + 1 == 'X') && ('X' + 1 == 'Y') \ 58 && ('Y' + 1 == 'Z') 59#define C_CTYPE_CONSECUTIVE_UPPERCASE 1 60#endif 61 62#if ('a' <= 'z') \ 63 && ('a' + 1 == 'b') && ('b' + 1 == 'c') && ('c' + 1 == 'd') \ 64 && ('d' + 1 == 'e') && ('e' + 1 == 'f') && ('f' + 1 == 'g') \ 65 && ('g' + 1 == 'h') && ('h' + 1 == 'i') && ('i' + 1 == 'j') \ 66 && ('j' + 1 == 'k') && ('k' + 1 == 'l') && ('l' + 1 == 'm') \ 67 && ('m' + 1 == 'n') && ('n' + 1 == 'o') && ('o' + 1 == 'p') \ 68 && ('p' + 1 == 'q') && ('q' + 1 == 'r') && ('r' + 1 == 's') \ 69 && ('s' + 1 == 't') && ('t' + 1 == 'u') && ('u' + 1 == 'v') \ 70 && ('v' + 1 == 'w') && ('w' + 1 == 'x') && ('x' + 1 == 'y') \ 71 && ('y' + 1 == 'z') 72#define C_CTYPE_CONSECUTIVE_LOWERCASE 1 73#endif 74 75#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ 76 && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ 77 && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ 78 && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ 79 && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ 80 && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ 81 && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ 82 && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ 83 && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ 84 && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ 85 && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ 86 && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ 87 && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ 88 && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ 89 && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ 90 && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ 91 && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ 92 && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ 93 && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ 94 && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ 95 && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ 96 && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ 97 && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126) 98/* The character set is ASCII or one of its variants or extensions, not EBCDIC. 99 Testing the value of '\n' and '\r' is not relevant. */ 100#define C_CTYPE_ASCII 1 101#endif 102 103 104/* Function declarations. */ 105 106/* Unlike the functions in <ctype.h>, which require an argument in the range 107 of the 'unsigned char' type, the functions here operate on values that are 108 in the 'unsigned char' range or in the 'char' range. In other words, 109 when you have a 'char' value, you need to cast it before using it as 110 argument to a <ctype.h> function: 111 112 const char *s = ...; 113 if (isalpha ((unsigned char) *s)) ... 114 115 but you don't need to cast it for the functions defined in this file: 116 117 const char *s = ...; 118 if (c_isalpha (*s)) ... 119 */ 120 121extern bool c_isascii (int c); /* not locale dependent */ 122 123extern bool c_isalnum (int c); 124extern bool c_isalpha (int c); 125extern bool c_isblank (int c); 126extern bool c_iscntrl (int c); 127extern bool c_isdigit (int c); 128extern bool c_islower (int c); 129extern bool c_isgraph (int c); 130extern bool c_isprint (int c); 131extern bool c_ispunct (int c); 132extern bool c_isspace (int c); 133extern bool c_isupper (int c); 134extern bool c_isxdigit (int c); 135 136extern int c_tolower (int c); 137extern int c_toupper (int c); 138 139 140#if defined __GNUC__ && defined __OPTIMIZE__ && !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