1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
5 #define _GNU_SOURCE /* for vasprintf */
11 #include <ecoli_malloc.h>
12 #include <ecoli_string.h>
13 #include <ecoli_log.h>
15 static ec_log_t ec_log_fct = ec_log_default_cb;
16 static void *ec_log_opaque;
20 enum ec_log_level level;
23 static struct ec_log_type *log_types;
24 static size_t log_types_len;
25 static enum ec_log_level global_level = EC_LOG_WARNING;
27 int ec_log_level_set(enum ec_log_level level)
29 if (level < 0 || level > EC_LOG_DEBUG)
36 enum ec_log_level ec_log_level_get(void)
41 int ec_log_default_cb(int type, enum ec_log_level level, void *opaque,
46 if (level > ec_log_level_get())
49 if (fprintf(stderr, "[%d] %-12s %s", level, ec_log_name(type), str) < 0)
55 int ec_log_fct_register(ec_log_t usr_log, void *opaque)
59 if (usr_log == NULL) {
60 ec_log_fct = ec_log_default_cb;
64 ec_log_opaque = opaque;
71 ec_log_lookup(const char *name)
75 for (i = 0; i < log_types_len; i++) {
76 if (log_types[i].name == NULL)
78 if (strcmp(name, log_types[i].name) == 0)
86 ec_log_type_register(const char *name)
88 struct ec_log_type *new_types;
92 id = ec_log_lookup(name);
96 new_types = ec_realloc(log_types,
97 sizeof(*new_types) * (log_types_len + 1));
98 if (new_types == NULL)
99 return -1; /* errno is set */
100 log_types = new_types;
102 copy = ec_strdup(name);
104 return -1; /* errno is set */
106 id = log_types_len++;
107 log_types[id].name = copy;
108 log_types[id].level = EC_LOG_DEBUG;
114 ec_log_name(int type)
116 if (type < 0 || (unsigned int)type >= log_types_len)
118 return log_types[type].name;
121 int ec_vlog(int type, enum ec_log_level level, const char *format, va_list ap)
126 /* don't use ec_vasprintf here, because it will call
127 * ec_malloc(), then ec_log(), ec_vasprintf()...
128 * -> stack overflow */
129 ret = vasprintf(&s, format, ap);
133 ret = ec_log_fct(type, level, ec_log_opaque, s);
139 int ec_log(int type, enum ec_log_level level, const char *format, ...)
144 va_start(ap, format);
145 ret = ec_vlog(type, level, format, ap);