core: do aligned transfers in bcopy32
[syslinux.git] / com32 / lib / strntoumax.c
blob4e30637d2c3bd5ebf8a219693693852da3ba9d3b
1 /*
2 * strntoumax.c
4 * The strntoumax() function and associated
5 */
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <ctype.h>
11 static inline int digitval(int ch)
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;
24 uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n)
26 int minus = 0;
27 uintmax_t v = 0;
28 int d;
30 while ( n && isspace((unsigned char)*nptr) ) {
31 nptr++;
32 n--;
35 /* Single optional + or - */
36 if ( n && *nptr == '-' ) {
37 minus = 1;
38 nptr++;
39 n--;
40 } else if ( n && *nptr == '+' ) {
41 nptr++;
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;
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;
65 while ( n && (d = digitval(*nptr)) >= 0 && d < base ) {
66 v = v*base + d;
67 n--;
68 nptr++;
71 if ( endptr )
72 *endptr = (char *)nptr;
74 return minus ? -v : v;