From: Christian Grothoff Date: Sat, 5 Nov 2011 14:36:34 +0000 (+0000) Subject: LRN: Use regexps in logdefs X-Git-Tag: initial-import-from-subversion-38251~16030 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=317d91ed37b5b85d298ac7d704a5b934cbea9e8a;p=oweals%2Fgnunet.git LRN: Use regexps in logdefs Now "*" is not valid anymore (it's not like anyone had a lot of opportunities to use it though). Empty string means ".*", so it's still compatible. Matching is case-sensitive. ^ and $ match the beginning and the end of the text, newine matches a newline character. All regexps are considered non-extended. Regex compilation errors are not reported in any way (the parsing process just fails, and that's it). --- diff --git a/src/util/common_logging.c b/src/util/common_logging.c index 0b7d06bab..d564530cc 100644 --- a/src/util/common_logging.c +++ b/src/util/common_logging.c @@ -30,6 +30,8 @@ #include "gnunet_strings_lib.h" #include "gnunet_time_lib.h" +#include + /** * After how many milliseconds do we always print * that "message X was repeated N times"? Use 12h. @@ -145,24 +147,19 @@ static FILE *GNUNET_stderr; struct LogDef { /** - * Component name. NULL means that this definition matches any component - */ - char *component; - - /** - * File name. NULL means that this definition matches any file + * Component name regex */ - char *file; + regex_t component_regex; /** - * Stores strlen(file) + * File name regex */ - int strlen_file; + regex_t file_regex; /** - * Function name. NULL means that this definition matches any function + * Function name regex */ - char *function; + regex_t function_regex; /** * Lowest line at which this definition matches. @@ -273,30 +270,48 @@ resize_logdefs () * @param to_line see struct LogDef * @param level see struct LogDef, must be >= 0 * @param force see struct LogDef + * @return 0 on success, regex-specific error otherwise */ -static void +static int add_definition (char *component, char *file, char *function, int from_line, int to_line, int level, int force) { + struct LogDef n; + int r; if (logdefs_size == logdefs_len) resize_logdefs (); - struct LogDef n; - memset (&n, 0, sizeof (n)); - if (strlen (component) > 0 && component[0] != '*') - n.component = GNUNET_strdup (component); - if (strlen (file) > 0 && file[0] != '*') - { - n.file = GNUNET_strdup (file); - n.strlen_file = strlen (file); - } - if ((NULL != function) && (strlen (function) > 0) && (function[0] != '*')) - n.function = GNUNET_strdup (function); + if (strlen (component) == 0) + component = (char *) ".*"; + r = regcomp (&n.component_regex, (const char *) component, REG_NOSUB); + if (r != 0) + { + return r; + } + if (strlen (file) == 0) + file = (char *) ".*"; + r = regcomp (&n.file_regex, (const char *) file, REG_NOSUB); + if (r != 0) + { + regfree (&n.component_regex); + return r; + } + if ( (NULL == function) || + (strlen (function) == 0)) + function = (char *) ".*"; + r = regcomp (&n.function_regex, (const char *) function, REG_NOSUB); + if (r != 0) + { + regfree (&n.component_regex); + regfree (&n.file_regex); + return r; + } n.from_line = from_line; n.to_line = to_line; n.level = level; n.force = force; logdefs[logdefs_len++] = n; + return 0; } @@ -320,7 +335,6 @@ GNUNET_get_log_call_status (int caller_level, const char *comp, struct LogDef *ld; int i; int force_only; - size_t strlen_file; if (comp == NULL) /* Use default component */ @@ -334,23 +348,18 @@ GNUNET_get_log_call_status (int caller_level, const char *comp, /* Only look for forced definitions? */ force_only = min_level >= 0; - strlen_file = strlen (file); for (i = 0; i < logdefs_len; i++) { - ld = &logdefs[i]; - if ((!force_only || ld->force) && - (line >= ld->from_line && line <= ld->to_line) && (ld->component == NULL - || strcmp (comp, - ld->component) - == 0) && - (ld->file == NULL || - (ld->strlen_file <= strlen_file && - strcmp (&file[strlen_file - ld->strlen_file], ld->file) == 0)) && - (ld->function == NULL || strcmp (function, ld->function) == 0)) - { - /* We're finished */ - return caller_level <= ld->level; - } + ld = &logdefs[i]; + if ((!force_only || ld->force) && + (line >= ld->from_line && line <= ld->to_line) && + (regexec (&ld->component_regex, comp, 0, NULL, 0) == 0) && + (regexec (&ld->file_regex, file, 0, NULL, 0) == 0) && + (regexec (&ld->function_regex, function, 0, NULL, 0) == 0)) + { + /* We're finished */ + return caller_level <= ld->level; + } } /* No matches - use global level, if defined */ if (min_level >= 0) @@ -411,82 +420,83 @@ parse_definitions (const char *constname, int force) to_line = INT_MAX; for (p = def, state = 0, start = def; keep_looking; p++) { - switch (p[0]) - { - case ';': /* found a field separator */ - p[0] = '\0'; - switch (state) - { - case 0: /* within a component name */ - comp = start; - break; - case 1: /* within a file name */ - file = start; - break; - case 2: /* within a function name */ - /* after a file name there must be a function name */ - function = start; - break; - case 3: /* within a from-to line range */ - if (strlen (start) > 0) - { - errno = 0; - from_line = strtol (start, &t, 10); - if (errno != 0 || from_line < 0) - { - free (def); - return counter; - } - if (t < p && t[0] == '-') - { - errno = 0; - start = t + 1; - to_line = strtol (start, &t, 10); - if (errno != 0 || to_line < 0 || t != p) - { - free (def); - return counter; - } - } - else /* one number means "match this line only" */ - to_line = from_line; - } - else /* default to 0-max */ - { - from_line = 0; - to_line = INT_MAX; - } - break; - } - start = p + 1; - state += 1; - break; - case '\0': /* found EOL */ - keep_looking = 0; - /* fall through to '/' */ - case '/': /* found a definition separator */ - switch (state) - { - case 4: /* within a log level */ - p[0] = '\0'; - state = 0; - level = get_type ((const char *) start); - if (level == GNUNET_ERROR_TYPE_INVALID || - level == GNUNET_ERROR_TYPE_UNSPECIFIED) - { - free (def); - return counter; - } - add_definition (comp, file, function, from_line, to_line, level, force); - counter += 1; - start = p + 1; - break; - default: - break; - } - default: - break; - } + switch (p[0]) + { + case ';': /* found a field separator */ + p[0] = '\0'; + switch (state) + { + case 0: /* within a component name */ + comp = start; + break; + case 1: /* within a file name */ + file = start; + break; + case 2: /* within a function name */ + /* after a file name there must be a function name */ + function = start; + break; + case 3: /* within a from-to line range */ + if (strlen (start) > 0) + { + errno = 0; + from_line = strtol (start, &t, 10); + if (errno != 0 || from_line < 0) + { + free (def); + return counter; + } + if (t < p && t[0] == '-') + { + errno = 0; + start = t + 1; + to_line = strtol (start, &t, 10); + if (errno != 0 || to_line < 0 || t != p) + { + free (def); + return counter; + } + } + else /* one number means "match this line only" */ + to_line = from_line; + } + else /* default to 0-max */ + { + from_line = 0; + to_line = INT_MAX; + } + break; + } + start = p + 1; + state += 1; + break; + case '\0': /* found EOL */ + keep_looking = 0; + /* fall through to '/' */ + case '/': /* found a definition separator */ + switch (state) + { + case 4: /* within a log level */ + p[0] = '\0'; + state = 0; + level = get_type ((const char *) start); + if (level == GNUNET_ERROR_TYPE_INVALID + || level == GNUNET_ERROR_TYPE_UNSPECIFIED + || 0 != add_definition (comp, file, function, from_line, + to_line, level, force)) + { + free (def); + return counter; + } + counter += 1; + start = p + 1; + break; + default: + break; + } + default: + break; + } } free (def); return counter;