version 1.1.1.2, 2012/05/29 09:29:43
|
version 1.1.1.3, 2021/03/17 13:38:46
|
Line 5
|
Line 5
|
<ctype.h> functions' behaviour depends on the current locale set via |
<ctype.h> functions' behaviour depends on the current locale set via |
setlocale. |
setlocale. |
|
|
Copyright (C) 2000-2003, 2006, 2008-2011 Free Software Foundation, Inc. | Copyright (C) 2000-2003, 2006, 2008-2019 Free Software Foundation, Inc. |
|
|
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
Line 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
Line 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
GNU General Public License for more details. |
GNU General Public License for more details. |
|
|
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software Foundation, | along with this program; if not, see <https://www.gnu.org/licenses/>. */ |
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | |
|
|
#ifndef C_CTYPE_H |
#ifndef C_CTYPE_H |
#define C_CTYPE_H |
#define C_CTYPE_H |
|
|
#include <stdbool.h> |
#include <stdbool.h> |
|
|
|
#ifndef _GL_INLINE_HEADER_BEGIN |
|
#error "Please include config.h first." |
|
#endif |
|
_GL_INLINE_HEADER_BEGIN |
|
#ifndef C_CTYPE_INLINE |
|
# define C_CTYPE_INLINE _GL_INLINE |
|
#endif |
|
|
#ifdef __cplusplus |
#ifdef __cplusplus |
extern "C" { |
extern "C" { |
Line 40 extern "C" {
|
Line 46 extern "C" {
|
characters. */ |
characters. */ |
|
|
|
|
/* Check whether the ASCII optimizations apply. */ |
|
|
|
/* ANSI C89 (and ISO C99 5.2.1.3 too) already guarantees that |
|
'0', '1', ..., '9' have consecutive integer values. */ |
|
#define C_CTYPE_CONSECUTIVE_DIGITS 1 |
|
|
|
#if ('A' <= 'Z') \ |
|
&& ('A' + 1 == 'B') && ('B' + 1 == 'C') && ('C' + 1 == 'D') \ |
|
&& ('D' + 1 == 'E') && ('E' + 1 == 'F') && ('F' + 1 == 'G') \ |
|
&& ('G' + 1 == 'H') && ('H' + 1 == 'I') && ('I' + 1 == 'J') \ |
|
&& ('J' + 1 == 'K') && ('K' + 1 == 'L') && ('L' + 1 == 'M') \ |
|
&& ('M' + 1 == 'N') && ('N' + 1 == 'O') && ('O' + 1 == 'P') \ |
|
&& ('P' + 1 == 'Q') && ('Q' + 1 == 'R') && ('R' + 1 == 'S') \ |
|
&& ('S' + 1 == 'T') && ('T' + 1 == 'U') && ('U' + 1 == 'V') \ |
|
&& ('V' + 1 == 'W') && ('W' + 1 == 'X') && ('X' + 1 == 'Y') \ |
|
&& ('Y' + 1 == 'Z') |
|
#define C_CTYPE_CONSECUTIVE_UPPERCASE 1 |
|
#endif |
|
|
|
#if ('a' <= 'z') \ |
|
&& ('a' + 1 == 'b') && ('b' + 1 == 'c') && ('c' + 1 == 'd') \ |
|
&& ('d' + 1 == 'e') && ('e' + 1 == 'f') && ('f' + 1 == 'g') \ |
|
&& ('g' + 1 == 'h') && ('h' + 1 == 'i') && ('i' + 1 == 'j') \ |
|
&& ('j' + 1 == 'k') && ('k' + 1 == 'l') && ('l' + 1 == 'm') \ |
|
&& ('m' + 1 == 'n') && ('n' + 1 == 'o') && ('o' + 1 == 'p') \ |
|
&& ('p' + 1 == 'q') && ('q' + 1 == 'r') && ('r' + 1 == 's') \ |
|
&& ('s' + 1 == 't') && ('t' + 1 == 'u') && ('u' + 1 == 'v') \ |
|
&& ('v' + 1 == 'w') && ('w' + 1 == 'x') && ('x' + 1 == 'y') \ |
|
&& ('y' + 1 == 'z') |
|
#define C_CTYPE_CONSECUTIVE_LOWERCASE 1 |
|
#endif |
|
|
|
#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ |
#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ |
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ |
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ |
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ |
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ |
Line 97 extern "C" {
|
Line 71 extern "C" {
|
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126) |
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126) |
/* The character set is ASCII or one of its variants or extensions, not EBCDIC. |
/* The character set is ASCII or one of its variants or extensions, not EBCDIC. |
Testing the value of '\n' and '\r' is not relevant. */ |
Testing the value of '\n' and '\r' is not relevant. */ |
#define C_CTYPE_ASCII 1 | # define C_CTYPE_ASCII 1 |
| #elif ! (' ' == '\x40' && '0' == '\xf0' \ |
| && 'A' == '\xc1' && 'J' == '\xd1' && 'S' == '\xe2' \ |
| && 'a' == '\x81' && 'j' == '\x91' && 's' == '\xa2') |
| # error "Only ASCII and EBCDIC are supported" |
#endif |
#endif |
|
|
|
#if 'A' < 0 |
|
# error "EBCDIC and char is signed -- not supported" |
|
#endif |
|
|
/* Function declarations. */ | /* Cases for control characters. */ |
|
|
|
#define _C_CTYPE_CNTRL \ |
|
case '\a': case '\b': case '\f': case '\n': \ |
|
case '\r': case '\t': case '\v': \ |
|
_C_CTYPE_OTHER_CNTRL |
|
|
|
/* ASCII control characters other than those with \-letter escapes. */ |
|
|
|
#if C_CTYPE_ASCII |
|
# define _C_CTYPE_OTHER_CNTRL \ |
|
case '\x00': case '\x01': case '\x02': case '\x03': \ |
|
case '\x04': case '\x05': case '\x06': case '\x0e': \ |
|
case '\x0f': case '\x10': case '\x11': case '\x12': \ |
|
case '\x13': case '\x14': case '\x15': case '\x16': \ |
|
case '\x17': case '\x18': case '\x19': case '\x1a': \ |
|
case '\x1b': case '\x1c': case '\x1d': case '\x1e': \ |
|
case '\x1f': case '\x7f' |
|
#else |
|
/* Use EBCDIC code page 1047's assignments for ASCII control chars; |
|
assume all EBCDIC code pages agree about these assignments. */ |
|
# define _C_CTYPE_OTHER_CNTRL \ |
|
case '\x00': case '\x01': case '\x02': case '\x03': \ |
|
case '\x07': case '\x0e': case '\x0f': case '\x10': \ |
|
case '\x11': case '\x12': case '\x13': case '\x18': \ |
|
case '\x19': case '\x1c': case '\x1d': case '\x1e': \ |
|
case '\x1f': case '\x26': case '\x27': case '\x2d': \ |
|
case '\x2e': case '\x32': case '\x37': case '\x3c': \ |
|
case '\x3d': case '\x3f' |
|
#endif |
|
|
|
/* Cases for lowercase hex letters, and lowercase letters, all offset by N. */ |
|
|
|
#define _C_CTYPE_LOWER_A_THRU_F_N(N) \ |
|
case 'a' + (N): case 'b' + (N): case 'c' + (N): case 'd' + (N): \ |
|
case 'e' + (N): case 'f' + (N) |
|
#define _C_CTYPE_LOWER_N(N) \ |
|
_C_CTYPE_LOWER_A_THRU_F_N(N): \ |
|
case 'g' + (N): case 'h' + (N): case 'i' + (N): case 'j' + (N): \ |
|
case 'k' + (N): case 'l' + (N): case 'm' + (N): case 'n' + (N): \ |
|
case 'o' + (N): case 'p' + (N): case 'q' + (N): case 'r' + (N): \ |
|
case 's' + (N): case 't' + (N): case 'u' + (N): case 'v' + (N): \ |
|
case 'w' + (N): case 'x' + (N): case 'y' + (N): case 'z' + (N) |
|
|
|
/* Cases for hex letters, digits, lower, punct, and upper. */ |
|
|
|
#define _C_CTYPE_A_THRU_F \ |
|
_C_CTYPE_LOWER_A_THRU_F_N (0): \ |
|
_C_CTYPE_LOWER_A_THRU_F_N ('A' - 'a') |
|
#define _C_CTYPE_DIGIT \ |
|
case '0': case '1': case '2': case '3': \ |
|
case '4': case '5': case '6': case '7': \ |
|
case '8': case '9' |
|
#define _C_CTYPE_LOWER _C_CTYPE_LOWER_N (0) |
|
#define _C_CTYPE_PUNCT \ |
|
case '!': case '"': case '#': case '$': \ |
|
case '%': case '&': case '\'': case '(': \ |
|
case ')': case '*': case '+': case ',': \ |
|
case '-': case '.': case '/': case ':': \ |
|
case ';': case '<': case '=': case '>': \ |
|
case '?': case '@': case '[': case '\\': \ |
|
case ']': case '^': case '_': case '`': \ |
|
case '{': case '|': case '}': case '~' |
|
#define _C_CTYPE_UPPER _C_CTYPE_LOWER_N ('A' - 'a') |
|
|
|
|
|
/* Function definitions. */ |
|
|
/* Unlike the functions in <ctype.h>, which require an argument in the range |
/* Unlike the functions in <ctype.h>, which require an argument in the range |
of the 'unsigned char' type, the functions here operate on values that are |
of the 'unsigned char' type, the functions here operate on values that are |
in the 'unsigned char' range or in the 'char' range. In other words, |
in the 'unsigned char' range or in the 'char' range. In other words, |
Line 118 extern "C" {
|
Line 165 extern "C" {
|
if (c_isalpha (*s)) ... |
if (c_isalpha (*s)) ... |
*/ |
*/ |
|
|
extern bool c_isascii (int c); /* not locale dependent */ | C_CTYPE_INLINE bool |
| c_isalnum (int c) |
| { |
| switch (c) |
| { |
| _C_CTYPE_DIGIT: |
| _C_CTYPE_LOWER: |
| _C_CTYPE_UPPER: |
| return true; |
| default: |
| return false; |
| } |
| } |
|
|
extern bool c_isalnum (int c); | C_CTYPE_INLINE bool |
extern bool c_isalpha (int c); | c_isalpha (int c) |
extern bool c_isblank (int c); | { |
extern bool c_iscntrl (int c); | switch (c) |
extern bool c_isdigit (int c); | { |
extern bool c_islower (int c); | _C_CTYPE_LOWER: |
extern bool c_isgraph (int c); | _C_CTYPE_UPPER: |
extern bool c_isprint (int c); | return true; |
extern bool c_ispunct (int c); | default: |
extern bool c_isspace (int c); | return false; |
extern bool c_isupper (int c); | } |
extern bool c_isxdigit (int c); | } |
|
|
extern int c_tolower (int c); | /* The function isascii is not locale dependent. |
extern int c_toupper (int c); | Its use in EBCDIC is questionable. */ |
| C_CTYPE_INLINE bool |
| c_isascii (int c) |
| { |
| switch (c) |
| { |
| case ' ': |
| _C_CTYPE_CNTRL: |
| _C_CTYPE_DIGIT: |
| _C_CTYPE_LOWER: |
| _C_CTYPE_PUNCT: |
| _C_CTYPE_UPPER: |
| return true; |
| default: |
| return false; |
| } |
| } |
|
|
|
C_CTYPE_INLINE bool |
|
c_isblank (int c) |
|
{ |
|
return c == ' ' || c == '\t'; |
|
} |
|
|
#if defined __GNUC__ && defined __OPTIMIZE__ && !defined __OPTIMIZE_SIZE__ && !defined NO_C_CTYPE_MACROS | C_CTYPE_INLINE bool |
| c_iscntrl (int c) |
| { |
| switch (c) |
| { |
| _C_CTYPE_CNTRL: |
| return true; |
| default: |
| return false; |
| } |
| } |
|
|
/* ASCII optimizations. */ | C_CTYPE_INLINE bool |
| c_isdigit (int c) |
| { |
| switch (c) |
| { |
| _C_CTYPE_DIGIT: |
| return true; |
| default: |
| return false; |
| } |
| } |
|
|
#undef c_isascii | C_CTYPE_INLINE bool |
#define c_isascii(c) \ | c_isgraph (int c) |
({ int __c = (c); \ | { |
(__c >= 0x00 && __c <= 0x7f); \ | switch (c) |
}) | { |
| _C_CTYPE_DIGIT: |
| _C_CTYPE_LOWER: |
| _C_CTYPE_PUNCT: |
| _C_CTYPE_UPPER: |
| return true; |
| default: |
| return false; |
| } |
| } |
|
|
#if C_CTYPE_CONSECUTIVE_DIGITS \ | C_CTYPE_INLINE bool |
&& C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE | c_islower (int c) |
#if C_CTYPE_ASCII | { |
#undef c_isalnum | switch (c) |
#define c_isalnum(c) \ | { |
({ int __c = (c); \ | _C_CTYPE_LOWER: |
((__c >= '0' && __c <= '9') \ | return true; |
|| ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z')); \ | default: |
}) | return false; |
#else | } |
#undef c_isalnum | } |
#define c_isalnum(c) \ | |
({ int __c = (c); \ | |
((__c >= '0' && __c <= '9') \ | |
|| (__c >= 'A' && __c <= 'Z') \ | |
|| (__c >= 'a' && __c <= 'z')); \ | |
}) | |
#endif | |
#endif | |
|
|
#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE | C_CTYPE_INLINE bool |
#if C_CTYPE_ASCII | c_isprint (int c) |
#undef c_isalpha | { |
#define c_isalpha(c) \ | switch (c) |
({ int __c = (c); \ | { |
((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z'); \ | case ' ': |
}) | _C_CTYPE_DIGIT: |
#else | _C_CTYPE_LOWER: |
#undef c_isalpha | _C_CTYPE_PUNCT: |
#define c_isalpha(c) \ | _C_CTYPE_UPPER: |
({ int __c = (c); \ | return true; |
((__c >= 'A' && __c <= 'Z') || (__c >= 'a' && __c <= 'z')); \ | default: |
}) | return false; |
#endif | } |
#endif | } |
|
|
#undef c_isblank | C_CTYPE_INLINE bool |
#define c_isblank(c) \ | c_ispunct (int c) |
({ int __c = (c); \ | { |
(__c == ' ' || __c == '\t'); \ | switch (c) |
}) | { |
| _C_CTYPE_PUNCT: |
| return true; |
| default: |
| return false; |
| } |
| } |
|
|
#if C_CTYPE_ASCII | C_CTYPE_INLINE bool |
#undef c_iscntrl | c_isspace (int c) |
#define c_iscntrl(c) \ | { |
({ int __c = (c); \ | switch (c) |
((__c & ~0x1f) == 0 || __c == 0x7f); \ | { |
}) | case ' ': case '\t': case '\n': case '\v': case '\f': case '\r': |
#endif | return true; |
| default: |
| return false; |
| } |
| } |
|
|
#if C_CTYPE_CONSECUTIVE_DIGITS | C_CTYPE_INLINE bool |
#undef c_isdigit | c_isupper (int c) |
#define c_isdigit(c) \ | { |
({ int __c = (c); \ | switch (c) |
(__c >= '0' && __c <= '9'); \ | { |
}) | _C_CTYPE_UPPER: |
#endif | return true; |
| default: |
| return false; |
| } |
| } |
|
|
#if C_CTYPE_CONSECUTIVE_LOWERCASE | C_CTYPE_INLINE bool |
#undef c_islower | c_isxdigit (int c) |
#define c_islower(c) \ | { |
({ int __c = (c); \ | switch (c) |
(__c >= 'a' && __c <= 'z'); \ | { |
}) | _C_CTYPE_DIGIT: |
#endif | _C_CTYPE_A_THRU_F: |
| return true; |
| default: |
| return false; |
| } |
| } |
|
|
#if C_CTYPE_ASCII | C_CTYPE_INLINE int |
#undef c_isgraph | c_tolower (int c) |
#define c_isgraph(c) \ | { |
({ int __c = (c); \ | switch (c) |
(__c >= '!' && __c <= '~'); \ | { |
}) | _C_CTYPE_UPPER: |
#endif | return c - 'A' + 'a'; |
| default: |
| return c; |
| } |
| } |
|
|
#if C_CTYPE_ASCII | C_CTYPE_INLINE int |
#undef c_isprint | c_toupper (int c) |
#define c_isprint(c) \ | { |
({ int __c = (c); \ | switch (c) |
(__c >= ' ' && __c <= '~'); \ | { |
}) | _C_CTYPE_LOWER: |
#endif | return c - 'a' + 'A'; |
| default: |
| return c; |
| } |
| } |
|
|
#if C_CTYPE_ASCII |
|
#undef c_ispunct |
|
#define c_ispunct(c) \ |
|
({ int _c = (c); \ |
|
(c_isgraph (_c) && ! c_isalnum (_c)); \ |
|
}) |
|
#endif |
|
|
|
#undef c_isspace |
|
#define c_isspace(c) \ |
|
({ int __c = (c); \ |
|
(__c == ' ' || __c == '\t' \ |
|
|| __c == '\n' || __c == '\v' || __c == '\f' || __c == '\r'); \ |
|
}) |
|
|
|
#if C_CTYPE_CONSECUTIVE_UPPERCASE |
|
#undef c_isupper |
|
#define c_isupper(c) \ |
|
({ int __c = (c); \ |
|
(__c >= 'A' && __c <= 'Z'); \ |
|
}) |
|
#endif |
|
|
|
#if C_CTYPE_CONSECUTIVE_DIGITS \ |
|
&& C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE |
|
#if C_CTYPE_ASCII |
|
#undef c_isxdigit |
|
#define c_isxdigit(c) \ |
|
({ int __c = (c); \ |
|
((__c >= '0' && __c <= '9') \ |
|
|| ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'F')); \ |
|
}) |
|
#else |
|
#undef c_isxdigit |
|
#define c_isxdigit(c) \ |
|
({ int __c = (c); \ |
|
((__c >= '0' && __c <= '9') \ |
|
|| (__c >= 'A' && __c <= 'F') \ |
|
|| (__c >= 'a' && __c <= 'f')); \ |
|
}) |
|
#endif |
|
#endif |
|
|
|
#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE |
|
#undef c_tolower |
|
#define c_tolower(c) \ |
|
({ int __c = (c); \ |
|
(__c >= 'A' && __c <= 'Z' ? __c - 'A' + 'a' : __c); \ |
|
}) |
|
#undef c_toupper |
|
#define c_toupper(c) \ |
|
({ int __c = (c); \ |
|
(__c >= 'a' && __c <= 'z' ? __c - 'a' + 'A' : __c); \ |
|
}) |
|
#endif |
|
|
|
#endif /* optimizing for speed */ |
|
|
|
|
|
#ifdef __cplusplus |
#ifdef __cplusplus |
} |
} |
#endif |
#endif |
|
|
|
_GL_INLINE_HEADER_END |
|
|
#endif /* C_CTYPE_H */ |
#endif /* C_CTYPE_H */ |