summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ylib/ylog.c48
-rw-r--r--ylib/ylog.h29
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);