#include #include #include #include #include #include #include #include #include "logerr.h" #include "trace.h" static thread_local enum TraceLevel LEVEL = TraceLevel_INFO; static thread_local FILE * STREAM = NULL; void vftracef( const char *const file, const char *const function, const int lineno, FILE *restrict stream, const enum TraceLevel level, const char *restrict format, va_list args ) { if (level > LEVEL) { return; } if (fprintf(stream, "%s:%s:%d: ", file, function, lineno) < 0) { logerr("fprintf() < 0: %s", strerror(errno)); } if (vfprintf(stream, format, args) < 0) { perror(__FILE__ ":vtrace(): vfprintf() < 0"); } if (fprintf(stream, "\n") < 0) { perror(__FILE__ ":vtrace(): fprintf() < 0"); } } void ftracef( const char *const file, const char *const function, const int lineno, FILE *restrict stream, const enum TraceLevel level, const char *restrict format, ... ) { va_list args; va_start(args, format); vftracef(file, function, lineno, stream, level, format, args); va_end(args); } void tracef( const char *const file, const char *const function, const int lineno, const enum TraceLevel level, const char *restrict format, ... ) { if (STREAM == NULL) { STREAM = stderr; } va_list args; va_start(args, format); vftracef(file, function, lineno, STREAM, level, format, args); va_end(args); } void trace_set_stream(FILE *stream) { STREAM = stream; } void trace_set_level(const enum TraceLevel level) { assert(level >= TraceLevel_NONE); assert(level <= TraceLevel_DEBUG); LEVEL = level; }