diff options
-rw-r--r-- | ylib/ylog.c | 48 | ||||
-rw-r--r-- | ylib/ylog.h | 29 |
2 files changed, 42 insertions, 35 deletions
diff --git a/ylib/ylog.c b/ylib/ylog.c index 345b88c..8860825 100644 --- a/ylib/ylog.c +++ b/ylib/ylog.c @@ -65,40 +65,41 @@ static int ylog_match(const char *pat, const char *fn) { /* Assumes the mutex is locked */ static void ylog_set_file_level(ylog_file_t *file) { - char *pat = ylog_pattern; - const char *start; - int level; - if(!pat) - goto fallback; + char *start, *pat = ylog_pattern; + int val; - while(*pat) { + while(pat && *pat) { start = pat; - while(*pat && *pat != ':') + while(*pat && *pat != ':' && *pat != ',') pat++; - *pat = 0; - if(!ylog_match(start, file->name)) { - *pat = ':'; - while(*pat && *pat != ',') - pat++; - continue; + /* No colon, assume that this is the <default_level> */ + if(*pat != ':') { + pat = start; + break; } + *pat = 0; + val = ylog_match(start, file->name); *(pat++) = ':'; - /* We have a match, get level */ - level = 0; - while(level < YLOG_MAX && *pat >= '0' && *pat <= '9') { - level = level*10 + (*pat-'0'); + if(val) + break; + while(*pat && pat[-1] != ',') + pat++; + } + + /* Early break, this means that we expect the numeric level for this string. */ + if(pat && *pat) { + start = pat; + val = 0; + while(val < YLOG_MAX && *pat >= '0' && *pat <= '9') { + val = val*10 + (*pat-'0'); pat++; } - if(level <= YLOG_MAX) { - file->level = level; + if(val <= YLOG_MAX && pat != start && (!*pat || *pat == ',')) { + file->level = val; return; } - goto fallback; - while(*pat && *pat != ',') - pat++; } -fallback: file->level = ylog_default_level; } @@ -205,6 +206,7 @@ void ylog_default_handler(const char *file, int line, int level, const char *mes case YLOG_WARN: strcpy(lvl, "WARN"); break; case YLOG_INFO: strcpy(lvl, "info"); break; case YLOG_DEBUG: strcpy(lvl, "debug"); break; + case YLOG_TRACE: strcpy(lvl, "trace"); break; default: sprintf(lvl, "%d", level); } diff --git a/ylib/ylog.h b/ylib/ylog.h index 1371f07..d342b95 100644 --- a/ylib/ylog.h +++ b/ylib/ylog.h @@ -55,13 +55,11 @@ * If logging functions in your application can be called from multiple * threads, be sure to compile ylog.c with thread-safety enabled: * -DYLOG_PTHREAD - * (Currently, only pthread is supported) * * This library uses the fnmatch() function, available on every POSIX OS. If * you want to use this library on Windows, you can probably find an * implementation of fnmatch() somewhere (musl-libc has a fairly simple - * implementation that should be trivially portable to windows). I also welcome - * an alternative matching approach that isn't too large and works with pure C. + * implementation that should be trivially portable to windows). * * * Caveats: @@ -185,7 +183,7 @@ void ylog_impl(ylog_file_t *file, int level, int line, const char *filename, con * logged, it should therefore not be used for any other situations than * described above. */ -#define ylog_enabled(lvl) ((lvl) < ylog_file.level) +#define ylog_enabled(lvl) ((lvl) <= ylog_file.level) /* First argument may be evaluated more than once. */ @@ -200,6 +198,7 @@ void ylog_impl(ylog_file_t *file, int level, int line, const char *filename, con #define ywarn(...) ylog(YLOG_WARN, __VA_ARGS__) #define yinfo(...) ylog(YLOG_INFO, __VA_ARGS__) #define ydebug(...) ylog(YLOG_DEBUG, __VA_ARGS__) +#define ytrace(...) ylog(YLOG_TRACE, __VA_ARGS__) typedef void(*ylog_handler_cb)(const char *file, int line, int level, const char *message); @@ -229,20 +228,25 @@ void ylog_set_handler(ylog_handler_cb cb); * patterns, describing the log level used for individual files. The format is * as follows: * - * <pattern_1>:<level_1>,<pattern_2>:<level_2>,... + * <pattern_1>:<level_1>,<pattern_2>:<level_2>,...,<default_level> * * Where <pattern_n> is a file-name pattern given to fnmatch(), and <level_n> a * decimal number indicating the log level used for files that match the * pattern. The list of patterns is traversed in the order given in the list, - * the first matching pattern is used. The .c, .h, .cc, .cpp, and .hpp file - * extensions are removed from the file name before matching, and any directory - * prefixes not mentioned in the pattern are ignored. Examples: + * the first matching pattern is used. A <default_level> can be specified at + * the end of the pattern, indicating the log level used when none of the + * previous patterns matched. The .c, .h, .cc, .cpp, and .hpp file extensions + * are removed from the file name before matching, and any directory prefixes + * not mentioned in the pattern are ignored. Examples: * - * "main:1,*:2" + * "3" or "*:3" + * Use log level 3 for all files. + * + * "main:1,2" * Use 1 as log level for main.(c,h,cc,cpp,hpp) in any directory, * Use 2 for all other files. */ -// "*_util:4,net/*:3,*:9" +// "*_util:4,net/*:3,9" // Use 4 for any filename ending with _util.(c,h,cc,cpp,hpp) in any // directory. // Use 3 for any file in a net/ directory, not matching *_util, @@ -250,8 +254,9 @@ void ylog_set_handler(ylog_handler_cb cb); // Use 9 for all other files. /* * If no pattern exists for a file (and there is no final catch-all pattern, as - * in the examples above), default_level will be used instead. This function - * overrides any previously used configuration. + * in the examples above), default_level will be used instead. default_level + * may also be used if the pattern string does not follow the above format. + * This function overrides any previously used configuration. */ void ylog_set_level(int default_level, const char *patterns); |