Add ConfigParser::getEnum for parsing enum values.

This commit is contained in:
Sadie Powell 2020-05-13 14:09:38 +01:00
parent 6c24f71abf
commit 437c2045ad
6 changed files with 69 additions and 74 deletions

View File

@ -71,6 +71,23 @@ class CoreExport ConfigTag : public refcountbase
*/
unsigned long getDuration(const std::string& key, unsigned long def, unsigned long min = 0, unsigned long max = ULONG_MAX) const;
template<typename TReturn>
TReturn getEnum(const std::string& key, TReturn def, std::initializer_list<std::pair<const char*, TReturn>> enumvals)
{
const std::string val = getString(key);
if (val.empty())
return def;
for (const std::pair<const char*, TReturn>& enumval : enumvals)
if (stdalgo::string::equalsci(val, enumval.first))
return enumval.second;
std::vector<const char*> enumkeys;
std::transform(enumvals.begin(), enumvals.end(), std::back_inserter(enumkeys), [](const std::pair<const char*, TReturn>& ev) { return ev.first; });
throw ModuleException(val + " is an invalid value for <" + tag + ":" + key + ">; acceptable values are " +
stdalgo::string::join(enumkeys, ' ') + ", at " + getTagLocation());
}
/** Get the value of an option
* @param key The option to get
* @param value The location to store the value (unmodified if does not exist)

View File

@ -178,18 +178,12 @@ class CoreModChannel
}
ConfigTag* securitytag = ServerInstance->Config->ConfValue("security");
const std::string announceinvites = securitytag->getString("announceinvites", "dynamic", 1);
Invite::AnnounceState newannouncestate;
if (stdalgo::string::equalsci(announceinvites, "none"))
newannouncestate = Invite::ANNOUNCE_NONE;
else if (stdalgo::string::equalsci(announceinvites, "all"))
newannouncestate = Invite::ANNOUNCE_ALL;
else if (stdalgo::string::equalsci(announceinvites, "ops"))
newannouncestate = Invite::ANNOUNCE_OPS;
else if (stdalgo::string::equalsci(announceinvites, "dynamic"))
newannouncestate = Invite::ANNOUNCE_DYNAMIC;
else
throw ModuleException(announceinvites + " is an invalid <security:announceinvites> value, at " + securitytag->getTagLocation());
Invite::AnnounceState newannouncestate = securitytag->getEnum("announceinvites", Invite::ANNOUNCE_DYNAMIC, {
{ "all", Invite::ANNOUNCE_NONE },
{ "dynamic", Invite::ANNOUNCE_ALL },
{ "none", Invite::ANNOUNCE_NONE },
{ "ops", Invite::ANNOUNCE_OPS },
});
// Config is valid, apply it

View File

@ -364,21 +364,15 @@ class CoreModWhois : public Module
void ReadConfig(ConfigStatus&) override
{
ConfigTag* tag = ServerInstance->Config->ConfValue("options");
const std::string splitwhois = tag->getString("splitwhois", "no", 1);
SplitWhoisState newsplitstate;
if (stdalgo::string::equalsci(splitwhois, "no"))
newsplitstate = SPLITWHOIS_NONE;
else if (stdalgo::string::equalsci(splitwhois, "split"))
newsplitstate = SPLITWHOIS_SPLIT;
else if (stdalgo::string::equalsci(splitwhois, "splitmsg"))
newsplitstate = SPLITWHOIS_SPLITMSG;
else
throw ModuleException(splitwhois + " is an invalid <options:splitwhois> value, at " + tag->getTagLocation());
ConfigTag* options = ServerInstance->Config->ConfValue("options");
cmd.splitwhois = options->getEnum("splitwhois", SPLITWHOIS_NONE, {
{ "no", SPLITWHOIS_NONE },
{ "split", SPLITWHOIS_SPLIT },
{ "splitmsg", SPLITWHOIS_SPLITMSG },
});
ConfigTag* security = ServerInstance->Config->ConfValue("security");
cmd.genericoper = security->getBool("genericoper");
cmd.splitwhois = newsplitstate;
}
};

View File

@ -62,19 +62,15 @@ class ModuleBlockAmsg : public Module
void ReadConfig(ConfigStatus& status) override
{
ConfigTag* tag = ServerInstance->Config->ConfValue("blockamsg");
ForgetDelay = tag->getDuration("delay", 3);
std::string act = tag->getString("action");
action = tag->getEnum("action", IBLOCK_KILLOPERS, {
{ "kill", IBLOCK_KILL },
{ "killopers", IBLOCK_KILLOPERS },
{ "notice", IBLOCK_NOTICE },
{ "noticeopers", IBLOCK_NOTICEOPERS },
{ "silent", IBLOCK_SILENT }
});
if (stdalgo::string::equalsci(act, "notice"))
action = IBLOCK_NOTICE;
else if (stdalgo::string::equalsci(act, "noticeopers"))
action = IBLOCK_NOTICEOPERS;
else if (stdalgo::string::equalsci(act, "silent"))
action = IBLOCK_SILENT;
else if (stdalgo::string::equalsci(act, "kill"))
action = IBLOCK_KILL;
else
action = IBLOCK_KILLOPERS;
ForgetDelay = tag->getDuration("delay", 3);
}
ModResult OnPreCommand(std::string& command, CommandBase::Params& parameters, LocalUser* user, bool validated) override

View File

@ -39,6 +39,19 @@ enum
ERR_KNOCKONCHAN = 714
};
// Actions which can be taken when a user knocks on a channel.
enum KnockNotify : uint8_t
{
// Send a notice when a user knocks on a channel.
KN_SEND_NOTICE = 1,
// Send a numeric when a user knocks on a channel.
KN_SEND_NUMERIC = 2,
// Send a notice and a numeric when a user knocks on a channel.
KN_SEND_BOTH = KN_SEND_NOTICE | KN_SEND_NUMERIC,
};
/** Handles the /KNOCK command
*/
class CommandKnock : public Command
@ -47,8 +60,8 @@ class CommandKnock : public Command
ChanModeReference inviteonlymode;
public:
bool sendnotice;
bool sendnumeric;
int notify;
CommandKnock(Module* Creator, SimpleChannelModeHandler& Noknockmode)
: Command(Creator,"KNOCK", 2, 2)
, noknockmode(Noknockmode)
@ -85,13 +98,13 @@ class CommandKnock : public Command
return CMD_FAILURE;
}
if (sendnotice)
if (notify & KN_SEND_NOTICE)
{
c->WriteNotice(InspIRCd::Format("User %s is KNOCKing on %s (%s)", user->nick.c_str(), c->name.c_str(), parameters[1].c_str()));
user->WriteNotice("KNOCKing on " + c->name);
}
if (sendnumeric)
if (notify & KN_SEND_NUMERIC)
{
Numeric::Numeric numeric(RPL_KNOCK);
numeric.push(c->name).push(user->GetFullHost()).push("is KNOCKing: " + parameters[1]);
@ -126,22 +139,12 @@ class ModuleKnock : public Module
void ReadConfig(ConfigStatus& status) override
{
std::string knocknotify = ServerInstance->Config->ConfValue("knock")->getString("notify");
if (stdalgo::string::equalsci(knocknotify, "numeric"))
{
cmd.sendnotice = false;
cmd.sendnumeric = true;
}
else if (stdalgo::string::equalsci(knocknotify, "both"))
{
cmd.sendnotice = true;
cmd.sendnumeric = true;
}
else
{
cmd.sendnotice = true;
cmd.sendnumeric = false;
}
ConfigTag* tag = ServerInstance->Config->ConfValue("knock");
cmd.notify = tag->getEnum("notify", KN_SEND_NOTICE, {
{ "both", KN_SEND_BOTH },
{ "notice", KN_SEND_NOTICE },
{ "numeric", KN_SEND_NUMERIC },
});
}
};

