1 /* vi: set sw=4 ts=4: */
3 * ascii-to-numbers implementations for busybox
5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
7 * Licensed under GPLv2, see file LICENSE in this tarball for details.
10 #if __GNUC_PREREQ(4,1)
11 # pragma GCC visibility push(hidden)
14 /* Provides extern declarations of functions */
15 #define DECLARE_STR_CONV(type, T, UT) \
17 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) FAST_FUNC; \
19 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) FAST_FUNC; \
21 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) FAST_FUNC; \
23 unsigned type xato##UT##_sfx(const char *str, const struct suffix_mult *sfx) FAST_FUNC; \
24 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) FAST_FUNC; \
26 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) FAST_FUNC; \
28 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) FAST_FUNC; \
30 type xato##T(const char *str) FAST_FUNC; \
32 /* Unsigned long long functions always exist */
33 DECLARE_STR_CONV(long long, ll, ull)
36 /* Provides inline definitions of functions */
37 /* (useful for mapping them to the type of the same width) */
38 #define DEFINE_EQUIV_STR_CONV(narrow, N, W, UN, UW) \
40 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) \
42 { return xstrto##UW##_range_sfx(str, b, l, u, sfx); } \
43 static ALWAYS_INLINE \
44 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); } \
46 static ALWAYS_INLINE \
47 unsigned narrow xstrto##UN##_sfx(const char *str, int b, const struct suffix_mult *sfx) \
48 { return xstrto##UW##_sfx(str, b, sfx); } \
49 static ALWAYS_INLINE \
50 unsigned narrow xstrto##UN(const char *str, int b) \
51 { return xstrto##UW(str, b); } \
52 static ALWAYS_INLINE \
53 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); } \
55 static ALWAYS_INLINE \
56 unsigned narrow xato##UN##_range(const char *str, unsigned narrow l, unsigned narrow u) \
57 { return xato##UW##_range(str, l, u); } \
58 static ALWAYS_INLINE \
59 unsigned narrow xato##UN##_sfx(const char *str, const struct suffix_mult *sfx) \
60 { return xato##UW##_sfx(str, sfx); } \
61 static ALWAYS_INLINE \
62 unsigned narrow xato##UN(const char *str) \
63 { return xato##UW(str); } \
64 static ALWAYS_INLINE \
65 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); } \
67 static ALWAYS_INLINE \
68 narrow xstrto##N##_range(const char *str, int b, narrow l, narrow u) \
69 { return xstrto##W##_range(str, b, l, u); } \
70 static ALWAYS_INLINE \
71 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); } \
73 static ALWAYS_INLINE \
74 narrow xato##N##_range(const char *str, narrow l, narrow u) \
75 { return xato##W##_range(str, l, u); } \
76 static ALWAYS_INLINE \
77 narrow xato##N##_sfx(const char *str, const struct suffix_mult *sfx) \
78 { return xato##W##_sfx(str, sfx); } \
79 static ALWAYS_INLINE \
80 narrow xato##N(const char *str) \
81 { return xato##W(str); } \
83 /* If long == long long, then just map them one-to-one */
84 #if ULONG_MAX == ULLONG_MAX
85 DEFINE_EQUIV_STR_CONV(long, l, ll, ul, ull)
87 /* Else provide extern defs */
88 DECLARE_STR_CONV(long, l, ul)
91 /* Same for int -> [long] long */
92 #if UINT_MAX == ULLONG_MAX
93 DEFINE_EQUIV_STR_CONV(int, i, ll, u, ull)
94 #elif UINT_MAX == ULONG_MAX
95 DEFINE_EQUIV_STR_CONV(int, i, l, u, ul)
97 DECLARE_STR_CONV(int, i, u)
102 int BUG_xatou32_unimplemented(void);
103 static ALWAYS_INLINE uint32_t xatou32(const char *numstr)
105 if (UINT_MAX == 0xffffffff)
106 return xatou(numstr);
107 if (ULONG_MAX == 0xffffffff)
108 return xatoul(numstr);
109 return BUG_xatou32_unimplemented();
112 /* Non-aborting kind of convertors: bb_strto[u][l]l */
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.
125 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) FAST_FUNC;
128 #if ULONG_MAX == ULLONG_MAX
130 unsigned long bb_strtoul(const char *arg, char **endp, int base)
131 { return bb_strtoull(arg, endp, base); }
133 long bb_strtol(const char *arg, char **endp, int base)
134 { return bb_strtoll(arg, endp, base); }
136 unsigned long bb_strtoul(const char *arg, char **endp, int base) FAST_FUNC;
137 long bb_strtol(const char *arg, char **endp, int base) FAST_FUNC;
140 #if UINT_MAX == ULLONG_MAX
142 unsigned bb_strtou(const char *arg, char **endp, int base)
143 { return bb_strtoull(arg, endp, base); }
145 int bb_strtoi(const char *arg, char **endp, int base)
146 { return bb_strtoll(arg, endp, base); }
147 #elif UINT_MAX == ULONG_MAX
149 unsigned bb_strtou(const char *arg, char **endp, int base)
150 { return bb_strtoul(arg, endp, base); }
152 int bb_strtoi(const char *arg, char **endp, int base)
153 { return bb_strtol(arg, endp, base); }
155 unsigned bb_strtou(const char *arg, char **endp, int base) FAST_FUNC;
156 int bb_strtoi(const char *arg, char **endp, int base) FAST_FUNC;
159 int BUG_bb_strtou32_unimplemented(void);
161 uint32_t bb_strtou32(const char *arg, char **endp, int base)
163 if (sizeof(uint32_t) == sizeof(unsigned))
164 return bb_strtou(arg, endp, base);
165 if (sizeof(uint32_t) == sizeof(unsigned long))
166 return bb_strtoul(arg, endp, base);
167 return BUG_bb_strtou32_unimplemented();
172 double bb_strtod(const char *arg, char **endp) FAST_FUNC;
174 #if __GNUC_PREREQ(4,1)
175 # pragma GCC visibility pop