source: trunk/sys/dietlibc/strtoull.c @ 428

Last change on this file since 428 was 1, checked in by alain, 8 years ago

First import

File size: 1.5 KB
RevLine 
[1]1#include <ctype.h>
2#include <stdlib.h>
3#include <errno.h>
4#include <limits.h>
5#include <inttypes.h>
6
7unsigned long long int strtoull(const char *ptr, char **endptr, int base)
8{
9  int neg = 0, overflow = 0;
10  long long int v=0;
11  const char* orig;
12  const char* nptr=ptr;
13
14  while(isspace(*nptr)) ++nptr;
15
16  if (*nptr == '-') { neg=1; nptr++; }
17  else if (*nptr == '+') ++nptr;
18  orig=nptr;
19  if (base==16 && nptr[0]=='0') goto skip0x;
20  if (base) {
21    register unsigned int b=base-2;
22    if (b>34) { errno=EINVAL; return 0; }
23  } else {
24    if (*nptr=='0') {
25      base=8;
26skip0x:
27      if (((*(nptr+1)=='x')||(*(nptr+1)=='X')) && isxdigit(nptr[2])) {
28        nptr+=2;
29        base=16;
30      }
31    } else
32      base=10;
33  }
34  while(*nptr) {
35    register unsigned char c=*nptr;
36    c=(c>='a'?c-'a'+10:c>='A'?c-'A'+10:c<='9'?c-'0':0xff);
37    if (c>=base) break; /* out of base */
38    {
39      register unsigned long x=(v&0xff)*base+c;
40      register unsigned long long w=(v>>8)*base+(x>>8);
41      if (w>(ULLONG_MAX>>8)) overflow=1;
42      v=(w<<8)+(x&0xff);
43    }
44    ++nptr;
45  }
46  if (nptr==orig) {             /* no conversion done */
47    nptr=ptr;
48    errno=EINVAL;
49    v=0;
50  }
51  if (endptr) *endptr=(char *)nptr;
52  if (overflow) {
53    errno=ERANGE;
54    return ULLONG_MAX;
55  }
56  return (neg?-v:v);
57}
58
59/* die, BSD, die!!! */
60unsigned long long int strtouq(const char *nptr, char **endptr, int base)
61        __attribute__((alias("strtoull")));
62
63uintmax_t strtoumax(const char *nptr, char **endptr, int base)
64        __attribute__((alias("strtoull")));
Note: See TracBrowser for help on using the repository browser.