strtol.c - scc - simple c99 compiler
(HTM) git clone git://git.simple-cc.org/scc
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
strtol.c (970B)
---
1 #include <ctype.h>
2 #include <errno.h>
3 #include <limits.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include "../libc.h"
8
9 #undef strtol
10
11 long
12 strtol(const char * restrict ptr, char ** restrict end, int base)
13 {
14 int d, sign = -1;
15 long n;
16 char *t, *s = (char *) ptr;
17
18 if (end)
19 *end = s;
20
21 while (isspace(*s))
22 ++s;
23
24 switch (*s) {
25 case '-':
26 sign = 1;
27 case '+':
28 ++s;
29 }
30
31 if (base == 0) {
32 if (*s == '0')
33 base = toupper(s[1]) == 'X' ? 16 : 8;
34 else
35 base = 10;
36 }
37 if (base == 16 && *s == '0' && toupper(s[1]) == 'X')
38 s += 2;
39
40 n = 0;
41 /* Compute n as a negative number to avoid overflow on LONG_MIN */
42 for (t = s; (d = _dtoi(*t)) < base; ++t) {
43 if (n < LONG_MIN/base)
44 goto overflow;
45 n *= base;
46 if (-d < LONG_MIN - n)
47 goto overflow;
48 n -= d;
49 if (n == LONG_MIN && sign < 0)
50 goto overflow;
51 }
52
53 if (end && t != s)
54 *end = t;
55
56 return n*sign;
57
58 overflow:
59 if (end)
60 *end = t;
61 errno = ERANGE;
62
63 return sign < 0 ? LONG_MAX : LONG_MIN;
64 }