diff --git a/src/CLI2.cpp b/src/CLI2.cpp index 31d41edc7..f0e9fc159 100644 --- a/src/CLI2.cpp +++ b/src/CLI2.cpp @@ -1141,7 +1141,7 @@ void CLI2::findStrayModifications () } //////////////////////////////////////////////////////////////////////////////// -// [.]:['"][]['"] --> name = value +// [.]:['"][]['"] --> name value void CLI2::desugarFilterAttributes () { bool changes = false; @@ -1157,6 +1157,8 @@ void CLI2::desugarFilterAttributes () std::string sep = a.attribute ("separator"); std::string value = a.attribute ("value"); + // An unquoted string, while equivalent to an empty string, doesn't cause + // an operand shortage in eval. if (value == "") value = "''"; @@ -1304,8 +1306,14 @@ void CLI2::desugarFilterAttributes () reconstructed.push_back (lhs); reconstructed.push_back (op); + // Do not modify this construct without full understanding. if (values.size () == 1 || ! evalSupported) + { + if (Lexer::isDOM (rhs.attribute ("raw"))) + rhs._lextype = Lexer::Type::dom; + reconstructed.push_back (rhs); + } else for (auto& v : values) reconstructed.push_back (v); diff --git a/src/Lexer.cpp b/src/Lexer.cpp index 2a1dba70d..090e15050 100644 --- a/src/Lexer.cpp +++ b/src/Lexer.cpp @@ -1323,6 +1323,20 @@ bool Lexer::isAllDigits (const std::string& text) return text.find_first_not_of ("0123456789") == std::string::npos; } +//////////////////////////////////////////////////////////////////////////////// +bool Lexer::isDOM (const std::string& text) +{ + Lexer lex (text); + int count = 0; + std::string token; + Lexer::Type type; + while (lex.token (token, type)) + ++count; + + return count == 1 && + type == Lexer::Type::dom; +} + //////////////////////////////////////////////////////////////////////////////// // Full implementation of a quoted word. Includes: // '\'' diff --git a/src/Lexer.h b/src/Lexer.h index a244bf030..1cb7aab0c 100644 --- a/src/Lexer.h +++ b/src/Lexer.h @@ -75,6 +75,7 @@ public: static bool isHardBoundary (int, int); static bool isPunctuation (int); static bool isAllDigits (const std::string&); + static bool isDOM (const std::string&); static void dequote (std::string&, const std::string& quotes = "'\""); static bool wasQuoted (const std::string&); static bool readWord (const std::string&, const std::string&, std::string::size_type&, std::string&); diff --git a/src/Task.cpp b/src/Task.cpp index c6a2559a7..0fdff40a9 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -37,6 +37,7 @@ #include #ifdef PRODUCT_TASKWARRIOR #include +#include #include #endif #include