[Debburn-devel] What is going on?

Albert Cahalan acahalan at gmail.com
Sun Sep 10 20:49:59 UTC 2006


On 9/10/06, Peter Samuelson <peter at p12n.org> wrote:
> [Albert Cahalan]
> > Note that a C99 requirement merely rules out many compilers.
> > You can use gcc on Windows, even without Cygwin.
>
> Well, I didn't just mean the compiler features, but also the runtime.
> For the compiler it would be nice to rely on <inttypes.h> (especially
> int64_t), but there's also C99 library APIs like strtoll() (which
> obviously wasn't in C89 because 'long long' wasn't).  Being able to
> rely on int64_t, but not things like strtoll, is still a bit limiting.

Unlike language features, those are easy to provide.
Put your gcc in C99 mode (-std=c99) and use this:

typedef long long int64_t;

long long strtol(const char *restrict cp, const char **restrict endp, int base){
        if(base<0 || base==1 || base>36){
                errno = EINVAL;
                return 0;
        }
        int i = 0;
        while(isspace(cp[i]))
                i++;
        int neg = 0;
        if(cp[i]=='-'){
                neg = 1;
                i++;
        }else if(cp[i]=='+'){
                i++;
        }
        if(!base){
                base = 10;
                if(cp[i]=='0'){
                        base = 8;
                        if(cp[i+1]==tolower('x') && isxdigit(cp[i+2])){
                                base = 16;
                                i += 2;
                        }
                }
        }
        int toobig = 0;
        unsigned long long ull = 0;
        unsigned long long limit = 0xffffffffffffffffull/base;
        for(;;){
                char c = cp[i];
                if(c>='0' && c<='9')
                        c-='0';
                else if(c>='a' && c<='z')
                        c-='a';
                else if(c>='A' && c<='Z')
                        c-='A';
                else
                        c=42;
                if(c>=base)
                        break;
                i++;
                if(ull > limit)
                        toobig = 1;
                ull *= base;
                if(ull+c < ull)
                        toobig = 1;
                ull += c;
        }
        if(neg){
                ull = -ull;
                if((long long)ull > 0)
                        toobig = 1;
                if(toobig)
                        ull = 0x8000000000000000ull;
        }else{
                if((long long)ull < 0)
                        toobig = 1;
                if(toobig)
                        ull = 0x7fffffffffffffffull;
        }

        if(toobig)
                errno=ERANGE;
        if(endp)
                *endp=cp+i;
        return ull;
}



More information about the Debburn-devel mailing list