Root/
Source at commit 1298 created 12 years 9 months ago. By meklort, Remove libsa. | |
---|---|
1 | /*␊ |
2 | * strntoumax.c␊ |
3 | *␊ |
4 | * The strntoumax() function and associated␊ |
5 | */␊ |
6 | #include <stdlib.h>␊ |
7 | #include <stdint.h>␊ |
8 | #include <ctype.h>␊ |
9 | ␊ |
10 | static inline int digitval(int ch)␊ |
11 | {␊ |
12 | ␉if (ch >= '0' && ch <= '9') {␊ |
13 | ␉␉return ch - '0';␊ |
14 | ␉} else if (ch >= 'A' && ch <= 'Z') {␊ |
15 | ␉␉return ch - 'A' + 10;␊ |
16 | ␉} else if (ch >= 'a' && ch <= 'z') {␊ |
17 | ␉␉return ch - 'a' + 10;␊ |
18 | ␉} else {␊ |
19 | ␉␉return -1;␊ |
20 | ␉}␊ |
21 | }␊ |
22 | ␊ |
23 | uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n)␊ |
24 | {␊ |
25 | ␉int minus = 0;␊ |
26 | ␉uintmax_t v = 0;␊ |
27 | ␉int d;␊ |
28 | ␊ |
29 | ␉while (n && isspace((unsigned char)*nptr)) {␊ |
30 | ␉␉nptr++;␊ |
31 | ␉␉n--;␊ |
32 | ␉}␊ |
33 | ␊ |
34 | ␉/* Single optional + or - */␊ |
35 | ␉if (n) {␊ |
36 | ␉␉char c = *nptr;␊ |
37 | ␉␉if (c == '-' || c == '+') {␊ |
38 | ␉␉␉minus = (c == '-');␊ |
39 | ␉␉␉nptr++;␊ |
40 | ␉␉␉n--;␊ |
41 | ␉␉}␊ |
42 | ␉}␊ |
43 | ␊ |
44 | ␉if (base == 0) {␊ |
45 | ␉␉if (n >= 2 && nptr[0] == '0' &&␊ |
46 | ␉␉ (nptr[1] == 'x' || nptr[1] == 'X')) {␊ |
47 | ␉␉␉n -= 2;␊ |
48 | ␉␉␉nptr += 2;␊ |
49 | ␉␉␉base = 16;␊ |
50 | ␉␉} else if (n >= 1 && nptr[0] == '0') {␊ |
51 | ␉␉␉n--;␊ |
52 | ␉␉␉nptr++;␊ |
53 | ␉␉␉base = 8;␊ |
54 | ␉␉} else {␊ |
55 | ␉␉␉base = 10;␊ |
56 | ␉␉}␊ |
57 | ␉} else if (base == 16) {␊ |
58 | ␉␉if (n >= 2 && nptr[0] == '0' &&␊ |
59 | ␉␉ (nptr[1] == 'x' || nptr[1] == 'X')) {␊ |
60 | ␉␉␉n -= 2;␊ |
61 | ␉␉␉nptr += 2;␊ |
62 | ␉␉}␊ |
63 | ␉}␊ |
64 | ␊ |
65 | ␉while (n && (d = digitval(*nptr)) >= 0 && d < base) {␊ |
66 | ␉␉v = v * base + d;␊ |
67 | ␉␉n--;␊ |
68 | ␉␉nptr++;␊ |
69 | ␉}␊ |
70 | ␊ |
71 | ␉if (endptr)␊ |
72 | ␉␉*endptr = (char *)nptr;␊ |
73 | ␊ |
74 | ␉return minus ? -v : v;␊ |
75 | }␊ |
76 |