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