Annotation of coherent/b/lib/libc/gen/strtol.c, revision 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.