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 /* Provides extern declarations of functions */
11 #define DECLARE_STR_CONV(type, T, UT) \
13 unsigned type xstrto##UT##_range_sfx(const char *str, int b, unsigned type l, unsigned type u, const struct suffix_mult *sfx); \
14 unsigned type xstrto##UT##_range(const char *str, int b, unsigned type l, unsigned type u); \
15 unsigned type xstrto##UT##_sfx(const char *str, int b, const struct suffix_mult *sfx); \
16 unsigned type xstrto##UT(const char *str, int b); \
17 unsigned type xato##UT##_range_sfx(const char *str, unsigned type l, unsigned type u, const struct suffix_mult *sfx); \
18 unsigned type xato##UT##_range(const char *str, unsigned type l, unsigned type u); \
19 unsigned type xato##UT##_sfx(const char *str, const struct suffix_mult *sfx); \
20 unsigned type xato##UT(const char *str); \
21 type xstrto##T##_range_sfx(const char *str, int b, type l, type u, const struct suffix_mult *sfx); \
22 type xstrto##T##_range(const char *str, int b, type l, type u); \
23 type xato##T##_range_sfx(const char *str, type l, type u, const struct suffix_mult *sfx); \
24 type xato##T##_range(const char *str, type l, type u); \
25 type xato##T##_sfx(const char *str, const struct suffix_mult *sfx); \
26 type xato##T(const char *str); \
28 /* Unsigned long long functions always exist */
29 DECLARE_STR_CONV(long long, ll, ull)
32 /* Provides inline definitions of functions */
33 /* (useful for mapping them to the type of the same width) */
34 #define DEFINE_EQUIV_STR_CONV(narrow, N, W, UN, UW) \
36 static ALWAYS_INLINE \
37 unsigned narrow xstrto##UN##_range_sfx(const char *str, int b, unsigned narrow l, unsigned narrow u, const struct suffix_mult *sfx) \
38 { return xstrto##UW##_range_sfx(str, b, l, u, sfx); } \
39 static ALWAYS_INLINE \
40 unsigned narrow xstrto##UN##_range(const char *str, int b, unsigned narrow l, unsigned narrow u) \
41 { return xstrto##UW##_range(str, b, l, u); } \
42 static ALWAYS_INLINE \
43 unsigned narrow xstrto##UN##_sfx(const char *str, int b, const struct suffix_mult *sfx) \
44 { return xstrto##UW##_sfx(str, b, sfx); } \
45 static ALWAYS_INLINE \
46 unsigned narrow xstrto##UN(const char *str, int b) \
47 { return xstrto##UW(str, b); } \
48 static ALWAYS_INLINE \
49 unsigned narrow xato##UN##_range_sfx(const char *str, unsigned narrow l, unsigned narrow u, const struct suffix_mult *sfx) \
50 { return xato##UW##_range_sfx(str, l, u, sfx); } \
51 static ALWAYS_INLINE \
52 unsigned narrow xato##UN##_range(const char *str, unsigned narrow l, unsigned narrow u) \
53 { return xato##UW##_range(str, l, u); } \
54 static ALWAYS_INLINE \
55 unsigned narrow xato##UN##_sfx(const char *str, const struct suffix_mult *sfx) \
56 { return xato##UW##_sfx(str, sfx); } \
57 static ALWAYS_INLINE \
58 unsigned narrow xato##UN(const char *str) \
59 { return xato##UW(str); } \
60 static ALWAYS_INLINE \
61 narrow xstrto##N##_range_sfx(const char *str, int b, narrow l, narrow u, const struct suffix_mult *sfx) \
62 { return xstrto##W##_range_sfx(str, b, l, u, sfx); } \
63 static ALWAYS_INLINE \
64 narrow xstrto##N##_range(const char *str, int b, narrow l, narrow u) \
65 { return xstrto##W##_range(str, b, l, u); } \
66 static ALWAYS_INLINE \
67 narrow xato##N##_range_sfx(const char *str, narrow l, narrow u, const struct suffix_mult *sfx) \
68 { return xato##W##_range_sfx(str, l, u, sfx); } \
69 static ALWAYS_INLINE \
70 narrow xato##N##_range(const char *str, narrow l, narrow u) \
71 { return xato##W##_range(str, l, u); } \
72 static ALWAYS_INLINE \
73 narrow xato##N##_sfx(const char *str, const struct suffix_mult *sfx) \
74 { return xato##W##_sfx(str, sfx); } \
75 static ALWAYS_INLINE \
76 narrow xato##N(const char *str) \
77 { return xato##W(str); } \
79 /* If long == long long, then just map them one-to-one */
80 #if ULONG_MAX == ULLONG_MAX
81 DEFINE_EQUIV_STR_CONV(long, l, ll, ul, ull)
83 /* Else provide extern defs */
84 DECLARE_STR_CONV(long, l, ul)
87 /* Same for int -> [long] long */
88 #if UINT_MAX == ULLONG_MAX
89 DEFINE_EQUIV_STR_CONV(int, i, ll, u, ull)
90 #elif UINT_MAX == ULONG_MAX
91 DEFINE_EQUIV_STR_CONV(int, i, l, u, ul)
93 DECLARE_STR_CONV(int, i, u)
98 int BUG_xatou32_unimplemented(void);
99 static ALWAYS_INLINE uint32_t xatou32(const char *numstr)
101 if (UINT_MAX == 0xffffffff)
102 return xatou(numstr);
103 if (ULONG_MAX == 0xffffffff)
104 return xatoul(numstr);
105 return BUG_xatou32_unimplemented();
108 /* Non-aborting kind of convertors */
110 unsigned long long bb_strtoull(const char *arg, char **endp, int base);
111 long long bb_strtoll(const char *arg, char **endp, int base);
113 #if ULONG_MAX == ULLONG_MAX
115 unsigned long bb_strtoul(const char *arg, char **endp, int base)
116 { return bb_strtoull(arg, endp, base); }
118 long bb_strtol(const char *arg, char **endp, int base)
119 { return bb_strtoll(arg, endp, base); }
121 unsigned long bb_strtoul(const char *arg, char **endp, int base);
122 long bb_strtol(const char *arg, char **endp, int base);
125 #if UINT_MAX == ULLONG_MAX
127 unsigned bb_strtou(const char *arg, char **endp, int base)
128 { return bb_strtoull(arg, endp, base); }
130 int bb_strtoi(const char *arg, char **endp, int base)
131 { return bb_strtoll(arg, endp, base); }
132 #elif UINT_MAX == ULONG_MAX
134 unsigned bb_strtou(const char *arg, char **endp, int base)
135 { return bb_strtoul(arg, endp, base); }
137 int bb_strtoi(const char *arg, char **endp, int base)
138 { return bb_strtol(arg, endp, base); }
140 unsigned bb_strtou(const char *arg, char **endp, int base);
141 int bb_strtoi(const char *arg, char **endp, int base);
144 int BUG_bb_strtou32_unimplemented(void);
146 uint32_t bb_strtou32(const char *arg, char **endp, int base)
148 if (sizeof(uint32_t) == sizeof(unsigned))
149 return bb_strtou(arg, endp, base);
150 if (sizeof(uint32_t) == sizeof(unsigned long))
151 return bb_strtoul(arg, endp, base);
152 return BUG_bb_strtou32_unimplemented();
157 /* double bb_strtod(const char *arg, char **endp); */