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