Home | History | Annotate | Download | only in lib
      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 
     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 
     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