Annotation of researchv10dc/cmd/worm/scsi/tcl/strtoul.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * strtoul.c --
                      3:  *
                      4:  *     Source code for the "strtoul" library procedure.
                      5:  *
                      6:  * Copyright 1988 Regents of the University of California
                      7:  * Permission to use, copy, modify, and distribute this
                      8:  * software and its documentation for any purpose and without
                      9:  * fee is hereby granted, provided that the above copyright
                     10:  * notice appear in all copies.  The University of California
                     11:  * makes no representations about the suitability of this
                     12:  * software for any purpose.  It is provided "as is" without
                     13:  * express or implied warranty.
                     14:  */
                     15: 
                     16: #ifndef lint
                     17: static char rcsid[] = "$Header: /sprite/src/lib/c/stdlib/RCS/strtoul.c,v 1.2 89/03/22 00:47:33 rab Exp $ SPRITE (Berkeley)";
                     18: #endif /* not lint */
                     19: 
                     20: #include <sprite.h>
                     21: #include <stdlib.h>
                     22: #include <ctype.h>
                     23: 
                     24: /*
                     25:  * The table below is used to convert from ASCII digits to a
                     26:  * numerical equivalent.  It maps from '0' through 'z' to integers
                     27:  * (100 for non-digit characters).
                     28:  */
                     29: 
                     30: static char cvtIn[] = {
                     31:     0, 1, 2, 3, 4, 5, 6, 7, 8, 9,              /* '0' - '9' */
                     32:     100, 100, 100, 100, 100, 100, 100,         /* punctuation */
                     33:     10, 11, 12, 13, 14, 15, 16, 17, 18, 19,    /* 'A' - 'Z' */
                     34:     20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                     35:     30, 31, 32, 33, 34, 35,
                     36:     100, 100, 100, 100, 100, 100,              /* punctuation */
                     37:     10, 11, 12, 13, 14, 15, 16, 17, 18, 19,    /* 'a' - 'z' */
                     38:     20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                     39:     30, 31, 32, 33, 34, 35};
                     40: 
                     41: /*
                     42:  *----------------------------------------------------------------------
                     43:  *
                     44:  * strtoul --
                     45:  *
                     46:  *     Convert an ASCII string into an integer.
                     47:  *
                     48:  * Results:
                     49:  *     The return value is the integer equivalent of string.  If endPtr
                     50:  *     is non-NULL, then *endPtr is filled in with the character
                     51:  *     after the last one that was part of the integer.  If string
                     52:  *     doesn't contain a valid integer value, then zero is returned
                     53:  *     and *endPtr is set to string.
                     54:  *
                     55:  * Side effects:
                     56:  *     None.
                     57:  *
                     58:  *----------------------------------------------------------------------
                     59:  */
                     60: 
                     61: unsigned long int
                     62: strtoul(string, endPtr, base)
                     63:     char *string;              /* String of ASCII digits, possibly
                     64:                                 * preceded by white space.  For bases
                     65:                                 * greater than 10, either lower- or
                     66:                                 * upper-case digits may be used.
                     67:                                 */
                     68:     char **endPtr;             /* Where to store address of terminating
                     69:                                 * character, or NULL. */
                     70:     int base;                  /* Base for conversion.  Must be less
                     71:                                 * than 37.  If 0, then the base is chosen
                     72:                                 * from the leading characters of string:
                     73:                                 * "0x" means hex, "0" means octal, anything
                     74:                                 * else means decimal.
                     75:                                 */
                     76: {
                     77:     register char *p;
                     78:     register unsigned long int result = 0;
                     79:     register unsigned digit;
                     80:     int anyDigits = FALSE;
                     81: 
                     82:     /*
                     83:      * Skip any leading blanks.
                     84:      */
                     85: 
                     86:     p = string;
                     87:     while (isspace(*p)) {
                     88:        p += 1;
                     89:     }
                     90: 
                     91:     /*
                     92:      * If no base was provided, pick one from the leading characters
                     93:      * of the string.
                     94:      */
                     95:     
                     96:     if (base == 0)
                     97:     {
                     98:        if (*p == '0') {
                     99:            p += 1;
                    100:            if (*p == 'x') {
                    101:                p += 1;
                    102:                base = 16;
                    103:            } else {
                    104: 
                    105:                /*
                    106:                 * Must set anyDigits here, otherwise "0" produces a
                    107:                 * "no digits" error.
                    108:                 */
                    109: 
                    110:                anyDigits = TRUE;
                    111:                base = 8;
                    112:            }
                    113:        }
                    114:        else base = 10;
                    115:     } else if (base == 16) {
                    116: 
                    117:        /*
                    118:         * Skip a leading "0x" from hex numbers.
                    119:         */
                    120: 
                    121:        if ((p[0] == '0') && (p[1] == 'x')) {
                    122:            p += 2;
                    123:        }
                    124:     }
                    125: 
                    126:     /*
                    127:      * Sorry this code is so messy, but speed seems important.  Do
                    128:      * different things for base 8, 10, 16, and other.
                    129:      */
                    130: 
                    131:     if (base == 8) {
                    132:        for ( ; ; p += 1) {
                    133:            digit = *p - '0';
                    134:            if (digit > 7) {
                    135:                break;
                    136:            }
                    137:            result = (result << 3) + digit;
                    138:            anyDigits = TRUE;
                    139:        }
                    140:     } else if (base == 10) {
                    141:        for ( ; ; p += 1) {
                    142:            digit = *p - '0';
                    143:            if (digit > 9) {
                    144:                break;
                    145:            }
                    146:            result = (10*result) + digit;
                    147:            anyDigits = TRUE;
                    148:        }
                    149:     } else if (base == 16) {
                    150:        for ( ; ; p += 1) {
                    151:            digit = *p - '0';
                    152:            if (digit > ('z' - '0')) {
                    153:                break;
                    154:            }
                    155:            digit = cvtIn[digit];
                    156:            if (digit > 15) {
                    157:                break;
                    158:            }
                    159:            result = (result << 4) + digit;
                    160:            anyDigits = TRUE;
                    161:        }
                    162:     } else {
                    163:        for ( ; ; p += 1) {
                    164:            digit = *p - '0';
                    165:            if (digit > ('z' - '0')) {
                    166:                break;
                    167:            }
                    168:            digit = cvtIn[digit];
                    169:            if (digit >= base) {
                    170:                break;
                    171:            }
                    172:            result = result*base + digit;
                    173:            anyDigits = TRUE;
                    174:        }
                    175:     }
                    176: 
                    177:     /*
                    178:      * See if there were any digits at all.
                    179:      */
                    180: 
                    181:     if (!anyDigits) {
                    182:        p = string;
                    183:     }
                    184: 
                    185:     if (endPtr != NULL) {
                    186:        *endPtr = p;
                    187:     }
                    188: 
                    189:     return result;
                    190: }

unix.superglobalmegacorp.com

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