7 |
* Licensed under GPLv2, see file LICENSE in this tarball for details. |
* Licensed under GPLv2, see file LICENSE in this tarball for details. |
8 |
*/ |
*/ |
9 |
|
|
10 |
|
#if __GNUC_PREREQ(4,1) |
11 |
|
# pragma GCC visibility push(hidden) |
12 |
|
#endif |
13 |
|
|
14 |
/* Provides extern declarations of functions */ |
/* Provides extern declarations of functions */ |
15 |
#define DECLARE_STR_CONV(type, T, UT) \ |
#define DECLARE_STR_CONV(type, T, UT) \ |
16 |
\ |
\ |
17 |
unsigned type xstrto##UT##_range_sfx(const char *str, int b, unsigned type l, unsigned type u, const struct suffix_mult *sfx); \ |
unsigned type xstrto##UT##_range_sfx(const char *str, int b, unsigned type l, unsigned type u, const struct suffix_mult *sfx) FAST_FUNC; \ |
18 |
unsigned type xstrto##UT##_range(const char *str, int b, unsigned type l, unsigned type u); \ |
unsigned type xstrto##UT##_range(const char *str, int b, unsigned type l, unsigned type u) FAST_FUNC; \ |
19 |
unsigned type xstrto##UT##_sfx(const char *str, int b, const struct suffix_mult *sfx); \ |
unsigned type xstrto##UT##_sfx(const char *str, int b, const struct suffix_mult *sfx) FAST_FUNC; \ |
20 |
unsigned type xstrto##UT(const char *str, int b); \ |
unsigned type xstrto##UT(const char *str, int b) FAST_FUNC; \ |
21 |
unsigned type xato##UT##_range_sfx(const char *str, unsigned type l, unsigned type u, const struct suffix_mult *sfx); \ |
unsigned type xato##UT##_range_sfx(const char *str, unsigned type l, unsigned type u, const struct suffix_mult *sfx) FAST_FUNC; \ |
22 |
unsigned type xato##UT##_range(const char *str, unsigned type l, unsigned type u); \ |
unsigned type xato##UT##_range(const char *str, unsigned type l, unsigned type u) FAST_FUNC; \ |
23 |
unsigned type xato##UT##_sfx(const char *str, const struct suffix_mult *sfx); \ |
unsigned type xato##UT##_sfx(const char *str, const struct suffix_mult *sfx) FAST_FUNC; \ |
24 |
unsigned type xato##UT(const char *str); \ |
unsigned type xato##UT(const char *str) FAST_FUNC; \ |
25 |
type xstrto##T##_range_sfx(const char *str, int b, type l, type u, const struct suffix_mult *sfx) ;\ |
type xstrto##T##_range_sfx(const char *str, int b, type l, type u, const struct suffix_mult *sfx) FAST_FUNC; \ |
26 |
type xstrto##T##_range(const char *str, int b, type l, type u); \ |
type xstrto##T##_range(const char *str, int b, type l, type u) FAST_FUNC; \ |
27 |
type xato##T##_range_sfx(const char *str, type l, type u, const struct suffix_mult *sfx); \ |
type xato##T##_range_sfx(const char *str, type l, type u, const struct suffix_mult *sfx) FAST_FUNC; \ |
28 |
type xato##T##_range(const char *str, type l, type u); \ |
type xato##T##_range(const char *str, type l, type u) FAST_FUNC; \ |
29 |
type xato##T##_sfx(const char *str, const struct suffix_mult *sfx); \ |
type xato##T##_sfx(const char *str, const struct suffix_mult *sfx) FAST_FUNC; \ |
30 |
type xato##T(const char *str); \ |
type xato##T(const char *str) FAST_FUNC; \ |
31 |
|
|
32 |
/* Unsigned long long functions always exist */ |
/* Unsigned long long functions always exist */ |
33 |
DECLARE_STR_CONV(long long, ll, ull) |
DECLARE_STR_CONV(long long, ll, ull) |
37 |
/* (useful for mapping them to the type of the same width) */ |
/* (useful for mapping them to the type of the same width) */ |
38 |
#define DEFINE_EQUIV_STR_CONV(narrow, N, W, UN, UW) \ |
#define DEFINE_EQUIV_STR_CONV(narrow, N, W, UN, UW) \ |
39 |
\ |
\ |
40 |
static ATTRIBUTE_ALWAYS_INLINE \ |
static ALWAYS_INLINE \ |
41 |
unsigned narrow xstrto##UN##_range_sfx(const char *str, int b, unsigned narrow l, unsigned narrow u, const struct suffix_mult *sfx) \ |
unsigned narrow xstrto##UN##_range_sfx(const char *str, int b, unsigned narrow l, unsigned narrow u, const struct suffix_mult *sfx) \ |
42 |
{ return xstrto##UW##_range_sfx(str, b, l, u, sfx); } \ |
{ return xstrto##UW##_range_sfx(str, b, l, u, sfx); } \ |
43 |
static ATTRIBUTE_ALWAYS_INLINE \ |
static ALWAYS_INLINE \ |
44 |
unsigned narrow xstrto##UN##_range(const char *str, int b, unsigned narrow l, unsigned narrow u) \ |
unsigned narrow xstrto##UN##_range(const char *str, int b, unsigned narrow l, unsigned narrow u) \ |
45 |
{ return xstrto##UW##_range(str, b, l, u); } \ |
{ return xstrto##UW##_range(str, b, l, u); } \ |
46 |
static ATTRIBUTE_ALWAYS_INLINE \ |
static ALWAYS_INLINE \ |
47 |
unsigned narrow xstrto##UN##_sfx(const char *str, int b, const struct suffix_mult *sfx) \ |
unsigned narrow xstrto##UN##_sfx(const char *str, int b, const struct suffix_mult *sfx) \ |
48 |
{ return xstrto##UW##_sfx(str, b, sfx); } \ |
{ return xstrto##UW##_sfx(str, b, sfx); } \ |
49 |
static ATTRIBUTE_ALWAYS_INLINE \ |
static ALWAYS_INLINE \ |
50 |
unsigned narrow xstrto##UN(const char *str, int b) \ |
unsigned narrow xstrto##UN(const char *str, int b) \ |
51 |
{ return xstrto##UW(str, b); } \ |
{ return xstrto##UW(str, b); } \ |
52 |
static ATTRIBUTE_ALWAYS_INLINE \ |
static ALWAYS_INLINE \ |
53 |
unsigned narrow xato##UN##_range_sfx(const char *str, unsigned narrow l, unsigned narrow u, const struct suffix_mult *sfx) \ |
unsigned narrow xato##UN##_range_sfx(const char *str, unsigned narrow l, unsigned narrow u, const struct suffix_mult *sfx) \ |
54 |
{ return xato##UW##_range_sfx(str, l, u, sfx); } \ |
{ return xato##UW##_range_sfx(str, l, u, sfx); } \ |
55 |
static ATTRIBUTE_ALWAYS_INLINE \ |
static ALWAYS_INLINE \ |
56 |
unsigned narrow xato##UN##_range(const char *str, unsigned narrow l, unsigned narrow u) \ |
unsigned narrow xato##UN##_range(const char *str, unsigned narrow l, unsigned narrow u) \ |
57 |
{ return xato##UW##_range(str, l, u); } \ |
{ return xato##UW##_range(str, l, u); } \ |
58 |
static ATTRIBUTE_ALWAYS_INLINE \ |
static ALWAYS_INLINE \ |
59 |
unsigned narrow xato##UN##_sfx(const char *str, const struct suffix_mult *sfx) \ |
unsigned narrow xato##UN##_sfx(const char *str, const struct suffix_mult *sfx) \ |
60 |
{ return xato##UW##_sfx(str, sfx); } \ |
{ return xato##UW##_sfx(str, sfx); } \ |
61 |
static ATTRIBUTE_ALWAYS_INLINE \ |
static ALWAYS_INLINE \ |
62 |
unsigned narrow xato##UN(const char *str) \ |
unsigned narrow xato##UN(const char *str) \ |
63 |
{ return xato##UW(str); } \ |
{ return xato##UW(str); } \ |
64 |
static ATTRIBUTE_ALWAYS_INLINE \ |
static ALWAYS_INLINE \ |
65 |
narrow xstrto##N##_range_sfx(const char *str, int b, narrow l, narrow u, const struct suffix_mult *sfx) \ |
narrow xstrto##N##_range_sfx(const char *str, int b, narrow l, narrow u, const struct suffix_mult *sfx) \ |
66 |
{ return xstrto##W##_range_sfx(str, b, l, u, sfx); } \ |
{ return xstrto##W##_range_sfx(str, b, l, u, sfx); } \ |
67 |
static ATTRIBUTE_ALWAYS_INLINE \ |
static ALWAYS_INLINE \ |
68 |
narrow xstrto##N##_range(const char *str, int b, narrow l, narrow u) \ |
narrow xstrto##N##_range(const char *str, int b, narrow l, narrow u) \ |
69 |
{ return xstrto##W##_range(str, b, l, u); } \ |
{ return xstrto##W##_range(str, b, l, u); } \ |
70 |
static ATTRIBUTE_ALWAYS_INLINE \ |
static ALWAYS_INLINE \ |
71 |
narrow xato##N##_range_sfx(const char *str, narrow l, narrow u, const struct suffix_mult *sfx) \ |
narrow xato##N##_range_sfx(const char *str, narrow l, narrow u, const struct suffix_mult *sfx) \ |
72 |
{ return xato##W##_range_sfx(str, l, u, sfx); } \ |
{ return xato##W##_range_sfx(str, l, u, sfx); } \ |
73 |
static ATTRIBUTE_ALWAYS_INLINE \ |
static ALWAYS_INLINE \ |
74 |
narrow xato##N##_range(const char *str, narrow l, narrow u) \ |
narrow xato##N##_range(const char *str, narrow l, narrow u) \ |
75 |
{ return xato##W##_range(str, l, u); } \ |
{ return xato##W##_range(str, l, u); } \ |
76 |
static ATTRIBUTE_ALWAYS_INLINE \ |
static ALWAYS_INLINE \ |
77 |
narrow xato##N##_sfx(const char *str, const struct suffix_mult *sfx) \ |
narrow xato##N##_sfx(const char *str, const struct suffix_mult *sfx) \ |
78 |
{ return xato##W##_sfx(str, sfx); } \ |
{ return xato##W##_sfx(str, sfx); } \ |
79 |
static ATTRIBUTE_ALWAYS_INLINE \ |
static ALWAYS_INLINE \ |
80 |
narrow xato##N(const char *str) \ |
narrow xato##N(const char *str) \ |
81 |
{ return xato##W(str); } \ |
{ return xato##W(str); } \ |
82 |
|
|
100 |
/* Specialized */ |
/* Specialized */ |
101 |
|
|
102 |
int BUG_xatou32_unimplemented(void); |
int BUG_xatou32_unimplemented(void); |
103 |
static ATTRIBUTE_ALWAYS_INLINE uint32_t xatou32(const char *numstr) |
static ALWAYS_INLINE uint32_t xatou32(const char *numstr) |
104 |
{ |
{ |
105 |
if (UINT_MAX == 0xffffffff) |
if (UINT_MAX == 0xffffffff) |
106 |
return xatou(numstr); |
return xatou(numstr); |
109 |
return BUG_xatou32_unimplemented(); |
return BUG_xatou32_unimplemented(); |
110 |
} |
} |
111 |
|
|
112 |
/* Non-aborting kind of convertors */ |
/* Non-aborting kind of convertors: bb_strto[u][l]l */ |
113 |
|
|
114 |
|
/* On exit: errno = 0 only if there was non-empty, '\0' terminated value |
115 |
|
* errno = EINVAL if value was not '\0' terminated, but otherwise ok |
116 |
|
* Return value is still valid, caller should just check whether end[0] |
117 |
|
* is a valid terminating char for particular case. OTOH, if caller |
118 |
|
* requires '\0' terminated input, [s]he can just check errno == 0. |
119 |
|
* errno = ERANGE if value had alphanumeric terminating char ("1234abcg"). |
120 |
|
* errno = ERANGE if value is out of range, missing, etc. |
121 |
|
* errno = ERANGE if value had minus sign for strtouXX (even "-0" is not ok ) |
122 |
|
* return value is all-ones in this case. |
123 |
|
*/ |
124 |
|
|
125 |
unsigned long long bb_strtoull(const char *arg, char **endp, int base); |
unsigned long long bb_strtoull(const char *arg, char **endp, int base) FAST_FUNC; |
126 |
long long bb_strtoll(const char *arg, char **endp, int base); |
long long bb_strtoll(const char *arg, char **endp, int base) FAST_FUNC; |
127 |
|
|
128 |
#if ULONG_MAX == ULLONG_MAX |
#if ULONG_MAX == ULLONG_MAX |
129 |
static ATTRIBUTE_ALWAYS_INLINE |
static ALWAYS_INLINE |
130 |
unsigned long bb_strtoul(const char *arg, char **endp, int base) |
unsigned long bb_strtoul(const char *arg, char **endp, int base) |
131 |
{ return bb_strtoull(arg, endp, base); } |
{ return bb_strtoull(arg, endp, base); } |
132 |
static ATTRIBUTE_ALWAYS_INLINE |
static ALWAYS_INLINE |
133 |
long bb_strtol(const char *arg, char **endp, int base) |
long bb_strtol(const char *arg, char **endp, int base) |
134 |
{ return bb_strtoll(arg, endp, base); } |
{ return bb_strtoll(arg, endp, base); } |
135 |
#else |
#else |
136 |
unsigned long bb_strtoul(const char *arg, char **endp, int base); |
unsigned long bb_strtoul(const char *arg, char **endp, int base) FAST_FUNC; |
137 |
long bb_strtol(const char *arg, char **endp, int base); |
long bb_strtol(const char *arg, char **endp, int base) FAST_FUNC; |
138 |
#endif |
#endif |
139 |
|
|
140 |
#if UINT_MAX == ULLONG_MAX |
#if UINT_MAX == ULLONG_MAX |
141 |
static ATTRIBUTE_ALWAYS_INLINE |
static ALWAYS_INLINE |
142 |
unsigned bb_strtou(const char *arg, char **endp, int base) |
unsigned bb_strtou(const char *arg, char **endp, int base) |
143 |
{ return bb_strtoull(arg, endp, base); } |
{ return bb_strtoull(arg, endp, base); } |
144 |
static ATTRIBUTE_ALWAYS_INLINE |
static ALWAYS_INLINE |
145 |
int bb_strtoi(const char *arg, char **endp, int base) |
int bb_strtoi(const char *arg, char **endp, int base) |
146 |
{ return bb_strtoll(arg, endp, base); } |
{ return bb_strtoll(arg, endp, base); } |
147 |
#elif UINT_MAX == ULONG_MAX |
#elif UINT_MAX == ULONG_MAX |
148 |
static ATTRIBUTE_ALWAYS_INLINE |
static ALWAYS_INLINE |
149 |
unsigned bb_strtou(const char *arg, char **endp, int base) |
unsigned bb_strtou(const char *arg, char **endp, int base) |
150 |
{ return bb_strtoul(arg, endp, base); } |
{ return bb_strtoul(arg, endp, base); } |
151 |
static ATTRIBUTE_ALWAYS_INLINE |
static ALWAYS_INLINE |
152 |
int bb_strtoi(const char *arg, char **endp, int base) |
int bb_strtoi(const char *arg, char **endp, int base) |
153 |
{ return bb_strtol(arg, endp, base); } |
{ return bb_strtol(arg, endp, base); } |
154 |
#else |
#else |
155 |
unsigned bb_strtou(const char *arg, char **endp, int base); |
unsigned bb_strtou(const char *arg, char **endp, int base) FAST_FUNC; |
156 |
int bb_strtoi(const char *arg, char **endp, int base); |
int bb_strtoi(const char *arg, char **endp, int base) FAST_FUNC; |
157 |
#endif |
#endif |
158 |
|
|
159 |
int BUG_bb_strtou32_unimplemented(void); |
int BUG_bb_strtou32_unimplemented(void); |
160 |
static ATTRIBUTE_ALWAYS_INLINE |
static ALWAYS_INLINE |
161 |
uint32_t bb_strtou32(const char *arg, char **endp, int base) |
uint32_t bb_strtou32(const char *arg, char **endp, int base) |
162 |
{ |
{ |
163 |
if (sizeof(uint32_t) == sizeof(unsigned)) |
if (sizeof(uint32_t) == sizeof(unsigned)) |
169 |
|
|
170 |
/* Floating point */ |
/* Floating point */ |
171 |
|
|
172 |
/* double bb_strtod(const char *arg, char **endp); */ |
double bb_strtod(const char *arg, char **endp) FAST_FUNC; |
173 |
|
|
174 |
|
#if __GNUC_PREREQ(4,1) |
175 |
|
# pragma GCC visibility pop |
176 |
|
#endif |