1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19unsigned 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
29
30 if (*numstr == '-' || *numstr == '+' || (isspace)(*numstr))
31 goto inval;
32
33
34
35
36 old_errno = errno;
37 errno = 0;
38 r = XSTR_STRTOU(numstr, &e, base);
39
40
41
42 if (errno || numstr == e)
43 goto inval;
44
45 errno = old_errno;
46
47
48
49
50 if (suffixes) {
51 while (suffixes->mult) {
52 if (strcmp(suffixes->suffix, e) == 0) {
53 if (XSTR_UTYPE_MAX / suffixes->mult < r)
54 goto range;
55 r *= suffixes->mult;
56 goto chk_range;
57 }
58 ++suffixes;
59 }
60 }
61
62
63
64 if (*e)
65 goto inval;
66 chk_range:
67
68 if (r >= lower && r <= upper)
69 return r;
70 range:
71 bb_error_msg_and_die("number %s is not in %llu..%llu range",
72 numstr, (unsigned long long)lower,
73 (unsigned long long)upper);
74 inval:
75 bb_error_msg_and_die("invalid number '%s'", numstr);
76}
77
78unsigned type FAST_FUNC xstrtou(_range)(const char *numstr, int base,
79 unsigned type lower,
80 unsigned type upper)
81{
82 return xstrtou(_range_sfx)(numstr, base, lower, upper, NULL);
83}
84
85unsigned type FAST_FUNC xstrtou(_sfx)(const char *numstr, int base,
86 const struct suffix_mult *suffixes)
87{
88 return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, suffixes);
89}
90
91unsigned type FAST_FUNC xstrtou()(const char *numstr, int base)
92{
93 return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, NULL);
94}
95
96unsigned type FAST_FUNC xatou(_range_sfx)(const char *numstr,
97 unsigned type lower,
98 unsigned type upper,
99 const struct suffix_mult *suffixes)
100{
101 return xstrtou(_range_sfx)(numstr, 10, lower, upper, suffixes);
102}
103
104unsigned type FAST_FUNC xatou(_range)(const char *numstr,
105 unsigned type lower,
106 unsigned type upper)
107{
108 return xstrtou(_range_sfx)(numstr, 10, lower, upper, NULL);
109}
110
111unsigned type FAST_FUNC xatou(_sfx)(const char *numstr,
112 const struct suffix_mult *suffixes)
113{
114 return xstrtou(_range_sfx)(numstr, 10, 0, XSTR_UTYPE_MAX, suffixes);
115}
116
117unsigned type FAST_FUNC xatou()(const char *numstr)
118{
119 return xatou(_sfx)(numstr, NULL);
120}
121
122
123
124type FAST_FUNC xstrto(_range_sfx)(const char *numstr, int base,
125 type lower,
126 type upper,
127 const struct suffix_mult *suffixes)
128{
129 unsigned type u = XSTR_TYPE_MAX;
130 type r;
131 const char *p = numstr;
132
133
134
135 if (p[0] == '+' || p[0] == '-') {
136 ++p;
137 if (p[0] == '-')
138 ++u;
139 }
140
141 r = xstrtou(_range_sfx)(p, base, 0, u, suffixes);
142
143 if (*numstr == '-') {
144 r = -r;
145 }
146
147 if (r < lower || r > upper) {
148 bb_error_msg_and_die("number %s is not in %lld..%lld range",
149 numstr, (long long)lower, (long long)upper);
150 }
151
152 return r;
153}
154
155type FAST_FUNC xstrto(_range)(const char *numstr, int base, type lower, type upper)
156{
157 return xstrto(_range_sfx)(numstr, base, lower, upper, NULL);
158}
159
160type FAST_FUNC xato(_range_sfx)(const char *numstr,
161 type lower,
162 type upper,
163 const struct suffix_mult *suffixes)
164{
165 return xstrto(_range_sfx)(numstr, 10, lower, upper, suffixes);
166}
167
168type FAST_FUNC xato(_range)(const char *numstr, type lower, type upper)
169{
170 return xstrto(_range_sfx)(numstr, 10, lower, upper, NULL);
171}
172
173type FAST_FUNC xato(_sfx)(const char *numstr, const struct suffix_mult *suffixes)
174{
175 return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, suffixes);
176}
177
178type FAST_FUNC xato()(const char *numstr)
179{
180 return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, NULL);
181}
182
183#undef type
184#undef xstrtou
185#undef xstrto
186#undef xatou
187#undef xato
188#undef XSTR_UTYPE_MAX
189#undef XSTR_TYPE_MAX
190#undef XSTR_TYPE_MIN
191#undef XSTR_STRTOU
192