From 1621a84f963c9fbfd61a52a85015fd8f2255dbf4 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 28 Jul 2020 16:43:59 +0100 Subject: Rewrite the regex system from scratch. * Move everything to the Regex namespace: - Regex -> Regex::Pattern - RegexException -> Regex::Exception - RegexFactory -> Regex::Engine * Add support for regex flags. - Regex::OPT_CASE_INSENSITIVE performs case-insensitive matching. * Add the Regex::EngineReference class as a friendly wrapper around dynamic_reference_nocheck. * Add the Regex::SimpleEngine template class for automating the implementation of regex factory classes. * Use std::shared_ptr for Regex::Pattern objects instead of making users manage memory manually. --- src/modules/m_regex_stdlib.cpp | 51 +++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'src/modules/m_regex_stdlib.cpp') diff --git a/src/modules/m_regex_stdlib.cpp b/src/modules/m_regex_stdlib.cpp index fffb2a7a6..db59fe6a1 100644 --- a/src/modules/m_regex_stdlib.cpp +++ b/src/modules/m_regex_stdlib.cpp @@ -22,58 +22,73 @@ #include "inspircd.h" #include "modules/regex.h" + #include -class StdRegex : public Regex +class StdLibPattern final + : public Regex::Pattern { - std::regex regexcl; + private: + std::regex regex; public: - StdRegex(const std::string& rx, std::regex::flag_type fltype) : Regex(rx) + StdLibPattern(const std::string& pattern, uint8_t options, std::regex::flag_type type) + : Regex::Pattern(pattern, options) { + // Convert the generic pattern options to stdlib pattern flags. + std::regex_constants::syntax_option_type flags = type | std::regex::optimize; + if (options & Regex::OPT_CASE_INSENSITIVE) + flags |= std::regex::icase; + try { - regexcl.assign(rx, fltype | std::regex::optimize); + regex.assign(pattern, flags); } - catch(const std::regex_error& rxerr) + catch(const std::regex_error& error) { - throw RegexException(rx, rxerr.what()); + throw Regex::Exception(pattern, error.what()); } } - bool Matches(const std::string& text) override + bool IsMatch(const std::string& text) override { - return std::regex_search(text, regexcl); + return std::regex_search(text, regex); } }; -class StdRegexFactory : public RegexFactory +class StdLibEngine final + : public Regex::Engine { public: std::regex::flag_type regextype; - StdRegexFactory(Module* m) : RegexFactory(m, "regex/stdregex") {} - Regex* Create(const std::string& expr) override + + StdLibEngine(Module* Creator) + : Regex::Engine(Creator, "stdregex") + { + } + + Regex::PatternPtr Create(const std::string& pattern, uint8_t options) override { - return new StdRegex(expr, regextype); + return std::make_shared(pattern, options, regextype); } }; -class ModuleRegexStd : public Module +class ModuleRegexStdLib : public Module { private: - StdRegexFactory ref; + StdLibEngine regex; public: - ModuleRegexStd() + ModuleRegexStdLib() : Module(VF_VENDOR, "Provides a regular expression engine which uses the C++11 std::regex regular expression matching system.") - , ref(this) + , regex(this) { } void ReadConfig(ConfigStatus& status) override { ConfigTag* tag = ServerInstance->Config->ConfValue("stdregex"); - ref.regextype = tag->getEnum("type", std::regex::ECMAScript, + regex.regextype = tag->getEnum("type", std::regex::ECMAScript, { { "awk", std::regex::awk }, { "bre", std::regex::basic }, @@ -85,4 +100,4 @@ class ModuleRegexStd : public Module } }; -MODULE_INIT(ModuleRegexStd) +MODULE_INIT(ModuleRegexStdLib) -- cgit v1.3.1-10-gc9f91