xatonum.h 7.2 KB

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