forked from qt-creator/qt-creator
add QMakeParser::ValueGrammar
this is a reduced RHS grammar to be used with expandVariablesReferences() to implement the expansions in QMAKE_SUBSTITUTES. using the parser+evaluator for that is consistently up to 25% slower than a purely interpreted approach - except for plain strings (with some quoting), which happens to be exactly what is found in the template files to substitute. Change-Id: I219266460b970c6ddcb43cf85a914fbde6540271 Reviewed-by: Daniel Teske <daniel.teske@nokia.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
This commit is contained in:
@@ -319,7 +319,6 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
m_operator = NoOperator;
|
m_operator = NoOperator;
|
||||||
m_markLine = m_lineNo;
|
m_markLine = m_lineNo;
|
||||||
m_inError = false;
|
m_inError = false;
|
||||||
Context context = CtxTest;
|
|
||||||
int parens = 0; // Braces in value context
|
int parens = 0; // Braces in value context
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
int wordCount = 0; // Number of words in currently accumulated expression
|
int wordCount = 0; // Number of words in currently accumulated expression
|
||||||
@@ -330,8 +329,15 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
ushort quote = 0;
|
ushort quote = 0;
|
||||||
ushort term = 0;
|
ushort term = 0;
|
||||||
|
|
||||||
ushort *ptr = buf;
|
Context context;
|
||||||
ptr += 4;
|
ushort *ptr;
|
||||||
|
if (grammar == ValueGrammar) {
|
||||||
|
context = CtxPureValue;
|
||||||
|
ptr = tokPtr + 2;
|
||||||
|
} else {
|
||||||
|
context = CtxTest;
|
||||||
|
ptr = buf + 4;
|
||||||
|
}
|
||||||
ushort *xprPtr = ptr;
|
ushort *xprPtr = ptr;
|
||||||
|
|
||||||
#define FLUSH_LHS_LITERAL() \
|
#define FLUSH_LHS_LITERAL() \
|
||||||
@@ -383,11 +389,23 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
putTok(tokPtr, TokValueTerminator); \
|
putTok(tokPtr, TokValueTerminator); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
const ushort *end; // End of this line
|
||||||
|
const ushort *cptr; // Start of next line
|
||||||
|
bool lineCont;
|
||||||
|
int indent;
|
||||||
|
|
||||||
|
if (context == CtxPureValue) {
|
||||||
|
end = (const ushort *)in.unicode() + in.length();
|
||||||
|
cptr = 0;
|
||||||
|
lineCont = false;
|
||||||
|
indent = 0; // just gcc being stupid
|
||||||
|
goto nextChr;
|
||||||
|
}
|
||||||
|
|
||||||
forever {
|
forever {
|
||||||
ushort c;
|
ushort c;
|
||||||
|
|
||||||
// First, skip leading whitespace
|
// First, skip leading whitespace
|
||||||
int indent;
|
|
||||||
for (indent = 0; ; ++cur, ++indent) {
|
for (indent = 0; ; ++cur, ++indent) {
|
||||||
c = *cur;
|
c = *cur;
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
@@ -402,8 +420,6 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Then strip comments. Yep - no escaping is possible.
|
// Then strip comments. Yep - no escaping is possible.
|
||||||
const ushort *end; // End of this line
|
|
||||||
const ushort *cptr; // Start of next line
|
|
||||||
for (cptr = cur;; ++cptr) {
|
for (cptr = cur;; ++cptr) {
|
||||||
c = *cptr;
|
c = *cptr;
|
||||||
if (c == '#') {
|
if (c == '#') {
|
||||||
@@ -432,7 +448,6 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Then look for line continuations. Yep - no escaping here as well.
|
// Then look for line continuations. Yep - no escaping here as well.
|
||||||
bool lineCont;
|
|
||||||
forever {
|
forever {
|
||||||
// We don't have to check for underrun here, as we already determined
|
// We don't have to check for underrun here, as we already determined
|
||||||
// that the line is non-empty.
|
// that the line is non-empty.
|
||||||
@@ -592,7 +607,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
*ptr++ = ' ';
|
*ptr++ = ' ';
|
||||||
}
|
}
|
||||||
goto nextChr;
|
goto nextChr;
|
||||||
} else if (c == ' ' || c == '\t') {
|
} else if ((c == ' ' || c == '\t') && context != CtxPureValue) {
|
||||||
putSpace = true;
|
putSpace = true;
|
||||||
goto nextChr;
|
goto nextChr;
|
||||||
} else if (c == '!' && ptr == xprPtr && context == CtxTest) {
|
} else if (c == '!' && ptr == xprPtr && context == CtxTest) {
|
||||||
@@ -602,12 +617,12 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
} else if (c == '\'' || c == '"') {
|
} else if (c == '\'' || c == '"') {
|
||||||
quote = c;
|
quote = c;
|
||||||
goto nextChr;
|
goto nextChr;
|
||||||
} else if (c == ' ' || c == '\t') {
|
|
||||||
FLUSH_LITERAL();
|
|
||||||
goto nextWord;
|
|
||||||
} else if (context == CtxArgs) {
|
} else if (context == CtxArgs) {
|
||||||
// Function arg context
|
// Function arg context
|
||||||
if (c == '(') {
|
if (c == ' ' || c == '\t') {
|
||||||
|
FLUSH_RHS_LITERAL();
|
||||||
|
goto nextWord;
|
||||||
|
} else if (c == '(') {
|
||||||
++parens;
|
++parens;
|
||||||
} else if (c == ')') {
|
} else if (c == ')') {
|
||||||
if (--parens < 0) {
|
if (--parens < 0) {
|
||||||
@@ -643,7 +658,10 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
}
|
}
|
||||||
} else if (context == CtxTest) {
|
} else if (context == CtxTest) {
|
||||||
// Test or LHS context
|
// Test or LHS context
|
||||||
if (c == '(') {
|
if (c == ' ' || c == '\t') {
|
||||||
|
FLUSH_LHS_LITERAL();
|
||||||
|
goto nextWord;
|
||||||
|
} else if (c == '(') {
|
||||||
FLUSH_LHS_LITERAL();
|
FLUSH_LHS_LITERAL();
|
||||||
if (wordCount != 1) {
|
if (wordCount != 1) {
|
||||||
if (wordCount)
|
if (wordCount)
|
||||||
@@ -739,8 +757,11 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
ptr = ++tokPtr;
|
ptr = ++tokPtr;
|
||||||
goto nextToken;
|
goto nextToken;
|
||||||
}
|
}
|
||||||
} else { // context == CtxValue
|
} else if (context == CtxValue) {
|
||||||
if (c == '{') {
|
if (c == ' ' || c == '\t') {
|
||||||
|
FLUSH_RHS_LITERAL();
|
||||||
|
goto nextWord;
|
||||||
|
} else if (c == '{') {
|
||||||
++parens;
|
++parens;
|
||||||
} else if (c == '}') {
|
} else if (c == '}') {
|
||||||
if (!parens) {
|
if (!parens) {
|
||||||
@@ -796,6 +817,8 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
if (context == CtxValue) {
|
if (context == CtxValue) {
|
||||||
tokPtr[-1] = 0; // sizehint
|
tokPtr[-1] = 0; // sizehint
|
||||||
putTok(tokPtr, TokValueTerminator);
|
putTok(tokPtr, TokValueTerminator);
|
||||||
|
} else if (context == CtxPureValue) {
|
||||||
|
putTok(tokPtr, TokValueTerminator);
|
||||||
} else {
|
} else {
|
||||||
bogusTest(tokPtr);
|
bogusTest(tokPtr);
|
||||||
}
|
}
|
||||||
@@ -803,6 +826,9 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
|
|||||||
FLUSH_VALUE_LIST();
|
FLUSH_VALUE_LIST();
|
||||||
if (parens)
|
if (parens)
|
||||||
languageWarning(fL1S("Possible braces mismatch"));
|
languageWarning(fL1S("Possible braces mismatch"));
|
||||||
|
} else if (context == CtxPureValue) {
|
||||||
|
tokPtr = ptr;
|
||||||
|
putTok(tokPtr, TokValueTerminator);
|
||||||
} else {
|
} else {
|
||||||
finalizeCond(tokPtr, buf, ptr, wordCount);
|
finalizeCond(tokPtr, buf, ptr, wordCount);
|
||||||
}
|
}
|
||||||
|
@@ -77,7 +77,7 @@ public:
|
|||||||
|
|
||||||
QMakeParser(ProFileCache *cache, QMakeParserHandler *handler);
|
QMakeParser(ProFileCache *cache, QMakeParserHandler *handler);
|
||||||
|
|
||||||
enum SubGrammar { FullGrammar, TestGrammar };
|
enum SubGrammar { FullGrammar, TestGrammar, ValueGrammar };
|
||||||
// fileName is expected to be absolute and cleanPath()ed.
|
// fileName is expected to be absolute and cleanPath()ed.
|
||||||
ProFile *parsedProFile(const QString &fileName, bool cache = false);
|
ProFile *parsedProFile(const QString &fileName, bool cache = false);
|
||||||
ProFile *parsedProBlock(const QString &contents, const QString &name, int line = 0,
|
ProFile *parsedProBlock(const QString &contents, const QString &name, int line = 0,
|
||||||
@@ -99,7 +99,7 @@ private:
|
|||||||
StCond // Conditionals met on current line
|
StCond // Conditionals met on current line
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Context { CtxTest, CtxValue, CtxArgs };
|
enum Context { CtxTest, CtxValue, CtxPureValue, CtxArgs };
|
||||||
struct ParseCtx {
|
struct ParseCtx {
|
||||||
int parens; // Nesting of non-functional parentheses
|
int parens; // Nesting of non-functional parentheses
|
||||||
int argc; // Number of arguments in current function call
|
int argc; // Number of arguments in current function call
|
||||||
|
Reference in New Issue
Block a user