scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

strtoull.c (866B)


      1 #include <ctype.h>
      2 #include <errno.h>
      3 #include <limits.h>
      4 #include <stdlib.h>
      5 #include <string.h>
      6 
      7 #include "../libc.h"
      8 
      9 #undef strtoull
     10 
     11 unsigned long long
     12 strtoull(const char * restrict ptr, char ** restrict end, int base)
     13 {
     14 	int d, sign = 1;
     15 	unsigned long long n;
     16 	char *t, *s = (char *) ptr;
     17 
     18 	if (end)
     19 		*end = s;
     20 
     21 	while (isspace(*s))
     22 		++s;
     23 
     24 	switch (*s) {
     25 	case '-':
     26 		sign = -1;
     27 	case '+':
     28 		++s;
     29 	}
     30 
     31 	if (base == 0) {
     32 		if (*s == '0')
     33 			base = toupper(s[1]) == 'X' ? 16 : 8;
     34 		else
     35 			base = 10;
     36 	}
     37 	if (base == 16 && *s == '0' && toupper(s[1]) == 'X')
     38 		s += 2;
     39 
     40 	n = 0;
     41 	for (t = s; (d = _dtoi(*t)) < base; ++t) {
     42 		if (n > ULLONG_MAX/base)
     43 			goto overflow;
     44 		n *= base;
     45 		if (d > ULLONG_MAX - n)
     46 			goto overflow;
     47 		n += d;
     48 	}
     49 
     50 	if (end && t != s)
     51 		*end = t;
     52 
     53 	return n*sign;
     54 
     55 overflow:
     56 	if (end)
     57 		*end = t;
     58 	errno = ERANGE;
     59 
     60 	return ULLONG_MAX;
     61 }