View File

@ -71,25 +71,16 @@ class ModuleRegexStd : public Module
void ReadConfig(ConfigStatus& status) override
{
ConfigTag* Conf = ServerInstance->Config->ConfValue("stdregex");
const std::string regextype = Conf->getString("type", "ecmascript", 1);
if (stdalgo::string::equalsci(regextype, "bre"))
ref.regextype = std::regex::basic;
else if (stdalgo::string::equalsci(regextype, "ere"))
ref.regextype = std::regex::extended;
else if (stdalgo::string::equalsci(regextype, "awk"))
ref.regextype = std::regex::awk;
else if (stdalgo::string::equalsci(regextype, "grep"))
ref.regextype = std::regex::grep;
else if (stdalgo::string::equalsci(regextype, "egrep"))
ref.regextype = std::regex::egrep;
else
ConfigTag* tag = ServerInstance->Config->ConfValue("stdregex");
ref.regextype = tag->getEnum("type", std::regex::ECMAScript,
{
if (!stdalgo::string::equalsci(regextype, "ecmascript"))
ServerInstance->SNO.WriteToSnoMask('a', "WARNING: Nonexistent regex engine '%s' specified. Falling back to ECMAScript.", regextype.c_str());
ref.regextype = std::regex::ECMAScript;
}
{ "awk", std::regex::awk },
{ "bre", std::regex::basic },
{ "ecmascript", std::regex::ECMAScript },
{ "egrep", std::regex::egrep },
{ "ere", std::regex::extended },
{ "grep", std::regex::grep },
});
}
};