forked from qt-creator/qt-creator
optimize assignments: record number of literals
that way the result vector can be pre-allocated - which gives zero resizes if no expansions are in the expression. for the joined argument lists of built-in functions, pre-allocate a fixed 5 elements, which covers all cases and more. the argument lists of user-defined functions are not pre-allocated yet.
This commit is contained in:
@@ -199,6 +199,8 @@ public:
|
|||||||
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
|
||||||
|
int litCount; // Number of literals in current expression
|
||||||
|
int expCount; // Number of expansions in current expression
|
||||||
Context context;
|
Context context;
|
||||||
ushort quote; // Enclosing quote type
|
ushort quote; // Enclosing quote type
|
||||||
ushort terminator; // '}' if replace function call is braced, ':' if test function
|
ushort terminator; // '}' if replace function call is braced, ':' if test function
|
||||||
@@ -266,7 +268,7 @@ public:
|
|||||||
static ProStringList split_value_list(const QString &vals);
|
static ProStringList split_value_list(const QString &vals);
|
||||||
bool isActiveConfig(const QString &config, bool regex = false);
|
bool isActiveConfig(const QString &config, bool regex = false);
|
||||||
ProStringList expandVariableReferences(const ProString &value, int *pos = 0, bool joined = false);
|
ProStringList expandVariableReferences(const ProString &value, int *pos = 0, bool joined = false);
|
||||||
ProStringList expandVariableReferences(const ushort *&tokPtr, bool joined = false);
|
ProStringList expandVariableReferences(const ushort *&tokPtr, int sizeHint = 0, bool joined = false);
|
||||||
ProStringList evaluateExpandFunction(const ProString &function, const ProString &arguments);
|
ProStringList evaluateExpandFunction(const ProString &function, const ProString &arguments);
|
||||||
ProStringList evaluateExpandFunction(const ProString &function, const ushort *&tokPtr);
|
ProStringList evaluateExpandFunction(const ProString &function, const ushort *&tokPtr);
|
||||||
ProStringList evaluateExpandFunction(const ProString &function, const ProStringList &args);
|
ProStringList evaluateExpandFunction(const ProString &function, const ProStringList &args);
|
||||||
@@ -681,6 +683,8 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
|
|||||||
Context context = CtxTest;
|
Context context = CtxTest;
|
||||||
int parens = 0;
|
int parens = 0;
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
|
int litCount = 0;
|
||||||
|
int expCount = 0;
|
||||||
bool inError = false;
|
bool inError = false;
|
||||||
bool putSpace = false; // Only ever true inside quoted string
|
bool putSpace = false; // Only ever true inside quoted string
|
||||||
bool lineMarked = true; // For in-expression markers
|
bool lineMarked = true; // For in-expression markers
|
||||||
@@ -714,6 +718,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
|
|||||||
xprPtr[-1] = tlen; \
|
xprPtr[-1] = tlen; \
|
||||||
if (setSep) \
|
if (setSep) \
|
||||||
needSep = TokNewStr; \
|
needSep = TokNewStr; \
|
||||||
|
litCount++; \
|
||||||
} else { \
|
} else { \
|
||||||
ptr -= 2; \
|
ptr -= 2; \
|
||||||
if (setSep && ptr != ((context == CtxValue) ? tokPtr : buf)) \
|
if (setSep && ptr != ((context == CtxValue) ? tokPtr : buf)) \
|
||||||
@@ -822,6 +827,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
|
|||||||
xprPtr[-2] = TokLiteral | needSep;
|
xprPtr[-2] = TokLiteral | needSep;
|
||||||
xprPtr[-1] = tlen;
|
xprPtr[-1] = tlen;
|
||||||
needSep = 0;
|
needSep = 0;
|
||||||
|
litCount++;
|
||||||
} else {
|
} else {
|
||||||
ptr -= 2;
|
ptr -= 2;
|
||||||
}
|
}
|
||||||
@@ -871,6 +877,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
|
|||||||
tok |= TokQuoted;
|
tok |= TokQuoted;
|
||||||
tok |= needSep;
|
tok |= needSep;
|
||||||
needSep = 0;
|
needSep = 0;
|
||||||
|
expCount++;
|
||||||
tlen = ptr - xprPtr;
|
tlen = ptr - xprPtr;
|
||||||
if (rtok == TokVariable) {
|
if (rtok == TokVariable) {
|
||||||
xprPtr[-4] = tok;
|
xprPtr[-4] = tok;
|
||||||
@@ -892,6 +899,8 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
|
|||||||
top.terminator = term;
|
top.terminator = term;
|
||||||
top.context = context;
|
top.context = context;
|
||||||
top.argc = argc;
|
top.argc = argc;
|
||||||
|
top.litCount = litCount;
|
||||||
|
top.expCount = expCount;
|
||||||
}
|
}
|
||||||
parens = 0;
|
parens = 0;
|
||||||
quote = 0;
|
quote = 0;
|
||||||
@@ -962,6 +971,8 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
|
|||||||
term = top.terminator;
|
term = top.terminator;
|
||||||
context = top.context;
|
context = top.context;
|
||||||
argc = top.argc;
|
argc = top.argc;
|
||||||
|
litCount = top.litCount;
|
||||||
|
expCount = top.expCount;
|
||||||
xprStack.resize(xprStack.size() - 1);
|
xprStack.resize(xprStack.size() - 1);
|
||||||
}
|
}
|
||||||
if (term == ':') {
|
if (term == ':') {
|
||||||
@@ -1070,7 +1081,8 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
|
|||||||
putBlock(tokPtr, buf, tlen);
|
putBlock(tokPtr, buf, tlen);
|
||||||
putTok(tokPtr, tok);
|
putTok(tokPtr, tok);
|
||||||
context = CtxValue;
|
context = CtxValue;
|
||||||
ptr = tokPtr;
|
ptr = ++tokPtr;
|
||||||
|
litCount = expCount = 0;
|
||||||
needSep = 0;
|
needSep = 0;
|
||||||
goto nextToken;
|
goto nextToken;
|
||||||
}
|
}
|
||||||
@@ -1109,6 +1121,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (context == CtxValue) {
|
if (context == CtxValue) {
|
||||||
|
tokPtr[-1] = litCount ? litCount + expCount : 0;
|
||||||
tokPtr = ptr;
|
tokPtr = ptr;
|
||||||
putTok(tokPtr, TokValueTerminator);
|
putTok(tokPtr, TokValueTerminator);
|
||||||
} else {
|
} else {
|
||||||
@@ -1837,7 +1850,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProLoop(
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
ProString variable;
|
ProString variable;
|
||||||
ProStringList oldVarVal;
|
ProStringList oldVarVal;
|
||||||
ProString it_list = expandVariableReferences(exprPtr, true).at(0);
|
ProString it_list = expandVariableReferences(exprPtr, 0, true).at(0);
|
||||||
if (_variable.isEmpty()) {
|
if (_variable.isEmpty()) {
|
||||||
if (it_list != statics.strever) {
|
if (it_list != statics.strever) {
|
||||||
logMessage(format("Invalid loop expression."));
|
logMessage(format("Invalid loop expression."));
|
||||||
@@ -1919,6 +1932,8 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProLoop(
|
|||||||
void ProFileEvaluator::Private::visitProVariable(
|
void ProFileEvaluator::Private::visitProVariable(
|
||||||
ushort tok, const ProStringList &curr, const ushort *&tokPtr)
|
ushort tok, const ProStringList &curr, const ushort *&tokPtr)
|
||||||
{
|
{
|
||||||
|
int sizeHint = *tokPtr++;
|
||||||
|
|
||||||
if (curr.size() != 1) {
|
if (curr.size() != 1) {
|
||||||
skipExpression(tokPtr);
|
skipExpression(tokPtr);
|
||||||
logMessage(format("Left hand side of assignment must expand to exactly one word."));
|
logMessage(format("Left hand side of assignment must expand to exactly one word."));
|
||||||
@@ -1929,7 +1944,7 @@ void ProFileEvaluator::Private::visitProVariable(
|
|||||||
if (tok == TokReplace) { // ~=
|
if (tok == TokReplace) { // ~=
|
||||||
// DEFINES ~= s/a/b/?[gqi]
|
// DEFINES ~= s/a/b/?[gqi]
|
||||||
|
|
||||||
const ProStringList &varVal = expandVariableReferences(tokPtr, true);
|
const ProStringList &varVal = expandVariableReferences(tokPtr, sizeHint, true);
|
||||||
const QString &val = varVal.at(0).toQString(m_tmp1);
|
const QString &val = varVal.at(0).toQString(m_tmp1);
|
||||||
if (val.length() < 4 || val.at(0) != QLatin1Char('s')) {
|
if (val.length() < 4 || val.at(0) != QLatin1Char('s')) {
|
||||||
logMessage(format("the ~= operator can handle only the s/// function."));
|
logMessage(format("the ~= operator can handle only the s/// function."));
|
||||||
@@ -1962,7 +1977,7 @@ void ProFileEvaluator::Private::visitProVariable(
|
|||||||
replaceInList(&m_filevaluemap[currentProFile()][varName], regexp, replace, global, m_tmp2);
|
replaceInList(&m_filevaluemap[currentProFile()][varName], regexp, replace, global, m_tmp2);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ProStringList varVal = expandVariableReferences(tokPtr);
|
ProStringList varVal = expandVariableReferences(tokPtr, sizeHint);
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
default: // whatever - cannot happen
|
default: // whatever - cannot happen
|
||||||
case TokAssign: // =
|
case TokAssign: // =
|
||||||
@@ -2641,9 +2656,10 @@ bool ProFileEvaluator::Private::isActiveConfig(const QString &config, bool regex
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProStringList ProFileEvaluator::Private::expandVariableReferences(
|
ProStringList ProFileEvaluator::Private::expandVariableReferences(
|
||||||
const ushort *&tokPtr, bool joined)
|
const ushort *&tokPtr, int sizeHint, bool joined)
|
||||||
{
|
{
|
||||||
ProStringList ret;
|
ProStringList ret;
|
||||||
|
ret.reserve(sizeHint);
|
||||||
forever {
|
forever {
|
||||||
evaluateExpression(tokPtr, &ret, joined);
|
evaluateExpression(tokPtr, &ret, joined);
|
||||||
switch (*tokPtr) {
|
switch (*tokPtr) {
|
||||||
@@ -2761,7 +2777,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction(
|
|||||||
return evaluateFunction(*it, prepareFunctionArgs(tokPtr), 0);
|
return evaluateFunction(*it, prepareFunctionArgs(tokPtr), 0);
|
||||||
|
|
||||||
//why don't the builtin functions just use args_list? --Sam
|
//why don't the builtin functions just use args_list? --Sam
|
||||||
return evaluateExpandFunction(func, expandVariableReferences(tokPtr, true));
|
return evaluateExpandFunction(func, expandVariableReferences(tokPtr, 5, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
ProStringList ProFileEvaluator::Private::evaluateExpandFunction(
|
ProStringList ProFileEvaluator::Private::evaluateExpandFunction(
|
||||||
@@ -3179,7 +3195,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit
|
|||||||
return evaluateBoolFunction(*it, prepareFunctionArgs(tokPtr), function);
|
return evaluateBoolFunction(*it, prepareFunctionArgs(tokPtr), function);
|
||||||
|
|
||||||
//why don't the builtin functions just use args_list? --Sam
|
//why don't the builtin functions just use args_list? --Sam
|
||||||
return evaluateConditionalFunction(function, expandVariableReferences(tokPtr, true));
|
return evaluateConditionalFunction(function, expandVariableReferences(tokPtr, 5, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateConditionalFunction(
|
ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateConditionalFunction(
|
||||||
|
|||||||
@@ -137,6 +137,8 @@ static const ushort *skipToken(ushort tok, const ushort *&tokPtr, int &lineNo)
|
|||||||
case TokAppendUnique:
|
case TokAppendUnique:
|
||||||
case TokRemove:
|
case TokRemove:
|
||||||
case TokReplace:
|
case TokReplace:
|
||||||
|
tokPtr++;
|
||||||
|
// fallthrough
|
||||||
case TokTestCall:
|
case TokTestCall:
|
||||||
skipExpression(tokPtr, lineNo);
|
skipExpression(tokPtr, lineNo);
|
||||||
break;
|
break;
|
||||||
@@ -206,7 +208,7 @@ void ProWriter::addFiles(ProFile *profile, QStringList *lines,
|
|||||||
lines->insert(lineNo, added);
|
lines->insert(lineNo, added);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
skipExpression(tokPtr, lineNo);
|
skipExpression(++tokPtr, lineNo);
|
||||||
} else {
|
} else {
|
||||||
lastXpr = skipToken(tok, tokPtr, lineNo);
|
lastXpr = skipToken(tok, tokPtr, lineNo);
|
||||||
}
|
}
|
||||||
@@ -236,7 +238,7 @@ static void findProVariables(const ushort *tokPtr, const QStringList &vars,
|
|||||||
} else if (tok == TokAssign || tok == TokAppend || tok == TokAppendUnique) {
|
} else if (tok == TokAssign || tok == TokAppend || tok == TokAppendUnique) {
|
||||||
if (getLiteral(lastXpr, tokPtr - 1, tmp) && vars.contains(tmp))
|
if (getLiteral(lastXpr, tokPtr - 1, tmp) && vars.contains(tmp))
|
||||||
*proVars << lineNo;
|
*proVars << lineNo;
|
||||||
skipExpression(tokPtr, lineNo);
|
skipExpression(++tokPtr, lineNo);
|
||||||
} else {
|
} else {
|
||||||
lastXpr = skipToken(tok, tokPtr, lineNo);
|
lastXpr = skipToken(tok, tokPtr, lineNo);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user