+2015-09-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ c-ctype: rewrite to use inline functions
+ This simplifies maintenance, since it makes for just one
+ implementation of each function, letting the compiler have the fun
+ of optimization. In practice this works well nowadays with GCC.
+ E.g., c_isascii might need only three instructions even though the
+ source code lists every ASCII character individually in a large
+ switch statement.
+ Also, fix some z/OS porting bugs reported by Daniel Richard G. in:
+ http://lists.gnu.org/archive/html/bug-gnulib/2015-09/msg00037.html
+ * NEWS: Document the API change.
+ * lib/c-ctype.c: Drastically simplify, since this now just expands
+ inline functions.
+ * lib/c-ctype.h: Use _GL_INLINE_HEADER_BEGIN, _GL_INLINE_HEADER_END.
+ (C_CTYPE_INLINE): New macro.
+ (C_CTYPE_CONSECUTIVE_DIGITS, C_CTYPE_CONSECUTIVE_LOWERCASE)
+ (C_CTYPE_CONSECUTIVE_UPPERCASE): Remove.
+ Verify that either ASCII or EBCDIC is being used.
+ (_C_CTYPE_SIGNED_EBCDIC, _C_CTYPE_CNTRL, _C_CTYPE_A_THRU_F_N)
+ (_C_CTYPE_DIGIT_N, _C_CTYPE_LOWER_N, _C_CTYPE_UPPER_N)
+ (_C_CTYPE_CASES, _C_CTYPE_A_THRU_F, _C_CTYPE_DIGIT, _C_CTYPE_LOWER)
+ (_C_CTYPE_UPPER, _C_CTYPE_PUNCT_PLAIN):
+ New private macros.
+ (_C_CTYPE_CNTRL): In EBCDIC, '\x07' is a control, not '\xff'.
+ (c_isalnum, c_isalpha, c_isascii, c_isblank, c_iscntrl, c_isdigit)
+ (c_isgraph, c_islower, c_isprint, c_ispunct, c_isspace, c_isupper)
+ (c_isxdigit, c_tolower, c_toupper): Now inline functions.
+ (c_tolower, c_toupper): When converting, return the unsigned char,
+ as that is what z/OS does.
+ * lib/c-strcaseeq.h (CASEEQ): Simplify in the light of the removal
+ of some c-ctype.h macros.
+ * modules/c-ctype (Depends-on): Add extern-inline; remove verify.
+ * tests/test-c-ctype.c (test_all): Fix test for c_toupper and
+ c_tolower promotion to be compatible with z/OS.
+
2015-09-24 Pavel Raiskup <praiskup@redhat.com>
gitlog-to-changelog: trim only trailing whitespaces
Date Modules Changes
+2015-09-25 c-ctype The following macros were removed:
+ C_CTYPE_CONSECUTIVE_DIGITS
+ C_CTYPE_CONSECUTIVE_LOWERCASE
+ C_CTYPE_CONSECUTIVE_UPPERCASE
+
2015-09-22 savewd SAVEWD_CHDIR_READABLE constant removed.
2015-07-24 fprintftime Exported functions' time zone arguments are now of
-/* Character handling in C locale.
-
- Copyright 2000-2003, 2006, 2009-2015 Free Software Foundation, Inc.
-
-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
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, see <http://www.gnu.org/licenses/>. */
-
#include <config.h>
-
-/* Specification. */
-#define NO_C_CTYPE_MACROS
+#define C_CTYPE_INLINE _GL_EXTERN_INLINE
#include "c-ctype.h"
-
-#include <limits.h>
-#include "verify.h"
-
-#ifndef C_CTYPE_ASCII
-enum { C_CTYPE_ASCII = false };
-#endif
-#ifndef C_CTYPE_CONSECUTIVE_DIGITS
-enum { C_CTYPE_CONSECUTIVE_DIGITS = false };
-#endif
-#ifndef C_CTYPE_CONSECUTIVE_LOWERCASE
-enum { C_CTYPE_CONSECUTIVE_LOWERCASE = false };
-#endif
-#ifndef C_CTYPE_CONSECUTIVE_UPPERCASE
-enum { C_CTYPE_CONSECUTIVE_UPPERCASE = false };
-#endif
-
-enum
- {
- /* True if this appears to be a host using EBCDIC. */
- C_CTYPE_EBCDIC = (' ' == '\x40' && '0' == '\xf0'
- && 'A' == '\xc1' && 'J' == '\xd1' && 'S' == '\xe2'
- && 'a' == '\x81' && 'j' == '\x91' && 's' == '\xa2')
- };
-
-/* The implementation currently supports ASCII and EBCDIC. */
-verify (C_CTYPE_ASCII || C_CTYPE_EBCDIC);
-
-/* Convert an int, which may be promoted from either an unsigned or a
- signed char, to the corresponding char. */
-
-static char
-to_char (int c)
-{
- enum { nchars = CHAR_MAX - CHAR_MIN + 1 };
- if (CHAR_MIN < 0 && CHAR_MAX < c && c < nchars)
- return c - nchars;
- return c;
-}
-
-/* The function isascii is not locale dependent. Its use in EBCDIC is
- questionable. */
-bool
-c_isascii (int c)
-{
- if (C_CTYPE_ASCII)
- return 0 <= c && c <= 0x7f;
-
- /* Use EBCDIC code page 1047's assignments for ASCII control chars;
- assume all EBCDIC code pages agree about these assignments. */
- switch (to_char (c))
- {
- case '\x00': case '\x01': case '\x02': case '\x03': case '\x05':
- case '\x0b': case '\x0c': case '\x0d': case '\x0e': case '\x0f':
- case '\x10': case '\x11': case '\x12': case '\x13': case '\x15':
- case '\x16': case '\x18': case '\x19': case '\x1c': case '\x1d':
- case '\x1e': case '\x1f': case '\x26': case '\x27': case '\x2d':
- case '\x2e': case '\x2f': case '\x32': case '\x37': case '\x3c':
- case '\x3d': case '\x3f': case '\xff':
- case '\xff' < 0 ? 0xff : -1:
-
- case ' ': case '!': case '"': case '#': case '$': case '%':
- case '&': case '\'': case '(': case ')': case '*': case '+':
- case ',': case '-': case '.': case '/':
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- case ':': case ';': case '<': case '=': case '>': case '?':
- case '@':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
- case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
- case 'Y': case 'Z':
- case '[': case '\\': case ']': case '^': case '_': case '`':
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
- case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
- case 's': case 't': case 'u': case 'v': case 'w': case 'x':
- case 'y': case 'z':
- case '{': case '|': case '}': case '~':
- return true;
- default:
- return false;
- }
-}
-
-bool
-c_isalnum (int c)
-{
- if (C_CTYPE_CONSECUTIVE_DIGITS
- && C_CTYPE_CONSECUTIVE_UPPERCASE
- && C_CTYPE_CONSECUTIVE_LOWERCASE)
- {
- if (C_CTYPE_ASCII)
- return (('0' <= c && c <= '9')
- || ('A' <= (c & ~0x20) && (c & ~0x20) <= 'Z'));
- else
- return (('0' <= c && c <= '9')
- || ('A' <= c && c <= 'Z')
- || ('a' <= c && c <= 'z'));
- }
-
- switch (to_char (c))
- {
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
- case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
- case 'Y': case 'Z':
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
- case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
- case 's': case 't': case 'u': case 'v': case 'w': case 'x':
- case 'y': case 'z':
- return true;
- default:
- return false;
- }
-}
-
-bool
-c_isalpha (int c)
-{
- if (C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE)
- {
- if (C_CTYPE_ASCII)
- return 'A' <= (c & ~0x20) && (c & ~0x20) <= 'Z';
- else
- return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z');
- }
-
- switch (to_char (c))
- {
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
- case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
- case 'Y': case 'Z':
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
- case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
- case 's': case 't': case 'u': case 'v': case 'w': case 'x':
- case 'y': case 'z':
- return true;
- default:
- return false;
- }
-}
-
-bool
-c_isblank (int c)
-{
- return (c == ' ' || c == '\t');
-}
-
-bool
-c_iscntrl (int c)
-{
- if (C_CTYPE_ASCII)
- return (0 <= c && c < ' ') || c == 0x7f;
-
- /* Use EBCDIC code page 1047's assignments for ASCII control chars;
- assume all EBCDIC code pages agree about these assignments. */
- switch (c)
- {
- case '\x00': case '\x01': case '\x02': case '\x03': case '\x05':
- case '\x0b': case '\x0c': case '\x0d': case '\x0e': case '\x0f':
- case '\x10': case '\x11': case '\x12': case '\x13': case '\x15':
- case '\x16': case '\x18': case '\x19': case '\x1c': case '\x1d':
- case '\x1e': case '\x1f': case '\x26': case '\x27': case '\x2d':
- case '\x2e': case '\x2f': case '\x32': case '\x37': case '\x3c':
- case '\x3d': case '\x3f': case '\xff':
- case '\xff' < 0 ? 0xff : -1:
- return true;
- default:
- return false;
- }
-}
-
-bool
-c_isdigit (int c)
-{
- if (C_CTYPE_ASCII)
- return '0' <= c && c <= '9';
-
- c = to_char (c);
- if (C_CTYPE_CONSECUTIVE_DIGITS)
- return '0' <= c && c <= '9';
-
- switch (c)
- {
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- return true;
- default:
- return false;
- }
-}
-
-bool
-c_islower (int c)
-{
- if (C_CTYPE_CONSECUTIVE_LOWERCASE)
- return 'a' <= c && c <= 'z';
-
- switch (to_char (c))
- {
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
- case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
- case 's': case 't': case 'u': case 'v': case 'w': case 'x':
- case 'y': case 'z':
- return true;
- default:
- return false;
- }
-}
-
-bool
-c_isgraph (int c)
-{
- if (C_CTYPE_ASCII)
- return '!' <= c && c <= '~';
-
- switch (to_char (c))
- {
- case '!': case '"': case '#': case '$': case '%': case '&':
- case '\'': case '(': case ')': case '*': case '+': case ',':
- case '-': case '.': case '/':
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- case ':': case ';': case '<': case '=': case '>': case '?':
- case '@':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
- case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
- case 'Y': case 'Z':
- case '[': case '\\': case ']': case '^': case '_': case '`':
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
- case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
- case 's': case 't': case 'u': case 'v': case 'w': case 'x':
- case 'y': case 'z':
- case '{': case '|': case '}': case '~':
- return true;
- default:
- return false;
- }
-}
-
-bool
-c_isprint (int c)
-{
- if (C_CTYPE_ASCII)
- return ' ' <= c && c <= '~';
-
- switch (to_char (c))
- {
- case ' ': case '!': case '"': case '#': case '$': case '%':
- case '&': case '\'': case '(': case ')': case '*': case '+':
- case ',': case '-': case '.': case '/':
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- case ':': case ';': case '<': case '=': case '>': case '?':
- case '@':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
- case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
- case 'Y': case 'Z':
- case '[': case '\\': case ']': case '^': case '_': case '`':
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
- case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
- case 's': case 't': case 'u': case 'v': case 'w': case 'x':
- case 'y': case 'z':
- case '{': case '|': case '}': case '~':
- return true;
- default:
- return false;
- }
-}
-
-bool
-c_ispunct (int c)
-{
- if (C_CTYPE_ASCII)
- return (('!' <= c && c <= '~')
- && !(('0' <= c && c <= '9')
- || ('A' <= (c & ~0x20) && (c & ~0x20) <= 'Z')));
-
- switch (to_char (c))
- {
- 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 '~':
- return true;
- default:
- return false;
- }
-}
-
-bool
-c_isspace (int c)
-{
- return (c == ' ' || c == '\t'
- || c == '\n' || c == '\v' || c == '\f' || c == '\r');
-}
-
-bool
-c_isupper (int c)
-{
- if (C_CTYPE_CONSECUTIVE_UPPERCASE)
- return 'A' <= c && c <= 'Z';
-
- switch (to_char (c))
- {
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
- case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
- case 'Y': case 'Z':
- return true;
- default:
- return false;
- }
-}
-
-bool
-c_isxdigit (int c)
-{
- if (C_CTYPE_CONSECUTIVE_DIGITS
- && C_CTYPE_CONSECUTIVE_UPPERCASE
- && C_CTYPE_CONSECUTIVE_LOWERCASE)
- {
- if ('0' <= c && c <= '9')
- return true;
- if (C_CTYPE_ASCII)
- return 'A' <= (c & ~0x20) && (c & ~0x20) <= 'F';
- return (('A' <= c && c <= 'F')
- || ('a' <= c && c <= 'f'));
- }
-
- switch (to_char (c))
- {
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- return true;
- default:
- return false;
- }
-}
-
-int
-c_tolower (int c)
-{
- if (C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE)
- return c_isupper (c) ? c - 'A' + 'a' : c;
-
- switch (to_char (c))
- {
- case 'A': return 'a';
- case 'B': return 'b';
- case 'C': return 'c';
- case 'D': return 'd';
- case 'E': return 'e';
- case 'F': return 'f';
- case 'G': return 'g';
- case 'H': return 'h';
- case 'I': return 'i';
- case 'J': return 'j';
- case 'K': return 'k';
- case 'L': return 'l';
- case 'M': return 'm';
- case 'N': return 'n';
- case 'O': return 'o';
- case 'P': return 'p';
- case 'Q': return 'q';
- case 'R': return 'r';
- case 'S': return 's';
- case 'T': return 't';
- case 'U': return 'u';
- case 'V': return 'v';
- case 'W': return 'w';
- case 'X': return 'x';
- case 'Y': return 'y';
- case 'Z': return 'z';
- default: return c;
- }
-}
-
-int
-c_toupper (int c)
-{
- if (C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE)
- return c_islower (c) ? c - 'a' + 'A' : c;
-
- switch (to_char (c))
- {
- case 'a': return 'A';
- case 'b': return 'B';
- case 'c': return 'C';
- case 'd': return 'D';
- case 'e': return 'E';
- case 'f': return 'F';
- case 'g': return 'G';
- case 'h': return 'H';
- case 'i': return 'I';
- case 'j': return 'J';
- case 'k': return 'K';
- case 'l': return 'L';
- case 'm': return 'M';
- case 'n': return 'N';
- case 'o': return 'O';
- case 'p': return 'P';
- case 'q': return 'Q';
- case 'r': return 'R';
- case 's': return 'S';
- case 't': return 'T';
- case 'u': return 'U';
- case 'v': return 'V';
- case 'w': return 'W';
- case 'x': return 'X';
- case 'y': return 'Y';
- case 'z': return 'Z';
- default: return c;
- }
-}
#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
extern "C" {
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) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
/* The character set is ASCII or one of its variants or extensions, not EBCDIC.
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
+
+#define _C_CTYPE_SIGNED_EBCDIC ('A' < 0)
+
+#if C_CTYPE_ASCII
+# define _C_CTYPE_CNTRL \
+ case '\x00': case '\x01': case '\x02': case '\x03': \
+ case '\x04': case '\x05': case '\x06': case '\x07': \
+ case '\x08': case '\x09': case '\x0a': case '\x0b': \
+ case '\x0c': case '\x0d': 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_CNTRL \
+ case '\x00': case '\x01': case '\x02': case '\x03': \
+ case '\x05': case '\x07': case '\x0b': case '\x0c': \
+ case '\x0d': case '\x0e': case '\x0f': case '\x10': \
+ case '\x11': case '\x12': case '\x13': case '\x16': \
+ case '\x18': case '\x19': case '\x1c': case '\x1d': \
+ case '\x1e': case '\x1f': case '\x25': case '\x26': \
+ case '\x27': case '\x2d': case '\x2e': case '\x2f': \
+ case '\x32': case '\x37': case '\x3c': case '\x3d': \
+ case '\x3f'
#endif
+/* Cases for hex letter digits, digits, lower, and upper, offset by N. */
+
+#define _C_CTYPE_A_THRU_F_N(n) \
+ case 'a' + (n): case 'b' + (n): case 'c' + (n): case 'd' + (n): \
+ case 'e' + (n): case 'f' + (n): \
+ case 'A' + (n): case 'B' + (n): case 'C' + (n): case 'D' + (n): \
+ case 'E' + (n): case 'F' + (n)
+#define _C_CTYPE_DIGIT_N(n) \
+ case '0' + (n): case '1' + (n): case '2' + (n): case '3' + (n): \
+ case '4' + (n): case '5' + (n): case '6' + (n): case '7' + (n): \
+ case '8' + (n): case '9' + (n)
+#define _C_CTYPE_LOWER_N(n) \
+ case 'a' + (n): case 'b' + (n): case 'c' + (n): case 'd' + (n): \
+ case 'e' + (n): case 'f' + (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)
+#define _C_CTYPE_UPPER_N(n) \
+ case 'A' + (n): case 'B' + (n): case 'C' + (n): case 'D' + (n): \
+ case 'E' + (n): case 'F' + (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)
+
+/* Given MACRO_N, expand to all the cases for the corresponding class. */
+#if _C_CTYPE_SIGNED_EBCDIC
+# define _C_CTYPE_CASES(macro_n) macro_n (0): macro_n (256)
+#else
+# define _C_CTYPE_CASES(macro_n) macro_n (0)
+#endif
-/* Function declarations. */
+/* Cases for hex letter digits, digits, lower, and upper, with another
+ case for unsigned char if the original char is negative. */
+
+#define _C_CTYPE_A_THRU_F _C_CTYPE_CASES (_C_CTYPE_A_THRU_F_N)
+#define _C_CTYPE_DIGIT _C_CTYPE_CASES (_C_CTYPE_DIGIT_N)
+#define _C_CTYPE_LOWER _C_CTYPE_CASES (_C_CTYPE_LOWER_N)
+#define _C_CTYPE_UPPER _C_CTYPE_CASES (_C_CTYPE_UPPER_N)
+
+/* The punct class differs because some punctuation characters may be
+ negative while others are nonnegative. Instead of attempting to
+ define _C_CTYPE_PUNCT, define just the plain chars here, and do any
+ cases-plus-256 by hand after using this macro. */
+#define _C_CTYPE_PUNCT_PLAIN \
+ 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 '~'
+
+/* Function definitions. */
/* 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
if (c_isalpha (*s)) ...
*/
-extern bool c_isascii (int c) _GL_ATTRIBUTE_CONST; /* 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) _GL_ATTRIBUTE_CONST;
-extern bool c_isalpha (int c) _GL_ATTRIBUTE_CONST;
-extern bool c_isblank (int c) _GL_ATTRIBUTE_CONST;
-extern bool c_iscntrl (int c) _GL_ATTRIBUTE_CONST;
-extern bool c_isdigit (int c) _GL_ATTRIBUTE_CONST;
-extern bool c_islower (int c) _GL_ATTRIBUTE_CONST;
-extern bool c_isgraph (int c) _GL_ATTRIBUTE_CONST;
-extern bool c_isprint (int c) _GL_ATTRIBUTE_CONST;
-extern bool c_ispunct (int c) _GL_ATTRIBUTE_CONST;
-extern bool c_isspace (int c) _GL_ATTRIBUTE_CONST;
-extern bool c_isupper (int c) _GL_ATTRIBUTE_CONST;
-extern bool c_isxdigit (int c) _GL_ATTRIBUTE_CONST;
+C_CTYPE_INLINE bool
+c_isalpha (int c)
+{
+ switch (c)
+ {
+ _C_CTYPE_LOWER:
+ _C_CTYPE_UPPER:
+ return true;
+
+ default:
+ return false;
+ }
+}
-extern int c_tolower (int c) _GL_ATTRIBUTE_CONST;
-extern int c_toupper (int c) _GL_ATTRIBUTE_CONST;
+/* The function isascii is not locale dependent.
+ 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_UPPER:
+
+ _C_CTYPE_PUNCT_PLAIN:
+#if '!' < 0
+ case '!' + 256:
+#endif
+#if '"' < 0
+ case '"' + 256:
+#endif
+#if '#' < 0
+ case '#' + 256:
+#endif
+#if '$' < 0
+ case '$' + 256:
+#endif
+#if '%' < 0
+ case '%' + 256:
+#endif
+#if '&' < 0
+ case '&' + 256:
+#endif
+#if '\'' < 0
+ case '\'' + 256:
+#endif
+#if '(' < 0
+ case '(' + 256:
+#endif
+#if ')' < 0
+ case ')' + 256:
+#endif
+#if '*' < 0
+ case '*' + 256:
+#endif
+#if '+' < 0
+ case '+' + 256:
+#endif
+#if ',' < 0
+ case ',' + 256:
+#endif
+#if '-' < 0
+ case '-' + 256:
+#endif
+#if '.' < 0
+ case '.' + 256:
+#endif
+#if '/' < 0
+ case '/' + 256:
+#endif
+#if ':' < 0
+ case ':' + 256:
+#endif
+#if ';' < 0
+ case ';' + 256:
+#endif
+#if '<' < 0
+ case '<' + 256:
+#endif
+#if '=' < 0
+ case '=' + 256:
+#endif
+#if '>' < 0
+ case '>' + 256:
+#endif
+#if '?' < 0
+ case '?' + 256:
+#endif
+#if '@' < 0
+ case '@' + 256:
+#endif
+#if '[' < 0
+ case '[' + 256:
+#endif
+#if '\\' < 0
+ case '\\' + 256:
+#endif
+#if ']' < 0
+ case ']' + 256:
+#endif
+#if '^' < 0
+ case '^' + 256:
+#endif
+#if '_' < 0
+ case '_' + 256:
+#endif
+#if '`' < 0
+ case '`' + 256:
+#endif
+#if '{' < 0
+ case '{' + 256:
+#endif
+#if '|' < 0
+ case '|' + 256:
+#endif
+#if '}' < 0
+ case '}' + 256:
+#endif
+#if '~' < 0
+ case '~' + 256:
+#endif
+ return true;
+ default:
+ return false;
+ }
+}
-#if (defined __GNUC__ && !defined __STRICT_ANSI__ && defined __OPTIMIZE__ \
- && !defined __OPTIMIZE_SIZE__ && !defined NO_C_CTYPE_MACROS)
+C_CTYPE_INLINE bool
+c_isblank (int c)
+{
+ return c == ' ' || c == '\t';
+}
-/* ASCII optimizations. */
+C_CTYPE_INLINE bool
+c_iscntrl (int c)
+{
+ switch (c)
+ {
+ _C_CTYPE_CNTRL:
+ return true;
+ default:
+ return false;
+ }
+}
-#undef c_isascii
-#define c_isascii(c) \
- ({ int __c = (c); \
- (__c >= 0x00 && __c <= 0x7f); \
- })
+C_CTYPE_INLINE bool
+c_isdigit (int c)
+{
+ switch (c)
+ {
+ _C_CTYPE_DIGIT:
+ return true;
+ default:
+ return false;
+ }
+}
-#if C_CTYPE_CONSECUTIVE_DIGITS \
- && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
-#if C_CTYPE_ASCII
-#undef c_isalnum
-#define c_isalnum(c) \
- ({ int __c = (c); \
- ((__c >= '0' && __c <= '9') \
- || ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z')); \
- })
-#else
-#undef c_isalnum
-#define c_isalnum(c) \
- ({ int __c = (c); \
- ((__c >= '0' && __c <= '9') \
- || (__c >= 'A' && __c <= 'Z') \
- || (__c >= 'a' && __c <= 'z')); \
- })
+C_CTYPE_INLINE bool
+c_isgraph (int c)
+{
+ switch (c)
+ {
+ _C_CTYPE_DIGIT:
+ _C_CTYPE_LOWER:
+ _C_CTYPE_UPPER:
+
+ _C_CTYPE_PUNCT_PLAIN:
+#if '!' < 0
+ case '!' + 256:
#endif
+#if '"' < 0
+ case '"' + 256:
#endif
-
-#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
-#if C_CTYPE_ASCII
-#undef c_isalpha
-#define c_isalpha(c) \
- ({ int __c = (c); \
- ((__c & ~0x20) >= 'A' && (__c & ~0x20) <= 'Z'); \
- })
-#else
-#undef c_isalpha
-#define c_isalpha(c) \
- ({ int __c = (c); \
- ((__c >= 'A' && __c <= 'Z') || (__c >= 'a' && __c <= 'z')); \
- })
+#if '#' < 0
+ case '#' + 256:
+#endif
+#if '$' < 0
+ case '$' + 256:
+#endif
+#if '%' < 0
+ case '%' + 256:
+#endif
+#if '&' < 0
+ case '&' + 256:
+#endif
+#if '\'' < 0
+ case '\'' + 256:
+#endif
+#if '(' < 0
+ case '(' + 256:
+#endif
+#if ')' < 0
+ case ')' + 256:
+#endif
+#if '*' < 0
+ case '*' + 256:
+#endif
+#if '+' < 0
+ case '+' + 256:
+#endif
+#if ',' < 0
+ case ',' + 256:
+#endif
+#if '-' < 0
+ case '-' + 256:
+#endif
+#if '.' < 0
+ case '.' + 256:
+#endif
+#if '/' < 0
+ case '/' + 256:
+#endif
+#if ':' < 0
+ case ':' + 256:
+#endif
+#if ';' < 0
+ case ';' + 256:
+#endif
+#if '<' < 0
+ case '<' + 256:
+#endif
+#if '=' < 0
+ case '=' + 256:
+#endif
+#if '>' < 0
+ case '>' + 256:
+#endif
+#if '?' < 0
+ case '?' + 256:
+#endif
+#if '@' < 0
+ case '@' + 256:
+#endif
+#if '[' < 0
+ case '[' + 256:
+#endif
+#if '\\' < 0
+ case '\\' + 256:
+#endif
+#if ']' < 0
+ case ']' + 256:
+#endif
+#if '^' < 0
+ case '^' + 256:
+#endif
+#if '_' < 0
+ case '_' + 256:
+#endif
+#if '`' < 0
+ case '`' + 256:
+#endif
+#if '{' < 0
+ case '{' + 256:
+#endif
+#if '|' < 0
+ case '|' + 256:
+#endif
+#if '}' < 0
+ case '}' + 256:
#endif
+#if '~' < 0
+ case '~' + 256:
#endif
+ return true;
-#undef c_isblank
-#define c_isblank(c) \
- ({ int __c = (c); \
- (__c == ' ' || __c == '\t'); \
- })
+ default:
+ return false;
+ }
+}
-#if C_CTYPE_ASCII
-#undef c_iscntrl
-#define c_iscntrl(c) \
- ({ int __c = (c); \
- ((__c & ~0x1f) == 0 || __c == 0x7f); \
- })
-#endif
+C_CTYPE_INLINE bool
+c_islower (int c)
+{
+ switch (c)
+ {
+ _C_CTYPE_LOWER:
+ return true;
+ default:
+ return false;
+ }
+}
-#if C_CTYPE_CONSECUTIVE_DIGITS
-#undef c_isdigit
-#define c_isdigit(c) \
- ({ int __c = (c); \
- (__c >= '0' && __c <= '9'); \
- })
+C_CTYPE_INLINE bool
+c_isprint (int c)
+{
+ switch (c)
+ {
+ case ' ':
+ _C_CTYPE_DIGIT:
+ _C_CTYPE_LOWER:
+ _C_CTYPE_UPPER:
+
+ _C_CTYPE_PUNCT_PLAIN:
+#if '!' < 0
+ case '!' + 256:
#endif
-
-#if C_CTYPE_CONSECUTIVE_LOWERCASE
-#undef c_islower
-#define c_islower(c) \
- ({ int __c = (c); \
- (__c >= 'a' && __c <= 'z'); \
- })
+#if '"' < 0
+ case '"' + 256:
#endif
-
-#if C_CTYPE_ASCII
-#undef c_isgraph
-#define c_isgraph(c) \
- ({ int __c = (c); \
- (__c >= '!' && __c <= '~'); \
- })
+#if '#' < 0
+ case '#' + 256:
#endif
-
-#if C_CTYPE_ASCII
-#undef c_isprint
-#define c_isprint(c) \
- ({ int __c = (c); \
- (__c >= ' ' && __c <= '~'); \
- })
+#if '$' < 0
+ case '$' + 256:
+#endif
+#if '%' < 0
+ case '%' + 256:
+#endif
+#if '&' < 0
+ case '&' + 256:
+#endif
+#if '\'' < 0
+ case '\'' + 256:
+#endif
+#if '(' < 0
+ case '(' + 256:
+#endif
+#if ')' < 0
+ case ')' + 256:
+#endif
+#if '*' < 0
+ case '*' + 256:
+#endif
+#if '+' < 0
+ case '+' + 256:
+#endif
+#if ',' < 0
+ case ',' + 256:
+#endif
+#if '-' < 0
+ case '-' + 256:
+#endif
+#if '.' < 0
+ case '.' + 256:
+#endif
+#if '/' < 0
+ case '/' + 256:
+#endif
+#if ':' < 0
+ case ':' + 256:
+#endif
+#if ';' < 0
+ case ';' + 256:
#endif
+#if '<' < 0
+ case '<' + 256:
+#endif
+#if '=' < 0
+ case '=' + 256:
+#endif
+#if '>' < 0
+ case '>' + 256:
+#endif
+#if '?' < 0
+ case '?' + 256:
+#endif
+#if '@' < 0
+ case '@' + 256:
+#endif
+#if '[' < 0
+ case '[' + 256:
+#endif
+#if '\\' < 0
+ case '\\' + 256:
+#endif
+#if ']' < 0
+ case ']' + 256:
+#endif
+#if '^' < 0
+ case '^' + 256:
+#endif
+#if '_' < 0
+ case '_' + 256:
+#endif
+#if '`' < 0
+ case '`' + 256:
+#endif
+#if '{' < 0
+ case '{' + 256:
+#endif
+#if '|' < 0
+ case '|' + 256:
+#endif
+#if '}' < 0
+ case '}' + 256:
+#endif
+#if '~' < 0
+ case '~' + 256:
+#endif
+ return true;
-#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')); \
- })
+ default:
+ return false;
+ }
+}
+
+C_CTYPE_INLINE bool
+c_ispunct (int c)
+{
+ switch (c)
+ {
+ _C_CTYPE_PUNCT_PLAIN:
+#if '!' < 0
+ case '!' + 256:
+#endif
+#if '"' < 0
+ case '"' + 256:
#endif
+#if '#' < 0
+ case '#' + 256:
#endif
+#if '$' < 0
+ case '$' + 256:
+#endif
+#if '%' < 0
+ case '%' + 256:
+#endif
+#if '&' < 0
+ case '&' + 256:
+#endif
+#if '\'' < 0
+ case '\'' + 256:
+#endif
+#if '(' < 0
+ case '(' + 256:
+#endif
+#if ')' < 0
+ case ')' + 256:
+#endif
+#if '*' < 0
+ case '*' + 256:
+#endif
+#if '+' < 0
+ case '+' + 256:
+#endif
+#if ',' < 0
+ case ',' + 256:
+#endif
+#if '-' < 0
+ case '-' + 256:
+#endif
+#if '.' < 0
+ case '.' + 256:
+#endif
+#if '/' < 0
+ case '/' + 256:
+#endif
+#if ':' < 0
+ case ':' + 256:
+#endif
+#if ';' < 0
+ case ';' + 256:
+#endif
+#if '<' < 0
+ case '<' + 256:
+#endif
+#if '=' < 0
+ case '=' + 256:
+#endif
+#if '>' < 0
+ case '>' + 256:
+#endif
+#if '?' < 0
+ case '?' + 256:
+#endif
+#if '@' < 0
+ case '@' + 256:
+#endif
+#if '[' < 0
+ case '[' + 256:
+#endif
+#if '\\' < 0
+ case '\\' + 256:
+#endif
+#if ']' < 0
+ case ']' + 256:
+#endif
+#if '^' < 0
+ case '^' + 256:
+#endif
+#if '_' < 0
+ case '_' + 256:
+#endif
+#if '`' < 0
+ case '`' + 256:
+#endif
+#if '{' < 0
+ case '{' + 256:
+#endif
+#if '|' < 0
+ case '|' + 256:
+#endif
+#if '}' < 0
+ case '}' + 256:
+#endif
+#if '~' < 0
+ case '~' + 256:
+#endif
+ return true;
-#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); \
- })
+ default:
+ return false;
+ }
+}
+
+C_CTYPE_INLINE bool
+c_isspace (int c)
+{
+ switch (c)
+ {
+ case ' ': case '\t': case '\n': case '\v': case '\f': case '\r':
+ return true;
+ default:
+ return false;
+ }
+}
+
+C_CTYPE_INLINE bool
+c_isupper (int c)
+{
+ switch (c)
+ {
+ _C_CTYPE_UPPER:
+ return true;
+ default:
+ return false;
+ }
+}
+
+C_CTYPE_INLINE bool
+c_isxdigit (int c)
+{
+ switch (c)
+ {
+ _C_CTYPE_DIGIT:
+ _C_CTYPE_A_THRU_F:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+C_CTYPE_INLINE int
+c_tolower (int c)
+{
+ switch (c)
+ {
+ _C_CTYPE_UPPER_N (0):
+#if _C_CTYPE_SIGNED_EBCDIC
+ c += 256;
+ /* Fall through. */
+ _C_CTYPE_UPPER_N (256):
#endif
+ return c - 'A' + 'a';
-#endif /* optimizing for speed */
+ default:
+ return c;
+ }
+}
+C_CTYPE_INLINE int
+c_toupper (int c)
+{
+ switch (c)
+ {
+ _C_CTYPE_LOWER_N (0):
+#if _C_CTYPE_SIGNED_EBCDIC
+ c += 256;
+ /* Fall through. */
+ _C_CTYPE_LOWER_N (256):
+#endif
+ return c - 'a' + 'A';
+
+ default:
+ return c;
+ }
+}
#ifdef __cplusplus
}
#endif
+_GL_INLINE_HEADER_END
+
#endif /* C_CTYPE_H */
# if C_CTYPE_ASCII
# define CASEEQ(other,upper) \
(c_isupper (upper) ? ((other) & ~0x20) == (upper) : (other) == (upper))
-# elif C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
-# define CASEEQ(other,upper) \
- (c_isupper (upper) ? (other) == (upper) || (other) == (upper) - 'A' + 'a' : (other) == (upper))
# else
# define CASEEQ(other,upper) \
(c_toupper (other) == (upper))
lib/c-ctype.c
Depends-on:
+extern-inline
stdbool
-verify
configure.ac:
switch (to_char (c))
{
- case 'A':
- ASSERT (c_tolower (c) == 'a');
- ASSERT (c_toupper (c) == c);
- break;
- case 'B':
- ASSERT (c_tolower (c) == 'b');
- ASSERT (c_toupper (c) == c);
- break;
- case 'C':
- ASSERT (c_tolower (c) == 'c');
- ASSERT (c_toupper (c) == c);
- break;
- case 'D':
- ASSERT (c_tolower (c) == 'd');
- ASSERT (c_toupper (c) == c);
- break;
- case 'E':
- ASSERT (c_tolower (c) == 'e');
- ASSERT (c_toupper (c) == c);
- break;
- case 'F':
- ASSERT (c_tolower (c) == 'f');
- ASSERT (c_toupper (c) == c);
- break;
- case 'G':
- ASSERT (c_tolower (c) == 'g');
- ASSERT (c_toupper (c) == c);
- break;
- case 'H':
- ASSERT (c_tolower (c) == 'h');
- ASSERT (c_toupper (c) == c);
- break;
- case 'I':
- ASSERT (c_tolower (c) == 'i');
- ASSERT (c_toupper (c) == c);
- break;
- case 'J':
- ASSERT (c_tolower (c) == 'j');
- ASSERT (c_toupper (c) == c);
- break;
- case 'K':
- ASSERT (c_tolower (c) == 'k');
- ASSERT (c_toupper (c) == c);
- break;
- case 'L':
- ASSERT (c_tolower (c) == 'l');
- ASSERT (c_toupper (c) == c);
- break;
- case 'M':
- ASSERT (c_tolower (c) == 'm');
- ASSERT (c_toupper (c) == c);
- break;
- case 'N':
- ASSERT (c_tolower (c) == 'n');
- ASSERT (c_toupper (c) == c);
- break;
- case 'O':
- ASSERT (c_tolower (c) == 'o');
- ASSERT (c_toupper (c) == c);
- break;
- case 'P':
- ASSERT (c_tolower (c) == 'p');
- ASSERT (c_toupper (c) == c);
- break;
- case 'Q':
- ASSERT (c_tolower (c) == 'q');
- ASSERT (c_toupper (c) == c);
- break;
- case 'R':
- ASSERT (c_tolower (c) == 'r');
- ASSERT (c_toupper (c) == c);
- break;
- case 'S':
- ASSERT (c_tolower (c) == 's');
- ASSERT (c_toupper (c) == c);
- break;
- case 'T':
- ASSERT (c_tolower (c) == 't');
- ASSERT (c_toupper (c) == c);
- break;
- case 'U':
- ASSERT (c_tolower (c) == 'u');
- ASSERT (c_toupper (c) == c);
- break;
- case 'V':
- ASSERT (c_tolower (c) == 'v');
- ASSERT (c_toupper (c) == c);
- break;
- case 'W':
- ASSERT (c_tolower (c) == 'w');
- ASSERT (c_toupper (c) == c);
- break;
- case 'X':
- ASSERT (c_tolower (c) == 'x');
- ASSERT (c_toupper (c) == c);
- break;
- case 'Y':
- ASSERT (c_tolower (c) == 'y');
- ASSERT (c_toupper (c) == c);
- break;
- case 'Z':
- ASSERT (c_tolower (c) == 'z');
- ASSERT (c_toupper (c) == c);
- break;
- case 'a':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'A');
- break;
- case 'b':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'B');
- break;
- case 'c':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'C');
- break;
- case 'd':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'D');
- break;
- case 'e':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'E');
- break;
- case 'f':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'F');
- break;
- case 'g':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'G');
- break;
- case 'h':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'H');
- break;
- case 'i':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'I');
- break;
- case 'j':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'J');
- break;
- case 'k':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'K');
- break;
- case 'l':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'L');
- break;
- case 'm':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'M');
- break;
- case 'n':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'N');
- break;
- case 'o':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'O');
- break;
- case 'p':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'P');
- break;
- case 'q':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'Q');
- break;
- case 'r':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'R');
- break;
- case 's':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'S');
- break;
- case 't':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'T');
- break;
- case 'u':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'U');
- break;
- case 'v':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'V');
- break;
- case 'w':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'W');
- break;
- case 'x':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'X');
- break;
- case 'y':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'Y');
- break;
- case 'z':
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == 'Z');
- break;
- default:
- ASSERT (c_tolower (c) == c);
- ASSERT (c_toupper (c) == c);
- break;
+ case 'A': ASSERT (to_char (c_tolower (c)) == 'a'); break;
+ case 'B': ASSERT (to_char (c_tolower (c)) == 'b'); break;
+ case 'C': ASSERT (to_char (c_tolower (c)) == 'c'); break;
+ case 'D': ASSERT (to_char (c_tolower (c)) == 'd'); break;
+ case 'E': ASSERT (to_char (c_tolower (c)) == 'e'); break;
+ case 'F': ASSERT (to_char (c_tolower (c)) == 'f'); break;
+ case 'G': ASSERT (to_char (c_tolower (c)) == 'g'); break;
+ case 'H': ASSERT (to_char (c_tolower (c)) == 'h'); break;
+ case 'I': ASSERT (to_char (c_tolower (c)) == 'i'); break;
+ case 'J': ASSERT (to_char (c_tolower (c)) == 'j'); break;
+ case 'K': ASSERT (to_char (c_tolower (c)) == 'k'); break;
+ case 'L': ASSERT (to_char (c_tolower (c)) == 'l'); break;
+ case 'M': ASSERT (to_char (c_tolower (c)) == 'm'); break;
+ case 'N': ASSERT (to_char (c_tolower (c)) == 'n'); break;
+ case 'O': ASSERT (to_char (c_tolower (c)) == 'o'); break;
+ case 'P': ASSERT (to_char (c_tolower (c)) == 'p'); break;
+ case 'Q': ASSERT (to_char (c_tolower (c)) == 'q'); break;
+ case 'R': ASSERT (to_char (c_tolower (c)) == 'r'); break;
+ case 'S': ASSERT (to_char (c_tolower (c)) == 's'); break;
+ case 'T': ASSERT (to_char (c_tolower (c)) == 't'); break;
+ case 'U': ASSERT (to_char (c_tolower (c)) == 'u'); break;
+ case 'V': ASSERT (to_char (c_tolower (c)) == 'v'); break;
+ case 'W': ASSERT (to_char (c_tolower (c)) == 'w'); break;
+ case 'X': ASSERT (to_char (c_tolower (c)) == 'x'); break;
+ case 'Y': ASSERT (to_char (c_tolower (c)) == 'y'); break;
+ case 'Z': ASSERT (to_char (c_tolower (c)) == 'z'); break;
+ default: ASSERT (c_tolower (c) == c); break;
+ }
+
+ switch (to_char (c))
+ {
+ case 'a': ASSERT (to_char (c_toupper (c)) == 'A'); break;
+ case 'b': ASSERT (to_char (c_toupper (c)) == 'B'); break;
+ case 'c': ASSERT (to_char (c_toupper (c)) == 'C'); break;
+ case 'd': ASSERT (to_char (c_toupper (c)) == 'D'); break;
+ case 'e': ASSERT (to_char (c_toupper (c)) == 'E'); break;
+ case 'f': ASSERT (to_char (c_toupper (c)) == 'F'); break;
+ case 'g': ASSERT (to_char (c_toupper (c)) == 'G'); break;
+ case 'h': ASSERT (to_char (c_toupper (c)) == 'H'); break;
+ case 'i': ASSERT (to_char (c_toupper (c)) == 'I'); break;
+ case 'j': ASSERT (to_char (c_toupper (c)) == 'J'); break;
+ case 'k': ASSERT (to_char (c_toupper (c)) == 'K'); break;
+ case 'l': ASSERT (to_char (c_toupper (c)) == 'L'); break;
+ case 'm': ASSERT (to_char (c_toupper (c)) == 'M'); break;
+ case 'n': ASSERT (to_char (c_toupper (c)) == 'N'); break;
+ case 'o': ASSERT (to_char (c_toupper (c)) == 'O'); break;
+ case 'p': ASSERT (to_char (c_toupper (c)) == 'P'); break;
+ case 'q': ASSERT (to_char (c_toupper (c)) == 'Q'); break;
+ case 'r': ASSERT (to_char (c_toupper (c)) == 'R'); break;
+ case 's': ASSERT (to_char (c_toupper (c)) == 'S'); break;
+ case 't': ASSERT (to_char (c_toupper (c)) == 'T'); break;
+ case 'u': ASSERT (to_char (c_toupper (c)) == 'U'); break;
+ case 'v': ASSERT (to_char (c_toupper (c)) == 'V'); break;
+ case 'w': ASSERT (to_char (c_toupper (c)) == 'W'); break;
+ case 'x': ASSERT (to_char (c_toupper (c)) == 'X'); break;
+ case 'y': ASSERT (to_char (c_toupper (c)) == 'Y'); break;
+ case 'z': ASSERT (to_char (c_toupper (c)) == 'Z'); break;
+ default: ASSERT (c_toupper (c) == c); break;
}
}