conv.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  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. #include "faux/str.h"
  9. /** @brief Converts string to long int
  10. *
  11. * Converts string to long int and check for overflow and valid
  12. * input values. Function indicates error by return value. It
  13. * returns the convertion result by second argument.
  14. *
  15. * @param [in] str Input string to convert.
  16. * @param [out] val Pointer to result value.
  17. * @param [in] base Base to convert.
  18. * @return BOOL_TRUE - success, BOOL_FALSE - error
  19. */
  20. bool_t faux_conv_atol(const char *str, long int *val, int base)
  21. {
  22. char *endptr = NULL;
  23. long int res = 0;
  24. errno = 0; // man recommends to do so
  25. res = strtol(str, &endptr, base);
  26. // Check for overflow
  27. if (((LONG_MIN == res) || (LONG_MAX == res)) && (ERANGE == errno))
  28. return BOOL_FALSE;
  29. // No valid digits at all
  30. if ((0 == res) && ((endptr == str) || (errno != 0)))
  31. return BOOL_FALSE;
  32. *val = res;
  33. return BOOL_TRUE;
  34. }
  35. /** @brief Converts string to unsigned long int
  36. *
  37. * Converts string to unsigned long int and check for overflow and valid
  38. * input values. Function indicates error by return value. It
  39. * returns the convertion result by second argument.
  40. *
  41. * @param [in] str Input string to convert.
  42. * @param [out] val Pointer to result value.
  43. * @param [in] base Base to convert.
  44. * @return BOOL_TRUE - success, BOOL_FALSE - error
  45. */
  46. bool_t faux_conv_atoul(const char *str, unsigned long int *val, int base)
  47. {
  48. char *endptr = NULL;
  49. unsigned long int res = 0;
  50. errno = 0; // man recommends to do so
  51. res = strtoul(str, &endptr, base);
  52. // Check for overflow
  53. if ((ULONG_MAX == res) && (ERANGE == errno))
  54. return BOOL_FALSE;
  55. // No valid digits at all
  56. if ((0 == res) && ((endptr == str) || (errno != 0)))
  57. return BOOL_FALSE;
  58. *val = res;
  59. return BOOL_TRUE;
  60. }
  61. /** @brief Converts string to long long int
  62. *
  63. * Converts string to long long int and check for overflow and valid
  64. * input values. Function indicates error by return value. It
  65. * returns the convertion result by second argument.
  66. *
  67. * @param [in] str Input string to convert.
  68. * @param [out] val Pointer to result value.
  69. * @param [in] base Base to convert.
  70. * @return BOOL_TRUE - success, BOOL_FALSE - error
  71. */
  72. bool_t faux_conv_atoll(const char *str, long long int *val, int base)
  73. {
  74. char *endptr = NULL;
  75. long long int res = 0;
  76. errno = 0; // man recommends to do so
  77. res = strtoll(str, &endptr, base);
  78. // Check for overflow
  79. if (((LLONG_MIN == res) || (LLONG_MAX == res)) && (ERANGE == errno))
  80. return BOOL_FALSE;
  81. // No valid digits at all
  82. if ((0 == res) && ((endptr == str) || (errno != 0)))
  83. return BOOL_FALSE;
  84. *val = res;
  85. return BOOL_TRUE;
  86. }
  87. /** @brief Converts string to unsigned long long int
  88. *
  89. * Converts string to unsigned long long int and check for overflow and valid
  90. * input values. Function indicates error by return value. It
  91. * returns the convertion result by second argument.
  92. *
  93. * @param [in] str Input string to convert.
  94. * @param [out] val Pointer to result value.
  95. * @param [in] base Base to convert.
  96. * @return BOOL_TRUE - success, BOOL_FALSE - error
  97. */
  98. bool_t faux_conv_atoull(const char *str, unsigned long long int *val, int base)
  99. {
  100. char *endptr = NULL;
  101. unsigned long long int res = 0;
  102. errno = 0; // man recommends to do so
  103. res = strtoull(str, &endptr, base);
  104. // Check for overflow
  105. if ((ULLONG_MAX == res) && (ERANGE == errno))
  106. return BOOL_FALSE;
  107. // No valid digits at all
  108. if ((0 == res) && ((endptr == str) || (errno != 0)))
  109. return BOOL_FALSE;
  110. *val = res;
  111. return BOOL_TRUE;
  112. }
  113. /** @brief Converts string to int
  114. *
  115. * Converts string to int and check for overflow and valid
  116. * input values. Function indicates error by return value. It
  117. * returns the convertion result by second argument.
  118. *
  119. * @param [in] str Input string to convert.
  120. * @param [out] val Pointer to result value.
  121. * @param [in] base Base to convert.
  122. * @return BOOL_TRUE - success, BOOL_FALSE - error
  123. */
  124. bool_t faux_conv_atoi(const char *str, int *val, int base)
  125. {
  126. long int tmp = 0;
  127. // Use existent func. The long int is longer or equal to int.
  128. if (faux_conv_atol(str, &tmp, base) < 0)
  129. return BOOL_FALSE;
  130. if ((tmp < INT_MIN) || (tmp > INT_MAX)) // Overflow
  131. return BOOL_FALSE;
  132. *val = tmp;
  133. return BOOL_TRUE;
  134. }
  135. /** @brief Converts string to unsigned int
  136. *
  137. * Converts string to unsigned int and check for overflow and valid
  138. * input values. Function indicates error by return value. It
  139. * returns the convertion result by second argument.
  140. *
  141. * @param [in] str Input string to convert.
  142. * @param [out] val Pointer to result value.
  143. * @param [in] base Base to convert.
  144. * @return BOOL_TRUE - success, BOOL_FALSE - error
  145. */
  146. bool_t faux_conv_atoui(const char *str, unsigned int *val, int base)
  147. {
  148. unsigned long int tmp = 0;
  149. // Use existent func. The long int is longer or equal to int.
  150. if (faux_conv_atoul(str, &tmp, base) < 0)
  151. return BOOL_FALSE;
  152. if (tmp > UINT_MAX) // Overflow
  153. return BOOL_FALSE;
  154. *val = tmp;
  155. return BOOL_TRUE;
  156. }
  157. /** @brief Converts string to short
  158. *
  159. * Converts string to short and check for overflow and valid
  160. * input values. Function indicates error by return value. It
  161. * returns the convertion result by second argument.
  162. *
  163. * @param [in] str Input string to convert.
  164. * @param [out] val Pointer to result value.
  165. * @param [in] base Base to convert.
  166. * @return BOOL_TRUE - success, BOOL_FALSE - error
  167. */
  168. bool_t faux_conv_atos(const char *str, short *val, int base)
  169. {
  170. long int tmp = 0;
  171. if (faux_conv_atol(str, &tmp, base) < 0)
  172. return BOOL_FALSE;
  173. if ((tmp < SHRT_MIN) || (tmp > SHRT_MAX)) // Overflow
  174. return BOOL_FALSE;
  175. *val = tmp;
  176. return BOOL_TRUE;
  177. }
  178. /** @brief Converts string to unsigned short
  179. *
  180. * Converts string to unsigned short and check for overflow and valid
  181. * input values. Function indicates error by return value. It
  182. * returns the convertion result by second argument.
  183. *
  184. * @param [in] str Input string to convert.
  185. * @param [out] val Pointer to result value.
  186. * @param [in] base Base to convert.
  187. * @return BOOL_TRUE - success, BOOL_FALSE - error
  188. */
  189. bool_t faux_conv_atous(const char *str, unsigned short *val, int base)
  190. {
  191. unsigned long int tmp = 0;
  192. if (faux_conv_atoul(str, &tmp, base) < 0)
  193. return BOOL_FALSE;
  194. if (tmp > USHRT_MAX) // Overflow
  195. return BOOL_FALSE;
  196. *val = tmp;
  197. return BOOL_TRUE;
  198. }
  199. /** @brief Converts string to char
  200. *
  201. * Converts string to char and check for overflow and valid
  202. * input values. Function indicates error by return value. It
  203. * returns the convertion result by second argument.
  204. *
  205. * @param [in] str Input string to convert.
  206. * @param [out] val Pointer to result value.
  207. * @param [in] base Base to convert.
  208. * @return BOOL_TRUE - success, BOOL_FALSE - error
  209. */
  210. bool_t faux_conv_atoc(const char *str, char *val, int base)
  211. {
  212. long int tmp = 0;
  213. if (faux_conv_atol(str, &tmp, base) < 0)
  214. return BOOL_FALSE;
  215. if ((tmp < CHAR_MIN) || (tmp > CHAR_MAX)) // Overflow
  216. return BOOL_FALSE;
  217. *val = tmp;
  218. return BOOL_TRUE;
  219. }
  220. /** @brief Converts string to unsigned char
  221. *
  222. * Converts string to unsigned char and check for overflow and valid
  223. * input values. Function indicates error by return value. It
  224. * returns the convertion result by second argument.
  225. *
  226. * @param [in] str Input string to convert.
  227. * @param [out] val Pointer to result value.
  228. * @param [in] base Base to convert.
  229. * @return BOOL_TRUE - success, BOOL_FALSE - error
  230. */
  231. bool_t faux_conv_atouc(const char *str, unsigned char *val, int base)
  232. {
  233. unsigned long int tmp = 0;
  234. if (faux_conv_atoul(str, &tmp, base) < 0)
  235. return BOOL_FALSE;
  236. if (tmp > UCHAR_MAX) // Overflow
  237. return BOOL_FALSE;
  238. *val = tmp;
  239. return BOOL_TRUE;
  240. }
  241. /** @brief Converts string to bool_t
  242. *
  243. * Case insensitive.
  244. *
  245. * @param [in] str Input string to convert.
  246. * @param [out] val Pointer to result value.
  247. * @return BOOL_TRUE - success, BOOL_FALSE - error
  248. */
  249. bool_t faux_conv_str2bool(const char *str, bool_t *val)
  250. {
  251. if (!str)
  252. return BOOL_FALSE;
  253. if (faux_str_casecmp(str, "true") == 0) {
  254. if (val)
  255. *val = BOOL_TRUE;
  256. return BOOL_TRUE;
  257. }
  258. if (faux_str_casecmp(str, "false") == 0) {
  259. if (val)
  260. *val = BOOL_FALSE;
  261. return BOOL_TRUE;
  262. }
  263. return BOOL_FALSE;
  264. }
  265. /** @brief Converts bool_t to string
  266. *
  267. * @param [in] val Boolean value.
  268. * @return "true" or "false" strings
  269. */
  270. const char *faux_conv_bool2str(bool_t val)
  271. {
  272. if (val)
  273. return "true";
  274. return "false";
  275. }
  276. /** @brief Converts string to tri_t
  277. *
  278. * Case insensitive.
  279. *
  280. * @param [in] str Input string to convert.
  281. * @param [out] val Pointer to result value.
  282. * @return BOOL_TRUE - success, BOOL_FALSE - error
  283. */
  284. bool_t faux_conv_str2tri(const char *str, tri_t *val)
  285. {
  286. if (!str)
  287. return BOOL_FALSE;
  288. if (faux_str_casecmp(str, "true") == 0) {
  289. if (val)
  290. *val = TRI_TRUE;
  291. return BOOL_TRUE;
  292. }
  293. if (faux_str_casecmp(str, "false") == 0) {
  294. if (val)
  295. *val = TRI_FALSE;
  296. return BOOL_TRUE;
  297. }
  298. if (faux_str_casecmp(str, "undefined") == 0) {
  299. if (val)
  300. *val = TRI_UNDEFINED;
  301. return BOOL_TRUE;
  302. }
  303. return BOOL_FALSE;
  304. }
  305. /** @brief Converts tri_t to string
  306. *
  307. * @param [in] val tri_t value.
  308. * @return "true"/"false"/"undefined" strings
  309. */
  310. const char *faux_conv_tri2str(tri_t val)
  311. {
  312. if (TRI_TRUE == val)
  313. return "true";
  314. if (TRI_FALSE == val)
  315. return "false";
  316. return "undefined";
  317. }