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