ACK: [PATCH] lib: fwts_klog: optimize regex scanning
Alex Hung
alex.hung at canonical.com
Fri Jul 27 07:01:11 UTC 2012
On 07/24/2012 03:55 AM, Colin King wrote:
> 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);
> }
> }
>
>
Acked-by: Alex Hung <alex.hung at canonical.com>
More information about the fwts-devel
mailing list