summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2006-03-11 20:40:26 +0000
committerStef Walter <stef@memberwebs.com>2006-03-11 20:40:26 +0000
commitcb091770076f9b92d8df5a7589505f6bf64341b9 (patch)
treed27acdeecd80c4cbe852800017147aa847c4a1dd
parenta50303c1cb7a4f6b3dd3b78aa2ee076ef0a758e8 (diff)
Add support for using standard regular expression library.
-rw-r--r--configure.in24
-rw-r--r--src/bsnmp-regex.c127
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 <fcntl.h>
#include <bsnmp/snmpmod.h>
+
+#ifdef WITH_PCRE
#include <pcre.h>
+#else
+#include <regex.h>
+#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) {