make split_value_list() mostly sane
authorOswald Buddenhagen <oswald.buddenhagen@digia.com>
Thu, 7 Mar 2013 20:47:42 +0000 (21:47 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Tue, 21 May 2013 12:43:15 +0000 (14:43 +0200)
don't count parentheses, don't nest quotes, don't create empty elements.
the backslash still escapes only quotes (and itself) - $$list() (one of
the main users of this function) is commonly used with (windows) path
lists, so letting it escape anything would make a royal mess.

Change-Id: I29252fbe14fd6d28217450ec41cf8acfb2e30681
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
(cherry picked from qtbase/6c22b9b3e86d1617665f7b81b105c032f43c6d72)
(cherry picked from qtbase/a5c2ab47867a558d6f8f62126fb8e4f2777cfe06)

src/linguist/shared/qmakeevaluator.cpp

index ce2a5d1..ef86f00 100644 (file)
@@ -264,48 +264,55 @@ ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFil
 {
     QString build;
     ProStringList ret;
-    QStack<char> quote;
-
-    const ushort SPACE = ' ';
-    const ushort LPAREN = '(';
-    const ushort RPAREN = ')';
-    const ushort SINGLEQUOTE = '\'';
-    const ushort DOUBLEQUOTE = '"';
-    const ushort BACKSLASH = '\\';
 
     if (!source)
         source = currentProFile();
 
-    ushort unicode;
     const QChar *vals_data = vals.data();
     const int vals_len = vals.length();
-    int parens = 0;
+    ushort quote = 0;
+    bool hadWord = false;
     for (int x = 0; x < vals_len; x++) {
-        unicode = vals_data[x].unicode();
-        if (x != (int)vals_len-1 && unicode == BACKSLASH &&
-            (vals_data[x+1].unicode() == SINGLEQUOTE || vals_data[x+1].unicode() == DOUBLEQUOTE)) {
-            build += vals_data[x++]; //get that 'escape'
-        } else if (!quote.isEmpty() && unicode == quote.top()) {
-            quote.pop();
-        } else if (unicode == SINGLEQUOTE || unicode == DOUBLEQUOTE) {
-            quote.push(unicode);
-        } else if (unicode == RPAREN) {
-            --parens;
-        } else if (unicode == LPAREN) {
-            ++parens;
+        ushort unicode = vals_data[x].unicode();
+        if (unicode == quote) {
+            quote = 0;
+            continue;
         }
-
-        if (!parens && quote.isEmpty() && vals_data[x] == SPACE) {
-            ret << ProString(build).setSource(source);
-            build.clear();
-        } else {
-            build += vals_data[x];
+        switch (unicode) {
+        case '"':
+        case '\'':
+            quote = unicode;
+            hadWord = true;
+            continue;
+        case ' ':
+        case '\t':
+            if (!quote) {
+                if (hadWord) {
+                    ret << ProString(build).setSource(source);
+                    build.clear();
+                    hadWord = false;
+                }
+                continue;
+            }
+            build += QChar(unicode);
+            break;
+        case '\\':
+            if (x + 1 != vals_len) {
+                ushort next = vals_data[++x].unicode();
+                if (next == '\'' || next == '"' || next == '\\')
+                    unicode = next;
+                else
+                    --x;
+            }
+            // fallthrough
+        default:
+            hadWord = true;
+            build += QChar(unicode);
+            break;
         }
     }
-    if (!build.isEmpty())
+    if (hadWord)
         ret << ProString(build).setSource(source);
-    if (parens)
-        deprecationWarning(fL1S("Unmatched parentheses are deprecated."));
     return ret;
 }