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 == ':') {
|
} else if (c == ':') {
|
||||||
FLUSH_LHS_LITERAL();
|
FLUSH_LHS_LITERAL();
|
||||||
finalizeCond(tokPtr, buf, ptr, wordCount);
|
finalizeCond(tokPtr, buf, ptr, wordCount);
|
||||||
|
warnOperator("in front of AND operator");
|
||||||
if (m_state == StNew)
|
if (m_state == StNew)
|
||||||
parseError(fL1S("AND operator without prior condition."));
|
parseError(fL1S("AND operator without prior condition."));
|
||||||
else
|
else
|
||||||
@ -681,6 +682,7 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
} else if (c == '|') {
|
} else if (c == '|') {
|
||||||
FLUSH_LHS_LITERAL();
|
FLUSH_LHS_LITERAL();
|
||||||
finalizeCond(tokPtr, buf, ptr, wordCount);
|
finalizeCond(tokPtr, buf, ptr, wordCount);
|
||||||
|
warnOperator("in front of OR operator");
|
||||||
if (m_state != StCond)
|
if (m_state != StCond)
|
||||||
parseError(fL1S("OR operator without prior condition."));
|
parseError(fL1S("OR operator without prior condition."));
|
||||||
else
|
else
|
||||||
@ -689,7 +691,13 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
} else if (c == '{') {
|
} else if (c == '{') {
|
||||||
FLUSH_LHS_LITERAL();
|
FLUSH_LHS_LITERAL();
|
||||||
finalizeCond(tokPtr, buf, ptr, wordCount);
|
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);
|
flushCond(tokPtr);
|
||||||
|
m_state = StNew; // Reset possible StCtrl, so colons get rejected.
|
||||||
++m_blockstack.top().braceLevel;
|
++m_blockstack.top().braceLevel;
|
||||||
if (grammar == TestGrammar)
|
if (grammar == TestGrammar)
|
||||||
parseError(fL1S("Opening scope not permitted in this context."));
|
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
|
m_state = StNew; // De-facto newline
|
||||||
closeScope:
|
closeScope:
|
||||||
flushScopes(tokPtr);
|
flushScopes(tokPtr);
|
||||||
|
failOperator("in front of closing brace");
|
||||||
if (!m_blockstack.top().braceLevel) {
|
if (!m_blockstack.top().braceLevel) {
|
||||||
parseError(fL1S("Excess closing brace."));
|
parseError(fL1S("Excess closing brace."));
|
||||||
} else if (!--m_blockstack.top().braceLevel
|
} else if (!--m_blockstack.top().braceLevel
|
||||||
@ -731,6 +740,7 @@ void QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
doOp:
|
doOp:
|
||||||
FLUSH_LHS_LITERAL();
|
FLUSH_LHS_LITERAL();
|
||||||
flushCond(tokPtr);
|
flushCond(tokPtr);
|
||||||
|
acceptColon("in front of assignment");
|
||||||
putLineMarker(tokPtr);
|
putLineMarker(tokPtr);
|
||||||
if (grammar == TestGrammar) {
|
if (grammar == TestGrammar) {
|
||||||
parseError(fL1S("Assignment not permitted in this context."));
|
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);
|
putTok(tokPtr, TokValueTerminator);
|
||||||
} else {
|
} else {
|
||||||
finalizeCond(tokPtr, buf, ptr, wordCount);
|
finalizeCond(tokPtr, buf, ptr, wordCount);
|
||||||
|
warnOperator("at end of line");
|
||||||
}
|
}
|
||||||
if (!cur)
|
if (!cur)
|
||||||
break;
|
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)
|
void QMakeParser::putOperator(ushort *&tokPtr)
|
||||||
{
|
{
|
||||||
if (m_operator== AndOperator) {
|
if (m_operator== AndOperator) {
|
||||||
@ -961,10 +1014,8 @@ void QMakeParser::finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wor
|
|||||||
if (uce == ptr) {
|
if (uce == ptr) {
|
||||||
m_tmp.setRawData((QChar *)uc + 4, nlen);
|
m_tmp.setRawData((QChar *)uc + 4, nlen);
|
||||||
if (!m_tmp.compare(statics.strelse, Qt::CaseInsensitive)) {
|
if (!m_tmp.compare(statics.strelse, Qt::CaseInsensitive)) {
|
||||||
if (m_invert || m_operator != NoOperator) {
|
if (failOperator("in front of else"))
|
||||||
parseError(fL1S("Unexpected operator in front of else."));
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
BlockScope &top = m_blockstack.top();
|
BlockScope &top = m_blockstack.top();
|
||||||
if (m_canElse && (!top.special || top.braceLevel)) {
|
if (m_canElse && (!top.special || top.braceLevel)) {
|
||||||
// A list of tests (the last one likely with side effects),
|
// 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;
|
const QString *defName;
|
||||||
ushort defType;
|
ushort defType;
|
||||||
if (m_tmp == statics.strfor) {
|
if (m_tmp == statics.strfor) {
|
||||||
if (m_invert || m_operator == OrOperator) {
|
if (!acceptColon("in front of for()")) {
|
||||||
// '|' could actually work reasonably, but qmake does nonsense here.
|
bogusTest(tokPtr, QString());
|
||||||
bogusTest(tokPtr, fL1S("Unexpected operator in front of for()."));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
flushCond(tokPtr);
|
flushCond(tokPtr);
|
||||||
|
@ -144,6 +144,9 @@ private:
|
|||||||
const ushort *cur, const QString &in);
|
const ushort *cur, const QString &in);
|
||||||
void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount);
|
void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount);
|
||||||
void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc);
|
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 putOperator(ushort *&tokPtr);
|
||||||
void finalizeTest(ushort *&tokPtr);
|
void finalizeTest(ushort *&tokPtr);
|
||||||
void bogusTest(ushort *&tokPtr, const QString &msg);
|
void bogusTest(ushort *&tokPtr, const QString &msg);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user