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>
This commit is contained in:
parent
7dcc2b3246
commit
73c84fb32b
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user