Commit ed745564 authored by Oswald Buddenhagen's avatar Oswald Buddenhagen
Browse files

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: default avatarDaniel Teske <daniel.teske@nokia.com>
Reviewed-by: default avatarOswald Buddenhagen <oswald.buddenhagen@nokia.com>
parent 98afdc92
......@@ -319,7 +319,6 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
m_operator = NoOperator;
m_markLine = m_lineNo;
m_inError = false;
Context context = CtxTest;
int parens = 0; // Braces in value context
int argc = 0;
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 term = 0;
ushort *ptr = buf;
ptr += 4;
Context context;
ushort *ptr;
if (grammar == ValueGrammar) {
context = CtxPureValue;
ptr = tokPtr + 2;
} else {
context = CtxTest;
ptr = buf + 4;
}
ushort *xprPtr = ptr;
#define FLUSH_LHS_LITERAL() \
......@@ -383,11 +389,23 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
putTok(tokPtr, TokValueTerminator); \
} 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 {
ushort c;
// First, skip leading whitespace
int indent;
for (indent = 0; ; ++cur, ++indent) {
c = *cur;
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.
const ushort *end; // End of this line
const ushort *cptr; // Start of next line
for (cptr = cur;; ++cptr) {
c = *cptr;
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.
bool lineCont;
forever {
// We don't have to check for underrun here, as we already determined
// that the line is non-empty.
......@@ -592,7 +607,7 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
*ptr++ = ' ';
}
goto nextChr;
} else if (c == ' ' || c == '\t') {
} else if ((c == ' ' || c == '\t') && context != CtxPureValue) {
putSpace = true;
goto nextChr;
} 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 == '"') {
quote = c;
goto nextChr;
} else if (c == ' ' || c == '\t') {
FLUSH_LITERAL();
goto nextWord;
} else if (context == CtxArgs) {
// Function arg context
if (c == '(') {
if (c == ' ' || c == '\t') {
FLUSH_RHS_LITERAL();
goto nextWord;
} else if (c == '(') {
++parens;
} else if (c == ')') {
if (--parens < 0) {
......@@ -643,7 +658,10 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
}
} else if (context == CtxTest) {
// Test or LHS context
if (c == '(') {
if (c == ' ' || c == '\t') {
FLUSH_LHS_LITERAL();
goto nextWord;
} else if (c == '(') {
FLUSH_LHS_LITERAL();
if (wordCount != 1) {
if (wordCount)
......@@ -739,8 +757,11 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
ptr = ++tokPtr;
goto nextToken;
}
} else { // context == CtxValue
if (c == '{') {
} else if (context == CtxValue) {
if (c == ' ' || c == '\t') {
FLUSH_RHS_LITERAL();
goto nextWord;
} else if (c == '{') {
++parens;
} else if (c == '}') {
if (!parens) {
......@@ -796,6 +817,8 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
if (context == CtxValue) {
tokPtr[-1] = 0; // sizehint
putTok(tokPtr, TokValueTerminator);
} else if (context == CtxPureValue) {
putTok(tokPtr, TokValueTerminator);
} else {
bogusTest(tokPtr);
}
......@@ -803,6 +826,9 @@ bool QMakeParser::read(ProFile *pro, const QString &in, int line, SubGrammar gra
FLUSH_VALUE_LIST();
if (parens)
languageWarning(fL1S("Possible braces mismatch"));
} else if (context == CtxPureValue) {
tokPtr = ptr;
putTok(tokPtr, TokValueTerminator);
} else {
finalizeCond(tokPtr, buf, ptr, wordCount);
}
......
......@@ -77,7 +77,7 @@ public:
QMakeParser(ProFileCache *cache, QMakeParserHandler *handler);
enum SubGrammar { FullGrammar, TestGrammar };
enum SubGrammar { FullGrammar, TestGrammar, ValueGrammar };
// fileName is expected to be absolute and cleanPath()ed.
ProFile *parsedProFile(const QString &fileName, bool cache = false);
ProFile *parsedProBlock(const QString &contents, const QString &name, int line = 0,
......@@ -99,7 +99,7 @@ private:
StCond // Conditionals met on current line
};
enum Context { CtxTest, CtxValue, CtxArgs };
enum Context { CtxTest, CtxValue, CtxPureValue, CtxArgs };
struct ParseCtx {
int parens; // Nesting of non-functional parentheses
int argc; // Number of arguments in current function call
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment