#include <errno.h>
#include <ecoli_malloc.h>
+#include <ecoli_string.h>
#include <ecoli_log.h>
-static ec_log_t ec_log_fct = ec_log_default;
+static ec_log_t ec_log_fct = ec_log_default_cb;
static void *ec_log_opaque;
struct ec_log_type {
char *name;
- unsigned int level;
+ enum ec_log_level level;
};
static struct ec_log_type *log_types;
static size_t log_types_len;
+static enum ec_log_level global_level = EC_LOG_WARNING;
-int ec_log_default(int type, unsigned int level, void *opaque, const char *str)
+int ec_log_level_set(enum ec_log_level level)
{
- (void)opaque;
+ if (level < 0 || level > EC_LOG_DEBUG)
+ return -1;
+ global_level = level;
- return printf("[%d] %-12s %s", level, ec_log_name(type), str);
+ return 0;
}
-int ec_log_fct_register(ec_log_t usr_log, void *opaque)
+enum ec_log_level ec_log_level_get(void)
{
- if (usr_log == NULL)
- return -1;
+ return global_level;
+}
+
+int ec_log_default_cb(int type, enum ec_log_level level, void *opaque,
+ const char *str)
+{
+ (void)opaque;
- ec_log_fct = usr_log;
- ec_log_opaque = opaque;
+ if (level > ec_log_level_get())
+ return 0;
+
+ if (fprintf(stderr, "[%d] %-12s %s", level, ec_log_name(type), str) < 0)
+ return -1;
return 0;
}
-void ec_log_fct_unregister(void)
+int ec_log_fct_register(ec_log_t usr_log, void *opaque)
{
- ec_log_fct = NULL;
+ errno = 0;
+
+ if (usr_log == NULL) {
+ ec_log_fct = ec_log_default_cb;
+ ec_log_opaque = NULL;
+ } else {
+ ec_log_fct = usr_log;
+ ec_log_opaque = opaque;
+ }
+
+ return 0;
}
static int
return -1;
}
-const char *
-ec_log_name(int type)
-{
- if (type < 0 || (unsigned int)type >= log_types_len)
- return "unknown";
- return log_types[type].name;
-}
-
int
ec_log_type_register(const char *name)
{
new_types = ec_realloc(log_types,
sizeof(*new_types) * (log_types_len + 1));
if (new_types == NULL)
- return -ENOMEM;
+ return -1; /* errno is set */
log_types = new_types;
copy = ec_strdup(name);
if (copy == NULL)
- return -ENOMEM;
+ return -1; /* errno is set */
id = log_types_len++;
log_types[id].name = copy;
return id;
}
-int ec_vlog(int type, unsigned int level, const char *format, va_list ap)
+const char *
+ec_log_name(int type)
+{
+ if (type < 0 || (unsigned int)type >= log_types_len)
+ return "unknown";
+ return log_types[type].name;
+}
+
+int ec_vlog(int type, enum ec_log_level level, const char *format, va_list ap)
{
char *s;
int ret;
- if (ec_log_fct == NULL) {
- errno = ENODEV;
- return -1;
- }
-
+ /* don't use ec_vasprintf here, because it will call
+ * ec_malloc(), then ec_log(), ec_vasprintf()...
+ * -> stack overflow */
ret = vasprintf(&s, format, ap);
if (ret < 0)
return ret;
return ret;
}
-int ec_log(int type, unsigned int level, const char *format, ...)
+int ec_log(int type, enum ec_log_level level, const char *format, ...)
{
va_list ap;
int ret;