From cb091770076f9b92d8df5a7589505f6bf64341b9 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Sat, 11 Mar 2006 20:40:26 +0000 Subject: Add support for using standard regular expression library. --- configure.in | 24 +++++++---- src/bsnmp-regex.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 139 insertions(+), 12 deletions(-) diff --git a/configure.in b/configure.in index b4d83d2..fbaa423 100644 --- a/configure.in +++ b/configure.in @@ -19,21 +19,29 @@ AC_ARG_ENABLE(debug, [Compile binaries in debug mode])) if test "$enable_debug" = "yes"; then - CFLAGS="$CFLAGS -g -O0 -Wall" - AC_DEFINE_UNQUOTED(_DEBUG, 1, [In debug mode]) - echo "enabling debug compile mode" + CFLAGS="$CFLAGS -g -O0 -Wall" + AC_DEFINE_UNQUOTED(_DEBUG, 1, [In debug mode]) + echo "enabling debug compile mode" fi # Some checks for libraries AC_CHECK_LIB(bsnmp, snmp_close, , [echo "Couldn't find the bsnmp library"; exit 1]) -AC_CHECK_LIB(pcre, pcre_compile, , - [echo "Couldn't find the pcre library"; exit 1]) - + # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS("pcre.h", , - [echo "Couldn't find pcre headers"; exit 1]) + +AC_ARG_ENABLE(pcre, + AC_HELP_STRING([--with-pcre], + [Use PCRE instead of the default regular expression library])) + +if test "$enable_pcre" = "yes"; then + AC_CHECK_LIB(pcre, pcre_compile, , + [echo "Couldn't find the pcre library"; exit 1]) + AC_CHECK_HEADERS("pcre.h", , + [echo "Couldn't find pcre headers"; exit 1]) + AC_DEFINE_UNQUOTED(WITH_PCRE, 1, [Use PCRE regular expression library]) +fi # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST diff --git a/src/bsnmp-regex.c b/src/bsnmp-regex.c index 091fbf8..cf06114 100644 --- a/src/bsnmp-regex.c +++ b/src/bsnmp-regex.c @@ -12,7 +12,12 @@ #include #include + +#ifdef WITH_PCRE #include +#else +#include +#endif #include "regex_tree.h" #include "regex_oid.h" @@ -43,8 +48,12 @@ struct data_entry { int type; char *descr; +#ifdef WITH_PCRE pcre *regex; pcre_extra *extra; +#else + regex_t regex; +#endif char *result; uint64_t last_update; @@ -139,6 +148,53 @@ getcurrticks () return t; } +#ifndef WITH_PCRE + +static const char* +regex_msg (int code) +{ + ASSERT (code != 0); + + switch (code) { + case REG_NOMATCH: + return "The regexec() function failed to match"; + case REG_BADPAT: + return "invalid regular expression"; + case REG_ECOLLATE: + return "invalid collating element"; + case REG_ECTYPE: + return "invalid character class"; + case REG_EESCAPE: + return "'\' applied to unescapable character"; + case REG_ESUBREG: + return "invalid backreference number"; + case REG_EBRACK: + return "brackets '[ ]' not balanced"; + case REG_EPAREN: + return "parentheses '( )' not balanced"; + case REG_EBRACE: + return "braces '{ }' not balanced"; + case REG_BADBR: + return "invalid repetition count(s) in '{ }'"; + case REG_ERANGE: + return "invalid character range in '[ ]'"; + case REG_ESPACE: + return "ran out of memory"; + case REG_BADRPT: + return "'?', '*', or '+' operand invalid"; + case REG_EMPTY: + return "empty (sub)expression"; + case REG_ILLSEQ: + return "illegal byte sequence (bad multibyte character)"; + + case REG_ASSERT: + case REG_INVARG: + default: + return "internal or unknown error"; + } +} + +#endif /* WITH_PCRE */ /* ----------------------------------------------------------------------------- * MATCHING @@ -186,7 +242,11 @@ process_match (struct data_entry *data, char *result) static char* process_result (struct data_entry *data, char *line, int len, - int *ovector, int substrings) +#ifdef WITH_PCRE + int *ovector, int substrings) +#else + regmatch_t *pm) +#endif { char *result; char *p, *t; @@ -208,6 +268,7 @@ process_result (struct data_entry *data, char *line, int len, continue; idx = p[0] - '0'; ASSERT (idx >= 0 && idx <= 9); +#ifdef WITH_PCRE if (idx < substrings) { ASSERT (ovector[(idx * 2) + 1] >= ovector[idx * 2]); ASSERT (ovector[(idx * 2) + 1] < len); @@ -215,6 +276,15 @@ process_result (struct data_entry *data, char *line, int len, rlen += (ovector[(idx * 2) + 1]) - (ovector[idx * 2]); rlen += 1; } +#else /* WITH_PCRE */ + if (pm[idx].rm_so != -1 && pm[idx].rm_eo != -1) { + ASSERT (pm[idx].rm_eo >= pm[idx].rm_so); + ASSERT (pm[idx].rm_eo < len); + ASSERT (pm[idx].rm_so < len); + rlen += (pm[idx].rm_eo - pm[idx].rm_so); + rlen += 1; + } +#endif /* WITH_PCRE */ } } @@ -229,11 +299,20 @@ process_result (struct data_entry *data, char *line, int len, p++; if (isdigit(p[0])) { idx = p[0] - '0'; +#ifdef WITH_PCRE if (idx < substrings) { l = (ovector[(idx * 2) + 1]) - (ovector[idx * 2]); memcpy (t, line + (ovector[idx * 2]), l); t += l; } +#else /* WITH_PCRE */ + if (pm[idx].rm_so != -1 && pm[idx].rm_eo != -1) { + l = pm[idx].rm_eo - pm[idx].rm_so; + memcpy (t, line + pm[idx].rm_so, l); + t += l; + } +#endif /* WITH _PCRE */ + continue; } } @@ -249,16 +328,22 @@ static void process_log (char *line, int len) { struct data_entry *data; - int ovector[30]; char *result; int r; +#ifdef WITH_PCRE + int ovector[30]; +#else + regmatch_t pm[10]; +#endif + for (data = TAILQ_FIRST (&entries); data; data = TAILQ_NEXT (data, link)) { - memset (ovector, 0, sizeof (ovector)); result = NULL; +#ifdef WITH_PCRE + memset (ovector, 0, sizeof (ovector)); r = pcre_exec (data->regex, data->extra, line, len, 0, PCRE_NOTEMPTY | PCRE_NO_UTF8_CHECK, ovector, 30); @@ -273,6 +358,19 @@ process_log (char *line, int len) } result = process_result (data, line, len, ovector, r); + +#else + r = regexec (&(data->regex), line, 10, pm, 0); + if (r == REG_NOMATCH) + continue; + else if (r != 0) { + emsg ("internal error in matching code: %d", r); + return; + } + + result = process_result (data, line, len, pm); +#endif + process_match (data, result); free (result); } @@ -402,10 +500,15 @@ open_fifo () static void config_free (struct data_entry *data) { +#ifdef WITH_PCRE if (data->regex) free (data->regex); if (data->extra) free (data->extra); +#else + regfree (&(data->regex)); +#endif + free (data); } @@ -423,9 +526,14 @@ static int config_entry (struct data_entry *data, char *name, char type, char *regex, char *result, char *flags, int line) { +#ifdef WITH_PCRE const char *errptr; int erroffset; int options = 0; +#else + int options = REG_EXTENDED; + int r; +#endif ASSERT (regex); ASSERT (flags); @@ -452,7 +560,11 @@ config_entry (struct data_entry *data, char *name, char type, char *regex, for (; *flags; flags++) { switch (flags[0]) { case 'i': +#ifdef WITH_PCRE options |= PCRE_CASELESS; +#else + options |= REG_ICASE; +#endif break; default: emsg ("[line %d] invalid flag: %c", line, flags[0]); @@ -464,14 +576,21 @@ config_entry (struct data_entry *data, char *name, char type, char *regex, data->descr = name; /* Parse the regex */ +#ifdef WITH_PCRE data->regex = pcre_compile (regex, options, &errptr, &erroffset, NULL); if (!data->regex) { emsg ("[line %d] invalid regular expression: %s", line, errptr); return -1; } - /* Optimize the regex, ignore errors */ data->extra = pcre_study (data->regex, 0, &errptr); +#else + r = regcomp (&(data->regex), regex, options); + if (r != 0) { + emsg ("[line %d] invalid regular expression: %s", line, regex_msg (r)); + return -1; + } +#endif /* Replacement data */ if (data->type != TYPE_COUNTER && !result) { -- cgit v1.2.3