Magellan Linux

Contents of /tags/mkinitrd-6.1.5/busybox/libbb/xatonum_template.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 898 - (show annotations) (download)
Wed Aug 5 17:52:14 2009 UTC (14 years, 10 months ago) by niro
File MIME type: text/plain
File size: 4930 byte(s)
tagged 'mkinitrd-6.1.5'
1 /*
2 You need to define the following (example):
3
4 #define type long
5 #define xstrtou(rest) xstrtoul##rest
6 #define xstrto(rest) xstrtol##rest
7 #define xatou(rest) xatoul##rest
8 #define xato(rest) xatol##rest
9 #define XSTR_UTYPE_MAX ULONG_MAX
10 #define XSTR_TYPE_MAX LONG_MAX
11 #define XSTR_TYPE_MIN LONG_MIN
12 #define XSTR_STRTOU strtoul
13 */
14
15 unsigned type FAST_FUNC xstrtou(_range_sfx)(const char *numstr, int base,
16 unsigned type lower,
17 unsigned type upper,
18 const struct suffix_mult *suffixes)
19 {
20 unsigned type r;
21 int old_errno;
22 char *e;
23
24 /* Disallow '-' and any leading whitespace. Make sure we get the
25 * actual isspace function rather than a macro implementaion. */
26 if (*numstr == '-' || *numstr == '+' || (isspace)(*numstr))
27 goto inval;
28
29 /* Since this is a lib function, we're not allowed to reset errno to 0.
30 * Doing so could break an app that is deferring checking of errno.
31 * So, save the old value so that we can restore it if successful. */
32 old_errno = errno;
33 errno = 0;
34 r = XSTR_STRTOU(numstr, &e, base);
35 /* Do the initial validity check. Note: The standards do not
36 * guarantee that errno is set if no digits were found. So we
37 * must test for this explicitly. */
38 if (errno || numstr == e)
39 goto inval; /* error / no digits / illegal trailing chars */
40
41 errno = old_errno; /* Ok. So restore errno. */
42
43 /* Do optional suffix parsing. Allow 'empty' suffix tables.
44 * Note that we also allow nul suffixes with associated multipliers,
45 * to allow for scaling of the numstr by some default multiplier. */
46 if (suffixes) {
47 while (suffixes->mult) {
48 if (strcmp(suffixes->suffix, e) == 0) {
49 if (XSTR_UTYPE_MAX / suffixes->mult < r)
50 goto range; /* overflow! */
51 r *= suffixes->mult;
52 goto chk_range;
53 }
54 ++suffixes;
55 }
56 }
57
58 /* Note: trailing space is an error.
59 It would be easy enough to allow though if desired. */
60 if (*e)
61 goto inval;
62 chk_range:
63 /* Finally, check for range limits. */
64 if (r >= lower && r <= upper)
65 return r;
66 range:
67 bb_error_msg_and_die("number %s is not in %llu..%llu range",
68 numstr, (unsigned long long)lower,
69 (unsigned long long)upper);
70 inval:
71 bb_error_msg_and_die("invalid number '%s'", numstr);
72 }
73
74 unsigned type FAST_FUNC xstrtou(_range)(const char *numstr, int base,
75 unsigned type lower,
76 unsigned type upper)
77 {
78 return xstrtou(_range_sfx)(numstr, base, lower, upper, NULL);
79 }
80
81 unsigned type FAST_FUNC xstrtou(_sfx)(const char *numstr, int base,
82 const struct suffix_mult *suffixes)
83 {
84 return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, suffixes);
85 }
86
87 unsigned type FAST_FUNC xstrtou()(const char *numstr, int base)
88 {
89 return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, NULL);
90 }
91
92 unsigned type FAST_FUNC xatou(_range_sfx)(const char *numstr,
93 unsigned type lower,
94 unsigned type upper,
95 const struct suffix_mult *suffixes)
96 {
97 return xstrtou(_range_sfx)(numstr, 10, lower, upper, suffixes);
98 }
99
100 unsigned type FAST_FUNC xatou(_range)(const char *numstr,
101 unsigned type lower,
102 unsigned type upper)
103 {
104 return xstrtou(_range_sfx)(numstr, 10, lower, upper, NULL);
105 }
106
107 unsigned type FAST_FUNC xatou(_sfx)(const char *numstr,
108 const struct suffix_mult *suffixes)
109 {
110 return xstrtou(_range_sfx)(numstr, 10, 0, XSTR_UTYPE_MAX, suffixes);
111 }
112
113 unsigned type FAST_FUNC xatou()(const char *numstr)
114 {
115 return xatou(_sfx)(numstr, NULL);
116 }
117
118 /* Signed ones */
119
120 type FAST_FUNC xstrto(_range_sfx)(const char *numstr, int base,
121 type lower,
122 type upper,
123 const struct suffix_mult *suffixes)
124 {
125 unsigned type u = XSTR_TYPE_MAX;
126 type r;
127 const char *p = numstr;
128
129 /* NB: if you'll decide to disallow '+':
130 * at least renice applet needs to allow it */
131 if (p[0] == '+' || p[0] == '-') {
132 ++p;
133 if (p[0] == '-')
134 ++u; /* = <type>_MIN (01111... + 1 == 10000...) */
135 }
136
137 r = xstrtou(_range_sfx)(p, base, 0, u, suffixes);
138
139 if (*numstr == '-') {
140 r = -r;
141 }
142
143 if (r < lower || r > upper) {
144 bb_error_msg_and_die("number %s is not in %lld..%lld range",
145 numstr, (long long)lower, (long long)upper);
146 }
147
148 return r;
149 }
150
151 type FAST_FUNC xstrto(_range)(const char *numstr, int base, type lower, type upper)
152 {
153 return xstrto(_range_sfx)(numstr, base, lower, upper, NULL);
154 }
155
156 type FAST_FUNC xato(_range_sfx)(const char *numstr,
157 type lower,
158 type upper,
159 const struct suffix_mult *suffixes)
160 {
161 return xstrto(_range_sfx)(numstr, 10, lower, upper, suffixes);
162 }
163
164 type FAST_FUNC xato(_range)(const char *numstr, type lower, type upper)
165 {
166 return xstrto(_range_sfx)(numstr, 10, lower, upper, NULL);
167 }
168
169 type FAST_FUNC xato(_sfx)(const char *numstr, const struct suffix_mult *suffixes)
170 {
171 return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, suffixes);
172 }
173
174 type FAST_FUNC xato()(const char *numstr)
175 {
176 return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, NULL);
177 }
178
179 #undef type
180 #undef xstrtou
181 #undef xstrto
182 #undef xatou
183 #undef xato
184 #undef XSTR_UTYPE_MAX
185 #undef XSTR_TYPE_MAX
186 #undef XSTR_TYPE_MIN
187 #undef XSTR_STRTOU