From cc09453cb106d160679dce3d5624f5f094c55497 Mon Sep 17 00:00:00 2001
From: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
Date: Wed, 15 Apr 2009 20:20:17 +0200
Subject: [PATCH] make quote/escape parsing more qmake-compatible

---
 src/shared/proparser/profileevaluator.cpp | 120 ++++++++++++----------
 1 file changed, 68 insertions(+), 52 deletions(-)

diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp
index 676506b4550..1313f7c0306 100644
--- a/src/shared/proparser/profileevaluator.cpp
+++ b/src/shared/proparser/profileevaluator.cpp
@@ -151,6 +151,8 @@ public:
     QString m_pendingComment;
     bool m_syntaxError;
     bool m_contNextLine;
+    bool m_inQuote;
+    int m_parens;
 
     /////////////// Evaluating pro file contents
 
@@ -251,6 +253,8 @@ bool ProFileEvaluator::Private::read(ProFile *pro)
     // Parser state
     m_block = 0;
     m_commentItem = 0;
+    m_inQuote = false;
+    m_parens = 0;
     m_contNextLine = false;
     m_syntaxError = false;
     m_lineNo = 1;
@@ -274,71 +278,83 @@ bool ProFileEvaluator::Private::parseLine(const QString &line0)
     if (m_blockstack.isEmpty())
         return false;
 
-    ushort quote = 0;
-    int parens = 0;
-    bool contNextLine = false;
+    int parens = m_parens;
+    bool inQuote = m_inQuote;
+    bool escaped = false;
     QString line = line0.simplified();
 
     for (int i = 0; !m_syntaxError && i < line.length(); ++i) {
         ushort c = line.at(i).unicode();
-        if (quote && c == quote)
-            quote = 0;
-        else if (c == '(')
-            ++parens;
-        else if (c == ')')
-            --parens;
-        else if (c == '"' && (i == 0 || line.at(i - 1).unicode() != '\\'))
-            quote = c;
-        else if (!parens && !quote) {
-            if (c == '#') {
-                insertComment(line.mid(i + 1));
-                contNextLine = m_contNextLine;
-                break;
-            }
-            if (c == '\\' && i >= line.count() - 1) {
-                updateItem();
-                contNextLine = true;
-                continue;
-            }
-            if (m_block && (m_block->blockKind() & ProBlock::VariableKind)) {
-                if (c == ' ')
-                    updateItem();
-                else
-                    m_proitem += c;
-                continue;
-            }
-            if (c == ':') {
-                enterScope(false);
-                continue;
-            }
-            if (c == '{') {
-                enterScope(true);
-                continue;
-            }
-            if (c == '}') {
-                leaveScope();
+        if (c == '#') { // Yep - no escaping possible
+            insertComment(line.mid(i + 1));
+            escaped = m_contNextLine;
+            break;
+        }
+        if (!escaped) {
+            if (c == '\\') {
+                escaped = true;
+                m_proitem += c;
                 continue;
-            }
-            if (c == '=') {
-                insertVariable(line, &i);
+            } else if (c == '"') {
+                inQuote = !inQuote;
+                m_proitem += c;
                 continue;
             }
-            if (c == '|' || c == '!') {
-                insertOperator(c);
-                continue;
+        } else {
+            escaped = false;
+        }
+        if (!inQuote) {
+            if (c == '(') {
+                ++parens;
+            } else if (c == ')') {
+                --parens;
+            } else if (!parens) {
+                if (m_block && (m_block->blockKind() & ProBlock::VariableKind)) {
+                    if (c == ' ')
+                        updateItem();
+                    else
+                        m_proitem += c;
+                    continue;
+                }
+                if (c == ':') {
+                    enterScope(false);
+                    continue;
+                }
+                if (c == '{') {
+                    enterScope(true);
+                    continue;
+                }
+                if (c == '}') {
+                    leaveScope();
+                    continue;
+                }
+                if (c == '=') {
+                    insertVariable(line, &i);
+                    continue;
+                }
+                if (c == '|' || c == '!') {
+                    insertOperator(c);
+                    continue;
+                }
             }
         }
 
         m_proitem += c;
     }
-    m_contNextLine = contNextLine;
-
-    if (!m_syntaxError) {
-        updateItem();
-        if (!m_contNextLine)
-            finalizeBlock();
+    m_inQuote = inQuote;
+    m_parens = parens;
+    m_contNextLine = escaped;
+    if (escaped) {
+        m_proitem.chop(1);
+        return true;
+    } else {
+        if (!m_syntaxError) {
+            updateItem();
+            if (!m_contNextLine)
+                finalizeBlock();
+        }
+        return !m_syntaxError;
     }
-    return !m_syntaxError;
 }
 
 void ProFileEvaluator::Private::finalizeBlock()
-- 
GitLab