[PATCH] lib: fwts_klog: optimize regex scanning
Colin King
colin.king at canonical.com
Mon Jul 23 19:55:41 UTC 2012
From: Colin Ian King <colin.king at canonical.com>
pcre allows one to optimize regex matching and without it i386
systems seem to randomly break (which isn't expected) on some
regex pattern matches. So, use the pcre study and also add some
safe-guarding in the code to ensure we only compare regexes if
the compiled form is not NULL.
Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
src/lib/include/fwts_klog.h | 1 +
src/lib/src/fwts_klog.c | 26 ++++++++++++++++++++++----
2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/src/lib/include/fwts_klog.h b/src/lib/include/fwts_klog.h
index 3bbed5f..a47cf7a 100644
--- a/src/lib/include/fwts_klog.h
+++ b/src/lib/include/fwts_klog.h
@@ -44,6 +44,7 @@ typedef struct {
const char *pattern;
const char *advice;
pcre *re;
+ pcre_extra *extra;
} fwts_klog_pattern;
typedef void (*fwts_klog_progress_func)(fwts_framework *fw, int percent);
diff --git a/src/lib/src/fwts_klog.c b/src/lib/src/fwts_klog.c
index 93dbb06..ea713e8 100644
--- a/src/lib/src/fwts_klog.c
+++ b/src/lib/src/fwts_klog.c
@@ -230,7 +230,8 @@ void fwts_klog_scan_patterns(fwts_framework *fw,
int matched = 0;
switch (pattern->compare_mode) {
case FWTS_COMPARE_REGEX:
- matched = (pcre_exec(pattern->re, NULL, line, strlen(line), 0, 0, vector, 1) == 0);
+ if (pattern->re)
+ matched = (pcre_exec(pattern->re, pattern->extra, line, strlen(line), 0, 0, vector, 1) == 0);
break;
case FWTS_COMPARE_STRING:
default:
@@ -354,8 +355,16 @@ static int fwts_klog_check(fwts_framework *fw,
if ((patterns[i].advice = fwts_json_str(fw, table, i, obj, "advice")) == NULL)
goto fail;
- if ((patterns[i].re = pcre_compile(patterns[i].pattern, 0, &error, &erroffset, NULL)) == NULL)
+ if ((patterns[i].re = pcre_compile(patterns[i].pattern, 0, &error, &erroffset, NULL)) == NULL) {
fwts_log_error(fw, "Regex %s failed to compile: %s.", patterns[i].pattern, error);
+ patterns[i].re = NULL;
+ } else {
+ patterns[i].extra = pcre_study(patterns[i].re, 0, &error);
+ if (error != NULL) {
+ fwts_log_error(fw, "Regex %s failed to optimize: %s.", patterns[i].pattern, error);
+ patterns[i].re = NULL;
+ }
+ }
}
/* We've now collected up the scan patterns, lets scan the log for errors */
ret = fwts_klog_scan(fw, klog, fwts_klog_scan_patterns, progress, patterns, errors);
@@ -364,6 +373,8 @@ fail:
for (i=0; i<n; i++)
if (patterns[i].re)
pcre_free(patterns[i].re);
+ if (patterns[i].extra)
+ pcre_free(patterns[i].extra);
free(patterns);
fail_put:
json_object_put(klog_objs);
@@ -398,15 +409,22 @@ static void fwts_klog_regex_find_callback(fwts_framework *fw, char *line, int re
const char *error;
int erroffset;
pcre *re;
+ pcre_extra *extra;
int rc;
int vector[1];
re = pcre_compile(pattern, 0, &error, &erroffset, NULL);
if (re != NULL) {
- rc = pcre_exec(re, NULL, line, strlen(line), 0, 0, vector, 1);
+ extra = pcre_study(re, 0, &error);
+ if (error)
+ return;
+
+ rc = pcre_exec(re, extra, line, strlen(line), 0, 0, vector, 1);
+ if (extra)
+ free(extra);
+ pcre_free(re);
if (rc == 0)
(*match)++;
- pcre_free(re);
}
}
--
1.7.10.4
More information about the fwts-devel
mailing list