Fix isalpha(0x100000001LL) and friends on 64-bit machines.
* libc/include/ctype.h (__ctype_lookup): New macro. (isalpha, isupper, islower, isdigit, isxdigit, isspace, ispunct) (isalnum, isprint, isgraph, iscntrl, isblank): Use it to fix bug on 64-bit machines.
This commit is contained in:
parent
e83fef9d35
commit
9b2b7c4a6b
|
@ -1,3 +1,10 @@
|
||||||
|
2009-10-24 Eric Blake <ebb9@byu.net>
|
||||||
|
|
||||||
|
* libc/include/ctype.h (__ctype_lookup): New macro.
|
||||||
|
(isalpha, isupper, islower, isdigit, isxdigit, isspace, ispunct)
|
||||||
|
(isalnum, isprint, isgraph, iscntrl, isblank): Use it to fix bug
|
||||||
|
on 64-bit machines.
|
||||||
|
|
||||||
2009-10-20 Jeff Johnston <jjohnstn@redhat.com>
|
2009-10-20 Jeff Johnston <jjohnstn@redhat.com>
|
||||||
|
|
||||||
* configure.host: Don't set -O2 flag in newlib_cflags. Leave
|
* configure.host: Don't set -O2 flag in newlib_cflags. Leave
|
||||||
|
|
|
@ -47,24 +47,32 @@ extern __IMPORT char *__ctype_ptr__;
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
/* These macros are intentionally written in a manner that will trigger
|
/* These macros are intentionally written in a manner that will trigger
|
||||||
a gcc -Wall warning if the user mistakenly passes a 'char' instead
|
a gcc -Wall warning if the user mistakenly passes a 'char' instead
|
||||||
of an int containing an 'unsigned char'. */
|
of an int containing an 'unsigned char'. Note that the sizeof will
|
||||||
#define isalpha(__c) ((__ctype_ptr__+1)[__c]&(_U|_L))
|
always be 1, which is what we want for mapping EOF to __ctype_ptr__[0];
|
||||||
#define isupper(__c) (((__ctype_ptr__+1)[__c]&(_U|_L))==_U)
|
the use of a raw index inside the sizeof triggers the gcc warning if
|
||||||
#define islower(__c) (((__ctype_ptr__+1)[__c]&(_U|_L))==_L)
|
__c was of type char, and sizeof masks side effects of the extra __c.
|
||||||
#define isdigit(__c) ((__ctype_ptr__+1)[__c]&_N)
|
Meanwhile, the real index to __ctype_ptr__+1 must be cast to int,
|
||||||
#define isxdigit(__c) ((__ctype_ptr__+1)[__c]&(_X|_N))
|
since isalpha(0x100000001LL) must equal isalpha(1), rather than being
|
||||||
#define isspace(__c) ((__ctype_ptr__+1)[__c]&_S)
|
an out-of-bounds reference on a 64-bit machine. */
|
||||||
#define ispunct(__c) ((__ctype_ptr__+1)[__c]&_P)
|
#define __ctype_lookup(__c) ((__ctype_ptr__+sizeof(""[__c]))[(int)__c])
|
||||||
#define isalnum(__c) ((__ctype_ptr__+1)[__c]&(_U|_L|_N))
|
|
||||||
#define isprint(__c) ((__ctype_ptr__+1)[__c]&(_P|_U|_L|_N|_B))
|
#define isalpha(__c) (__ctype_lookup(__c)&(_U|_L))
|
||||||
#define isgraph(__c) ((__ctype_ptr__+1)[__c]&(_P|_U|_L|_N))
|
#define isupper(__c) ((__ctype_lookup(__c)&(_U|_L))==_U)
|
||||||
#define iscntrl(__c) ((__ctype_ptr__+1)[__c]&_C)
|
#define islower(__c) ((__ctype_lookup(__c)&(_U|_L))==_L)
|
||||||
|
#define isdigit(__c) (__ctype_lookup(__c)&_N)
|
||||||
|
#define isxdigit(__c) (__ctype_lookup(__c)&(_X|_N))
|
||||||
|
#define isspace(__c) (__ctype_lookup(__c)&_S)
|
||||||
|
#define ispunct(__c) (__ctype_lookup(__c)&_P)
|
||||||
|
#define isalnum(__c) (__ctype_lookup(__c)&(_U|_L|_N))
|
||||||
|
#define isprint(__c) (__ctype_lookup(__c)&(_P|_U|_L|_N|_B))
|
||||||
|
#define isgraph(__c) (__ctype_lookup(__c)&(_P|_U|_L|_N))
|
||||||
|
#define iscntrl(__c) (__ctype_lookup(__c)&_C)
|
||||||
|
|
||||||
#if defined(__GNUC__) && \
|
#if defined(__GNUC__) && \
|
||||||
(!defined(__STRICT_ANSI__) || __STDC_VERSION__ >= 199901L)
|
(!defined(__STRICT_ANSI__) || __STDC_VERSION__ >= 199901L)
|
||||||
#define isblank(__c) \
|
#define isblank(__c) \
|
||||||
__extension__ ({ __typeof__ (__c) __x = (__c); \
|
__extension__ ({ __typeof__ (__c) __x = (__c); \
|
||||||
((__ctype_ptr__+1)[__x]&_B) || (__x) == '\t';})
|
(__ctype_lookup(__x)&_B) || (int) (__x) == '\t';})
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue