error.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /** @file error.c
  2. * @brief Functions for working with errors.
  3. */
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <assert.h>
  9. #include "private.h"
  10. #include "faux/faux.h"
  11. #include "faux/str.h"
  12. #include "faux/error.h"
  13. /** @brief Allocates new error object.
  14. *
  15. * Before working with error object it must be allocated and initialized.
  16. *
  17. * @return Allocated and initialized error object or NULL on error.
  18. */
  19. faux_error_t *faux_error_new(void)
  20. {
  21. faux_error_t *error = NULL;
  22. error = faux_zmalloc(sizeof(*error));
  23. if (!error)
  24. return NULL;
  25. // Init
  26. error->list = faux_list_new(FAUX_LIST_UNSORTED, FAUX_LIST_NONUNIQUE,
  27. NULL, NULL, (void (*)(void *))faux_str_free);
  28. return error;
  29. }
  30. /** @brief Frees the error object.
  31. *
  32. * After using the error object must be freed.
  33. *
  34. * @param [in] error Allocated and initialized error object.
  35. */
  36. void faux_error_free(faux_error_t *error)
  37. {
  38. if (!error)
  39. return;
  40. faux_list_free(error->list);
  41. faux_free(error);
  42. }
  43. /** @brief Reset error object to empty state.
  44. *
  45. * After using the error object must be freed.
  46. * @param [in] error Allocated and initialized error object.
  47. */
  48. void faux_error_reset(faux_error_t *error)
  49. {
  50. if (!error)
  51. return;
  52. faux_list_del_all(error->list);
  53. }
  54. /** @brief Current status of error object.
  55. *
  56. * If error list contains any entries then function returns BOOL_TRUE else
  57. * BOOL_FALSE.
  58. *
  59. * @param [in] error Allocated and initialized error object.
  60. * @return BOOL_TRUE if object contains errors or BOOL_FALSE.
  61. */
  62. bool_t faux_error(const faux_error_t *error)
  63. {
  64. if (!error)
  65. return BOOL_FALSE;
  66. if (faux_list_len(error->list) > 0)
  67. return BOOL_TRUE;
  68. return BOOL_FALSE;
  69. }
  70. /** @brief Adds error message to message stack.
  71. *
  72. * @param [in] error Allocated and initialized error object.
  73. * @return success - BOOL_TRUE, fail - BOOL_FALSE.
  74. */
  75. bool_t faux_error_add(faux_error_t *error, const char *str)
  76. {
  77. char *tmp = NULL;
  78. assert(error);
  79. if (!error)
  80. return BOOL_FALSE;
  81. assert(str);
  82. if (!str)
  83. return BOOL_FALSE;
  84. tmp = faux_str_dup(str);
  85. if (!tmp)
  86. return BOOL_FALSE;
  87. if (!faux_list_add(error->list, tmp)) {
  88. faux_str_free(tmp);
  89. return BOOL_FALSE;
  90. }
  91. return BOOL_TRUE;
  92. }
  93. /** @brief Initializes iterator to iterate through the entire error object.
  94. *
  95. * Before iterating with the faux_error_each() function the iterator must be
  96. * initialized. This function do it.
  97. *
  98. * @param [in] error Allocated and initialized error object.
  99. * @return Initialized iterator.
  100. * @sa faux_error_each()
  101. */
  102. faux_error_node_t *faux_error_iter(const faux_error_t *error)
  103. {
  104. assert(error);
  105. if (!error)
  106. return NULL;
  107. return (faux_error_node_t *)faux_list_head(error->list);
  108. }
  109. /** @brief Initializes iterator to iterate through error object in reverse order.
  110. *
  111. * Before iterating with the faux_error_eachr() function the iterator must be
  112. * initialized. This function do it.
  113. *
  114. * @param [in] error Allocated and initialized error object.
  115. * @return Initialized iterator.
  116. * @sa faux_error_each()
  117. */
  118. faux_error_node_t *faux_error_iterr(const faux_error_t *error)
  119. {
  120. assert(error);
  121. if (!error)
  122. return NULL;
  123. return (faux_error_node_t *)faux_list_tail(error->list);
  124. }
  125. /** @brief Iterate entire error object.
  126. *
  127. * Before iteration the iterator must be initialized by faux_error_iter()
  128. * function. Doesn't use faux_error_each() with uninitialized iterator.
  129. *
  130. * On each call function returns error string and modifies iterator.
  131. * Stop iteration when function returns NULL.
  132. *
  133. * @param [in,out] iter Iterator.
  134. * @return String with error description.
  135. * @sa faux_error_iter()
  136. */
  137. const char *faux_error_each(faux_error_node_t **iter)
  138. {
  139. return (const char *)faux_list_each((faux_list_node_t **)iter);
  140. }
  141. /** @brief Iterate entire error object in reverse order.
  142. *
  143. * Before iteration the iterator must be initialized by faux_error_iterr()
  144. * function. Doesn't use faux_error_each() with uninitialized iterator.
  145. *
  146. * On each call function returns error string and modifies iterator.
  147. * Stop iteration when function returns NULL.
  148. *
  149. * @param [in,out] iter Iterator.
  150. * @return String with error description.
  151. * @sa faux_error_iter()
  152. */
  153. const char *faux_error_eachr(faux_error_node_t **iter)
  154. {
  155. return (const char *)faux_list_eachr((faux_list_node_t **)iter);
  156. }
  157. /** @brief Print error stack.
  158. *
  159. * @param [in] error Allocated and initialized error object.
  160. * @param [in] handle File handler to write to.
  161. * @param [in] reverse Print errors in reverse order.
  162. * @param [in] hierarchy Print errors using hierarchy view (or peer view).
  163. * @return BOOL_TRUE - success, BOOL_FALSE - fail.
  164. */
  165. static bool_t faux_error_show(const faux_error_t *error, FILE *handle,
  166. bool_t reverse, bool_t hierarchy)
  167. {
  168. faux_error_node_t *iter = NULL;
  169. const char *str = NULL;
  170. int level = 0;
  171. if (!error)
  172. return BOOL_FALSE;
  173. iter = reverse ? faux_error_iterr(error) : faux_error_iter(error);
  174. while ((str = (reverse ? faux_error_eachr(&iter) : faux_error_each(&iter)))) {
  175. if ((hierarchy) && (level > 0))
  176. fprintf(handle, "%*c", level, ' ');
  177. fprintf(handle, "%s\n", str);
  178. level ++;
  179. }
  180. return BOOL_TRUE;
  181. }
  182. /** @brief Print error stack.
  183. *
  184. * @param [in] error Allocated and initialized error object.
  185. * @param [in] handle File handler to write to.
  186. * @return BOOL_TRUE - success, BOOL_FALSE - fail.
  187. */
  188. bool_t faux_error_fprint(const faux_error_t *error, FILE *handle)
  189. {
  190. return faux_error_show(error, handle, BOOL_FALSE, BOOL_FALSE);
  191. }
  192. /** @brief Print error stack.
  193. *
  194. * @param [in] error Allocated and initialized error object.
  195. * @return BOOL_TRUE - success, BOOL_FALSE - fail.
  196. */
  197. bool_t faux_error_print(const faux_error_t *error)
  198. {
  199. return faux_error_fprint(error, stderr);
  200. }