Browse Source

faux: Add faux_error_t class for error strings stack

Serj Kalichev 3 years ago
parent
commit
61b2406a69
6 changed files with 291 additions and 0 deletions
  1. 3 0
      faux/Makefile.am
  2. 1 0
      faux/all.h
  3. 32 0
      faux/error.h
  4. 7 0
      faux/error/Makefile.am
  5. 241 0
      faux/error/error.c
  6. 7 0
      faux/error/private.h

+ 3 - 0
faux/Makefile.am

@@ -26,6 +26,7 @@ nobase_include_HEADERS += \
 	faux/msg.h \
 	faux/eloop.h \
 	faux/async.h \
+	faux/error.h \
 	faux/testc_helpers.h
 
 EXTRA_DIST += \
@@ -46,6 +47,7 @@ EXTRA_DIST += \
 	faux/msg/Makefile.am \
 	faux/eloop/Makefile.am \
 	faux/async/Makefile.am \
+	faux/error/Makefile.am \
 	faux/testc_helpers/Makefile.am
 
 include $(top_srcdir)/faux/base/Makefile.am
@@ -65,6 +67,7 @@ include $(top_srcdir)/faux/net/Makefile.am
 include $(top_srcdir)/faux/msg/Makefile.am
 include $(top_srcdir)/faux/eloop/Makefile.am
 include $(top_srcdir)/faux/async/Makefile.am
+include $(top_srcdir)/faux/error/Makefile.am
 include $(top_srcdir)/faux/testc_helpers/Makefile.am
 
 if TESTC

+ 1 - 0
faux/all.h

@@ -20,4 +20,5 @@
 #include <faux/sched.h>
 #include <faux/msg.h>
 #include <faux/eloop.h>
+#include <faux/error.h>
 #include <faux/testc_helpers.h>

+ 32 - 0
faux/error.h

@@ -0,0 +1,32 @@
+/** @file error.h
+ * @brief Public interface to work with advanced error class.
+ */
+
+#ifndef _faux_error_h
+#define _faux_error_h
+
+#include <stdio.h>
+
+#include <faux/faux.h>
+
+typedef struct faux_error_s faux_error_t;
+typedef faux_list_node_t faux_error_node_t;
+
+C_DECL_BEGIN
+
+faux_error_t *faux_error_new(void);
+void faux_error_free(faux_error_t *error);
+void faux_error_reset(faux_error_t *error);
+bool_t faux_error(const faux_error_t *error);
+bool_t faux_error_add(faux_error_t *error, const char *str);
+
+faux_error_node_t *faux_error_iter(const faux_error_t *error);
+faux_error_node_t *faux_error_iterr(const faux_error_t *error);
+const char *faux_error_each(faux_error_node_t **iter);
+const char *faux_error_eachr(faux_error_node_t **iter);
+bool_t faux_error_fprint(const faux_error_t *error, FILE *handle);
+bool_t faux_error_print(const faux_error_t *error);
+
+C_DECL_END
+
+#endif				/* _faux_error_h */

+ 7 - 0
faux/error/Makefile.am

@@ -0,0 +1,7 @@
+libfaux_la_SOURCES += \
+	faux/error/error.c \
+	faux/error/private.h
+
+#if TESTC
+#libfaux_la_SOURCES += faux/error/testc_error.c
+#endif

+ 241 - 0
faux/error/error.c

