UbixOS V2 2.0

strtol.c
Go to the documentation of this file.
1 /*-
2 * Copyright (c) 2002-2018 The UbixOS Project.
3 * All rights reserved.
4 *
5 * This was developed by Christopher W. Olsen for the UbixOS Project.
6 *
7 * Redistribution and use in source and binary forms, with or without modification, are permitted
8 * provided that the following conditions are met:
9 *
10 * 1) Redistributions of source code must retain the above copyright notice, this list of
11 * conditions, the following disclaimer and the list of authors.
12 * 2) Redistributions in binary form must reproduce the above copyright notice, this list of
13 * conditions, the following disclaimer and the list of authors in the documentation and/or
14 * other materials provided with the distribution.
15 * 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
16 * endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 //#include <limits.h>
31 //#include <ctype.h>
32 //#include <stdlib.h>
33
34 #define LONG_MIN (-0x7fffffffL - 1)
35 #define LONG_MAX 0x7fffffffL
36
37 long strtol(const char * __restrict nptr, char ** __restrict endptr, int base) {
38 const char *s;
39 unsigned long acc;
40 char c = 0x0; /* to remove warning */
41 unsigned long cutoff;
42 int neg, any, cutlim;
43
44 /*
45 * Skip white space and pick up leading +/- sign if any.
46 * If base is 0, allow 0x for hex and 0 for octal, else
47 * assume decimal; if base is already 16, allow 0x.
48 */
49 s = nptr;
50 /*
51 do {
52 c = *s++;
53 } while (isspace((unsigned char)c));
54 */
55 if (c == '-') {
56 neg = 1;
57 c = *s++;
58 }
59 else {
60 neg = 0;
61 if (c == '+')
62 c = *s++;
63 }
64 if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) {
65 c = s[1];
66 s += 2;
67 base = 16;
68 }
69 if (base == 0)
70 base = c == '0' ? 8 : 10;
71 acc = any = 0;
72 if (base < 2 || base > 36)
73 goto noconv;
74
75 /*
76 * Compute the cutoff value between legal numbers and illegal
77 * numbers. That is the largest legal value, divided by the
78 * base. An input number that is greater than this value, if
79 * followed by a legal input character, is too big. One that
80 * is equal to this value may be valid or not; the limit
81 * between valid and invalid numbers is then based on the last
82 * digit. For instance, if the range for longs is
83 * [-2147483648..2147483647] and the input base is 10,
84 * cutoff will be set to 214748364 and cutlim to either
85 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
86 * a value > 214748364, or equal but the next digit is > 7 (or 8),
87 * the number is too big, and we will return a range error.
88 *
89 * Set 'any' if any `digits' consumed; make it negative to indicate
90 * overflow.
91 */
92 cutoff = neg ? (unsigned long) -(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX;
93 cutlim = cutoff % base;
94 cutoff /= base;
95 for (;; c = *s++) {
96 if (c >= '0' && c <= '9')
97 c -= '0';
98 else if (c >= 'A' && c <= 'Z')
99 c -= 'A' - 10;
100 else if (c >= 'a' && c <= 'z')
101 c -= 'a' - 10;
102 else
103 break;
104 if (c >= base)
105 break;
106 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
107 any = -1;
108 else {
109 any = 1;
110 acc *= base;
111 acc += c;
112 }
113 }
114 if (any < 0) {
115 acc = neg ? LONG_MIN : LONG_MAX;
116 //errno = ERANGE;
117 }
118 else if (!any) {
119 noconv:
120 //errno = EINVAL;
121 cutoff = 0x0; //UBU
122 }
123 else if (neg)
124 acc = -acc;
125 if (endptr != 0x0)
126 *endptr = (char *) (any ? s - 1 : nptr);
127 return (acc);
128 }
strtol
long strtol(const char *__restrict nptr, char **__restrict endptr, int base)
Definition: strtol.c:37
LONG_MIN
#define LONG_MIN
Definition: strtol.c:34
__restrict
#define __restrict
Definition: cdefs.h:435
cdefs.h
LONG_MAX
#define LONG_MAX
Definition: strtol.c:35