This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: [PATCH/RFA] Distinguish between EOF and character with value 0xff
Eric Blake <ebb9 <at> byu.net> writes:
> > Should any attempt be made to make it cleaner for those who don't?
>
> One way might be to write it in such a way that, for decent compilers, we
> trigger warnings. Gcc is already smart enough to warn the user about the use
> of a char array index:
>
>
> Maybe the trick is to rewrite the macros such that we force the original
input
> to be treated as an array index; it is too late after the addition (at which
> point things have been promoted to int if they weren't already). Untested:
>
> #define isalpha(c) ((*((&__ctype_ptr__[c])+1))&(_U|_L))
I spent some time and actually tested my proposal. I've verified that with the
patch below, the assembly produced by isalpha(i) is identical both before and
after the patch under gcc 4.3.2. Meanwhile, 'gcc -Wall' is now able to
complain about isalpha((char)i) while staying silent for isalpha((unsigned char)
i).
OK to apply? (And pardon the fact that gmane botched the long lines.)
2009-04-22 Eric Blake <ebb9@byu.net>
Trigger gcc warning if isFoo macros are called with plain char.
* libc/include/ctype.h (isalpha, isupper, islower, isdigit)
(isxdigit, isspace, ispunct, isalnum, isprint, isgraph)
(iscntrl, isblank): Rewrite to let 'gcc -Wall' warn when user
calls macro with a char argument.
--- ctype.h.orig 2009-04-22 13:39:01.702341400 -0600
+++ ctype.h 2009-04-22 15:19:08.381510200 -0600
@@ -45,22 +45,22 @@
extern __IMPORT char *__ctype_ptr__;
#ifndef __cplusplus
-#define isalpha(c) ((__ctype_ptr__)[(unsigned)((c)+1)]&(_U|_L))
-#define isupper(c) (((__ctype_ptr__)[(unsigned)((c)+1)]&(_U|_L))
==_U)
-#define islower(c) (((__ctype_ptr__)[(unsigned)((c)+1)]&(_U|_L))
==_L)
-#define isdigit(c) ((__ctype_ptr__)[(unsigned)((c)+1)]&_N)
-#define isxdigit(c) ((__ctype_ptr__)[(unsigned)((c)+1)]&(_X|_N))
-#define isspace(c) ((__ctype_ptr__)[(unsigned)((c)+1)]&_S)
-#define ispunct(c) ((__ctype_ptr__)[(unsigned)((c)+1)]&_P)
-#define isalnum(c) ((__ctype_ptr__)[(unsigned)((c)+1)]&(_U|_L|_N))
-#define isprint(c) ((__ctype_ptr__)[(unsigned)((c)+1)]&(_P|_U|_L|_N|_B))
-#define isgraph(c) ((__ctype_ptr__)[(unsigned)((c)+1)]&
(_P|_U|_L|_N))
-#define iscntrl(c) ((__ctype_ptr__)[(unsigned)((c)+1)]&_C)
+#define isalpha(c) ((__ctype_ptr__+1)[c]&(_U|_L))
+#define isupper(c) (((__ctype_ptr__+1)[c]&(_U|_L))==_U)
+#define islower(c) (((__ctype_ptr__+1)[c]&(_U|_L))==_L)
+#define isdigit(c) ((__ctype_ptr__+1)[c]&_N)
+#define isxdigit(c) ((__ctype_ptr__+1)[c]&(_X|_N))
+#define isspace(c) ((__ctype_ptr__+1)[c]&_S)
+#define ispunct(c) ((__ctype_ptr__+1)[c]&_P)
+#define isalnum(c) ((__ctype_ptr__+1)[c]&(_U|_L|_N))
+#define isprint(c) ((__ctype_ptr__+1)[c]&(_P|_U|_L|_N|_B))
+#define isgraph(c) ((__ctype_ptr__+1)[c]&(_P|_U|_L|_N))
+#define iscntrl(c) ((__ctype_ptr__+1)[c]&_C)
#if defined(__GNUC__) && \
(!defined(__STRICT_ANSI__) || __STDC_VERSION__ >= 199901L)
#define isblank(c) \
- __extension__ ({ int __c = (c); ((__ctype_ptr__)[(unsigned)((__c)+1)]
&_B) || (__c) == '\t';})
+ __extension__ ({ int __c = (c); ((__ctype_ptr__+1)[__c]&_B) || (__c)
== '\t';})
#endif