aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-11-05 14:36:34 +0000
committerChristian Grothoff <christian@grothoff.org>2011-11-05 14:36:34 +0000
commit317d91ed37b5b85d298ac7d704a5b934cbea9e8a (patch)
tree611e7f17a4971269d07febf081116eeedb9f65fc /src/util
parent262a695388efa539a23ba82eb2d0187961a4c894 (diff)
downloadgnunet-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')
-rw-r--r--src/util/common_logging.c240
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;
145struct LogDef 147struct 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 */
277static void 275static int
278add_definition (char *component, char *file, char *function, int from_line, 276add_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;