diff options
Diffstat (limited to 'qmake/library')
-rw-r--r-- | qmake/library/qmakeparser.cpp | 62 | ||||
-rw-r--r-- | qmake/library/qmakeparser.h | 3 |
2 files changed, 59 insertions, 6 deletions
diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp index 6eff04278f..d4e9bac86f 100644 --- a/qmake/library/qmakeparser.cpp +++ b/qmake/library/qmakeparser.cpp @@ -671,6 +671,7 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra } else if (c == ':') { FLUSH_LHS_LITERAL(); finalizeCond(tokPtr, buf, ptr, wordCount); + warnOperator("in front of AND operator"); if (m_state == StNew) parseError(fL1S("AND operator without prior condition.")); else @@ -681,6 +682,7 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra } else if (c == '|') { FLUSH_LHS_LITERAL(); finalizeCond(tokPtr, buf, ptr, wordCount); + warnOperator("in front of OR operator"); if (m_state != StCond) parseError(fL1S("OR operator without prior condition.")); else @@ -689,7 +691,13 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra } else if (c == '{') { FLUSH_LHS_LITERAL(); finalizeCond(tokPtr, buf, ptr, wordCount); + if (m_operator == AndOperator) { + languageWarning(fL1S("Excess colon in front of opening brace.")); + m_operator = NoOperator; + } + failOperator("in front of opening brace"); flushCond(tokPtr); + m_state = StNew; // Reset possible StCtrl, so colons get rejected. ++m_blockstack.top().braceLevel; if (grammar == TestGrammar) parseError(fL1S("Opening scope not permitted in this context.")); @@ -700,6 +708,7 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra m_state = StNew; // De-facto newline closeScope: flushScopes(tokPtr); + failOperator("in front of closing brace"); if (!m_blockstack.top().braceLevel) { parseError(fL1S("Excess closing brace.")); } else if (!--m_blockstack.top().braceLevel @@ -731,6 +740,7 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra doOp: FLUSH_LHS_LITERAL(); flushCond(tokPtr); + acceptColon("in front of assignment"); putLineMarker(tokPtr); if (grammar == TestGrammar) { parseError(fL1S("Assignment not permitted in this context.")); @@ -815,6 +825,7 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra putTok(tokPtr, TokValueTerminator); } else { finalizeCond(tokPtr, buf, ptr, wordCount); + warnOperator("at end of line"); } if (!cur) break; @@ -908,6 +919,48 @@ void QMakeParser::flushCond(ushort *&tokPtr) } } +void QMakeParser::warnOperator(const char *msg) +{ + if (m_invert) { + languageWarning(fL1S("Stray NOT operator %1.").arg(fL1S(msg))); + m_invert = false; + } + if (m_operator == AndOperator) { + languageWarning(fL1S("Stray AND operator %1.").arg(fL1S(msg))); + m_operator = NoOperator; + } else if (m_operator == OrOperator) { + languageWarning(fL1S("Stray OR operator %1.").arg(fL1S(msg))); + m_operator = NoOperator; + } +} + +bool QMakeParser::failOperator(const char *msg) +{ + bool fail = false; + if (m_invert) { + parseError(fL1S("Unexpected NOT operator %1.").arg(fL1S(msg))); + m_invert = false; + fail = true; + } + if (m_operator == AndOperator) { + parseError(fL1S("Unexpected AND operator %1.").arg(fL1S(msg))); + m_operator = NoOperator; + fail = true; + } else if (m_operator == OrOperator) { + parseError(fL1S("Unexpected OR operator %1.").arg(fL1S(msg))); + m_operator = NoOperator; + fail = true; + } + return fail; +} + +bool QMakeParser::acceptColon(const char *msg) +{ + if (m_operator == AndOperator) + m_operator = NoOperator; + return !failOperator(msg); +} + void QMakeParser::putOperator(ushort *&tokPtr) { if (m_operator== AndOperator) { @@ -961,10 +1014,8 @@ void QMakeParser::finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wor if (uce == ptr) { m_tmp.setRawData((QChar *)uc + 4, nlen); if (!m_tmp.compare(statics.strelse, Qt::CaseInsensitive)) { - if (m_invert || m_operator != NoOperator) { - parseError(fL1S("Unexpected operator in front of else.")); + if (failOperator("in front of else")) return; - } BlockScope &top = m_blockstack.top(); if (m_canElse && (!top.special || top.braceLevel)) { // A list of tests (the last one likely with side effects), @@ -1009,9 +1060,8 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg const QString *defName; ushort defType; if (m_tmp == statics.strfor) { - if (m_invert || m_operator == OrOperator) { - // '|' could actually work reasonably, but qmake does nonsense here. - bogusTest(tokPtr, fL1S("Unexpected operator in front of for().")); + if (!acceptColon("in front of for()")) { + bogusTest(tokPtr, QString()); return; } flushCond(tokPtr); diff --git a/qmake/library/qmakeparser.h b/qmake/library/qmakeparser.h index 09f8d1b7a7..66b26ac759 100644 --- a/qmake/library/qmakeparser.h +++ b/qmake/library/qmakeparser.h @@ -144,6 +144,9 @@ private: const ushort *cur, const QString &in); void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount); void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc); + void warnOperator(const char *msg); + bool failOperator(const char *msg); + bool acceptColon(const char *msg); void putOperator(ushort *&tokPtr); void finalizeTest(ushort *&tokPtr); void bogusTest(ushort *&tokPtr, const QString &msg); |