Re: hmm..

From: Valdis . Kletnieks
Date: Wed Dec 31 2003 - 01:25:37 EST


On Mon, 22 Dec 2003 13:31:51 PST, Linus Torvalds said:

> - algorithmically, there aren't that many ways to test whether a
> character is a number or not. That's _especially_ true in
> C, where a macro must not use it's argument more than once. So for
> example, the "obvious" implementation of "isdigit()" (which tests for
> whether a character is a digit or not) would be
>
> #define isdigit(x) ((x) >= '0' && (x) <= '9')
>
> but this is not actually allowed by the C standard (because 'x' is used
> twice).

Somebody tell IBM that. From the AIX 4.3.3 and 5.1 /usr/include/ctype.h:

#define _VALC(__c) ((__c)>=0&&(__c)<=256)
#define _IS(__c,__m) (__OBJ_DATA(__lc_ctype)->mask[__c] & __m)
#define isalpha(__a) (_VALC(__a)?_IS(__a,_ISALPHA):0)
#define isalnum(__a) (_VALC(__a)?_IS(__a,_ISALNUM):0)
#define iscntrl(__a) (_VALC(__a)?_IS(__a,_ISCNTRL):0)
#define isdigit(__a) (_VALC(__a)?_IS(__a,_ISDIGIT):0)
#define isgraph(__a) (_VALC(__a)?_IS(__a,_ISGRAPH):0)
#define islower(__a) (_VALC(__a)?_IS(__a,_ISLOWER):0)
#define isprint(__a) (_VALC(__a)?_IS(__a,_ISPRINT):0)
#define ispunct(__a) (_VALC(__a)?_IS(__a,_ISPUNCT):0)
#define isspace(__a) (_VALC(__a)?_IS(__a,_ISSPACE):0)
#define isupper(__a) (_VALC(__a)?_IS(__a,_ISUPPER):0)
#define isxdigit(__a) (_VALC(__a)?_IS(__a,_ISXDIGIT):0)
#define isascii(c) (!((c) & ~0177))

You'd be *amazed* how far through memory a 'while (isalpha(*s++)) {..};' can go
(which in fact is how I discovered this blecherousness).

The AIX 4.3 support I contributed to Sendmail 8.9.0 back in Feb 98 included a
work-around because IBM refused to fix it on the grounds that the VALC macro
was to protect against a SEGV if the macro was fed an 'int' rather than a
'char' (why they didn't just use 'mask[__c & 255]' is beyond me), and that you
only got hit if you compiled(*) with -D_ILS_MACROS. At least IBM eventually fixed
isascii(), which was originally broken the same way....

Feel free to file this under "Code we can prove that IBM never contributed" :)

(*) The default is to use actual function calls due to locale considerations - building
with _ILS_MACROS provides a measured 30%+ CPU savings for Sendmail, which
doesn't care if it's nailed into a 'LANG=C' environ anyhow...




Attachment: pgp00000.pgp
Description: PGP signature