diff options
-rw-r--r-- | tools/linguist/shared/profileevaluator.cpp | 117 |
1 files changed, 67 insertions, 50 deletions
diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp index 5c83f7e..0be6bec 100644 --- a/tools/linguist/shared/profileevaluator.cpp +++ b/tools/linguist/shared/profileevaluator.cpp @@ -163,6 +163,8 @@ public: QString m_pendingComment; bool m_syntaxError; bool m_contNextLine; + bool m_inQuote; + int m_parens; /////////////// Evaluating pro file contents @@ -261,6 +263,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; @@ -284,71 +288,84 @@ 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) { + m_inQuote = inQuote; + m_parens = parens; + m_contNextLine = escaped; + if (escaped) { + m_proitem.chop(1); updateItem(); - if (!m_contNextLine) + return true; + } else { + if (!m_syntaxError) { + updateItem(); finalizeBlock(); + return true; + } + return false; } - return !m_syntaxError; } void ProFileEvaluator::Private::finalizeBlock() |