diff --git a/src/text.cpp b/src/text.cpp index 7b37b0eb4..8ffc42ed1 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -33,10 +33,10 @@ #include #include #include -#include "Context.h" -#include "util.h" -#include "text.h" -#include "utf8.h" +#include +#include +#include +#include extern Context context; @@ -59,6 +59,48 @@ void wrapText ( } } +//////////////////////////////////////////////////////////////////////////////// +void splitq ( + std::vector& results, + const std::string& input, + const char delimiter) +{ + results.clear (); + + std::string::size_type start = 0; + std::string::size_type i = 0; + std::string word; + bool in_quote = false; + char quote; + + while (utf8_next_char (input, i)) + { + if (in_quote) + { + if (input[i] == quote) + { + in_quote = false; + } + } + else + { + if (input[i] == delimiter) + { + results.push_back (unquoteText (input.substr (start, i - start))); + start = i + 1; + } + else if (input[i] == '\'' || + input[i] == '"') + { + quote = input[i]; + in_quote = true; + } + } + } + + results.push_back (unquoteText (input.substr (start))); +} + //////////////////////////////////////////////////////////////////////////////// void split ( std::vector& results, diff --git a/src/text.h b/src/text.h index dcb3dfd23..dbb04a43e 100644 --- a/src/text.h +++ b/src/text.h @@ -39,6 +39,7 @@ std::string trim (const std::string& in, const std::string& t = " "); std::string unquoteText (const std::string&); int longestWord (const std::string&); void extractLine (std::string&, std::string&, int); +void splitq (std::vector&, const std::string&, const char); void split (std::vector&, const std::string&, const char); void split (std::vector&, const std::string&, const std::string&); void split_minimal (std::vector&, const std::string&, const char); diff --git a/test/text.t.cpp b/test/text.t.cpp index 6191e5c68..20cf347b4 100644 --- a/test/text.t.cpp +++ b/test/text.t.cpp @@ -35,7 +35,7 @@ Context context; //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (236); + UnitTest t (243); // void wrapText (std::vector & lines, const std::string& text, const int width) std::string text = "This is a test of the line wrapping code."; @@ -155,6 +155,17 @@ int main (int argc, char** argv) t.is (items[2], "bc", "split '-a-bc-def' '--' -> [2] 'bc'"); t.is (items[3], "def", "split '-a-bc-def' '--' -> [3] 'def'"); + // void splitq (std::vector&, const std::string&, const char); + unsplit = "one 'two' '' 'three four' \"five six seven\" eight'nine ten'"; + splitq (items, unsplit, ' '); + t.is (items.size () , (size_t) 6, "splitq 'one \\'two\\' \\'\\' \\'three four\\' \"five six seven\" eight'nine ten'"); + t.is (items[0], "one", "splitq 'one \\'two\\' \\'\\' \\'three four\\' \"five six seven\" eight'nine ten' -> [0] 'one'"); + t.is (items[1], "two", "splitq 'one \\'two\\' \\'\\' \\'three four\\' \"five six seven\" eight'nine ten' -> [1] 'two'"); + t.is (items[2], "", "splitq 'one \\'two\\' \\'\\' \\'three four\\' \"five six seven\" eight'nine ten' -> [2] ''"); + t.is (items[3], "three four", "splitq 'one \\'two\\' \\'\\' \\'three four\\' \"five six seven\" eight'nine ten' -> [3] 'three four'"); + t.is (items[4], "five six seven", "splitq 'one \\'two\\' \\'\\' \\'three four\\' \"five six seven\" eight'nine ten' -> [4] 'five six seven'"); + t.is (items[5], "eight'nine ten'", "splitq 'one \\'two\\' \\'\\' \\'three four\\' \"five six seven\" eight'nine ten' -> [4] 'eight\\'nine ten\\''"); + // void join (std::string& result, const std::string& separator, const std::vector& items) std::vector unjoined; std::string joined;