OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tcl/] [compat/] [strtoul.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.