@@ -0,0 +1,241 @@
+/** @file error.c
+ * @brief Functions for working with errors.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "private.h"
+#include "faux/faux.h"
+#include "faux/str.h"
+#include "faux/error.h"
+
+
+/** @brief Allocates new error object.
+ *
+ * Before working with error object it must be allocated and initialized.
+ *
+ * @return Allocated and initialized error object or NULL on error.
+ */
+faux_error_t *faux_error_new(void)
+{
+	faux_error_t *error = NULL;
+
+	error = faux_zmalloc(sizeof(*error));
+	if (!error)
+		return NULL;
+
+	// Init
+	error->list = faux_list_new(FAUX_LIST_UNSORTED, FAUX_LIST_NONUNIQUE,
+		NULL, NULL, (void (*)(void *))faux_str_free);
+
+	return error;
+}
+
+
+/** @brief Frees the error object.
+ *
+ * After using the error object must be freed.
+ *
+ * @param [in] error Allocated and initialized error object.
+ */
+void faux_error_free(faux_error_t *error)
+{
+	if (!error)
+		return;
+
+	faux_list_free(error->list);
+	faux_free(error);
+}
+
+
+/** @brief Reset error object to empty state.
+ *
+ * After using the error object must be freed.
+ * @param [in] error Allocated and initialized error object.
+ */
+void faux_error_reset(faux_error_t *error)
+{
+	if (!error)
+		return;
+
+	faux_list_del_all(error->list);
+}
+
+
+/** @brief Current status of error object.
+ *
+ * If error list contains any entries then function returns BOOL_TRUE else
+ * BOOL_FALSE.
+ *
+ * @param [in] error Allocated and initialized error object.
+ * @return BOOL_TRUE if object contains errors or BOOL_FALSE.
+ */
+bool_t faux_error(const faux_error_t *error)
+{
+	if (!error)
+		return BOOL_FALSE;
+
+	if (faux_list_len(error->list) > 0)
+		return BOOL_TRUE;
+
+	return BOOL_FALSE;
+}
+
+
+/** @brief Adds error message to message stack.
+ *
+ * @param [in] error Allocated and initialized error object.
+ * @return success - BOOL_TRUE, fail - BOOL_FALSE.
+ */
+bool_t faux_error_add(faux_error_t *error, const char *str)
+{
+	char *tmp = NULL;
+
+	assert(error);
+	if (!error)
+		return BOOL_FALSE;
+	assert(str);
+	if (!str)
+		return BOOL_FALSE;
+
+	tmp = faux_str_dup(str);
+	if (!tmp)
+		return BOOL_FALSE;
+	if (!faux_list_add(error->list, tmp)) {
+		faux_str_free(tmp);
+		return BOOL_FALSE;
+	}
+
+	return BOOL_TRUE;
+}
+
+
+/** @brief Initializes iterator to iterate through the entire error object.
+ *
+ * Before iterating with the faux_error_each() function the iterator must be
+ * initialized. This function do it.
+ *
+ * @param [in] error Allocated and initialized error object.
+ * @return Initialized iterator.
+ * @sa faux_error_each()
+ */
+faux_error_node_t *faux_error_iter(const faux_error_t *error)
+{
+	assert(error);
+	if (!error)
+		return NULL;
+
+	return (faux_error_node_t *)faux_list_head(error->list);
+}
+
+
+/** @brief Initializes iterator to iterate through error object in reverse order.
+ *
+ * Before iterating with the faux_error_eachr() function the iterator must be
+ * initialized. This function do it.
+ *
+ * @param [in] error Allocated and initialized error object.
+ * @return Initialized iterator.
+ * @sa faux_error_each()
+ */
+faux_error_node_t *faux_error_iterr(const faux_error_t *error)
+{
+	assert(error);
+	if (!error)
+		return NULL;
+
+	return (faux_error_node_t *)faux_list_tail(error->list);
+}
+
+
+/** @brief Iterate entire error object.
+ *
+ * Before iteration the iterator must be initialized by faux_error_iter()
+ * function. Doesn't use faux_error_each() with uninitialized iterator.
+ *
+ * On each call function returns error string and modifies iterator.
+ * Stop iteration when function returns NULL.
+ *
+ * @param [in,out] iter Iterator.
+ * @return String with error description.
+ * @sa faux_error_iter()
+ */
+const char *faux_error_each(faux_error_node_t **iter)
+{
+	return (const char *)faux_list_each((faux_list_node_t **)iter);
+}
+
+
+/** @brief Iterate entire error object in reverse order.
+ *
+ * Before iteration the iterator must be initialized by faux_error_iterr()
+ * function. Doesn't use faux_error_each() with uninitialized iterator.
+ *
+ * On each call function returns error string and modifies iterator.
+ * Stop iteration when function returns NULL.
+ *
+ * @param [in,out] iter Iterator.
+ * @return String with error description.
+ * @sa faux_error_iter()
+ */
+const char *faux_error_eachr(faux_error_node_t **iter)
+{
+	return (const char *)faux_list_eachr((faux_list_node_t **)iter);
+}
+
+
+/** @brief Print error stack.
+ *
+ * @param [in] error Allocated and initialized error object.
+ * @param [in] handle File handler to write to.
+ * @param [in] reverse Print errors in reverse order.
+ * @param [in] hierarchy Print errors using hierarchy view (or peer view).
+ * @return BOOL_TRUE - success, BOOL_FALSE - fail.
+ */
+static bool_t faux_error_show(const faux_error_t *error, FILE *handle,
+	bool_t reverse, bool_t hierarchy)
+{
+	faux_error_node_t *iter = NULL;
+	const char *str = NULL;
+	int level = 0;
+
+	if (!error)
+		return BOOL_FALSE;
+
+	iter = reverse ? faux_error_iterr(error) : faux_error_iter(error);
+	while ((str = (reverse ? faux_error_eachr(&iter) : faux_error_each(&iter)))) {
+		if ((hierarchy) && (level > 0))
+			fprintf(handle, "%*c", level, ' ');
+		fprintf(handle, "%s\n", str);
+		level ++;
+	}
+
+	return BOOL_TRUE;
+}
+
+
+/** @brief Print error stack.
+ *
+ * @param [in] error Allocated and initialized error object.
+ * @param [in] handle File handler to write to.
+ * @return BOOL_TRUE - success, BOOL_FALSE - fail.
+ */
+bool_t faux_error_fprint(const faux_error_t *error, FILE *handle)
+{
+	return faux_error_show(error, handle, BOOL_FALSE, BOOL_FALSE);
+}
+
+
+/** @brief Print error stack.
+ *
+ * @param [in] error Allocated and initialized error object.
+ * @return BOOL_TRUE - success, BOOL_FALSE - fail.
+ */
+bool_t faux_error_print(const faux_error_t *error)
+{
+	return faux_error_fprint(error, stderr);
+}

+ 7 - 0
faux/error/private.h

@@ -0,0 +1,7 @@
+#include "faux/faux.h"
+#include "faux/list.h"
+#include "faux/error.h"
+
+struct faux_error_s {
+	faux_list_t *list;
+};