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