diff options
author | Erik Verbruggen <erik.verbruggen@nokia.com> | 2009-07-16 09:43:30 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@nokia.com> | 2009-07-16 09:43:30 +0200 |
commit | 519a1a97b32ea145286ebcc71de9ec987ec4fa00 (patch) | |
tree | 265fe755b8ad4ac9f41153bb4f2713e1c12b5de5 /src/shared | |
parent | c8f155c0fc2fd64f01d50f6c085dd811cfdae17e (diff) | |
parent | fc33e35554fb93dbd2ceabd4f8a60b90cc7fce0e (diff) | |
download | qt-creator-519a1a97b32ea145286ebcc71de9ec987ec4fa00.tar.gz |
Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/proparser/profileevaluator.cpp | 196 |
1 files changed, 119 insertions, 77 deletions
diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index 4f309d914c..46734d78e4 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -140,7 +140,7 @@ public: ProBlock *currentBlock(); void updateItem(); bool parseLine(const QString &line); - void insertVariable(const QString &line, int *i); + void insertVariable(const ushort **pCur, const ushort *end); void insertOperator(const char op); void insertComment(const QString &comment); void enterScope(bool multiLine); @@ -153,11 +153,14 @@ public: ProItem *m_commentItem; QString m_proitem; QString m_pendingComment; + ushort *m_proitemPtr; bool m_syntaxError; bool m_contNextLine; bool m_inQuote; int m_parens; + enum StrState { NotStarted, Started, PutSpace }; + /////////////// Evaluating pro file contents // implementation of AbstractProItemVisitor @@ -304,32 +307,36 @@ bool ProFileEvaluator::Private::read(ProFile *pro, QTextStream *ts) return true; } -bool ProFileEvaluator::Private::parseLine(const QString &line0) +bool ProFileEvaluator::Private::parseLine(const QString &line) { if (m_blockstack.isEmpty()) return false; + const ushort *cur = (const ushort *)line.unicode(), + *end = cur + line.length(); 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(); + m_proitem.reserve(line.length()); + m_proitemPtr = (ushort *)m_proitem.unicode(); + nextItem: + ushort *ptr = m_proitemPtr; + StrState sts = NotStarted; + while (cur < end) { + ushort c = *cur++; if (c == '#') { // Yep - no escaping possible - insertComment(line.mid(i + 1)); - escaped = m_contNextLine; - break; + m_proitemPtr = ptr; + insertComment(line.right(end - cur).simplified()); + goto done; } if (!escaped) { if (c == '\\') { escaped = true; - m_proitem += c; - continue; + goto putch; } else if (c == '"') { inQuote = !inQuote; - m_proitem += c; - continue; + goto putch; } } else { escaped = false; @@ -341,52 +348,70 @@ bool ProFileEvaluator::Private::parseLine(const QString &line0) --parens; } else if (!parens) { if (m_block && (m_block->blockKind() & ProBlock::VariableKind)) { - if (c == ' ') + if (c == ' ' || c == '\t') { + m_proitemPtr = ptr; 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; + goto nextItem; + } + } else { + if (c == ':') { + m_proitemPtr = ptr; + enterScope(false); + goto nextItem; + } + if (c == '{') { + m_proitemPtr = ptr; + enterScope(true); + goto nextItem; + } + if (c == '}') { + m_proitemPtr = ptr; + leaveScope(); + if (m_syntaxError) + goto done1; + goto nextItem; + } + if (c == '=') { + m_proitemPtr = ptr; + insertVariable(&cur, end); + goto nextItem; + } + if (c == '|' || c == '!') { + m_proitemPtr = ptr; + insertOperator(c); + goto nextItem; + } } } } - m_proitem += c; + if (c == ' ' || c == '\t') { + if (sts == Started) + sts = PutSpace; + } else { + putch: + if (sts == PutSpace) + *ptr++ = ' '; + *ptr++ = c; + sts = Started; + } } + m_proitemPtr = ptr; + done1: + m_contNextLine = escaped; + done: m_inQuote = inQuote; m_parens = parens; - m_contNextLine = escaped; + if (m_syntaxError) + return false; if (escaped) { - m_proitem.chop(1); + --m_proitemPtr; updateItem(); - return true; } else { - if (!m_syntaxError) { - updateItem(); - finalizeBlock(); - return true; - } - return false; + updateItem(); + finalizeBlock(); } + return true; } void ProFileEvaluator::Private::finalizeBlock() @@ -401,37 +426,44 @@ void ProFileEvaluator::Private::finalizeBlock() } } -void ProFileEvaluator::Private::insertVariable(const QString &line, int *i) +void ProFileEvaluator::Private::insertVariable(const ushort **pCur, const ushort *end) { ProVariable::VariableOperator opkind; + ushort *uc = (ushort *)m_proitem.unicode(); + ushort *ptr = m_proitemPtr; - if (m_proitem.isEmpty()) // Line starting with '=', like a conflict marker + if (ptr == uc) // Line starting with '=', like a conflict marker return; - switch (m_proitem.at(m_proitem.length() - 1).unicode()) { + switch (*(ptr - 1)) { case '+': - m_proitem.chop(1); + --ptr; opkind = ProVariable::AddOperator; break; case '-': - m_proitem.chop(1); + --ptr; opkind = ProVariable::RemoveOperator; break; case '*': - m_proitem.chop(1); + --ptr; opkind = ProVariable::UniqueAddOperator; break; case '~': - m_proitem.chop(1); + --ptr; opkind = ProVariable::ReplaceOperator; break; default: opkind = ProVariable::SetOperator; } + while (ptr != uc && *(ptr - 1) == ' ') + --ptr; + m_proitem.resize(ptr - uc); + QString proVar = m_proitem; + proVar.detach(); + ProBlock *block = m_blockstack.top(); - m_proitem = m_proitem.trimmed(); - ProVariable *variable = new ProVariable(m_proitem, block); + ProVariable *variable = new ProVariable(proVar, block); variable->setLineNumber(m_lineNo); variable->setVariableOperator(opkind); block->appendItem(variable); @@ -443,26 +475,31 @@ void ProFileEvaluator::Private::insertVariable(const QString &line, int *i) } m_commentItem = variable; - m_proitem.clear(); - if (opkind == ProVariable::ReplaceOperator) { // skip util end of line or comment - while (1) { - ++(*i); - - // end of line? - if (*i >= line.count()) + StrState sts = NotStarted; + ptr = uc; + const ushort *cur = *pCur; + while (cur < end) { + ushort c = *cur; + if (c == '#') // comment? break; + ++cur; - // comment? - if (line.at(*i).unicode() == '#') { - --(*i); - break; + if (c == ' ' || c == '\t') { + if (sts == Started) + sts = PutSpace; + } else { + if (sts == PutSpace) + *ptr++ = ' '; + *ptr++ = c; + sts = Started; } - - m_proitem += line.at(*i); } - m_proitem = m_proitem.trimmed(); + *pCur = cur; + m_proitemPtr = ptr; + } else { + m_proitemPtr = uc; } } @@ -563,22 +600,27 @@ ProBlock *ProFileEvaluator::Private::currentBlock() void ProFileEvaluator::Private::updateItem() { - m_proitem = m_proitem.trimmed(); - if (m_proitem.isEmpty()) + ushort *uc = (ushort *)m_proitem.unicode(); + ushort *ptr = m_proitemPtr; + + if (ptr == uc) return; + m_proitem.resize(ptr - uc); + m_proitemPtr = uc; + QString proItem = m_proitem; + proItem.detach(); + ProBlock *block = currentBlock(); if (block->blockKind() & ProBlock::VariableKind) { - m_commentItem = new ProValue(m_proitem, static_cast<ProVariable*>(block)); - } else if (m_proitem.endsWith(QLatin1Char(')'))) { - m_commentItem = new ProFunction(m_proitem); + m_commentItem = new ProValue(proItem, static_cast<ProVariable*>(block)); + } else if (proItem.endsWith(QLatin1Char(')'))) { + m_commentItem = new ProFunction(proItem); } else { - m_commentItem = new ProCondition(m_proitem); + m_commentItem = new ProCondition(proItem); } m_commentItem->setLineNumber(m_lineNo); block->appendItem(m_commentItem); - - m_proitem.clear(); } |