summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am4
-rw-r--r--src/utils/paramerers.cpp24
-rw-r--r--src/utils/paramerers.h2
-rw-r--r--src/utils/paramerers_unittest.cc141
-rw-r--r--src/utils/stringutils.cpp15
-rw-r--r--src/utils/stringutils.h4
-rw-r--r--src/utils/stringutils_unittest.cc13
7 files changed, 164 insertions, 39 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index f0ec53a9e..756e695a8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1727,12 +1727,12 @@ manaplustests_CXXFLAGS = ${manaplus_CXXFLAGS} \
-DUNITTESTS
manaplustests_SOURCES = ${manaplus_SOURCES} \
enums/enums_unittest.cc \
- utils/paramerers_unittest.cc \
utils/xml_unittest.cc \
utils/xmlutils_unittest.cc \
utils/mathutils_unittest.cc \
- utils/stringutils_unittest.cc \
utils/files_unittest.cc \
+ utils/stringutils_unittest.cc \
+ utils/paramerers_unittest.cc \
resources/mstack_unittest.cc \
utils/translation/poparser_unittest.cc \
resources/sprite/animatedsprite_unittest.cc \
diff --git a/src/utils/paramerers.cpp b/src/utils/paramerers.cpp
index 12c20a18e..418e15ab7 100644
--- a/src/utils/paramerers.cpp
+++ b/src/utils/paramerers.cpp
@@ -31,22 +31,20 @@
static inline void addToken(StringVect &tokens,
std::string str)
{
- const size_t sz = str.size();
- std::string item;
+ std::string item = trim(str);
+ const size_t sz = item.size();
if (sz > 1)
{
if (str[0] == '\"' &&
str[sz - 1] == '\"' &&
str[sz - 2] != '\\')
{
- str = str.substr(1, sz - 2);
- item = trim(str);
+ item = item.substr(1, sz - 2);
replaceAll(item, "\\\"", "\"");
tokens.push_back(item);
return;
}
}
- item = trim(str);
replaceAll(item, "\\\"", "\"");
if (!item.empty())
tokens.push_back(item);
@@ -57,15 +55,17 @@ static inline size_t findNextQuote(const std::string &str,
const size_t pos)
{
size_t idx = str.find(quote, pos);
- if (idx == std::string::npos)
- return idx;
- while (idx > 0 && str[idx - 1] == '\\')
+ while (idx > 0 &&
+ idx != std::string::npos &&
+ str[idx - 1] == '\\')
+ {
idx = str.find(quote, idx + 1);
+ }
return idx;
}
-static inline size_t findNextSplit(std::string &str,
- const char separator,
+static inline size_t findNextSplit(const std::string &str,
+ const std::string &separator,
const char quote)
{
size_t pos = 0;
@@ -73,7 +73,7 @@ static inline size_t findNextSplit(std::string &str,
while (true)
{
// search for next separator
- idx1 = str.find(separator, pos);
+ idx1 = findAny(str, separator, pos);
// search for next open quote, skipping escaped quotes
size_t idx2 = findNextQuote(str, quote, pos);
if (idx2 == std::string::npos) // not quotes, return next separator
@@ -99,7 +99,7 @@ static inline size_t findNextSplit(std::string &str,
bool splitParameters(StringVect &tokens,
std::string text,
- const char separator,
+ const std::string &separator,
const char quote)
{
size_t idx = findNextSplit(text, separator, quote);
diff --git a/src/utils/paramerers.h b/src/utils/paramerers.h
index bdd91a9f2..d93f7a207 100644
--- a/src/utils/paramerers.h
+++ b/src/utils/paramerers.h
@@ -27,7 +27,7 @@
bool splitParameters(StringVect &tokens,
std::string text,
- const char separator,
+ const std::string &separator,
const char quote);
#endif // UTILS_PARAMETERS_H
diff --git a/src/utils/paramerers_unittest.cc b/src/utils/paramerers_unittest.cc
index 6303331e5..fbccef0e1 100644
--- a/src/utils/paramerers_unittest.cc
+++ b/src/utils/paramerers_unittest.cc
@@ -27,14 +27,14 @@
TEST_CASE("parameters basic 1")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "", ',', '\"') == true);
+ REQUIRE(splitParameters(pars, "", ",", '\"') == true);
REQUIRE(pars.size() == 0);
}
TEST_CASE("parameters basic 2")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "one,two, tree", ',', '\"') == true);
+ REQUIRE(splitParameters(pars, "one,two, tree", ",", '\"') == true);
REQUIRE(pars.size() == 3);
REQUIRE(pars[0] == "one");
REQUIRE(pars[1] == "two");
@@ -44,14 +44,14 @@ TEST_CASE("parameters basic 2")
TEST_CASE("parameters basic 3")
{
StringVect pars;
- REQUIRE(splitParameters(pars, ", ,,,", ',', '\"') == true);
+ REQUIRE(splitParameters(pars, ", ,,,", ",", '\"') == true);
REQUIRE(pars.size() == 0);
}
TEST_CASE("parameters basic 4")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "one,,two, tree", ',', '\"') == true);
+ REQUIRE(splitParameters(pars, "one,,two, tree", ",", '\"') == true);
REQUIRE(pars.size() == 3);
REQUIRE(pars[0] == "one");
REQUIRE(pars[1] == "two");
@@ -61,7 +61,7 @@ TEST_CASE("parameters basic 4")
TEST_CASE("parameters escape 1")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\\\"", ',', '\"') == true);
+ REQUIRE(splitParameters(pars, "\\\"", ",", '\"') == true);
REQUIRE(pars.size() == 1);
REQUIRE(pars[0] == "\"");
}
@@ -69,7 +69,7 @@ TEST_CASE("parameters escape 1")
TEST_CASE("parameters escape 2")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\\\", test", ',', '\"') == true);
+ REQUIRE(splitParameters(pars, "\\\", test", ",", '\"') == true);
REQUIRE(pars.size() == 2);
REQUIRE(pars[0] == "\"");
REQUIRE(pars[1] == "test");
@@ -78,7 +78,7 @@ TEST_CASE("parameters escape 2")
TEST_CASE("parameters escape 3")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "test,\\\"", ',', '\"') == true);
+ REQUIRE(splitParameters(pars, "test,\\\"", ",", '\"') == true);
REQUIRE(pars.size() == 2);
REQUIRE(pars[0] == "test");
REQUIRE(pars[1] == "\"");
@@ -87,7 +87,7 @@ TEST_CASE("parameters escape 3")
TEST_CASE("parameters quote 1")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\"one\",,two, tree", ',', '\"') == true);
+ REQUIRE(splitParameters(pars, "\"one\",,two, tree", ",", '\"') == true);
REQUIRE(pars.size() == 3);
REQUIRE(pars[0] == "one");
REQUIRE(pars[1] == "two");
@@ -97,7 +97,7 @@ TEST_CASE("parameters quote 1")
TEST_CASE("parameters quote 2")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\"\",,two, tree", ',', '\"') == true);
+ REQUIRE(splitParameters(pars, "\"\",,two, tree", ",", '\"') == true);
REQUIRE(pars.size() == 3);
REQUIRE(pars[0] == "");
REQUIRE(pars[1] == "two");
@@ -107,7 +107,7 @@ TEST_CASE("parameters quote 2")
TEST_CASE("parameters quote 3")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\"one test\",,two, tree", ',', '\"') ==
+ REQUIRE(splitParameters(pars, "\"one test\",,two, tree", ",", '\"') ==
true);
REQUIRE(pars.size() == 3);
REQUIRE(pars[0] == "one test");
@@ -118,7 +118,7 @@ TEST_CASE("parameters quote 3")
TEST_CASE("parameters quote 4")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\"\\\"one test\\\"\",,two, tree", ',', '\"')
+ REQUIRE(splitParameters(pars, "\"\\\"one test\\\"\",,two, tree", ",", '\"')
== true);
REQUIRE(pars.size() == 3);
REQUIRE(pars[0] == "\"one test\"");
@@ -129,8 +129,8 @@ TEST_CASE("parameters quote 4")
TEST_CASE("parameters quote 5")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\"\\\"one \\\"test\\\"\",,two, tree", ',', '\"')
- == true);
+ REQUIRE(splitParameters(pars, "\"\\\"one \\\"test\\\"\",,two, tree",
+ ",", '\"') == true);
REQUIRE(pars.size() == 3);
REQUIRE(pars[0] == "\"one \"test\"");
REQUIRE(pars[1] == "two");
@@ -140,7 +140,7 @@ TEST_CASE("parameters quote 5")
TEST_CASE("parameters quote 6")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\"one, test\",,two, tree", ',', '\"')
+ REQUIRE(splitParameters(pars, "\"one, test\",,two, tree", ",", '\"')
== true);
REQUIRE(pars.size() == 3);
REQUIRE(pars[0] == "one, test");
@@ -151,8 +151,8 @@ TEST_CASE("parameters quote 6")
TEST_CASE("parameters quote 7")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\"\\\"one, test\\\"\",,two, tree", ',', '\"')
- == true);
+ REQUIRE(splitParameters(pars, "\"\\\"one, test\\\"\",,two, tree",
+ ",", '\"') == true);
REQUIRE(pars.size() == 3);
REQUIRE(pars[0] == "\"one, test\"");
REQUIRE(pars[1] == "two");
@@ -162,7 +162,7 @@ TEST_CASE("parameters quote 7")
TEST_CASE("parameters quote 8")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\"\\\"\",,two, tree", ',', '\"')
+ REQUIRE(splitParameters(pars, "\"\\\"\",,two, tree", ",", '\"')
== true);
REQUIRE(pars.size() == 3);
REQUIRE(pars[0] == "\"");
@@ -173,7 +173,7 @@ TEST_CASE("parameters quote 8")
TEST_CASE("parameters quote 9")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\"\\\",,two, tree", ',', '\"')
+ REQUIRE(splitParameters(pars, "\"\\\",,two, tree", ",", '\"')
== true);
REQUIRE(pars.size() == 1);
REQUIRE(pars[0] == "\"\",,two, tree");
@@ -182,7 +182,7 @@ TEST_CASE("parameters quote 9")
TEST_CASE("parameters quote 10")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\"", ',', '\"')
+ REQUIRE(splitParameters(pars, "\"", ",", '\"')
== true);
REQUIRE(pars.size() == 1);
REQUIRE(pars[0] == "\"");
@@ -191,7 +191,7 @@ TEST_CASE("parameters quote 10")
TEST_CASE("parameters quote 11")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\\\"", ',', '\"')
+ REQUIRE(splitParameters(pars, "\\\"", ",", '\"')
== true);
REQUIRE(pars.size() == 1);
REQUIRE(pars[0] == "\"");
@@ -200,7 +200,7 @@ TEST_CASE("parameters quote 11")
TEST_CASE("parameters quote 12")
{
StringVect pars;
- REQUIRE(splitParameters(pars, ",\"", ',', '\"')
+ REQUIRE(splitParameters(pars, ",\"", ",", '\"')
== true);
REQUIRE(pars.size() == 1);
REQUIRE(pars[0] == "\"");
@@ -209,7 +209,7 @@ TEST_CASE("parameters quote 12")
TEST_CASE("parameters quote 13")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\",", ',', '\"')
+ REQUIRE(splitParameters(pars, "\",", ",", '\"')
== true);
REQUIRE(pars.size() == 1);
REQUIRE(pars[0] == "\",");
@@ -218,7 +218,7 @@ TEST_CASE("parameters quote 13")
TEST_CASE("parameters quote 14")
{
StringVect pars;
- REQUIRE(splitParameters(pars, "\\\",", ',', '\"')
+ REQUIRE(splitParameters(pars, "\\\",", ",", '\"')
== true);
REQUIRE(pars.size() == 1);
REQUIRE(pars[0] == "\"");
@@ -227,8 +227,101 @@ TEST_CASE("parameters quote 14")
TEST_CASE("parameters quote 15")
{
StringVect pars;
- REQUIRE(splitParameters(pars, ",\\\"", ',', '\"')
+ REQUIRE(splitParameters(pars, ",\\\"", ",", '\"')
== true);
REQUIRE(pars.size() == 1);
REQUIRE(pars[0] == "\"");
}
+
+TEST_CASE("parameters quote 16")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"one test\"", ",", '\"') ==
+ true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "one test");
+}
+
+TEST_CASE("parameters quote 17")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"one, test\"", ",", '\"') ==
+ true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "one, test");
+}
+
+TEST_CASE("parameters quote 18")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"one\\\" test\"", ",", '\"') ==
+ true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "one\" test");
+}
+
+TEST_CASE("parameters quote 19")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"one\\\" ,test\"", ",", '\"') ==
+ true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "one\" ,test");
+}
+
+TEST_CASE("parameters quote 20")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"one\\\" test,\"", ",", '\"') ==
+ true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "one\" test,");
+}
+
+TEST_CASE("parameters complex 1")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"test\" \"line\"", ",", '\"') == true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "test\" \"line");
+}
+
+TEST_CASE("parameters complex 2")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"test\", \"line\"", ",", '\"') == true);
+ REQUIRE(pars.size() == 2);
+ REQUIRE(pars[0] == "test");
+ REQUIRE(pars[1] == "line");
+}
+
+TEST_CASE("parameters complex 3")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"test,\" \"line\"", ",", '\"') == true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "test,\" \"line");
+}
+
+TEST_CASE("parameters broken 1")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, "\"", ",", '\"') == true);
+ REQUIRE(pars.size() == 1);
+ REQUIRE(pars[0] == "\"");
+}
+
+TEST_CASE("parameters broken 2")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars, ",", ",", '\"') == true);
+ REQUIRE(pars.size() == 0);
+}
+
+TEST_CASE("parameters broken 3")
+{
+ StringVect pars;
+ REQUIRE(splitParameters(pars,
+ ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,", ",", '\"') == true);
+ REQUIRE(pars.size() == 0);
+}
diff --git a/src/utils/stringutils.cpp b/src/utils/stringutils.cpp
index 9cc21f23a..e7887bc48 100644
--- a/src/utils/stringutils.cpp
+++ b/src/utils/stringutils.cpp
@@ -210,6 +210,21 @@ size_t findI(std::string text, const StringVect &list)
return std::string::npos;
}
+size_t findAny(const std::string &restrict text,
+ const std::string &restrict chars,
+ const size_t pos)
+{
+ size_t idx = std::string::npos;
+ const size_t sz = chars.size();
+ for (size_t f = 0; f < sz; f ++)
+ {
+ const size_t idx2 = text.find(chars[f], pos);
+ if (idx2 != std::string::npos && idx2 < idx)
+ idx = idx2;
+ }
+ return idx;
+}
+
namespace
{
unsigned int base = 94;
diff --git a/src/utils/stringutils.h b/src/utils/stringutils.h
index 67e91a464..ab9290378 100644
--- a/src/utils/stringutils.h
+++ b/src/utils/stringutils.h
@@ -142,6 +142,10 @@ size_t findI(std::string str, std::string subStr) A_WARN_UNUSED;
size_t findI(std::string text, const StringVect &list) A_WARN_UNUSED;
+size_t findAny(const std::string &restrict text,
+ const std::string &restrict chars,
+ const size_t pos) A_WARN_UNUSED;
+
const std::string encodeStr(unsigned int value,
const unsigned int size = 0) A_WARN_UNUSED;
diff --git a/src/utils/stringutils_unittest.cc b/src/utils/stringutils_unittest.cc
index f6586558c..b921cf509 100644
--- a/src/utils/stringutils_unittest.cc
+++ b/src/utils/stringutils_unittest.cc
@@ -593,6 +593,19 @@ TEST_CASE("stringuntils isDigit")
REQUIRE_FALSE(isDigit("12-34"));
}
+TEST_CASE("stringuntils findAny")
+{
+ std::string str;
+
+ REQUIRE(findAny("test line", ",", 0) == std::string::npos);
+ REQUIRE(findAny("test line", " ", 0) == 4U);
+ REQUIRE(findAny("test, line", ", ", 0) == 4U);
+ REQUIRE(findAny("test ,line", ", ", 0) == 4U);
+ REQUIRE(findAny("test, line", " ,", 2) == 4U);
+ REQUIRE(findAny("test ,line", " ,", 3) == 4U);
+ REQUIRE(findAny("\"one\",,two, tree", ",", 5) == 5U);
+}
+
TEST_CASE("stringuntils replaceItemLinks")
{
ItemDB::NamedItemInfos &infos = ItemDB::getNamedItemInfosTest();