]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libc/port/strtoull.c
libregexp: improve the transition to next available thread, instruction, and generation
[plan9front.git] / sys / src / libc / port / strtoull.c
1 #include <u.h>
2 #include <libc.h>
3
4 #define UVLONG_MAX      (1LL<<63)
5
6 uvlong
7 strtoull(char *nptr, char **endptr, int base)
8 {
9         char *p;
10         uvlong n, nn, m;
11         int c, ovfl, v, neg, ndig;
12
13         p = nptr;
14         neg = 0;
15         n = 0;
16         ndig = 0;
17         ovfl = 0;
18
19         /*
20          * White space
21          */
22         for(;; p++) {
23                 switch(*p) {
24                 case ' ':
25                 case '\t':
26                 case '\n':
27                 case '\f':
28                 case '\r':
29                 case '\v':
30                         continue;
31                 }
32                 break;
33         }
34
35         /*
36          * Sign
37          */
38         if(*p == '-' || *p == '+')
39                 if(*p++ == '-')
40                         neg = 1;
41
42         /*
43          * Base
44          */
45         if(base == 0) {
46                 base = 10;
47                 if(*p == '0') {
48                         base = 8;
49                         if(p[1] == 'x' || p[1] == 'X'){
50                                 p += 2;
51                                 base = 16;
52                         }
53                 }
54         } else
55         if(base == 16 && *p == '0') {
56                 if(p[1] == 'x' || p[1] == 'X')
57                         p += 2;
58         } else
59         if(base < 0 || 36 < base)
60                 goto Return;
61
62         /*
63          * Non-empty sequence of digits
64          */
65         m = UVLONG_MAX/base;
66         for(;; p++,ndig++) {
67                 c = *p;
68                 v = base;
69                 if('0' <= c && c <= '9')
70                         v = c - '0';
71                 else
72                 if('a' <= c && c <= 'z')
73                         v = c - 'a' + 10;
74                 else
75                 if('A' <= c && c <= 'Z')
76                         v = c - 'A' + 10;
77                 if(v >= base)
78                         break;
79                 if(n > m)
80                         ovfl = 1;
81                 nn = n*base + v;
82                 if(nn < n)
83                         ovfl = 1;
84                 n = nn;
85         }
86
87 Return:
88         if(ndig == 0)
89                 p = nptr;
90         if(endptr)
91                 *endptr = p;
92         if(ovfl)
93                 return UVLONG_MAX;
94         if(neg)
95                 return -n;
96         return n;
97 }