Magellan Linux

Annotation of /tags/mkinitrd-6_1_11/busybox/libbb/xatonum_template.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 928 - (hide annotations) (download)
Wed Oct 28 13:31:19 2009 UTC (14 years, 7 months ago) by niro
File MIME type: text/plain
File size: 4930 byte(s)
tagged 'mkinitrd-6_1_11'
1 niro 532 /*
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 niro 816 unsigned type FAST_FUNC xstrtou(_range_sfx)(const char *numstr, int base,
16 niro 532 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 niro 816 /* Disallow '-' and any leading whitespace. Make sure we get the
25     * actual isspace function rather than a macro implementaion. */
26 niro 532 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 niro 816 while (suffixes->mult) {
48 niro 532 if (strcmp(suffixes->suffix, e) == 0) {
49     if (XSTR_UTYPE_MAX / suffixes->mult < r)
50     goto range; /* overflow! */
51     r *= suffixes->mult;
52 niro 816 goto chk_range;
53 niro 532 }
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 niro 816 chk_range:
63 niro 532 /* 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 niro 816 unsigned type FAST_FUNC xstrtou(_range)(const char *numstr, int base,
75 niro 532 unsigned type lower,
76     unsigned type upper)
77     {
78     return xstrtou(_range_sfx)(numstr, base, lower, upper, NULL);
79     }
80    
81 niro 816 unsigned type FAST_FUNC xstrtou(_sfx)(const char *numstr, int base,
82 niro 532 const struct suffix_mult *suffixes)
83     {
84     return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, suffixes);
85     }
86    
87 niro 816 unsigned type FAST_FUNC xstrtou()(const char *numstr, int base)
88 niro 532 {
89     return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, NULL);
90     }
91    
92 niro 816 unsigned type FAST_FUNC xatou(_range_sfx)(const char *numstr,
93 niro 532 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 niro 816 unsigned type FAST_FUNC xatou(_range)(const char *numstr,
101 niro 532 unsigned type lower,
102     unsigned type upper)
103     {
104     return xstrtou(_range_sfx)(numstr, 10, lower, upper, NULL);
105     }
106    
107 niro 816 unsigned type FAST_FUNC xatou(_sfx)(const char *numstr,
108 niro 532 const struct suffix_mult *suffixes)
109     {
110     return xstrtou(_range_sfx)(numstr, 10, 0, XSTR_UTYPE_MAX, suffixes);
111     }
112    
113 niro 816 unsigned type FAST_FUNC xatou()(const char *numstr)
114 niro 532 {
115     return xatou(_sfx)(numstr, NULL);
116     }
117    
118     /* Signed ones */
119    
120 niro 816 type FAST_FUNC xstrto(_range_sfx)(const char *numstr, int base,
121 niro 532 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 niro 816 /* NB: if you'll decide to disallow '+':
130     * at least renice applet needs to allow it */
131     if (p[0] == '+' || p[0] == '-') {
132 niro 532 ++p;
133 niro 816 if (p[0] == '-')
134     ++u; /* = <type>_MIN (01111... + 1 == 10000...) */
135 niro 532 }
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 niro 816 type FAST_FUNC xstrto(_range)(const char *numstr, int base, type lower, type upper)
152 niro 532 {
153     return xstrto(_range_sfx)(numstr, base, lower, upper, NULL);
154     }
155    
156 niro 816 type FAST_FUNC xato(_range_sfx)(const char *numstr,
157 niro 532 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 niro 816 type FAST_FUNC xato(_range)(const char *numstr, type lower, type upper)
165 niro 532 {
166     return xstrto(_range_sfx)(numstr, 10, lower, upper, NULL);
167     }
168    
169 niro 816 type FAST_FUNC xato(_sfx)(const char *numstr, const struct suffix_mult *suffixes)
170 niro 532 {
171     return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, suffixes);
172     }
173    
174 niro 816 type FAST_FUNC xato()(const char *numstr)
175 niro 532 {
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