Annotation of researchv10no/cmd/sort/strtoul.c, revision 1.1.1.1

1.1       root        1: /* Copyright AT&T Bell Laboratories, 1993 */
                      2: /* Convert string to unsigned long.
                      3: ** Assumes ASCII properties - contiguity of 0-9, A-Z, a-z,
                      4: ** digits less than letters, lower case maskable to upper.
                      5: */
                      6: #include <ctype.h>
                      7: #include <errno.h>
                      8: 
                      9: #define DIGIT(x)       ((x)<='9'? (x)-'0': TOUPPER(x)+10-'A')
                     10: #define TOUPPER(x)     ((x) & ~('a'-'A'))
                     11: #define MBASE  ('z' - 'a' + 1 + 10)
                     12: #define T_ULONG_MAX    ~(unsigned long)0
                     13: 
                     14: unsigned long
                     15: strtoul(str, nptr, base)
                     16: char *str;
                     17: char **nptr;
                     18: int base;
                     19: {
                     20:        register unsigned long val;
                     21:        register int c;
                     22:        int xx;
                     23:        int overflow = 0, neg = 0;
                     24:        unsigned long   multmax;
                     25: 
                     26:        if (nptr)
                     27:                *nptr = str; /* in case no number is formed */
                     28:        c = *str;
                     29:        while (isspace(c))
                     30:                c = *++str;
                     31:        switch(c) {
                     32:        case '-':
                     33:                neg = 1;
                     34:        case'+':
                     35:                c = *++str;
                     36:        }
                     37:        if (base == 0)
                     38:                if (c != '0')
                     39:                        base = 10;
                     40:                else if (TOUPPER(str[1]) == 'X')
                     41:                        base = 16;
                     42:                else
                     43:                        base = 8;
                     44:        if (base < 2 || base > MBASE)
                     45:                return (0); /* base is invalid -- should be a fatal error */
                     46:        if (!isalnum(c) || DIGIT(c) >= base)
                     47:                return (0); /* no number formed */
                     48:        if (base == 16 && c == '0' && (TOUPPER(str[1]) == 'X') &&
                     49:                isxdigit(str[2]))
                     50:                c = *(str += 2); /* skip over leading "0x" or "0X" */
                     51: 
                     52:        multmax = T_ULONG_MAX / (unsigned)base;
                     53:        for (val = DIGIT(c); isalnum(c = *++str) && (xx = DIGIT(c)) < base; )
                     54:                if (val > multmax || (val = val*base + xx) < xx)
                     55:                        overflow = 1;
                     56:        if (nptr)
                     57:                *nptr = str;
                     58:        if (overflow) {
                     59:                errno = ERANGE;
                     60:                return T_ULONG_MAX;
                     61:        } else
                     62:                return neg? -val: val;
                     63: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.