Handle escaped commas in parsed arguments (#493)
Co-authored-by: friendlyanon <friendlyanon@users.noreply.github.com>
diff --git a/doctest/parts/doctest.cpp b/doctest/parts/doctest.cpp
index 5b74420..e209878 100644
--- a/doctest/parts/doctest.cpp
+++ b/doctest/parts/doctest.cpp
@@ -3333,18 +3333,42 @@
std::vector<String>& res) {
String filtersString;
if(parseOption(argc, argv, pattern, &filtersString)) {
- // tokenize with "," as a separator
- // cppcheck-suppress strtokCalled
- DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
- auto pch = std::strtok(filtersString.c_str(), ","); // modifies the string
- while(pch != nullptr) {
- if(strlen(pch))
- res.push_back(pch);
- // uses the strtok() internal state to go to the next token
- // cppcheck-suppress strtokCalled
- pch = std::strtok(nullptr, ",");
+ // tokenize with "," as a separator, unless escaped with backslash
+ std::ostringstream s;
+ auto flush = [&s, &res]() {
+ auto string = s.str();
+ if(string.size() > 0) {
+ res.push_back(string.c_str());
+ }
+ s.str("");
+ };
+
+ bool seenBackslash = false;
+ const char* current = filtersString.c_str();
+ const char* end = current + strlen(current);
+ while(current != end) {
+ char character = *current++;
+ if(seenBackslash) {
+ seenBackslash = false;
+ if(character == ',') {
+ s.put(',');
+ continue;
+ }
+ s.put('\\');
+ }
+ if(character == '\\') {
+ seenBackslash = true;
+ } else if(character == ',') {
+ flush();
+ } else {
+ s.put(character);
+ }
}
- DOCTEST_CLANG_SUPPRESS_WARNING_POP
+
+ if(seenBackslash) {
+ s.put('\\');
+ }
+ flush();
return true;
}
return false;