summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/anope.h69
-rw-r--r--include/config.h9
-rw-r--r--include/convert.h133
-rw-r--r--include/modules/sql.h13
-rw-r--r--include/protocol.h6
-rw-r--r--include/uplink.h8
-rw-r--r--modules/botserv/botserv.cpp8
-rw-r--r--modules/botserv/bs_badwords.cpp4
-rw-r--r--modules/botserv/bs_info.cpp2
-rw-r--r--modules/botserv/bs_kick.cpp96
-rw-r--r--modules/chanserv/cs_access.cpp33
-rw-r--r--modules/chanserv/cs_akick.cpp4
-rw-r--r--modules/chanserv/cs_enforce.cpp10
-rw-r--r--modules/chanserv/cs_entrymsg.cpp23
-rw-r--r--modules/chanserv/cs_flags.cpp2
-rw-r--r--modules/chanserv/cs_info.cpp2
-rw-r--r--modules/chanserv/cs_list.cpp12
-rw-r--r--modules/chanserv/cs_log.cpp2
-rw-r--r--modules/chanserv/cs_mode.cpp2
-rw-r--r--modules/chanserv/cs_set.cpp17
-rw-r--r--modules/chanserv/cs_xop.cpp4
-rw-r--r--modules/database/db_atheme.cpp27
-rw-r--r--modules/database/db_flatfile.cpp9
-rw-r--r--modules/database/db_old.cpp4
-rw-r--r--modules/database/db_redis.cpp50
-rw-r--r--modules/database/db_sql.cpp18
-rw-r--r--modules/database/db_sql_live.cpp15
-rw-r--r--modules/encryption/enc_bcrypt.cpp20
-rw-r--r--modules/extra/mysql.cpp4
-rw-r--r--modules/extra/regex_pcre2.cpp2
-rw-r--r--modules/extra/sqlite.cpp4
-rw-r--r--modules/hostserv/hs_list.cpp13
-rw-r--r--modules/hostserv/hs_request.cpp2
-rw-r--r--modules/httpd.cpp9
-rw-r--r--modules/memoserv/memoserv.cpp4
-rw-r--r--modules/memoserv/ms_list.cpp4
-rw-r--r--modules/memoserv/ms_set.cpp16
-rw-r--r--modules/nickserv/nickserv.cpp2
-rw-r--r--modules/nickserv/ns_ajoin.cpp8
-rw-r--r--modules/nickserv/ns_alist.cpp6
-rw-r--r--modules/nickserv/ns_list.cpp12
-rw-r--r--modules/operserv/os_akill.cpp4
-rw-r--r--modules/operserv/os_defcon.cpp8
-rw-r--r--modules/operserv/os_dns.cpp25
-rw-r--r--modules/operserv/os_list.cpp4
-rw-r--r--modules/operserv/os_logsearch.cpp26
-rw-r--r--modules/operserv/os_news.cpp18
-rw-r--r--modules/operserv/os_session.cpp26
-rw-r--r--modules/operserv/os_set.cpp6
-rw-r--r--modules/operserv/os_sxline.cpp4
-rw-r--r--modules/protocol/bahamut.cpp38
-rw-r--r--modules/protocol/hybrid.cpp24
-rw-r--r--modules/protocol/inspircd.cpp103
-rw-r--r--modules/protocol/ngircd.cpp7
-rw-r--r--modules/protocol/plexus.cpp22
-rw-r--r--modules/protocol/ratbox.cpp4
-rw-r--r--modules/protocol/solanum.cpp2
-rw-r--r--modules/protocol/unrealircd.cpp91
-rw-r--r--modules/proxyscan.cpp10
-rw-r--r--modules/redis.cpp27
-rw-r--r--modules/rewrite.cpp41
-rw-r--r--modules/webcpanel/pages/memoserv/memos.cpp12
-rw-r--r--modules/webcpanel/pages/nickserv/alist.cpp4
-rw-r--r--modules/webcpanel/pages/operserv/akill.cpp2
-rw-r--r--modules/xmlrpc_main.cpp28
-rw-r--r--src/config.cpp16
-rw-r--r--src/init.cpp6
-rw-r--r--src/misc.cpp80
-rw-r--r--src/modes.cpp27
-rw-r--r--src/modulemanager.cpp2
-rw-r--r--src/nickcore.cpp2
-rw-r--r--src/protocol.cpp2
-rw-r--r--src/regchannel.cpp11
-rw-r--r--src/socketengines/epoll.cpp2
-rw-r--r--src/socketengines/poll.cpp4
-rw-r--r--src/sockets.cpp8
76 files changed, 573 insertions, 811 deletions
diff --git a/include/anope.h b/include/anope.h
index fd3728d84..c4a2079aa 100644
--- a/include/anope.h
+++ b/include/anope.h
@@ -39,6 +39,7 @@ namespace Anope
typedef std::string::reverse_iterator reverse_iterator;
typedef std::string::const_reverse_iterator const_reverse_iterator;
typedef std::string::size_type size_type;
+ typedef std::string::value_type value_type;
static const size_type npos = static_cast<size_type>(-1);
/**
@@ -729,72 +730,6 @@ public:
virtual ~ModuleException() noexcept = default;
};
-class CoreExport ConvertException final
- : public CoreException
-{
-public:
- ConvertException(const Anope::string &reason = "") : CoreException(reason) { }
-
- virtual ~ConvertException() noexcept = default;
-};
-
-/** Convert something to a string
- */
-inline Anope::string stringify(const Anope::string &x)
-{
- return x;
-}
-
-template<typename T> inline Anope::string stringify(const T &x)
-{
- std::ostringstream stream;
-
- if (!(stream << x))
- throw ConvertException("Stringify fail");
-
- return stream.str();
-}
-
-template<typename T> inline void convert(const Anope::string &s, T &x, Anope::string &leftover, bool failIfLeftoverChars = true)
-{
- leftover.clear();
- std::istringstream i(s.str());
- char c;
- if (!(i >> x))
- throw ConvertException("Convert fail");
- if (failIfLeftoverChars)
- {
- if (i.get(c))
- throw ConvertException("Convert fail");
- }
- else
- {
- std::string left;
- getline(i, left);
- leftover = left;
- }
-}
-
-template<typename T> inline void convert(const Anope::string &s, T &x, bool failIfLeftoverChars = true)
-{
- Anope::string Unused;
- convert(s, x, Unused, failIfLeftoverChars);
-}
-
-template<typename T> inline T convertTo(const Anope::string &s, Anope::string &leftover, bool failIfLeftoverChars = true)
-{
- T x;
- convert(s, x, leftover, failIfLeftoverChars);
- return x;
-}
-
-template<typename T> inline T convertTo(const Anope::string &s, bool failIfLeftoverChars = true)
-{
- T x;
- convert(s, x, failIfLeftoverChars);
- return x;
-}
-
/** Casts to be used instead of dynamic_cast, this uses dynamic_cast
* for debug builds and static_cast on release builds
* to speed up the program because dynamic_cast relies on RTTI.
@@ -814,3 +749,5 @@ template<typename T, typename O> inline T anope_dynamic_static_cast(O ptr)
return static_cast<T>(ptr);
}
#endif
+
+#include "convert.h"
diff --git a/include/config.h b/include/config.h
index 022ee503d..652d42a7a 100644
--- a/include/config.h
+++ b/include/config.h
@@ -46,14 +46,7 @@ namespace Configuration
template<typename T> T Get(const Anope::string &tag, const Anope::string &def = "") const
{
- const Anope::string &value = this->Get<const Anope::string>(tag, def);
- if (!value.empty())
- try
- {
- return convertTo<T>(value);
- }
- catch (const ConvertException &) { }
- return T();
+ return Anope::TryConvert<T>(this->Get<const Anope::string>(tag, def)).value_or(T());
}
bool Set(const Anope::string &tag, const Anope::string &value);
diff --git a/include/convert.h b/include/convert.h
new file mode 100644
index 000000000..3cdbcd787
--- /dev/null
+++ b/include/convert.h
@@ -0,0 +1,133 @@
+/*
+ *
+ * (C) 2003-2024 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ */
+
+#pragma once
+
+#include <optional>
+
+namespace Anope
+{
+ /** Attempts to convert a string to any type.
+ * @param in The value to convert.
+ * @param leftover If non-nullptr then the location to store leftover data.
+ */
+ template<typename T>
+ inline std::optional<T> TryConvert(const Anope::string &in, Anope::string *leftover = nullptr)
+ {
+ std::istringstream tmp(in.str());
+ T out;
+ if (!(tmp >> out))
+ return std::nullopt;
+
+ if (leftover)
+ {
+ std::string extra;
+ std::getline(tmp, extra);
+ *leftover = extra;
+ }
+ else
+ {
+ char extra;
+ if (tmp >> extra)
+ return std::nullopt;
+ }
+ return out;
+ }
+
+ /** Converts a string to any type.
+ * @param in The value to convert.
+ * @param def The default to use if the conversion failed.
+ * @param leftover If non-nullptr then the location to store leftover data.
+ */
+ template<typename T>
+ inline T Convert(const Anope::string &in, T def, Anope::string *leftover = nullptr)
+ {
+ return TryConvert<T>(in, leftover).value_or(def);
+ }
+
+ /** Attempts to convert any type to a string.
+ * @param in The value to convert.
+ */
+ template <class T>
+ inline std::optional<Anope::string> TryString(const T &in)
+ {
+ std::ostringstream tmp;
+ if (!(tmp << in))
+ return std::nullopt;
+ return tmp.str();
+ }
+
+ /** No-op function that returns the string that was passed to it.
+ * @param in The string to return.
+ */
+ inline const string &ToString(const string &in)
+ {
+ return in;
+ }
+
+ /** Converts a std::string to a string.
+ * @param in The value to convert.
+ */
+ inline string ToString(const std::string &in)
+ {
+ return in;
+ }
+
+ /** Converts a char array to a string.
+ * @param in The value to convert.
+ */
+ inline string ToString(const char *in)
+ {
+ return string(in);
+ }
+
+ /** Converts a char to a string.
+ * @param in The value to convert.
+ */
+ inline string ToString(char in)
+ {
+ return string(1, static_cast<string::value_type>(in));
+ }
+
+ /** Converts an unsigned char to a string.
+ * @param in The value to convert.
+ */
+ inline string ToString(unsigned char in)
+ {
+ return string(1, static_cast<string::value_type>(in));
+ }
+
+ /** Converts a bool to a string.
+ * @param in The value to convert.
+ */
+ inline string ToString(bool in)
+ {
+ return (in ? "1" : "0");
+ }
+
+ /** Converts a type that std::to_string is implemented for to a string.
+ * @param in The value to convert.
+ */
+ template<typename Stringable>
+ inline std::enable_if_t<std::is_arithmetic_v<Stringable>, string> ToString(const Stringable &in)
+ {
+ return std::to_string(in);
+ }
+
+ /** Converts any type to a string.
+ * @param in The value to convert.
+ */
+ template <class T>
+ inline std::enable_if_t<!std::is_arithmetic_v<T>, string> ToString(const T &in)
+ {
+ return TryString(in).value_or(Anope::string());
+ }
+}
diff --git a/include/modules/sql.h b/include/modules/sql.h
index 8ac03803f..4c1b7d455 100644
--- a/include/modules/sql.h
+++ b/include/modules/sql.h
@@ -128,13 +128,12 @@ namespace SQL
template<typename T> void SetValue(const Anope::string &key, const T &value, bool escape = true)
{
- try
- {
- Anope::string string_value = stringify(value);
- this->parameters[key].data = string_value;
- this->parameters[key].escape = escape;
- }
- catch (const ConvertException &ex) { }
+ auto str = Anope::TryString(value);
+ if (!str.has_value())
+ return;
+
+ this->parameters[key].data = str.value();
+ this->parameters[key].escape = escape;
}
};
diff --git a/include/protocol.h b/include/protocol.h
index 88bb94bfc..612593c89 100644
--- a/include/protocol.h
+++ b/include/protocol.h
@@ -164,14 +164,14 @@ public:
template <typename... Args>
void SendMode(const MessageSource &source, Channel *chan, const Anope::string &modes, Args &&...args)
{
- SendModeInternal(source, chan, modes, { stringify(args)... });
+ SendModeInternal(source, chan, modes, { Anope::ToString(args)... });
}
virtual void SendModeInternal(const MessageSource &source, User *u, const Anope::string &modes, const std::vector<Anope::string> &values);
template <typename... Args>
void SendMode(const MessageSource &source, User *u, const Anope::string &modes, Args &&...args)
{
- SendModeInternal(source, u, modes, { stringify(args)... });
+ SendModeInternal(source, u, modes, { Anope::ToString(args)... });
}
/** Introduces a client to the rest of the network
@@ -258,7 +258,7 @@ public:
template <typename... Args>
void SendNumeric(int numeric, const Anope::string &dest, Args &&...args)
{
- SendNumericInternal(numeric, dest, { stringify(args)... });
+ SendNumericInternal(numeric, dest, { Anope::ToString(args)... });
}
virtual void SendLogin(User *u, NickAlias *na) = 0;
diff --git a/include/uplink.h b/include/uplink.h
index 12365dd65..924c05cfc 100644
--- a/include/uplink.h
+++ b/include/uplink.h
@@ -23,25 +23,25 @@ namespace Uplink
template<typename... Args>
void Send(const Anope::map<Anope::string> &tags, const MessageSource &source, const Anope::string &command, Args &&...args)
{
- SendInternal(tags, source, command, { stringify(args)... });
+ SendInternal(tags, source, command, { Anope::ToString(args)... });
}
template<typename... Args>
void Send(const Anope::map<Anope::string> &tags, const Anope::string &command, Args &&...args)
{
- SendInternal(tags, Me, command, { stringify(args)... });
+ SendInternal(tags, Me, command, { Anope::ToString(args)... });
}
template<typename... Args>
void Send(const MessageSource &source, const Anope::string &command, Args &&...args)
{
- SendInternal({}, source, command, { stringify(args)... });
+ SendInternal({}, source, command, { Anope::ToString(args)... });
}
template<typename... Args>
void Send(const Anope::string &command, Args &&...args)
{
- SendInternal({}, Me, command, { stringify(args)... });
+ SendInternal({}, Me, command, { Anope::ToString(args)... });
}
}
diff --git a/modules/botserv/botserv.cpp b/modules/botserv/botserv.cpp
index d2b8df4bb..706865522 100644
--- a/modules/botserv/botserv.cpp
+++ b/modules/botserv/botserv.cpp
@@ -67,12 +67,8 @@ public:
Anope::string Limit;
unsigned limit = 0;
- try
- {
- if (c->GetParam("LIMIT", Limit))
- limit = convertTo<unsigned>(Limit);
- }
- catch (const ConvertException &) { }
+ if (c->GetParam("LIMIT", Limit))
+ limit = Anope::Convert<unsigned>(Limit, limit);
/* Should we be invited? */
if (c->HasMode("INVITE") || (limit && c->users.size() >= limit))
diff --git a/modules/botserv/bs_badwords.cpp b/modules/botserv/bs_badwords.cpp
index 5dee8ed2c..09e96564b 100644
--- a/modules/botserv/bs_badwords.cpp
+++ b/modules/botserv/bs_badwords.cpp
@@ -222,7 +222,7 @@ private:
const BadWord *b = bw->GetBadWord(Number - 1);
ListFormatter::ListEntry entry;
- entry["Number"] = stringify(Number);
+ entry["Number"] = Anope::ToString(Number);
entry["Word"] = b->word;
entry["Type"] = b->type == BW_SINGLE ? "(SINGLE)" : (b->type == BW_START ? "(START)" : (b->type == BW_END ? "(END)" : ""));
this->list.AddEntry(entry);
@@ -241,7 +241,7 @@ private:
continue;
ListFormatter::ListEntry entry;
- entry["Number"] = stringify(i + 1);
+ entry["Number"] = Anope::ToString(i + 1);
entry["Word"] = b->word;
entry["Type"] = b->type == BW_SINGLE ? "(SINGLE)" : (b->type == BW_START ? "(START)" : (b->type == BW_END ? "(END)" : ""));
list.AddEntry(entry);
diff --git a/modules/botserv/bs_info.cpp b/modules/botserv/bs_info.cpp
index c8e05577b..b4a5592b1 100644
--- a/modules/botserv/bs_info.cpp
+++ b/modules/botserv/bs_info.cpp
@@ -55,7 +55,7 @@ public:
info[_("Real name")] = bi->realname;
info[_("Created")] = Anope::strftime(bi->created, source.GetAccount());
info[_("Options")] = bi->oper_only ? _("Private") : _("None");
- info[_("Used on")] = stringify(bi->GetChannelCount()) + " channel(s)";
+ info[_("Used on")] = Anope::ToString(bi->GetChannelCount()) + " channel(s)";
FOREACH_MOD(OnBotInfo, (source, bi, ci, info));
diff --git a/modules/botserv/bs_kick.cpp b/modules/botserv/bs_kick.cpp
index 29c8cb598..9183eae22 100644
--- a/modules/botserv/bs_kick.cpp
+++ b/modules/botserv/bs_kick.cpp
@@ -106,11 +106,10 @@ struct KickerDataImpl final
data["ttb"] >> ttb;
spacesepstream sep(ttb);
for (int i = 0; sep.GetToken(tok) && i < TTB_SIZE; ++i)
- try
- {
- kd->ttb[i] = convertTo<int16_t>(tok);
- }
- catch (const ConvertException &) { }
+ {
+ if (auto n = Anope::TryConvert<int16_t>(tok))
+ kd->ttb[i] = n.value();
+ }
kd->Check(ci);
}
@@ -206,21 +205,13 @@ protected:
{
if (!ttb.empty())
{
- int16_t i;
-
- try
- {
- i = convertTo<int16_t>(ttb);
- if (i < 0)
- throw ConvertException();
- }
- catch (const ConvertException &)
+ kd->ttb[ttb_idx] = Anope::Convert<int16_t>(ttb, -1);
+ if (kd->ttb[ttb_idx] < 0)
{
+ kd->ttb[ttb_idx] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return;
}
-
- kd->ttb[ttb_idx] = i;
}
else
kd->ttb[ttb_idx] = 0;
@@ -386,13 +377,8 @@ public:
if (!ttb.empty())
{
- try
- {
- kd->ttb[TTB_CAPS] = convertTo<int16_t>(ttb);
- if (kd->ttb[TTB_CAPS] < 0)
- throw ConvertException();
- }
- catch (const ConvertException &)
+ kd->ttb[TTB_CAPS] = Anope::Convert<int16_t>(ttb, -1);
+ if (kd->ttb[TTB_CAPS] < 0)
{
kd->ttb[TTB_CAPS] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
@@ -402,21 +388,11 @@ public:
else
kd->ttb[TTB_CAPS] = 0;
- kd->capsmin = 10;
- try
- {
- kd->capsmin = convertTo<int16_t>(min);
- }
- catch (const ConvertException &) { }
+ kd->capsmin = Anope::Convert(min, 0);
if (kd->capsmin < 1)
kd->capsmin = 10;
- kd->capspercent = 25;
- try
- {
- kd->capspercent = convertTo<int16_t>(percent);
- }
- catch (const ConvertException &) { }
+ kd->capspercent = Anope::Convert(percent, 0);
if (kd->capspercent < 1 || kd->capspercent > 100)
kd->capspercent = 25;
@@ -518,42 +494,25 @@ public:
if (!ttb.empty())
{
- int16_t i;
-
- try
- {
- i = convertTo<int16_t>(ttb);
- if (i < 0)
- throw ConvertException();
- }
- catch (const ConvertException &)
+ kd->ttb[TTB_FLOOD] = Anope::Convert<int16_t>(ttb, -1);
+ if (kd->ttb[TTB_FLOOD] < 0)
{
+ kd->ttb[TTB_FLOOD] = 0;
source.Reply(_("\002%s\002 cannot be taken as times to ban."), ttb.c_str());
return;
}
-
- kd->ttb[TTB_FLOOD] = i;
}
else
kd->ttb[TTB_FLOOD] = 0;
- kd->floodlines = 6;
- try
- {
- kd->floodlines = convertTo<int16_t>(lines);
- }
- catch (const ConvertException &) { }
+ kd->floodlines = Anope::Convert(lines, -1);
if (kd->floodlines < 2)
kd->floodlines = 6;
- kd->floodsecs = 10;
- try
- {
- kd->floodsecs = convertTo<int16_t>(secs);
- }
- catch (const ConvertException &) { }
+ kd->floodsecs = Anope::Convert(secs, -1);
if (kd->floodsecs < 1)
kd->floodsecs = 10;
+
if (kd->floodsecs > Config->GetModule(me)->Get<time_t>("keepdata"))
kd->floodsecs = Config->GetModule(me)->Get<time_t>("keepdata");
@@ -651,31