diff options
author | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2015-02-18 11:20:01 +0100 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2015-02-25 13:54:58 +0000 |
commit | 73c84fb32bfb09a87d3a63b1f0c78d3f500ba20b (patch) | |
tree | a0e72c721949368bca160038ea37afb2ed44495a /qmake/library/qmakeparser.cpp | |
parent | 7dcc2b3246bba323e8da8d1af5a4f87e82c0e9e0 (diff) |
be more strict about bogus operators
we now warn about the pointless ones, and error out in cases that
already were semantically bogus.
Change-Id: Ifd80014af0fc53e3cc42561c4270d1dca234568f
Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Diffstat (limited to 'qmake/library/qmakeparser.cpp')
-rw-r--r-- | qmake/library/qmakeparser.cpp | 62 |
1 files changed, 56 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); |