1 /* A wrapper around strtol() and strtoul() to correct some
2 * "out of bounds" cases that don't work well on at least UTS.
3 * If a value is Larger than the max, strto[u]l should return
4 * the max value, and set errno to ERANGE
5 * The same if a value is smaller than the min value (only
6 * relevant for strtol(); not strtoul()), except the minimum
7 * value is returned (and errno == ERANGE).
12 #include <sys/errno.h>
21 #define U32 unsigned int
28 char *Long_min_str; /* Absolute value */
30 int Ulong_max_str_len;
32 int Long_min_str_len; /* Absolute value */
36 I32 Long_min; /* NOT Absolute value */
38 static struct base_info Base_info[37];
40 static struct base_info Base_info_16 = {
41 "0123456789abcdefABCDEF",
42 "4294967295", "2147483648" /* <== ABS VAL */ , "2147483647",
44 4294967295, 2147483647, - 2147483648,
47 static struct base_info Base_info_10 = {
49 "4294967295", "2147483648" /* <== ABS VAL */ , "2147483647",
51 4294967295, 2147483647, - 2147483648,
54 /* Used eventually (if this is fully developed) to hold info
55 * for processing bases 2-36. So that we can just plug the
56 * base in as a selector for its info, we sacrifice
57 * Base_info[0] and Base_info[1] (unless they are used
58 * at some point for special information).
61 /* This may be replaced later by something more universal */
65 if(Base_info[10].ValidChars) return;
66 Base_info[10] = Base_info_10;
67 Base_info[16] = Base_info_16;
71 strtoul_wrap32(char *s, char **pEnd, int base)
79 while(*s && isspace(*s)) ++s;
84 while(*s && isspace(*s)) ++s;
88 if(s[1] == 'x' || s[1] == 'X') {
95 } else if(isdigit(*s)) {
100 return strtoul(sOrig, pEnd, base);
103 Len = strspn(s, Base_info[base].ValidChars);
105 if(Len > Base_info[base].Ulong_max_str_len
107 (Len == Base_info[base].Ulong_max_str_len
109 strncmp(Base_info[base].Ulong_max_str, s, Len) < 0)
111 /* In case isNegated is set - what to do?? */
112 /* Mightn't we say a negative number is ERANGE for strtoul? */
114 return Base_info[base].Ulong_max;
117 return strtoul(sOrig, pEnd, base);
121 strtol_wrap32(char *s, char **pEnd, int base)
129 while(*s && isspace(*s)) ++s;
134 while(*s && isspace(*s)) ++s;
138 if(s[1] == 'x' || s[1] == 'X') {
145 } else if(isdigit(*s)) {
150 return strtol(sOrig, pEnd, base);
153 Len = strspn(s, Base_info[base].ValidChars);
155 if(Len > Base_info[base].Long_max_str_len
157 (!isNegated && Len == Base_info[base].Long_max_str_len
159 strncmp(Base_info[base].Long_max_str, s, Len) < 0)
161 (isNegated && Len == Base_info[base].Long_min_str_len
163 strncmp(Base_info[base].Long_min_str, s, Len) < 0)
165 /* In case isNegated is set - what to do?? */
166 /* Mightn't we say a negative number is ERANGE for strtol? */
168 return(isNegated ? Base_info[base].Long_min
170 Base_info[base].Long_min);
173 return strtol(sOrig, pEnd, base);