Annotation of coherent/b/lib/libc/gen/strtol.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * C general utilities library.
                      3:  * strtol(), strtoul()
                      4:  * ANSI 4.10.1.5, 4.10.1.6.
                      5:  * Convert ASCII to long or unsigned long (the System V way).
                      6:  * atol() was so simple before System V/ANSI got hold of it...
                      7:  */
                      8: 
                      9: #include <stdlib.h>
                     10: #include <ctype.h>
                     11: #include <errno.h>
                     12: #include <limits.h>
                     13: 
                     14: extern unsigned long _strtoul();
                     15: 
                     16: long
                     17: strtol(nptr, endptr, base) char *nptr; char **endptr; int base;
                     18: {
                     19:        return (long)_strtoul(nptr, endptr, base, 0);
                     20: }
                     21: 
                     22: unsigned long
                     23: strtoul(nptr, endptr, base) char *nptr; char **endptr; int base;
                     24: {
                     25:        return _strtoul(nptr, endptr, base, 1);
                     26: }
                     27: 
                     28: static
                     29: unsigned long
                     30: _strtoul(nptr, endptr, base, uflag) char *nptr; char **endptr; int base, uflag;
                     31: {
                     32:        register char *cp;
                     33:        register unsigned long val;
                     34:        register int c, sign, overflow, pflag, dlimit, ulimit, llimit;
                     35:        unsigned long quot, rem;
                     36: 
                     37:        cp = nptr;
                     38:        val = pflag = overflow = sign = 0;
                     39: 
                     40:        /* Leading white space. */
                     41:        while (isspace(c = *cp++))
                     42:                ;
                     43: 
                     44:        /* Optional sign. */
                     45:        switch(c) {
                     46:        case '-':
                     47:                sign = 1;
                     48:                /* fall through... */
                     49:        case '+':
                     50:                c = *cp++;
                     51:        }
                     52: 
                     53:        /* Determine implicit base. */
                     54:        if (base == 0) {
                     55:                if (c == '0')
                     56:                        base = (*cp == 'x' || *cp == 'X') ? 16 : 8;
                     57:                else if (isdigit(c))
                     58:                        base = 10;
                     59:                else {                  /* expected form not found */
                     60:                        cp = nptr;
                     61:                        goto done;
                     62:                }
                     63:        }
                     64: 
                     65:        /* Skip optional hex base "0x" or "0X". */
                     66:        if (base == 16 && c == '0' && (*cp == 'x' || *cp == 'X')) {
                     67:                ++pflag;
                     68:                ++cp;
                     69:                c = *cp++;
                     70:        }
                     71: 
                     72:        /* Initialize legal character limits. */
                     73:        dlimit = '0' + base;
                     74:        ulimit = 'A' + base - 10;
                     75:        llimit = 'a' + base - 10;
                     76: 
                     77:        /* The next character must be a legitimate digit; e.g. " +@" fails. */
                     78:        /* Watch out for e.g. "0xy", which is "0" followed by "xy". */
                     79:        if (!(   (isdigit(c) && c < dlimit)
                     80:              || (isupper(c) && c < ulimit)
                     81:              || (islower(c) && c < llimit))) {
                     82:                cp = (pflag) ? cp - 2 : nptr;
                     83:                goto done;
                     84:        }
                     85: 
                     86:        /* Determine limits for overflow computation. */
                     87:        /* This would use ldiv() if it worked for unsigned long. */
                     88:        if (uflag) {
                     89:                quot = ULONG_MAX / base;
                     90:                rem = ULONG_MAX % base;
                     91:        } else {
                     92:                quot = LONG_MAX / base;
                     93:                rem = LONG_MAX % base;
                     94:        }
                     95: 
                     96:        /* Process digit string. */
                     97:        for ( ; ; c = *cp++) {
                     98:                if (isdigit(c) && c < dlimit)
                     99:                        c -= '0';
                    100:                else if (isupper(c) && c < ulimit)
                    101:                        c -= 'A'-10;
                    102:                else if (islower(c) && c < llimit)
                    103:                        c -= 'a'-10;
                    104:                else {
                    105:                        --cp;
                    106:                        break;
                    107:                }
                    108:                if (val < quot || (val == quot && c <= rem))
                    109:                        val = val * base + c;
                    110:                else
                    111:                        ++overflow;
                    112:        }
                    113: 
                    114: done:
                    115:        /* Store end pointer and return approriate result. */
                    116:        if (endptr != (char **)NULL)
                    117:                *endptr = cp;
                    118:        if (overflow) {
                    119:                errno = ERANGE;
                    120:                if (uflag)
                    121:                        return ULONG_MAX;
                    122:                return (unsigned long)(sign ? LONG_MIN : LONG_MAX);
                    123:        }
                    124:        return (sign) ? (unsigned long)(-(long)val) : val;
                    125: }
                    126: 
                    127: /* end of strtol.c */

unix.superglobalmegacorp.com

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