Skip to content
Snippets Groups Projects

Add simple C logging framework.

Closed Nathan E. Egge requested to merge unlord/dav1d:logging into master
5 unresolved threads
2 files
+ 242
0
Compare changes
  • Side-by-side
  • Inline
Files
2
src/logging.c 0 → 100644
+ 166
0
/*
* Copyright © 2018, VideoLAN and dav1d authors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "src/logging.h"
const char *LOG_CATEGORY_NAMES[LOG_CATEGORY_MAX] = {
"unknown",
Please register or sign in to reply
"generic",
"test"
};
const char *LOG_LEVEL_NAMES[LOG_LEVEL_MAX] = {
"INVALID",
"FATAL",
"ERROR",
"WARN",
"INFO",
"DEBUG",
};
#if defined(ENABLE_LOGGING)
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
static unsigned int log_levels[LOG_CATEGORY_MAX] = { 0 };
static int log_fprintf_stdout(LogCategory cat, LogLevel level,
const char *fmt, va_list ap) {
fprintf(stdout, "[%s/%s] ", LOG_CATEGORY_NAMES[cat], LOG_LEVEL_NAMES[level]);
vfprintf(stdout, fmt, ap);
fprintf(stdout, "\n");
return EXIT_SUCCESS;
}
static logger_function logger = log_fprintf_stdout;
    • Further: Why are you adding this as global state. This breaks e.g. having dav1d as at transient dependency, since they'll clobber eachother. State should be in the context.

Please register or sign in to reply
static LogCategory find_category(const char *str) {
LogCategory cat;
int i;
cat = LOG_UNKNOWN;
for (i = 0; i < LOG_CATEGORY_MAX; i++) {
if (strcmp(str, LOG_CATEGORY_NAMES[i]) == 0) {
cat = (LogCategory)i;
break;
}
}
return cat;
}
static LogLevel find_level(const char *str) {
LogLevel level = LOG_INVALID;
int i;
for (i = 0; i < LOG_LEVEL_MAX; i++) {
if (strcmp(str, LOG_LEVEL_NAMES[i]) == 0) {
level = (LogLevel)i;
break;
}
}
return level;
}
void log_init(logger_function logger) {
char *env;
if (logger != NULL) {
logger = logger;
}
env = getenv("LOG");
Please register or sign in to reply
/* This code clobbers the environment variable and thus log_init() should
only be run once at the start of the program. */
if (env) {
do {
char *next;
char *split;
next = strchr(env, ',');
if (next) {
*next = '\0';
next += 1;
}
else {
next = env + strlen(env);
}
split = strchr(env, ':');
if (split) {
LogCategory cat;
*split = '\0';
split += 1;
cat = find_category(env);
if (cat == LOG_UNKNOWN) {
fprintf(stderr, "Unknown category '%s'\n", env);
Please register or sign in to reply
}
else {
LogLevel level;
level = find_level(split);
if (level == LOG_INVALID) {
fprintf(stderr, "Invalid level '%s'\n", split);
}
else {
log_set_level(cat, level);
}
}
}
else {
fprintf(stderr, "Bad clause '%s'\n", env);
}
env = next;
}
while (strlen(env) > 0);
}
}
LogLevel log_get_level(LogCategory cat) {
return log_levels[cat];
}
void log_set_level(LogCategory cat, LogLevel level) {
log_levels[cat] = level;
}
static void log_impl(LogCategory cat, LogLevel level,
const char *fmt, va_list ap) {
if (logging_active(cat, level)) {
logger(cat, level, fmt, ap);
}
}
void log(LogCategory cat, LogLevel level, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
log_impl(cat, level, fmt, ap);
va_end(ap);
}
int logging_active(LogCategory cat, LogLevel level) {
if (cat >= LOG_CATEGORY_MAX) {
return 0;
}
if (log_levels[cat] < level) {
return 0;
}
return 1;
}
#endif
Loading