turns printfs back on
[freebsd-src/fkvm-freebsd.git] / contrib / cvs / lib / strtoul.c
blob7d42c210f67c40a17b81cc3a6dcb06989124b1a5
1 /*
2 * strtol : convert a string to long.
4 * Andy Wilson, 2-Oct-89.
5 */
7 #include <errno.h>
8 #include <ctype.h>
9 #include <stdio.h>
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
15 #ifndef ULONG_MAX
16 #define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */
17 #endif
19 extern int errno;
21 unsigned long
22 strtoul(s, ptr, base)
23 const char *s; char **ptr; int base;
25 unsigned long total = 0;
26 unsigned digit;
27 const char *start=s;
28 int did_conversion=0;
29 int overflow = 0;
30 int negate = 0;
31 unsigned long maxdiv, maxrem;
33 if (s==NULL)
35 errno = ERANGE;
36 if (!ptr)
37 *ptr = (char *)start;
38 return 0L;
41 while (isspace(*s))
42 s++;
43 if (*s == '+')
44 s++;
45 else if (*s == '-')
46 s++, negate = 1;
47 if (base==0 || base==16) /* the 'base==16' is for handling 0x */
49 int tmp;
52 * try to infer base from the string
54 if (*s != '0')
55 tmp = 10; /* doesn't start with 0 - assume decimal */
56 else if (s[1] == 'X' || s[1] == 'x')
57 tmp = 16, s += 2; /* starts with 0x or 0X - hence hex */
58 else
59 tmp = 8; /* starts with 0 - hence octal */
60 if (base==0)
61 base = (int)tmp;
64 maxdiv = ULONG_MAX / base;
65 maxrem = ULONG_MAX % base;
67 while ((digit = *s) != '\0')
69 if (digit >= '0' && digit < ('0'+base))
70 digit -= '0';
71 else
72 if (base > 10)
74 if (digit >= 'a' && digit < ('a'+(base-10)))
75 digit = digit - 'a' + 10;
76 else if (digit >= 'A' && digit < ('A'+(base-10)))
77 digit = digit - 'A' + 10;
78 else
79 break;
81 else
82 break;
83 did_conversion = 1;
84 if (total > maxdiv
85 || (total == maxdiv && digit > maxrem))
86 overflow = 1;
87 total = (total * base) + digit;
88 s++;
90 if (overflow)
92 errno = ERANGE;
93 if (ptr != NULL)
94 *ptr = (char *)s;
95 return (ULONG_MAX);
97 if (ptr != NULL)
98 *ptr = (char *) ((did_conversion) ? (char *)s : (char *)start);
99 return negate ? -total : total;