summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/anope.example.conf2
-rw-r--r--data/modules.example.conf24
-rw-r--r--docs/Changes.conf1
-rw-r--r--modules/m_regex_stdlib.cpp107
4 files changed, 132 insertions, 2 deletions
diff --git a/data/anope.example.conf b/data/anope.example.conf
index 118f2f2f5..62eaa8154 100644
--- a/data/anope.example.conf
+++ b/data/anope.example.conf
@@ -527,7 +527,7 @@ options
*
* Note for this to work the regex module providing the regex engine must be loaded.
*/
- #regexengine = "regex/pcre"
+ #regexengine = "regex/stdlib"
/*
* A list of languages to load on startup that will be available in /NICKSERV SET LANGUAGE.
diff --git a/data/modules.example.conf b/data/modules.example.conf
index 6630bc750..fdf5b57be 100644
--- a/data/modules.example.conf
+++ b/data/modules.example.conf
@@ -412,11 +412,33 @@ module { name = "help" }
* m_regex_posix [EXTRA]
*
* Provides the regex engine regex/posix, which uses the POSIX compliant regular expressions.
- * This is likely the only regex module you will not need extra libraries for.
*/
#module { name = "m_regex_posix" }
/*
+ * m_regex_stdlib
+ *
+ * Provides the regex engine regex/stdlib, which uses the regular expression library that is part of
+ * the C++ standard library.
+*/
+module
+{
+ name = "m_regex_stdlib"
+
+ /*
+ * The syntax scheme to use. Can be set to awk to use the regular expression grammar used by the
+ * awk utility in POSIX, basic to use the basic POSIX regular expression grammar, ecmascript to
+ * use the modified ECMAScript regular expression grammar, egrep to use the regular expression
+ * grammar used by the grep utility with the -E option in POSIX, extended to use the extended
+ * POSIX regular expression grammar, or grep to use the regular expression grammar used by the
+ * grep utility in POSIX.
+ *
+ * See https://en.cppreference.com/w/cpp/regex/syntax_option_type for more information.
+ */
+ syntax = "ecmascript"
+}
+
+/*
* m_regex_tre [EXTRA]
*
* Provides the regex engine regex/tre, which uses the TRE regex library.
diff --git a/docs/Changes.conf b/docs/Changes.conf
index fdd729b04..7397a8588 100644
--- a/docs/Changes.conf
+++ b/docs/Changes.conf
@@ -1,5 +1,6 @@
Anope Version 2.1.1-git
-----------------------
+Added the m_regex_stdlib module.
Removed the m_regex_pcre module (use m_regex_pcre2 instead).
Anope Version 2.1.0
diff --git a/modules/m_regex_stdlib.cpp b/modules/m_regex_stdlib.cpp
new file mode 100644
index 000000000..67fceedae
--- /dev/null
+++ b/modules/m_regex_stdlib.cpp
@@ -0,0 +1,107 @@
+/*
+ *
+ * (C) 2012-2023 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ */
+
+#include "module.h"
+
+#include <regex>
+
+class StdLibRegex final
+ : public Regex
+{
+private:
+ std::regex regex;
+
+public:
+ StdLibRegex(const Anope::string &expr, std::regex::flag_type type)
+ : Regex(expr)
+ {
+ try
+ {
+ regex.assign(expr.str(), type | std::regex::optimize);
+ }
+ catch (const std::regex_error& error)
+ {
+ throw RegexException("Error in regex " + expr + ": " + error.what());
+ }
+ }
+
+ bool Matches(const Anope::string &str)
+ {
+ return std::regex_search(str.str(), regex);
+ }
+};
+
+class StdLibRegexProvider final
+ : public RegexProvider
+{
+public:
+ std::regex_constants::syntax_option_type type;
+
+ StdLibRegexProvider(Module *creator)
+ : RegexProvider(creator, "regex/stdlib")
+ {
+ }
+
+ Regex *Compile(const Anope::string &expression) override
+ {
+ return new StdLibRegex(expression, type);
+ }
+};
+
+class ModuleRegexStdLib final
+ : public Module
+{
+private:
+ StdLibRegexProvider stdlib_regex_provider;
+
+public:
+ ModuleRegexStdLib(const Anope::string &modname, const Anope::string &creator)
+ : Module(modname, creator, EXTRA | VENDOR)
+ , stdlib_regex_provider(this)
+ {
+ this->SetPermanent(true);
+ }
+
+ void OnReload(Configuration::Conf *conf) override
+ {
+ Configuration::Block *block = conf->GetModule(this);
+
+ const Anope::string syntax = block->Get<const Anope::string>("syntax", "ecmascript");
+ if (syntax == "awk")
+ stdlib_regex_provider.type = std::regex::awk;
+ else if (syntax == "basic")
+ stdlib_regex_provider.type = std::regex::basic;
+ else if (syntax == "ecmascript")
+ stdlib_regex_provider.type = std::regex::ECMAScript;
+ else if (syntax == "egrep")
+ stdlib_regex_provider.type = std::regex::egrep;
+ else if (syntax == "extended")
+ stdlib_regex_provider.type = std::regex::extended;
+ else if (syntax == "grep")
+ stdlib_regex_provider.type = std::regex::grep;
+ else
+ throw ConfigException(this->name + ": syntax must be set to awk, basic, ecmascript, egrep, extended, or grep.");
+ }
+
+ ~ModuleRegexStdLib()
+ {
+ for (auto *xlm : XLineManager::XLineManagers)
+ {
+ for (auto *x : xlm->GetList())
+ {
+ if (x->regex && dynamic_cast<StdLibRegex *>(x->regex))
+ {
+ delete x->regex;
+ x->regex = NULL;
+ }
+ }
+ }
+ }
+};
+
+MODULE_INIT(ModuleRegexStdLib)