diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-11-05 14:36:34 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-11-05 14:36:34 +0000 |
commit | 317d91ed37b5b85d298ac7d704a5b934cbea9e8a (patch) | |
tree | 611e7f17a4971269d07febf081116eeedb9f65fc /src/util/common_logging.c | |
parent | 262a695388efa539a23ba82eb2d0187961a4c894 (diff) | |
download | gnunet-317d91ed37b5b85d298ac7d704a5b934cbea9e8a.tar.gz gnunet-317d91ed37b5b85d298ac7d704a5b934cbea9e8a.zip |
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).
Diffstat (limited to 'src/util/common_logging.c')
-rw-r--r-- | src/util/common_logging.c | 240 |
1 files changed, 125 insertions, 115 deletions
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 @@ | |||
30 | #include "gnunet_strings_lib.h" | 30 | #include "gnunet_strings_lib.h" |
31 | #include "gnunet_time_lib.h" | 31 | #include "gnunet_time_lib.h" |
32 | 32 | ||
33 | #include <regex.h> | ||
34 | |||
33 | /** | 35 | /** |
34 | * After how many milliseconds do we always print | 36 | * After how many milliseconds do we always print |
35 | * that "message X was repeated N times"? Use 12h. | 37 | * that "message X was repeated N times"? Use 12h. |
@@ -145,24 +147,19 @@ static FILE *GNUNET_stderr; | |||
145 | struct LogDef | 147 | struct LogDef |
146 | { | 148 | { |
147 | /** | 149 | /** |
148 | * Component name. NULL means that this definition matches any component | 150 | * Component name regex |
149 | */ | ||
150 | char *component; | ||
151 | |||
152 | /** | ||
153 | * File name. NULL means that this definition matches any file | ||
154 | */ | 151 | */ |
155 | char *file; | 152 | regex_t component_regex; |
156 | 153 | ||
157 | /** | 154 | /** |
158 | * Stores strlen(file) | 155 | * File name regex |
159 | */ | 156 | */ |
160 | int strlen_file; | 157 | regex_t file_regex; |
161 | 158 | ||
162 | /** | 159 | /** |
163 | * Function name. NULL means that this definition matches any function | 160 | * Function name regex |
164 | */ | 161 | */ |
165 | char *function; | 162 | regex_t function_regex; |
166 | 163 | ||
167 | /** | 164 | /** |
168 | * Lowest line at which this definition matches. | 165 | * Lowest line at which this definition matches. |
@@ -273,30 +270,48 @@ resize_logdefs () | |||
273 | * @param to_line see struct LogDef | 270 | * @param to_line see struct LogDef |
274 | * @param level see struct LogDef, must be >= 0 | 271 | * @param level see struct LogDef, must be >= 0 |
275 | * @param force see struct LogDef | 272 | * @param force see struct LogDef |
273 | * @return 0 on success, regex-specific error otherwise | ||
276 | */ | 274 | */ |
277 | static void | 275 | static int |
278 | add_definition (char *component, char *file, char *function, int from_line, | 276 | add_definition (char *component, char *file, char *function, int from_line, |
279 | int to_line, int level, int force) | 277 | int to_line, int level, int force) |
280 | { | 278 | { |
279 | struct LogDef n; | ||
280 | int r; | ||
281 | if (logdefs_size == logdefs_len) | 281 | if (logdefs_size == logdefs_len) |
282 | resize_logdefs (); | 282 | resize_logdefs (); |
283 | struct LogDef n; | ||
284 | |||
285 | memset (&n, 0, sizeof (n)); | 283 | memset (&n, 0, sizeof (n)); |
286 | if (strlen (component) > 0 && component[0] != '*') | 284 | if (strlen (component) == 0) |
287 | n.component = GNUNET_strdup (component); | 285 | component = (char *) ".*"; |
288 | if (strlen (file) > 0 && file[0] != '*') | 286 | r = regcomp (&n.component_regex, (const char *) component, REG_NOSUB); |
289 | { | 287 | if (r != 0) |
290 | n.file = GNUNET_strdup (file); | 288 | { |
291 | n.strlen_file = strlen (file); | 289 | return r; |
292 | } | 290 | } |
293 | if ((NULL != function) && (strlen (function) > 0) && (function[0] != '*')) | 291 | if (strlen (file) == 0) |
294 | n.function = GNUNET_strdup (function); | 292 | file = (char *) ".*"; |
293 | r = regcomp (&n.file_regex, (const char *) file, REG_NOSUB); | ||
294 | if (r != 0) | ||
295 | { | ||
296 | regfree (&n.component_regex); | ||
297 | return r; | ||
298 | } | ||
299 | if ( (NULL == function) || | ||
300 | (strlen (function) == 0)) | ||
301 | function = (char *) ".*"; | ||
302 | r = regcomp (&n.function_regex, (const char *) function, REG_NOSUB); | ||
303 | if (r != 0) | ||
304 | { | ||
305 | regfree (&n.component_regex); | ||
306 | regfree (&n.file_regex); | ||
307 | return r; | ||
308 | } | ||
295 | n.from_line = from_line; | 309 | n.from_line = from_line; |
296 | n.to_line = to_line; | 310 | n.to_line = to_line; |
297 | n.level = level; | 311 | n.level = level; |
298 | n.force = force; | 312 | n.force = force; |
299 | logdefs[logdefs_len++] = n; | 313 | logdefs[logdefs_len++] = n; |
314 | return 0; | ||
300 | } | 315 | } |
301 | 316 | ||
302 | 317 | ||
@@ -320,7 +335,6 @@ GNUNET_get_log_call_status (int caller_level, const char *comp, | |||
320 | struct LogDef *ld; | 335 | struct LogDef *ld; |
321 | int i; | 336 | int i; |
322 | int force_only; | 337 | int force_only; |
323 | size_t strlen_file; | ||
324 | 338 | ||
325 | if (comp == NULL) | 339 | if (comp == NULL) |
326 | /* Use default component */ | 340 | /* Use default component */ |
@@ -334,23 +348,18 @@ GNUNET_get_log_call_status (int caller_level, const char *comp, | |||
334 | 348 | ||
335 | /* Only look for forced definitions? */ | 349 | /* Only look for forced definitions? */ |
336 | force_only = min_level >= 0; | 350 | force_only = min_level >= 0; |
337 | strlen_file = strlen (file); | ||
338 | for (i = 0; i < logdefs_len; i++) | 351 | for (i = 0; i < logdefs_len; i++) |
339 | { | 352 | { |
340 | ld = &logdefs[i]; | 353 | ld = &logdefs[i]; |
341 | if ((!force_only || ld->force) && | 354 | if ((!force_only || ld->force) && |
342 | (line >= ld->from_line && line <= ld->to_line) && (ld->component == NULL | 355 | (line >= ld->from_line && line <= ld->to_line) && |
343 | || strcmp (comp, | 356 | (regexec (&ld->component_regex, comp, 0, NULL, 0) == 0) && |
344 | ld->component) | 357 | (regexec (&ld->file_regex, file, 0, NULL, 0) == 0) && |
345 | == 0) && | 358 | (regexec (&ld->function_regex, function, 0, NULL, 0) == 0)) |
346 | (ld->file == NULL || | 359 | { |
347 | (ld->strlen_file <= strlen_file && | 360 | /* We're finished */ |
348 | strcmp (&file[strlen_file - ld->strlen_file], ld->file) == 0)) && | 361 | return caller_level <= ld->level; |
349 | (ld->function == NULL || strcmp (function, ld->function) == 0)) | 362 | } |
350 | { | ||
351 | /* We're finished */ | ||
352 | return caller_level <= ld->level; | ||
353 | } | ||
354 | } | 363 | } |
355 | /* No matches - use global level, if defined */ | 364 | /* No matches - use global level, if defined */ |
356 | if (min_level >= 0) | 365 | if (min_level >= 0) |
@@ -411,82 +420,83 @@ parse_definitions (const char *constname, int force) | |||
411 | to_line = INT_MAX; | 420 | to_line = INT_MAX; |
412 | for (p = def, state = 0, start = def; keep_looking; p++) | 421 | for (p = def, state = 0, start = def; keep_looking; p++) |
413 | { | 422 | { |
414 | switch (p[0]) | 423 | switch (p[0]) |
415 | { | 424 | { |
416 | case ';': /* found a field separator */ | 425 | case ';': /* found a field separator */ |
417 | p[0] = '\0'; | 426 | p[0] = '\0'; |
418 | switch (state) | 427 | switch (state) |
419 | { | 428 | { |
420 | case 0: /* within a component name */ | 429 | case 0: /* within a component name */ |
421 | comp = start; | 430 | comp = start; |
422 | break; | 431 | break; |
423 | case 1: /* within a file name */ | 432 | case 1: /* within a file name */ |
424 | file = start; | 433 | file = start; |
425 | break; | 434 | break; |
426 | case 2: /* within a function name */ | 435 | case 2: /* within a function name */ |
427 | /* after a file name there must be a function name */ | 436 | /* after a file name there must be a function name */ |
428 | function = start; | 437 | function = start; |
429 | break; | 438 | break; |
430 | case 3: /* within a from-to line range */ | 439 | case 3: /* within a from-to line range */ |
431 | if (strlen (start) > 0) | 440 | if (strlen (start) > 0) |
432 | { | 441 | { |
433 | errno = 0; | 442 | errno = 0; |
434 | from_line = strtol (start, &t, 10); | 443 | from_line = strtol (start, &t, 10); |
435 | if (errno != 0 || from_line < 0) | 444 | if (errno != 0 || from_line < 0) |
436 | { | 445 | { |
437 | free (def); | 446 | free (def); |
438 | return counter; | 447 | return counter; |
439 | } | 448 | } |
440 | if (t < p && t[0] == '-') | 449 | if (t < p && t[0] == '-') |
441 | { | 450 | { |
442 | errno = 0; | 451 | errno = 0; |
443 | start = t + 1; | 452 | start = t + 1; |
444 | to_line = strtol (start, &t, 10); | 453 | to_line = strtol (start, &t, 10); |
445 | if (errno != 0 || to_line < 0 || t != p) | 454 | if (errno != 0 || to_line < 0 || t != p) |
446 | { | 455 | { |
447 | free (def); | 456 | free (def); |
448 | return counter; | 457 | return counter; |
449 | } | 458 | } |
450 | } | 459 | } |
451 | else /* one number means "match this line only" */ | 460 | else /* one number means "match this line only" */ |
452 | to_line = from_line; | 461 | to_line = from_line; |
453 | } | 462 | } |
454 | else /* default to 0-max */ | 463 | else /* default to 0-max */ |
455 | { | 464 | { |
456 | from_line = 0; | 465 | from_line = 0; |
457 | to_line = INT_MAX; | 466 | to_line = INT_MAX; |
458 | } | 467 | } |
459 | break; | 468 | break; |
460 | } | 469 | } |
461 | start = p + 1; | 470 | start = p + 1; |
462 | state += 1; | 471 | state += 1; |
463 | break; | 472 | break; |
464 | case '\0': /* found EOL */ | 473 | case '\0': /* found EOL */ |
465 | keep_looking = 0; | 474 | keep_looking = 0; |
466 | /* fall through to '/' */ | 475 | /* fall through to '/' */ |
467 | case '/': /* found a definition separator */ | 476 | case '/': /* found a definition separator */ |
468 | switch (state) | 477 | switch (state) |
469 | { | 478 | { |
470 | case 4: /* within a log level */ | 479 | case 4: /* within a log level */ |
471 | p[0] = '\0'; | 480 | p[0] = '\0'; |
472 | state = 0; | 481 | state = 0; |
473 | level = get_type ((const char *) start); | 482 | level = get_type ((const char *) start); |
474 | if (level == GNUNET_ERROR_TYPE_INVALID || | 483 | if (level == GNUNET_ERROR_TYPE_INVALID |
475 | level == GNUNET_ERROR_TYPE_UNSPECIFIED) | 484 | || level == GNUNET_ERROR_TYPE_UNSPECIFIED |
476 | { | 485 | || 0 != add_definition (comp, file, function, from_line, |
477 | free (def); | 486 | to_line, level, force)) |
478 | return counter; | 487 | { |
479 | } | 488 | free (def); |
480 | add_definition (comp, file, function, from_line, to_line, level, force); | 489 | return counter; |
481 | counter += 1; | 490 | } |
482 | start = p + 1; | 491 | counter += 1; |
483 | break; | 492 | start = p + 1; |
484 | default: | 493 | break; |
485 | break; | 494 | default: |
486 | } | 495 | break; |
487 | default: | 496 | } |
488 | break; | 497 | default: |
489 | } | 498 | break; |
499 | } | ||
490 | } | 500 | } |
491 | free (def); | 501 | free (def); |
492 | return counter; | 502 | return counter; |