source: trunk/sys/dietlibc/strtoul.c @ 200

Last change on this file since 200 was 1, checked in by alain, 7 years ago

First import

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