hush: get rid of charmap[]
[oweals/busybox.git] / include / xatonum.h
1 /* vi: set sw=4 ts=4: */
2 /*
3  * ascii-to-numbers implementations for busybox
4  *
5  * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
6  *
7  * 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 */
15 #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) 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; \
31
32 /* Unsigned long long functions always exist */
33 DECLARE_STR_CONV(long long, ll, ull)
34
35
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) \
39 \
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); } \
82
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)
86 #else
87 /* Else provide extern defs */
88 DECLARE_STR_CONV(long, l, ul)
89 #endif
90
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)
96 #else
97 DECLARE_STR_CONV(int, i, u)
98 #endif
99
100 /* Specialized */
101
102 int BUG_xatou32_unimplemented(void);
103 static ALWAYS_INLINE uint32_t xatou32(const char *numstr)
104 {
105         if (UINT_MAX == 0xffffffff)
106                 return xatou(numstr);
107         if (ULONG_MAX == 0xffffffff)
108                 return xatoul(numstr);
109         return BUG_xatou32_unimplemented();
110 }
111
112 /* 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) FAST_FUNC;
126 long long bb_strtoll(const char *arg, char **endp, int base) FAST_FUNC;
127
128 #if ULONG_MAX == ULLONG_MAX
129 static ALWAYS_INLINE
130 unsigned long bb_strtoul(const char *arg, char **endp, int base)
131 { return bb_strtoull(arg, endp, base); }
132 static ALWAYS_INLINE
133 long bb_strtol(const char *arg, char **endp, int base)
134 { return bb_strtoll(arg, endp, base); }
135 #else
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;
138 #endif
139
140 #if UINT_MAX == ULLONG_MAX
141 static ALWAYS_INLINE
142 unsigned bb_strtou(const char *arg, char **endp, int base)
143 { return bb_strtoull(arg, endp, base); }
144 static ALWAYS_INLINE
145 int bb_strtoi(const char *arg, char **endp, int base)
146 { return bb_strtoll(arg, endp, base); }
147 #elif UINT_MAX == ULONG_MAX
148 static ALWAYS_INLINE
149 unsigned bb_strtou(const char *arg, char **endp, int base)
150 { return bb_strtoul(arg, endp, base); }
151 static ALWAYS_INLINE
152 int bb_strtoi(const char *arg, char **endp, int base)
153 { return bb_strtol(arg, endp, base); }
154 #else
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;
157 #endif
158
159 int BUG_bb_strtou32_unimplemented(void);
160 static ALWAYS_INLINE
161 uint32_t bb_strtou32(const char *arg, char **endp, int base)
162 {
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();
168 }
169
170 /* Floating point */
171
172 double bb_strtod(const char *arg, char **endp) FAST_FUNC;
173
174 #if __GNUC_PREREQ(4,1)
175 # pragma GCC visibility pop
176 #endif