Contents of /trunk/mkinitrd-magellan/busybox/libbb/xatonum_template.c
Parent Directory | Revision Log
Revision 532 -
(show annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
File MIME type: text/plain
File size: 4715 byte(s)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
File MIME type: text/plain
File size: 4715 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd
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 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. Speed isn't critical here |
25 | * since we're parsing commandline args. So make sure we get the |
26 | * actual isspace function rather than a lnumstrer macro implementaion. */ |
27 | if (*numstr == '-' || *numstr == '+' || (isspace)(*numstr)) |
28 | goto inval; |
29 | |
30 | /* Since this is a lib function, we're not allowed to reset errno to 0. |
31 | * Doing so could break an app that is deferring checking of errno. |
32 | * So, save the old value so that we can restore it if successful. */ |
33 | old_errno = errno; |
34 | errno = 0; |
35 | r = XSTR_STRTOU(numstr, &e, base); |
36 | /* Do the initial validity check. Note: The standards do not |
37 | * guarantee that errno is set if no digits were found. So we |
38 | * must test for this explicitly. */ |
39 | if (errno || numstr == e) |
40 | goto inval; /* error / no digits / illegal trailing chars */ |
41 | |
42 | errno = old_errno; /* Ok. So restore errno. */ |
43 | |
44 | /* Do optional suffix parsing. Allow 'empty' suffix tables. |
45 | * Note that we also allow nul suffixes with associated multipliers, |
46 | * to allow for scaling of the numstr by some default multiplier. */ |
47 | if (suffixes) { |
48 | while (suffixes->suffix) { |
49 | if (strcmp(suffixes->suffix, e) == 0) { |
50 | if (XSTR_UTYPE_MAX / suffixes->mult < r) |
51 | goto range; /* overflow! */ |
52 | ++e; |
53 | r *= suffixes->mult; |
54 | break; |
55 | } |
56 | ++suffixes; |
57 | } |
58 | } |
59 | |
60 | /* Note: trailing space is an error. |
61 | It would be easy enough to allow though if desired. */ |
62 | if (*e) |
63 | goto inval; |
64 | /* Finally, check for range limits. */ |
65 | if (r >= lower && r <= upper) |
66 | return r; |
67 | range: |
68 | bb_error_msg_and_die("number %s is not in %llu..%llu range", |
69 | numstr, (unsigned long long)lower, |
70 | (unsigned long long)upper); |
71 | inval: |
72 | bb_error_msg_and_die("invalid number '%s'", numstr); |
73 | } |
74 | |
75 | unsigned type xstrtou(_range)(const char *numstr, int base, |
76 | unsigned type lower, |
77 | unsigned type upper) |
78 | { |
79 | return xstrtou(_range_sfx)(numstr, base, lower, upper, NULL); |
80 | } |
81 | |
82 | unsigned type xstrtou(_sfx)(const char *numstr, int base, |
83 | const struct suffix_mult *suffixes) |
84 | { |
85 | return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, suffixes); |
86 | } |
87 | |
88 | unsigned type xstrtou()(const char *numstr, int base) |
89 | { |
90 | return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, NULL); |
91 | } |
92 | |
93 | unsigned type xatou(_range_sfx)(const char *numstr, |
94 | unsigned type lower, |
95 | unsigned type upper, |
96 | const struct suffix_mult *suffixes) |
97 | { |
98 | return xstrtou(_range_sfx)(numstr, 10, lower, upper, suffixes); |
99 | } |
100 | |
101 | unsigned type xatou(_range)(const char *numstr, |
102 | unsigned type lower, |
103 | unsigned type upper) |
104 | { |
105 | return xstrtou(_range_sfx)(numstr, 10, lower, upper, NULL); |
106 | } |
107 | |
108 | unsigned type xatou(_sfx)(const char *numstr, |
109 | const struct suffix_mult *suffixes) |
110 | { |
111 | return xstrtou(_range_sfx)(numstr, 10, 0, XSTR_UTYPE_MAX, suffixes); |
112 | } |
113 | |
114 | unsigned type xatou()(const char *numstr) |
115 | { |
116 | return xatou(_sfx)(numstr, NULL); |
117 | } |
118 | |
119 | /* Signed ones */ |
120 | |
121 | type xstrto(_range_sfx)(const char *numstr, int base, |
122 | type lower, |
123 | type upper, |
124 | const struct suffix_mult *suffixes) |
125 | { |
126 | unsigned type u = XSTR_TYPE_MAX; |
127 | type r; |
128 | const char *p = numstr; |
129 | |
130 | if (p[0] == '-') { |
131 | ++p; |
132 | ++u; /* two's complement */ |
133 | } |
134 | |
135 | r = xstrtou(_range_sfx)(p, base, 0, u, suffixes); |
136 | |
137 | if (*numstr == '-') { |
138 | r = -r; |
139 | } |
140 | |
141 | if (r < lower || r > upper) { |
142 | bb_error_msg_and_die("number %s is not in %lld..%lld range", |
143 | numstr, (long long)lower, (long long)upper); |
144 | } |
145 | |
146 | return r; |
147 | } |
148 | |
149 | type xstrto(_range)(const char *numstr, int base, type lower, type upper) |
150 | { |
151 | return xstrto(_range_sfx)(numstr, base, lower, upper, NULL); |
152 | } |
153 | |
154 | type xato(_range_sfx)(const char *numstr, |
155 | type lower, |
156 | type upper, |
157 | const struct suffix_mult *suffixes) |
158 | { |
159 | return xstrto(_range_sfx)(numstr, 10, lower, upper, suffixes); |
160 | } |
161 | |
162 | type xato(_range)(const char *numstr, type lower, type upper) |
163 | { |
164 | return xstrto(_range_sfx)(numstr, 10, lower, upper, NULL); |
165 | } |
166 | |
167 | type xato(_sfx)(const char *numstr, const struct suffix_mult *suffixes) |
168 | { |
169 | return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, suffixes); |
170 | } |
171 | |
172 | type xato()(const char *numstr) |
173 | { |
174 | return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, NULL); |
175 | } |
176 | |
177 | #undef type |
178 | #undef xstrtou |
179 | #undef xstrto |
180 | #undef xatou |
181 | #undef xato |
182 | #undef XSTR_UTYPE_MAX |
183 | #undef XSTR_TYPE_MAX |
184 | #undef XSTR_TYPE_MIN |
185 | #undef XSTR_STRTOU |