From d130696e95f83a2b7cd38258034cebf7edb890f3 Mon Sep 17 00:00:00 2001 From: flx5 Date: Wed, 11 Mar 2015 04:14:17 +0100 Subject: Fixes #493 and #490 --- src/Bindings/ManualBindings.cpp | 16 ++++++++++++++++ src/Bindings/Plugin.h | 4 ++-- src/Bindings/PluginLua.cpp | 8 ++++---- src/Bindings/PluginLua.h | 4 ++-- src/Bindings/PluginManager.cpp | 6 +++--- src/Bindings/PluginManager.h | 2 +- src/Server.cpp | 2 +- src/StringUtils.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/StringUtils.h | 5 +++++ 9 files changed, 73 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index cac81f325..435d72eb9 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -266,6 +266,21 @@ static int tolua_StringSplit(lua_State * tolua_S) +static int tolua_StringSplitWithQuotes(lua_State * tolua_S) +{ + cLuaState LuaState(tolua_S); + std::string str = (std::string)tolua_tocppstring(LuaState, 1, 0); + std::string delim = (std::string)tolua_tocppstring(LuaState, 2, 0); + + AStringVector Split = StringSplitWithQuotes(str, delim); + LuaState.Push(Split); + return 1; +} + + + + + static int tolua_StringSplitAndTrim(lua_State * tolua_S) { cLuaState LuaState(tolua_S); @@ -3663,6 +3678,7 @@ void ManualBindings::Bind(lua_State * tolua_S) // Globals: tolua_function(tolua_S, "Clamp", tolua_Clamp); tolua_function(tolua_S, "StringSplit", tolua_StringSplit); + tolua_function(tolua_S, "StringSplitWithQuotes", tolua_StringSplitWithQuotes); tolua_function(tolua_S, "StringSplitAndTrim", tolua_StringSplitAndTrim); tolua_function(tolua_S, "LOG", tolua_LOG); tolua_function(tolua_S, "LOGINFO", tolua_LOGINFO); diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 6ade8ef9f..56277a68b 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -111,12 +111,12 @@ public: Command permissions have already been checked. Returns true if command handled successfully */ - virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player) = 0; + virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player, const AString & fullCommand) = 0; /** Handles the console command split into a_Split. Returns true if command handled successfully. Output is to be sent to the a_Output callback. */ - virtual bool HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output) = 0; + virtual bool HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & fullCommand) = 0; /// All bound commands are to be removed, do any language-dependent cleanup here virtual void ClearCommands(void) {} diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index fb7650d42..2026ef966 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1465,7 +1465,7 @@ bool cPluginLua::OnWorldTick(cWorld & a_World, std::chrono::milliseconds a_Dt, s -bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer & a_Player) +bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer & a_Player, const AString & fullCommand) { ASSERT(!a_Split.empty()); CommandMap::iterator cmd = m_Commands.find(a_Split[0]); @@ -1477,7 +1477,7 @@ bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer & a_Player cCSLock Lock(m_CriticalSection); bool res = false; - m_LuaState.Call(cmd->second, a_Split, &a_Player, cLuaState::Return, res); + m_LuaState.Call(cmd->second, a_Split, &a_Player, fullCommand, cLuaState::Return, res); return res; } @@ -1485,7 +1485,7 @@ bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer & a_Player -bool cPluginLua::HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output) +bool cPluginLua::HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & fullCommand) { ASSERT(!a_Split.empty()); CommandMap::iterator cmd = m_ConsoleCommands.find(a_Split[0]); @@ -1500,7 +1500,7 @@ bool cPluginLua::HandleConsoleCommand(const AStringVector & a_Split, cCommandOut cCSLock Lock(m_CriticalSection); bool res = false; AString str; - m_LuaState.Call(cmd->second, a_Split, cLuaState::Return, res, str); + m_LuaState.Call(cmd->second, a_Split, fullCommand, cLuaState::Return, res, str); if (res && !str.empty()) { a_Output.Out(str); diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 7b528501b..6fdb66553 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -131,9 +131,9 @@ public: virtual bool OnWorldStarted (cWorld & a_World) override; virtual bool OnWorldTick (cWorld & a_World, std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec) override; - virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player) override; + virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player, const AString & fullCommand) override; - virtual bool HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output) override; + virtual bool HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & fullCommand) override; virtual void ClearCommands(void) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 41b36337e..8935f7dd3 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1465,7 +1465,7 @@ cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer & a_Player, ASSERT(cmd->second.m_Plugin != nullptr); - if (!cmd->second.m_Plugin->HandleCommand(Split, a_Player)) + if (!cmd->second.m_Plugin->HandleCommand(Split, a_Player, a_Command)) { return crError; } @@ -1768,7 +1768,7 @@ bool cPluginManager::IsConsoleCommandBound(const AString & a_Command) -bool cPluginManager::ExecuteConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output) +bool cPluginManager::ExecuteConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & a_Command) { if (a_Split.empty()) { @@ -1795,7 +1795,7 @@ bool cPluginManager::ExecuteConsoleCommand(const AStringVector & a_Split, cComma return false; } - return cmd->second.m_Plugin->HandleConsoleCommand(a_Split, a_Output); + return cmd->second.m_Plugin->HandleConsoleCommand(a_Split, a_Output, a_Command); } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index c8b4de9d6..4efcbb6f3 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -284,7 +284,7 @@ public: bool IsConsoleCommandBound(const AString & a_Command); // tolua_export /** Executes the command split into a_Split, as if it was given on the console. Returns true if executed. Output is sent to the a_Output callback */ - bool ExecuteConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output); + bool ExecuteConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & a_Command); /** Appends all commands beginning with a_Text (case-insensitive) into a_Results. If a_Player is not nullptr, only commands for which the player has permissions are added. diff --git a/src/Server.cpp b/src/Server.cpp index 3f61be378..df2c7deef 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -549,7 +549,7 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac } #endif - else if (cPluginManager::Get()->ExecuteConsoleCommand(split, a_Output)) + else if (cPluginManager::Get()->ExecuteConsoleCommand(split, a_Output, a_Cmd)) { a_Output.Finished(); return; diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 4eb2d48b6..db406369b 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -140,6 +140,45 @@ AStringVector StringSplit(const AString & str, const AString & delim) +AStringVector StringSplitWithQuotes(const AString & str, const AString & delim) +{ + AStringVector results; + + size_t cutAt = 0; + size_t Prev = 0; + + while ((cutAt = str.find_first_of(delim, Prev)) != str.npos) + { + AString current = str.substr(Prev, cutAt - Prev); + if (current.at(0) == '"' || current.at(0) == '\'') { + Prev += 1; + cutAt = str.find_first_of(current.at(0), Prev); + if (cutAt != str.npos) { + current = str.substr(Prev, cutAt - Prev); + cutAt += 1; + } + } + + results.push_back(current); + Prev = cutAt + 1; + } + + if (Prev < str.length()) + { + AString current = str.substr(Prev); + + if (current.length() >= 2 && (current.front() == '"' || current.front() == '\'') && current.front() == current.back()) { + current = current.substr(1, current.length() - 2); + } + + results.push_back(current); + } + + return results; +} + + + AStringVector StringSplitAndTrim(const AString & str, const AString & delim) { diff --git a/src/StringUtils.h b/src/StringUtils.h index bc3bb7a2c..785197763 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -41,6 +41,11 @@ extern AString & AppendPrintf (AString & a_Dst, const char * format, ...) FORMAT Return the splitted strings as a stringvector. */ extern AStringVector StringSplit(const AString & str, const AString & delim); +/** Split the string at any of the listed delimiters. Keeps quoted content together +Resolves issue #490 +Return the splitted strings as a stringvector. */ +extern AStringVector StringSplitWithQuotes(const AString & str, const AString & delim); + /** Split the string at any of the listed delimiters and trim each value. Returns the splitted strings as a stringvector. */ extern AStringVector StringSplitAndTrim(const AString & str, const AString & delim); -- cgit v1.2.3 From 451ab6860fcdf53f4e4057465acd8712aea48bce Mon Sep 17 00:00:00 2001 From: flx5 Date: Wed, 11 Mar 2015 04:33:17 +0100 Subject: Fixed some markup issues --- src/StringUtils.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index db406369b..084a42280 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -150,10 +150,12 @@ AStringVector StringSplitWithQuotes(const AString & str, const AString & delim) while ((cutAt = str.find_first_of(delim, Prev)) != str.npos) { AString current = str.substr(Prev, cutAt - Prev); - if (current.at(0) == '"' || current.at(0) == '\'') { + if ((current.at(0) == '"') || (current.at(0) == '\'')) + { Prev += 1; cutAt = str.find_first_of(current.at(0), Prev); - if (cutAt != str.npos) { + if (cutAt != str.npos) + { current = str.substr(Prev, cutAt - Prev); cutAt += 1; } @@ -167,7 +169,7 @@ AStringVector StringSplitWithQuotes(const AString & str, const AString & delim) { AString current = str.substr(Prev); - if (current.length() >= 2 && (current.front() == '"' || current.front() == '\'') && current.front() == current.back()) { + if ((current.length() >= 2) && ((current.front() == '"') || (current.front() == '\'')) && (current.front() == current.back())) { current = current.substr(1, current.length() - 2); } -- cgit v1.2.3 From 76012ee090c7e500ef47c3b4114a386cad176bd9 Mon Sep 17 00:00:00 2001 From: flx5 Date: Wed, 11 Mar 2015 04:38:15 +0100 Subject: Fixed some markup issues --- src/StringUtils.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 084a42280..343f93ce3 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -150,11 +150,11 @@ AStringVector StringSplitWithQuotes(const AString & str, const AString & delim) while ((cutAt = str.find_first_of(delim, Prev)) != str.npos) { AString current = str.substr(Prev, cutAt - Prev); - if ((current.at(0) == '"') || (current.at(0) == '\'')) + if ((current.at(0) == '"') || (current.at(0) == '\'')) { Prev += 1; cutAt = str.find_first_of(current.at(0), Prev); - if (cutAt != str.npos) + if (cutAt != str.npos) { current = str.substr(Prev, cutAt - Prev); cutAt += 1; @@ -169,7 +169,8 @@ AStringVector StringSplitWithQuotes(const AString & str, const AString & delim) { AString current = str.substr(Prev); - if ((current.length() >= 2) && ((current.front() == '"') || (current.front() == '\'')) && (current.front() == current.back())) { + if ((current.length() >= 2) && ((current.front() == '"') || (current.front() == '\'')) && (current.front() == current.back())) + { current = current.substr(1, current.length() - 2); } -- cgit v1.2.3 From d8ab99e944f90dffcaa597b030c6475a675679b2 Mon Sep 17 00:00:00 2001 From: flx5 Date: Wed, 11 Mar 2015 19:52:49 +0100 Subject: Fixed issue with quotes not appearing in pairs --- src/StringUtils.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 343f93ce3..47fb6e5a1 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -146,6 +146,7 @@ AStringVector StringSplitWithQuotes(const AString & str, const AString & delim) size_t cutAt = 0; size_t Prev = 0; + size_t cutAtQuote = 0; while ((cutAt = str.find_first_of(delim, Prev)) != str.npos) { @@ -153,11 +154,11 @@ AStringVector StringSplitWithQuotes(const AString & str, const AString & delim) if ((current.at(0) == '"') || (current.at(0) == '\'')) { Prev += 1; - cutAt = str.find_first_of(current.at(0), Prev); - if (cutAt != str.npos) + cutAtQuote = str.find_first_of(current.at(0), Prev); + if (cutAtQuote != str.npos) { - current = str.substr(Prev, cutAt - Prev); - cutAt += 1; + current = str.substr(Prev, cutAtQuote - Prev); + cutAt = cutAtQuote + 1; } } -- cgit v1.2.3 From f6912bd01c80a1031c1d0f69a87eca4f0990da66 Mon Sep 17 00:00:00 2001 From: flx5 Date: Wed, 11 Mar 2015 20:02:11 +0100 Subject: Fixed coding conventions for Pull Request #1807 --- src/Bindings/ManualBindings.cpp | 33 ++++++++++++++++++--------------- src/Bindings/Plugin.h | 4 ++-- src/Bindings/PluginLua.cpp | 8 ++++---- src/Bindings/PluginLua.h | 4 ++-- src/StringUtils.cpp | 7 ++++++- 5 files changed, 32 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 435d72eb9..40ac12b41 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -268,12 +268,15 @@ static int tolua_StringSplit(lua_State * tolua_S) static int tolua_StringSplitWithQuotes(lua_State * tolua_S) { - cLuaState LuaState(tolua_S); - std::string str = (std::string)tolua_tocppstring(LuaState, 1, 0); - std::string delim = (std::string)tolua_tocppstring(LuaState, 2, 0); + cLuaState S(tolua_S); + + AString str; + AString delim; + + S.GetStackValues(1, str, delim); AStringVector Split = StringSplitWithQuotes(str, delim); - LuaState.Push(Split); + S.Push(Split); return 1; } @@ -3676,18 +3679,18 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_cclass(tolua_S, "cStringCompression", "cStringCompression", "", nullptr); // Globals: - tolua_function(tolua_S, "Clamp", tolua_Clamp); - tolua_function(tolua_S, "StringSplit", tolua_StringSplit); + tolua_function(tolua_S, "Clamp", tolua_Clamp); + tolua_function(tolua_S, "StringSplit", tolua_StringSplit); tolua_function(tolua_S, "StringSplitWithQuotes", tolua_StringSplitWithQuotes); - tolua_function(tolua_S, "StringSplitAndTrim", tolua_StringSplitAndTrim); - tolua_function(tolua_S, "LOG", tolua_LOG); - tolua_function(tolua_S, "LOGINFO", tolua_LOGINFO); - tolua_function(tolua_S, "LOGWARN", tolua_LOGWARN); - tolua_function(tolua_S, "LOGWARNING", tolua_LOGWARN); - tolua_function(tolua_S, "LOGERROR", tolua_LOGERROR); - tolua_function(tolua_S, "Base64Encode", tolua_Base64Encode); - tolua_function(tolua_S, "Base64Decode", tolua_Base64Decode); - tolua_function(tolua_S, "md5", tolua_md5_obsolete); // OBSOLETE, use cCryptoHash.md5() instead + tolua_function(tolua_S, "StringSplitAndTrim", tolua_StringSplitAndTrim); + tolua_function(tolua_S, "LOG", tolua_LOG); + tolua_function(tolua_S, "LOGINFO", tolua_LOGINFO); + tolua_function(tolua_S, "LOGWARN", tolua_LOGWARN); + tolua_function(tolua_S, "LOGWARNING", tolua_LOGWARN); + tolua_function(tolua_S, "LOGERROR", tolua_LOGERROR); + tolua_function(tolua_S, "Base64Encode", tolua_Base64Encode); + tolua_function(tolua_S, "Base64Decode", tolua_Base64Decode); + tolua_function(tolua_S, "md5", tolua_md5_obsolete); // OBSOLETE, use cCryptoHash.md5() instead tolua_beginmodule(tolua_S, "cFile"); tolua_function(tolua_S, "GetFolderContents", tolua_cFile_GetFolderContents); diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 56277a68b..3f9fa7655 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -111,12 +111,12 @@ public: Command permissions have already been checked. Returns true if command handled successfully */ - virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player, const AString & fullCommand) = 0; + virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player, const AString & a_FullCommand) = 0; /** Handles the console command split into a_Split. Returns true if command handled successfully. Output is to be sent to the a_Output callback. */ - virtual bool HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & fullCommand) = 0; + virtual bool HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & a_FullCommand) = 0; /// All bound commands are to be removed, do any language-dependent cleanup here virtual void ClearCommands(void) {} diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 2026ef966..263d1f005 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1465,7 +1465,7 @@ bool cPluginLua::OnWorldTick(cWorld & a_World, std::chrono::milliseconds a_Dt, s -bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer & a_Player, const AString & fullCommand) +bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer & a_Player, const AString & a_FullCommand) { ASSERT(!a_Split.empty()); CommandMap::iterator cmd = m_Commands.find(a_Split[0]); @@ -1477,7 +1477,7 @@ bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer & a_Player cCSLock Lock(m_CriticalSection); bool res = false; - m_LuaState.Call(cmd->second, a_Split, &a_Player, fullCommand, cLuaState::Return, res); + m_LuaState.Call(cmd->second, a_Split, &a_Player, a_FullCommand, cLuaState::Return, res); return res; } @@ -1485,7 +1485,7 @@ bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer & a_Player -bool cPluginLua::HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & fullCommand) +bool cPluginLua::HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & a_FullCommand) { ASSERT(!a_Split.empty()); CommandMap::iterator cmd = m_ConsoleCommands.find(a_Split[0]); @@ -1500,7 +1500,7 @@ bool cPluginLua::HandleConsoleCommand(const AStringVector & a_Split, cCommandOut cCSLock Lock(m_CriticalSection); bool res = false; AString str; - m_LuaState.Call(cmd->second, a_Split, fullCommand, cLuaState::Return, res, str); + m_LuaState.Call(cmd->second, a_Split, a_FullCommand, cLuaState::Return, res, str); if (res && !str.empty()) { a_Output.Out(str); diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 6fdb66553..4f3529fc9 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -131,9 +131,9 @@ public: virtual bool OnWorldStarted (cWorld & a_World) override; virtual bool OnWorldTick (cWorld & a_World, std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec) override; - virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player, const AString & fullCommand) override; + virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player, const AString & a_FullCommand) override; - virtual bool HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & fullCommand) override; + virtual bool HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & a_FullCommand) override; virtual void ClearCommands(void) override; diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 47fb6e5a1..95b3c7400 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -170,7 +170,12 @@ AStringVector StringSplitWithQuotes(const AString & str, const AString & delim) { AString current = str.substr(Prev); - if ((current.length() >= 2) && ((current.front() == '"') || (current.front() == '\'')) && (current.front() == current.back())) + // If the remant is wrapped in matching quotes, remove them: + if ( + (current.length() >= 2) && + ((current.front() == '"') || (current.front() == '\'')) && + (current.front() == current.back()) + ) { current = current.substr(1, current.length() - 2); } -- cgit v1.2.3