From b5bc73e31026ee2087f0ceb5c7d9f99bf3c288a6 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Thu, 19 Dec 2013 17:30:22 +0100 Subject: [PATCH] Add functor that does strict weak ordering based on national_case_insensitive_map --- include/hashcomp.h | 5 +++++ src/hashcomp.cpp | 19 +++++++++++++++++++ src/modules/m_alias.cpp | 32 ++++++++++++++++---------------- src/modules/m_helpop.cpp | 20 +++++++++++--------- src/modules/m_restrictchans.cpp | 8 +++----- 5 files changed, 54 insertions(+), 30 deletions(-) diff --git a/include/hashcomp.h b/include/hashcomp.h index 0bf306267..de556f393 100644 --- a/include/hashcomp.h +++ b/include/hashcomp.h @@ -114,6 +114,11 @@ namespace irc size_t CoreExport operator()(const std::string &s) const; }; + struct insensitive_swo + { + bool CoreExport operator()(const std::string& a, const std::string& b) const; + }; + /** The irc_char_traits class is used for RFC-style comparison of strings. * This class is used to implement irc::string, a case-insensitive, RFC- * comparing string class. diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp index 4eb416406..f1d0f0678 100644 --- a/src/hashcomp.cpp +++ b/src/hashcomp.cpp @@ -170,6 +170,25 @@ bool irc::StrHashComp::operator()(const std::string& s1, const std::string& s2) return (national_case_insensitive_map[*n1] == national_case_insensitive_map[*n2]); } +bool irc::insensitive_swo::operator()(const std::string& a, const std::string& b) const +{ + const unsigned char* charmap = national_case_insensitive_map; + std::string::size_type asize = a.size(); + std::string::size_type bsize = b.size(); + std::string::size_type maxsize = std::min(asize, bsize); + + for (std::string::size_type i = 0; i < maxsize; i++) + { + unsigned char A = charmap[(unsigned char)a[i]]; + unsigned char B = charmap[(unsigned char)b[i]]; + if (A > B) + return false; + else if (A < B) + return true; + } + return (asize < bsize); +} + size_t irc::insensitive::operator()(const std::string &s) const { /* XXX: NO DATA COPIES! :) diff --git a/src/modules/m_alias.cpp b/src/modules/m_alias.cpp index b0fda70bb..78628cf06 100644 --- a/src/modules/m_alias.cpp +++ b/src/modules/m_alias.cpp @@ -28,7 +28,7 @@ class Alias { public: /** The text of the alias command */ - irc::string AliasedCommand; + std::string AliasedCommand; /** Text to replace with */ std::string ReplaceFormat; @@ -63,7 +63,9 @@ class ModuleAlias : public Module * We can, however, use a fancy invention: the multimap. Maps a key to one or more values. * -- w00t */ - std::multimap Aliases; + typedef std::multimap AliasMap; + + AliasMap Aliases; /* whether or not +B users are allowed to use fantasy commands */ bool AllowBots; @@ -83,8 +85,8 @@ class ModuleAlias : public Module { ConfigTag* tag = i->second; Alias a; - std::string aliastext = tag->getString("text"); - a.AliasedCommand = aliastext.c_str(); + a.AliasedCommand = tag->getString("text"); + std::transform(a.AliasedCommand.begin(), a.AliasedCommand.end(), a.AliasedCommand.begin(), ::toupper); tag->readString("replace", a.ReplaceFormat, true); a.RequiredNick = tag->getString("requires"); a.ULineOnly = tag->getBool("uline"); @@ -134,7 +136,7 @@ class ModuleAlias : public Module ModResult OnPreCommand(std::string &command, std::vector ¶meters, LocalUser *user, bool validated, const std::string &original_line) CXX11_OVERRIDE { - std::multimap::iterator i, upperbound; + AliasMap::iterator i, upperbound; /* If theyre not registered yet, we dont want * to know. @@ -143,13 +145,12 @@ class ModuleAlias : public Module return MOD_RES_PASSTHRU; /* We dont have any commands looking like this? Stop processing. */ - i = Aliases.find(command.c_str()); + i = Aliases.find(command); if (i == Aliases.end()) return MOD_RES_PASSTHRU; /* Avoid iterating on to different aliases if no patterns match. */ - upperbound = Aliases.upper_bound(command.c_str()); + upperbound = Aliases.upper_bound(command); - irc::string c = command.c_str(); /* The parameters for the command in their original form, with the command stripped off */ std::string compare = original_line.substr(command.length()); while (*(compare.c_str()) == ' ') @@ -197,33 +198,32 @@ class ModuleAlias : public Module // text is like "!moo cows bite me", we want "!moo" first irc::spacesepstream ss(text); ss.GetToken(scommand); - irc::string fcommand = scommand.c_str(); - if (fcommand.empty()) + if (scommand.empty()) { return; // wtfbbq } // we don't want to touch non-fantasy stuff - if (*fcommand.c_str() != fprefix) + if (*scommand.c_str() != fprefix) { return; } // nor do we give a shit about the prefix - fcommand.erase(fcommand.begin()); + scommand.erase(scommand.begin()); - std::multimap::iterator i = Aliases.find(fcommand); + AliasMap::iterator i = Aliases.find(scommand); if (i == Aliases.end()) return; /* Avoid iterating on to other aliases if no patterns match */ - std::multimap::iterator upperbound = Aliases.upper_bound(fcommand); + AliasMap::iterator upperbound = Aliases.upper_bound(scommand); /* The parameters for the command in their original form, with the command stripped off */ - std::string compare = text.substr(fcommand.length() + 1); + std::string compare = text.substr(scommand.length() + 1); while (*(compare.c_str()) == ' ') compare.erase(compare.begin()); @@ -276,7 +276,7 @@ class ModuleAlias : public Module { if (!ServerInstance->ULine(u->server)) { - ServerInstance->SNO->WriteToSnoMask('a', "NOTICE -- Service "+a->RequiredNick+" required by alias "+std::string(a->AliasedCommand.c_str())+" is not on a u-lined server, possibly underhanded antics detected!"); + ServerInstance->SNO->WriteToSnoMask('a', "NOTICE -- Service "+a->RequiredNick+" required by alias "+a->AliasedCommand+" is not on a u-lined server, possibly underhanded antics detected!"); user->WriteNumeric(ERR_NOSUCHNICK, a->RequiredNick + " :is an imposter! Please inform an IRC operator as soon as possible."); return 1; } diff --git a/src/modules/m_helpop.cpp b/src/modules/m_helpop.cpp index d07898c90..64bdc2400 100644 --- a/src/modules/m_helpop.cpp +++ b/src/modules/m_helpop.cpp @@ -23,7 +23,8 @@ #include "inspircd.h" -static std::map helpop_map; +typedef std::map HelpopMap; +static HelpopMap helpop_map; /** Handles user mode +h */ @@ -40,23 +41,24 @@ class Helpop : public SimpleUserModeHandler */ class CommandHelpop : public Command { + const std::string startkey; public: - CommandHelpop(Module* Creator) : Command(Creator, "HELPOP", 0) + CommandHelpop(Module* Creator) + : Command(Creator, "HELPOP", 0) + , startkey("start") { syntax = ""; } CmdResult Handle (const std::vector ¶meters, User *user) { - irc::string parameter("start"); - if (parameters.size() > 0) - parameter = parameters[0].c_str(); + const std::string& parameter = (!parameters.empty() ? parameters[0] : startkey); if (parameter == "index") { /* iterate over all helpop items */ user->WriteNumeric(290, ":HELPOP topic index"); - for (std::map::iterator iter = helpop_map.begin(); iter != helpop_map.end(); iter++) + for (HelpopMap::const_iterator iter = helpop_map.begin(); iter != helpop_map.end(); iter++) user->WriteNumeric(292, ": %s", iter->first.c_str()); user->WriteNumeric(292, ":*** End of HELPOP topic index"); } @@ -65,14 +67,14 @@ class CommandHelpop : public Command user->WriteNumeric(290, ":*** HELPOP for %s", parameter.c_str()); user->WriteNumeric(292, ": -"); - std::map::iterator iter = helpop_map.find(parameter); + HelpopMap::const_iterator iter = helpop_map.find(parameter); if (iter == helpop_map.end()) { iter = helpop_map.find("nohelp"); } - std::string value = iter->second; + const std::string& value = iter->second; irc::sepstream stream(value, '\n'); std::string token = "*"; @@ -112,7 +114,7 @@ class ModuleHelpop : public Module for(ConfigIter i = tags.first; i != tags.second; ++i) { ConfigTag* tag = i->second; - irc::string key = assign(tag->getString("key")); + std::string key = tag->getString("key"); std::string value; tag->readString("value", value, true); /* Linefeeds allowed */ diff --git a/src/modules/m_restrictchans.cpp b/src/modules/m_restrictchans.cpp index f98c8c370..b619ee448 100644 --- a/src/modules/m_restrictchans.cpp +++ b/src/modules/m_restrictchans.cpp @@ -24,7 +24,7 @@ class ModuleRestrictChans : public Module { - std::set allowchans; + std::set allowchans; public: void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE @@ -35,19 +35,17 @@ class ModuleRestrictChans : public Module { ConfigTag* tag = i->second; std::string txt = tag->getString("name"); - allowchans.insert(txt.c_str()); + allowchans.insert(txt); } } ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven) CXX11_OVERRIDE { - irc::string x(cname.c_str()); - // channel does not yet exist (record is null, about to be created IF we were to allow it) if (!chan) { // user is not an oper and its not in the allow list - if ((!user->IsOper()) && (allowchans.find(x) == allowchans.end())) + if ((!user->IsOper()) && (allowchans.find(cname) == allowchans.end())) { user->WriteNumeric(ERR_BANNEDFROMCHAN, "%s :Only IRC operators may create new channels", cname.c_str()); return MOD_RES_DENY; -- 2.39.2