Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4973 right-hear 1
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
2
#include 
3
#include 
4
#include 
5
#include 
6
#include 
7
 
8
/*
9
 * Convert a string to an unsigned long integer.
10
 *
11
 * Ignores `locale' stuff.  Assumes that the upper and lower case
12
 * alphabets and digits are each contiguous.
13
 */
14
unsigned long
15
strtoul(const char *nptr, char **endptr, int base)
16
{
17
  const char *s = nptr;
18
  unsigned long acc;
19
  int c;
20
  unsigned long cutoff;
21
  int neg = 0, any, cutlim;
22
 
23
  /*
24
   * See strtol for comments as to the logic used.
25
   */
26
  do {
27
    c = *s++;
28
  } while (isspace(c));
29
  if (c == '-')
30
  {
31
    neg = 1;
32
    c = *s++;
33
  }
34
  else if (c == '+')
35
    c = *s++;
36
  if ((base == 0 || base == 16) &&
37
      c == '0' && (*s == 'x' || *s == 'X'))
38
  {
39
    c = s[1];
40
    s += 2;
41
    base = 16;
42
  }
43
  if (base == 0)
44
    base = c == '0' ? 8 : 10;
45
  cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
46
  cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
47
  for (acc = 0, any = 0;; c = *s++)
48
  {
49
    if (isdigit(c))
50
      c -= '0';
51
    else if (isalpha(c))
52
      c -= isupper(c) ? 'A' - 10 : 'a' - 10;
53
    else
54
      break;
55
    if (c >= base)
56
      break;
57
    if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
58
      any = -1;
59
    else {
60
      any = 1;
61
      acc *= base;
62
      acc += c;
63
    }
64
  }
65
  if (any < 0)
66
  {
67
    acc = ULONG_MAX;
68
    errno = ERANGE;
69
  }
70
  else if (neg)
71
    acc = -acc;
72
  if (endptr != 0)
73
    *endptr = any ? unconst(s, char *) - 1 : unconst(nptr, char *);
74
  return acc;
75
}