diff --git a/tools/binpac/lib/CMakeLists.txt b/tools/binpac/lib/CMakeLists.txt index bac8a2bebe..b4179e702c 100644 --- a/tools/binpac/lib/CMakeLists.txt +++ b/tools/binpac/lib/CMakeLists.txt @@ -22,6 +22,7 @@ set(binpac_headers set(binpac_lib_SRCS binpac_buffer.cc binpac_bytestring.cc + binpac_regex.cc ${binpac_headers} ) diff --git a/tools/binpac/lib/binpac_regex.cc b/tools/binpac/lib/binpac_regex.cc index e69de29bb2..6f276c3462 100644 --- a/tools/binpac/lib/binpac_regex.cc +++ b/tools/binpac/lib/binpac_regex.cc @@ -0,0 +1,10 @@ + +#include + +class RE_Matcher; + +namespace binpac { + +std::vector* uncompiled_re_matchers = 0; + +} diff --git a/tools/binpac/lib/binpac_regex.h b/tools/binpac/lib/binpac_regex.h index b41e6dbb90..d27083877b 100644 --- a/tools/binpac/lib/binpac_regex.h +++ b/tools/binpac/lib/binpac_regex.h @@ -9,12 +9,19 @@ class RE_Matcher; namespace binpac { +// Internal vector recording not yet compiled matchers. +extern std::vector* uncompiled_re_matchers; + class RegExMatcher { public: RegExMatcher(const char *pattern) : pattern_(pattern) { - re_matcher_ = 0; + if ( ! uncompiled_re_matchers ) + uncompiled_re_matchers = new std::vector; + + re_matcher_ = new RE_Matcher(pattern_.c_str()); + uncompiled_re_matchers->push_back(re_matcher_); } ~RegExMatcher() @@ -25,19 +32,45 @@ public: // Returns the length of longest match, or -1 on mismatch. int MatchPrefix(const_byteptr data, int len) { - if ( ! re_matcher_ ) - { - re_matcher_ = new RE_Matcher(pattern_.c_str()); - re_matcher_->Compile(); - } return re_matcher_->MatchPrefix(data, len); } private: + friend void ::binpac::init(); + + // Function, and state, for compiling matchers. + static void init(); + string pattern_; RE_Matcher *re_matcher_; }; +inline void RegExMatcher::init() + { + if ( ! uncompiled_re_matchers ) + return; + + for ( size_t i = 0; i < uncompiled_re_matchers->size(); ++i ) + { + if ( ! (*uncompiled_re_matchers)[i]->Compile() ) + { + fprintf(stderr, "binpac: cannot compile regular expression\n"); + exit(1); + } + } + + uncompiled_re_matchers->clear(); + } + +// Must be called before any binpac functionality is used. +// +// Note, this must be defined here, and inline, because the RE functionality +// can only be used when compiling from inside Bro. +inline void init() + { + RegExMatcher::init(); + } + } // namespace binpac #endif // binpac_regex_h