busybox/include/xatonum.h
<<
>>
Prefs
   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 source tree.
   8 */
   9
  10PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
  11
  12/* Provides extern declarations of functions */
  13#define DECLARE_STR_CONV(type, T, UT) \
  14\
  15unsigned type xstrto##UT##_range_sfx(const char *str, int b, unsigned type l, unsigned type u, const struct suffix_mult *sfx) FAST_FUNC; \
  16unsigned type xstrto##UT##_range(const char *str, int b, unsigned type l, unsigned type u) FAST_FUNC; \
  17unsigned type xstrto##UT##_sfx(const char *str, int b, const struct suffix_mult *sfx) FAST_FUNC; \
  18unsigned type xstrto##UT(const char *str, int b) FAST_FUNC; \
  19unsigned type xato##UT##_range_sfx(const char *str, unsigned type l, unsigned type u, const struct suffix_mult *sfx) FAST_FUNC; \
  20unsigned type xato##UT##_range(const char *str, unsigned type l, unsigned type u) FAST_FUNC; \
  21unsigned type xato##UT##_sfx(const char *str, const struct suffix_mult *sfx) FAST_FUNC; \
  22unsigned type xato##UT(const char *str) FAST_FUNC; \
  23type xstrto##T##_range_sfx(const char *str, int b, type l, type u, const struct suffix_mult *sfx) FAST_FUNC; \
  24type xstrto##T##_range(const char *str, int b, type l, type u) FAST_FUNC; \
  25type xstrto##T(const char *str, int b) FAST_FUNC; \
  26type xato##T##_range_sfx(const char *str, type l, type u, const struct suffix_mult *sfx) FAST_FUNC; \
  27type xato##T##_range(const char *str, type l, type u) FAST_FUNC; \
  28type xato##T##_sfx(const char *str, const struct suffix_mult *sfx) FAST_FUNC; \
  29type xato##T(const char *str) FAST_FUNC; \
  30
  31/* Unsigned long long functions always exist */
  32DECLARE_STR_CONV(long long, ll, ull)
  33
  34
  35/* Provides inline definitions of functions */
  36/* (useful for mapping them to the type of the same width) */
  37#define DEFINE_EQUIV_STR_CONV(narrow, N, W, UN, UW) \
  38\
  39static ALWAYS_INLINE \
  40unsigned narrow xstrto##UN##_range_sfx(const char *str, int b, unsigned narrow l, unsigned narrow u, const struct suffix_mult *sfx) \
  41{ return xstrto##UW##_range_sfx(str, b, l, u, sfx); } \
  42static ALWAYS_INLINE \
  43unsigned narrow xstrto##UN##_range(const char *str, int b, unsigned narrow l, unsigned narrow u) \
  44{ return xstrto##UW##_range(str, b, l, u); } \
  45static ALWAYS_INLINE \
  46unsigned narrow xstrto##UN##_sfx(const char *str, int b, const struct suffix_mult *sfx) \
  47{ return xstrto##UW##_sfx(str, b, sfx); } \
  48static ALWAYS_INLINE \
  49unsigned narrow xstrto##UN(const char *str, int b) \
  50{ return xstrto##UW(str, b); } \
  51static ALWAYS_INLINE \
  52unsigned narrow xato##UN##_range_sfx(const char *str, unsigned narrow l, unsigned narrow u, const struct suffix_mult *sfx) \
  53{ return xato##UW##_range_sfx(str, l, u, sfx); } \
  54static ALWAYS_INLINE \
  55unsigned narrow xato##UN##_range(const char *str, unsigned narrow l, unsigned narrow u) \
  56{ return xato##UW##_range(str, l, u); } \
  57static ALWAYS_INLINE \
  58unsigned narrow xato##UN##_sfx(const char *str, const struct suffix_mult *sfx) \
  59{ return xato##UW##_sfx(str, sfx); } \
  60static ALWAYS_INLINE \
  61unsigned narrow xato##UN(const char *str) \
  62{ return xato##UW(str); } \
  63static ALWAYS_INLINE \
  64narrow xstrto##N##_range_sfx(const char *str, int b, narrow l, narrow u, const struct suffix_mult *sfx) \
  65{ return xstrto##W##_range_sfx(str, b, l, u, sfx); } \
  66static ALWAYS_INLINE \
  67narrow xstrto##N##_range(const char *str, int b, narrow l, narrow u) \
  68{ return xstrto##W##_range(str, b, l, u); } \
  69static ALWAYS_INLINE \
  70narrow xstrto##N(const char *str, int b) \
  71{ return xstrto##W(str, b); } \
  72static ALWAYS_INLINE \
  73narrow xato##N##_range_sfx(const char *str, narrow l, narrow u, const struct suffix_mult *sfx) \
  74{ return xato##W##_range_sfx(str, l, u, sfx); } \
  75static ALWAYS_INLINE \
  76narrow xato##N##_range(const char *str, narrow l, narrow u) \
  77{ return xato##W##_range(str, l, u); } \
  78static ALWAYS_INLINE \
  79narrow xato##N##_sfx(const char *str, const struct suffix_mult *sfx) \
  80{ return xato##W##_sfx(str, sfx); } \
  81static ALWAYS_INLINE \
  82narrow xato##N(const char *str) \
  83{ return xato##W(str); } \
  84
  85/* If long == long long, then just map them one-to-one */
  86#if ULONG_MAX == ULLONG_MAX
  87DEFINE_EQUIV_STR_CONV(long, l, ll, ul, ull)
  88#else
  89/* Else provide extern defs */
  90DECLARE_STR_CONV(long, l, ul)
  91#endif
  92
  93/* Same for int -> [long] long */
  94#if UINT_MAX == ULLONG_MAX
  95DEFINE_EQUIV_STR_CONV(int, i, ll, u, ull)
  96#elif UINT_MAX == ULONG_MAX
  97DEFINE_EQUIV_STR_CONV(int, i, l, u, ul)
  98#else
  99DECLARE_STR_CONV(int, i, u)
 100#endif
 101
 102/* Specialized */
 103
 104uint32_t BUG_xatou32_unimplemented(void);
 105static ALWAYS_INLINE uint32_t xatou32(const char *numstr)
 106{
 107        if (UINT_MAX == 0xffffffff)
 108                return xatou(numstr);
 109        if (ULONG_MAX == 0xffffffff)
 110                return xatoul(numstr);
 111        return BUG_xatou32_unimplemented();
 112}
 113
 114/* Non-aborting kind of convertors: bb_strto[u][l]l */
 115
 116/* On exit: errno = 0 only if there was non-empty, '\0' terminated value
 117 * errno = EINVAL if value was not '\0' terminated, but otherwise ok
 118 *    Return value is still valid, caller should just check whether end[0]
 119 *    is a valid terminating char for particular case. OTOH, if caller
 120 *    requires '\0' terminated input, [s]he can just check errno == 0.
 121 * errno = ERANGE if value had alphanumeric terminating char ("1234abcg").
 122 * errno = ERANGE if value is out of range, missing, etc.
 123 * errno = ERANGE if value had minus sign for strtouXX (even "-0" is not ok )
 124 *    return value is all-ones in this case.
 125 */
 126
 127unsigned long long bb_strtoull(const char *arg, char **endp, int base) FAST_FUNC;
 128long long bb_strtoll(const char *arg, char **endp, int base) FAST_FUNC;
 129
 130#if ULONG_MAX == ULLONG_MAX
 131static ALWAYS_INLINE
 132unsigned long bb_strtoul(const char *arg, char **endp, int base)
 133{ return bb_strtoull(arg, endp, base); }
 134static ALWAYS_INLINE
 135long bb_strtol(const char *arg, char **endp, int base)
 136{ return bb_strtoll(arg, endp, base); }
 137#else
 138unsigned long bb_strtoul(const char *arg, char **endp, int base) FAST_FUNC;
 139long bb_strtol(const char *arg, char **endp, int base) FAST_FUNC;
 140#endif
 141
 142#if UINT_MAX == ULLONG_MAX
 143static ALWAYS_INLINE
 144unsigned bb_strtou(const char *arg, char **endp, int base)
 145{ return bb_strtoull(arg, endp, base); }
 146static ALWAYS_INLINE
 147int bb_strtoi(const char *arg, char **endp, int base)
 148{ return bb_strtoll(arg, endp, base); }
 149#elif UINT_MAX == ULONG_MAX
 150static ALWAYS_INLINE
 151unsigned bb_strtou(const char *arg, char **endp, int base)
 152{ return bb_strtoul(arg, endp, base); }
 153static ALWAYS_INLINE
 154int bb_strtoi(const char *arg, char **endp, int base)
 155{ return bb_strtol(arg, endp, base); }
 156#else
 157unsigned bb_strtou(const char *arg, char **endp, int base) FAST_FUNC;
 158int bb_strtoi(const char *arg, char **endp, int base) FAST_FUNC;
 159#endif
 160
 161uint32_t BUG_bb_strtou32_unimplemented(void);
 162static ALWAYS_INLINE
 163uint32_t bb_strtou32(const char *arg, char **endp, int base)
 164{
 165        if (sizeof(uint32_t) == sizeof(unsigned))
 166                return bb_strtou(arg, endp, base);
 167        if (sizeof(uint32_t) == sizeof(unsigned long))
 168                return bb_strtoul(arg, endp, base);
 169        return BUG_bb_strtou32_unimplemented();
 170}
 171static ALWAYS_INLINE
 172int32_t bb_strtoi32(const char *arg, char **endp, int base)
 173{
 174        if (sizeof(int32_t) == sizeof(int))
 175                return bb_strtoi(arg, endp, base);
 176        if (sizeof(int32_t) == sizeof(long))
 177                return bb_strtol(arg, endp, base);
 178        return BUG_bb_strtou32_unimplemented();
 179}
 180
 181/* Floating point */
 182
 183double bb_strtod(const char *arg, char **endp) FAST_FUNC;
 184
 185POP_SAVED_FUNCTION_VISIBILITY
 186