conv.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /** @file conv.c
  2. * @brief Functions to convert from string to integer.
  3. */
  4. #include <stdlib.h>
  5. #include <errno.h>
  6. #include <limits.h>
  7. #include "faux/conv.h"
  8. /** @brief Converts string to long int
  9. *
  10. * Converts string to long int and check for overflow and valid
  11. * input values. Function indicates error by return value. It
  12. * returns the convertion result by second argument.
  13. *
  14. * @param [in] str Input string to convert.
  15. * @param [out] val Pointer to result value.
  16. * @param [in] base Base to convert.
  17. * @return 0 - success, < 0 - error
  18. */
  19. int faux_conv_atol(const char *str, long int *val, int base) {
  20. char *endptr = NULL;
  21. long int res = 0;
  22. errno = 0; // man recommends to do so
  23. res = strtol(str, &endptr, base);
  24. // Check for overflow
  25. if (((LONG_MIN == res) || (LONG_MAX == res)) && (ERANGE == errno))
  26. return -1;
  27. // No valid digits at all
  28. if ((0 == res) && ((endptr == str) || (errno != 0)))
  29. return -1;
  30. *val = res;
  31. return 0;
  32. }
  33. /** @brief Converts string to unsigned long int
  34. *
  35. * Converts string to unsigned long int and check for overflow and valid
  36. * input values. Function indicates error by return value. It
  37. * returns the convertion result by second argument.
  38. *
  39. * @param [in] str Input string to convert.
  40. * @param [out] val Pointer to result value.
  41. * @param [in] base Base to convert.
  42. * @return 0 - success, < 0 - error
  43. */
  44. int faux_conv_atoul(const char *str, unsigned long int *val, int base) {
  45. char *endptr = NULL;
  46. unsigned long int res = 0;
  47. errno = 0; // man recommends to do so
  48. res = strtoul(str, &endptr, base);
  49. // Check for overflow
  50. if ((ULONG_MAX == res) && (ERANGE == errno))
  51. return -1;
  52. // No valid digits at all
  53. if ((0 == res) && ((endptr == str) || (errno != 0)))
  54. return -1;
  55. *val = res;
  56. return 0;
  57. }
  58. /** @brief Converts string to long long int
  59. *
  60. * Converts string to long long int and check for overflow and valid
  61. * input values. Function indicates error by return value. It
  62. * returns the convertion result by second argument.
  63. *
  64. * @param [in] str Input string to convert.
  65. * @param [out] val Pointer to result value.
  66. * @param [in] base Base to convert.
  67. * @return 0 - success, < 0 - error
  68. */
  69. int faux_conv_atoll(const char *str, long long int *val, int base) {
  70. char *endptr = NULL;
  71. long long int res = 0;
  72. errno = 0; // man recommends to do so
  73. res = strtoll(str, &endptr, base);
  74. // Check for overflow
  75. if (((LLONG_MIN == res) || (LLONG_MAX == res)) && (ERANGE == errno))
  76. return -1;
  77. // No valid digits at all
  78. if ((0 == res) && ((endptr == str) || (errno != 0)))
  79. return -1;
  80. *val = res;
  81. return 0;
  82. }
  83. /** @brief Converts string to unsigned long long int
  84. *
  85. * Converts string to unsigned long long int and check for overflow and valid
  86. * input values. Function indicates error by return value. It
  87. * returns the convertion result by second argument.
  88. *
  89. * @param [in] str Input string to convert.
  90. * @param [out] val Pointer to result value.
  91. * @param [in] base Base to convert.
  92. * @return 0 - success, < 0 - error
  93. */
  94. int faux_conv_atoull(const char *str, unsigned long long int *val, int base) {
  95. char *endptr = NULL;
  96. unsigned long long int res = 0;
  97. errno = 0; // man recommends to do so
  98. res = strtoull(str, &endptr, base);
  99. // Check for overflow
  100. if ((ULLONG_MAX == res) && (ERANGE == errno))
  101. return -1;
  102. // No valid digits at all
  103. if ((0 == res) && ((endptr == str) || (errno != 0)))
  104. return -1;
  105. *val = res;
  106. return 0;
  107. }
  108. /** @brief Converts string to int
  109. *
  110. * Converts string to int and check for overflow and valid
  111. * input values. Function indicates error by return value. It
  112. * returns the convertion result by second argument.
  113. *
  114. * @param [in] str Input string to convert.
  115. * @param [out] val Pointer to result value.
  116. * @param [in] base Base to convert.
  117. * @return 0 - success, < 0 - error
  118. */
  119. int faux_conv_atoi(const char *str, int *val, int base) {
  120. long int tmp = 0;
  121. // Use existent func. The long int is longer or equal to int.
  122. if (faux_conv_atol(str, &tmp, base) < 0)
  123. return -1;
  124. if ((tmp < INT_MIN) || (tmp > INT_MAX)) // Overflow
  125. return -1;
  126. *val = tmp;
  127. return 0;
  128. }
  129. /** @brief Converts string to unsigned int
  130. *
  131. * Converts string to unsigned int and check for overflow and valid
  132. * input values. Function indicates error by return value. It
  133. * returns the convertion result by second argument.
  134. *
  135. * @param [in] str Input string to convert.
  136. * @param [out] val Pointer to result value.
  137. * @param [in] base Base to convert.
  138. * @return 0 - success, < 0 - error
  139. */
  140. int faux_conv_atoui(const char *str, unsigned int *val, int base) {
  141. unsigned long int tmp = 0;
  142. // Use existent func. The long int is longer or equal to int.
  143. if (faux_conv_atoul(str, &tmp, base) < 0)
  144. return -1;
  145. if (tmp > UINT_MAX) // Overflow
  146. return -1;
  147. *val = tmp;
  148. return 0;
  149. }
  150. /** @brief Converts string to short
  151. *
  152. * Converts string to short and check for overflow and valid
  153. * input values. Function indicates error by return value. It
  154. * returns the convertion result by second argument.
  155. *
  156. * @param [in] str Input string to convert.
  157. * @param [out] val Pointer to result value.
  158. * @param [in] base Base to convert.
  159. * @return 0 - success, < 0 - error
  160. */
  161. int faux_conv_atos(const char *str, short *val, int base)
  162. {
  163. long int tmp = 0;
  164. if (faux_conv_atol(str, &tmp, base) < 0)
  165. return -1;
  166. if ((tmp < SHRT_MIN) || (tmp > SHRT_MAX)) // Overflow
  167. return -1;
  168. *val = tmp;
  169. return 0;
  170. }
  171. /** @brief Converts string to unsigned short
  172. *
  173. * Converts string to unsigned short and check for overflow and valid
  174. * input values. Function indicates error by return value. It
  175. * returns the convertion result by second argument.
  176. *
  177. * @param [in] str Input string to convert.
  178. * @param [out] val Pointer to result value.
  179. * @param [in] base Base to convert.
  180. * @return 0 - success, < 0 - error
  181. */
  182. int faux_conv_atous(const char *str, unsigned short *val, int base)
  183. {
  184. unsigned long int tmp = 0;
  185. if (faux_conv_atoul(str, &tmp, base) < 0)
  186. return -1;
  187. if (tmp > USHRT_MAX) // Overflow
  188. return -1;
  189. *val = tmp;
  190. return 0;
  191. }
  192. /** @brief Converts string to char
  193. *
  194. * Converts string to char and check for overflow and valid
  195. * input values. Function indicates error by return value. It
  196. * returns the convertion result by second argument.
  197. *
  198. * @param [in] str Input string to convert.
  199. * @param [out] val Pointer to result value.
  200. * @param [in] base Base to convert.
  201. * @return 0 - success, < 0 - error
  202. */
  203. int faux_conv_atoc(const char *str, char *val, int base)
  204. {
  205. long int tmp = 0;
  206. if (faux_conv_atol(str, &tmp, base) < 0)
  207. return -1;
  208. if ((tmp < CHAR_MIN) || (tmp > CHAR_MAX)) // Overflow
  209. return -1;
  210. *val = tmp;
  211. return 0;
  212. }
  213. /** @brief Converts string to unsigned char
  214. *
  215. * Converts string to unsigned char and check for overflow and valid
  216. * input values. Function indicates error by return value. It
  217. * returns the convertion result by second argument.
  218. *
  219. * @param [in] str Input string to convert.
  220. * @param [out] val Pointer to result value.
  221. * @param [in] base Base to convert.
  222. * @return 0 - success, < 0 - error
  223. */
  224. int faux_conv_atouc(const char *str, unsigned char *val, int base)
  225. {
  226. unsigned long int tmp = 0;
  227. if (faux_conv_atoul(str, &tmp, base) < 0)
  228. return -1;
  229. if (tmp > UCHAR_MAX) // Overflow
  230. return -1;
  231. *val = tmp;
  232. return 0;
  233. }