diff --git a/src/utils/error.c b/src/utils/error.c
index 6bb17d5821f5ea68259606cbc6bcd8312d55b04e..2bc99013ebe719199b7f53b2665f5e43dd7a95ae 100644 (file)
--- a/src/utils/error.c
+++ b/src/utils/error.c
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
#include "utils/error.h"
#include "utils/error.h"
+#include "utils/strbuf.h"
#include <pthread.h>
#include <stdarg.h>
#include <pthread.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdio.h>
-#include <string.h>
-
#include <stdlib.h>
#include <stdlib.h>
+#include <string.h>
/*
* private data types
/*
* private data types
typedef struct {
int prio;
typedef struct {
int prio;
- char msg[SDB_MAX_ERROR];
- _Bool logged;
+ sdb_strbuf_t *msg;
+ bool logged;
} sdb_error_ctx_t;
} sdb_error_ctx_t;
-#define SDB_ERROR_INIT { -1, "", 1 }
+#define SDB_ERROR_INIT { -1, NULL, 1 }
/*
* private variables
/*
* private variables
static sdb_error_ctx_t default_error_ctx = SDB_ERROR_INIT;
static pthread_key_t error_ctx_key;
static sdb_error_ctx_t default_error_ctx = SDB_ERROR_INIT;
static pthread_key_t error_ctx_key;
-static _Bool error_ctx_key_initialized = 0;
+static bool error_ctx_key_initialized = 0;
+
+static int (*logger)(int prio, const char *msg) = NULL;
/*
* private helper functions
*/
static void
/*
* private helper functions
*/
static void
-sdb_error_ctx_destructor(void *ctx)
+sdb_error_ctx_destructor(void *p)
{
{
+ sdb_error_ctx_t *ctx = p;
+
if (! ctx)
return;
if (! ctx)
return;
+
+ sdb_strbuf_destroy(ctx->msg);
free(ctx);
} /* sdb_error_ctx_destructor */
free(ctx);
} /* sdb_error_ctx_destructor */
return NULL;
*ctx = default_error_ctx;
return NULL;
*ctx = default_error_ctx;
+ ctx->msg = sdb_strbuf_create(64);
+ if (! ctx->msg) {
+ free(ctx);
+ return NULL;
+ }
if (! error_ctx_key_initialized)
sdb_error_ctx_init();
if (! error_ctx_key_initialized)
sdb_error_ctx_init();
} /* sdb_error_get_ctx */
static int
} /* sdb_error_get_ctx */
static int
-sdb_error_clear(void)
+sdb_error_vprintf(const char *fmt, va_list ap)
{
sdb_error_ctx_t *ctx;
{
sdb_error_ctx_t *ctx;
if (! ctx)
return -1;
if (! ctx)
return -1;
- ctx->prio = -1;
- ctx->msg[0] = '\0';
- ctx->logged = 1;
- return 0;
-} /* sdb_error_clear */
+ ctx->logged = 0;
+ return (int)sdb_strbuf_vsprintf(ctx->msg, fmt, ap);
+} /* sdb_error_vprintf */
static int
sdb_error_vappend(const char *fmt, va_list ap)
{
sdb_error_ctx_t *ctx;
static int
sdb_error_vappend(const char *fmt, va_list ap)
{
sdb_error_ctx_t *ctx;
- size_t len;
ctx = sdb_error_get_ctx();
if (! ctx)
return -1;
ctx = sdb_error_get_ctx();
if (! ctx)
return -1;
- len = strlen(ctx->msg);
- if (len >= sizeof(ctx->msg))
- return 0; /* nothing written */
-
ctx->logged = 0;
ctx->logged = 0;
- return vsnprintf(ctx->msg + len, sizeof(ctx->msg) - len, fmt, ap);
+ return (int)sdb_strbuf_vappend(ctx->msg, fmt, ap);
} /* sdb_error_vappend */
static int
} /* sdb_error_vappend */
static int
if (ctx->logged)
return 0;
if (ctx->logged)
return 0;
- ret = fprintf(stderr, "[%s] %s\n",
- SDB_LOG_PRIO_TO_STRING(prio), ctx->msg);
+ if (logger)
+ ret = logger(prio, sdb_strbuf_string(ctx->msg));
+ else
+ ret = fprintf(stderr, "[%s] %s\n", SDB_LOG_PRIO_TO_STRING(prio),
+ sdb_strbuf_string(ctx->msg));
+
ctx->logged = 1;
return ret;
} /* sdb_do_log */
ctx->logged = 1;
return ret;
} /* sdb_do_log */
* public API
*/
* public API
*/
+void
+sdb_error_set_logger(int (*f)(int, const char *))
+{
+ logger = f;
+} /* sdb_error_set_logger */
+
int
sdb_log(int prio, const char *fmt, ...)
{
va_list ap;
int ret;
int
sdb_log(int prio, const char *fmt, ...)
{
va_list ap;
int ret;
- if (sdb_error_clear())
- return -1;
-
va_start(ap, fmt);
va_start(ap, fmt);
- ret = sdb_error_vappend(fmt, ap);
+ ret = sdb_vlog(prio, fmt, ap);
va_end(ap);
va_end(ap);
-
- sdb_do_log(prio);
return ret;
} /* sdb_log */
return ret;
} /* sdb_log */
+int
+sdb_vlog(int prio, const char *fmt, va_list ap)
+{
+ int ret = sdb_error_vprintf(fmt, ap);
+ if (ret > 0)
+ sdb_do_log(prio);
+ return ret;
+} /* sdb_vlog */
+
int
sdb_error_set(const char *fmt, ...)
{
va_list ap;
int ret;
int
sdb_error_set(const char *fmt, ...)
{
va_list ap;
int ret;
- if (sdb_error_clear())
- return -1;
-
va_start(ap, fmt);
va_start(ap, fmt);
- ret = sdb_error_vappend(fmt, ap);
+ ret = sdb_error_vprintf(fmt, ap);
va_end(ap);
return ret;
va_end(ap);
return ret;
return ret;
} /* sdb_error_append */
return ret;
} /* sdb_error_append */
+int
+sdb_error_chomp(void)
+{
+ sdb_error_ctx_t *ctx;
+
+ ctx = sdb_error_get_ctx();
+ if (! ctx)
+ return -1;
+
+ sdb_strbuf_chomp(ctx->msg);
+ return 0;
+} /* sdb_error_chomp */
+
int
sdb_error_log(int prio)
{
int
sdb_error_log(int prio)
{
ctx = sdb_error_get_ctx();
if (! ctx)
return "success";
ctx = sdb_error_get_ctx();
if (! ctx)
return "success";
- return ctx->msg;
+ return sdb_strbuf_string(ctx->msg);
} /* sdb_error_get */
int
} /* sdb_error_get */
int
return ctx->prio;
} /* sdb_error_get_prio */
return ctx->prio;
} /* sdb_error_get_prio */
+int
+sdb_error_parse_priority(char *prio)
+{
+ if (! strcasecmp(prio, "EMERG"))
+ return SDB_LOG_EMERG;
+ else if (! strcasecmp(prio, "ERROR"))
+ return SDB_LOG_ERR;
+ else if (! strcasecmp(prio, "WARNING"))
+ return SDB_LOG_WARNING;
+ else if (! strcasecmp(prio, "NOTICE"))
+ return SDB_LOG_NOTICE;
+ else if (! strcasecmp(prio, "INFO"))
+ return SDB_LOG_INFO;
+ else if (! strcasecmp(prio, "DEBUG"))
+ return SDB_LOG_DEBUG;
+ return -1;
+} /* sdb_error_parse_priority */
+
char *
sdb_strerror(int errnum, char *strerrbuf, size_t buflen)
{
char *
sdb_strerror(int errnum, char *strerrbuf, size_t buflen)
{