forked from qt-creator/qt-creator
optimize assembly of arguments for built-in functions
this function class just joins each string list argument into a single string. so instead of first building a list and joining it right afterwards, create a single string in the first place.
This commit is contained in:
@@ -258,7 +258,7 @@ public:
|
|||||||
|
|
||||||
static QStringList split_value_list(const QString &vals);
|
static QStringList split_value_list(const QString &vals);
|
||||||
bool isActiveConfig(const QString &config, bool regex = false);
|
bool isActiveConfig(const QString &config, bool regex = false);
|
||||||
QStringList expandVariableReferences(const QString &value, int *pos = 0);
|
QStringList expandVariableReferences(const QString &value, int *pos = 0, bool joined = false);
|
||||||
QStringList evaluateExpandFunction(const QString &function, const QString &arguments);
|
QStringList evaluateExpandFunction(const QString &function, const QString &arguments);
|
||||||
QString format(const char *format) const;
|
QString format(const char *format) const;
|
||||||
void logMessage(const QString &msg) const;
|
void logMessage(const QString &msg) const;
|
||||||
@@ -1268,7 +1268,7 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitProLoop(ProLoop *loop)
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
QString variable;
|
QString variable;
|
||||||
QStringList oldVarVal;
|
QStringList oldVarVal;
|
||||||
QString it_list = expandVariableReferences(loop->expression()).join(statics.field_sep);
|
QString it_list = expandVariableReferences(loop->expression(), 0, true).first();
|
||||||
if (loop->variable().isEmpty()) {
|
if (loop->variable().isEmpty()) {
|
||||||
if (it_list != statics.strever) {
|
if (it_list != statics.strever) {
|
||||||
logMessage(format("Invalid loop expression."));
|
logMessage(format("Invalid loop expression."));
|
||||||
@@ -1351,12 +1351,11 @@ void ProFileEvaluator::Private::visitProVariable(ProVariable *var)
|
|||||||
{
|
{
|
||||||
m_lineNo = var->lineNumber();
|
m_lineNo = var->lineNumber();
|
||||||
const QString &varName = var->variable();
|
const QString &varName = var->variable();
|
||||||
QStringList varVal = expandVariableReferences(var->value());
|
|
||||||
|
|
||||||
if (var->variableOperator() == ProVariable::ReplaceOperator) { // ~=
|
if (var->variableOperator() == ProVariable::ReplaceOperator) { // ~=
|
||||||
// DEFINES ~= s/a/b/?[gqi]
|
// DEFINES ~= s/a/b/?[gqi]
|
||||||
|
|
||||||
QString val = varVal.join(statics.field_sep);
|
QString val = expandVariableReferences(var->value(), 0, true).first();
|
||||||
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."));
|
||||||
return;
|
return;
|
||||||
@@ -1388,6 +1387,7 @@ void ProFileEvaluator::Private::visitProVariable(ProVariable *var)
|
|||||||
replaceInList(&m_filevaluemap[currentProFile()][varName], regexp, replace, global);
|
replaceInList(&m_filevaluemap[currentProFile()][varName], regexp, replace, global);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
QStringList varVal = expandVariableReferences(var->value());
|
||||||
switch (var->variableOperator()) {
|
switch (var->variableOperator()) {
|
||||||
default: // ReplaceOperator - cannot happen
|
default: // ReplaceOperator - cannot happen
|
||||||
case ProVariable::SetOperator: // =
|
case ProVariable::SetOperator: // =
|
||||||
@@ -1796,7 +1796,7 @@ static void appendString(const QString &string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void flushCurrent(QStringList *ret,
|
static void flushCurrent(QStringList *ret,
|
||||||
QString *current, QChar **ptr, QString *pending)
|
QString *current, QChar **ptr, QString *pending, bool joined)
|
||||||
{
|
{
|
||||||
QChar *uc = (QChar*)current->constData();
|
QChar *uc = (QChar*)current->constData();
|
||||||
int len = *ptr - uc;
|
int len = *ptr - uc;
|
||||||
@@ -1806,12 +1806,14 @@ static void flushCurrent(QStringList *ret,
|
|||||||
} else if (!pending->isEmpty()) {
|
} else if (!pending->isEmpty()) {
|
||||||
ret->append(*pending);
|
ret->append(*pending);
|
||||||
pending->clear();
|
pending->clear();
|
||||||
|
} else if (joined) {
|
||||||
|
ret->append(QString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void flushFinal(QStringList *ret,
|
static inline void flushFinal(QStringList *ret,
|
||||||
const QString ¤t, const QChar *ptr, const QString &pending,
|
const QString ¤t, const QChar *ptr, const QString &pending,
|
||||||
const QString &str, bool replaced)
|
const QString &str, bool replaced, bool joined)
|
||||||
{
|
{
|
||||||
int len = ptr - current.data();
|
int len = ptr - current.data();
|
||||||
if (len) {
|
if (len) {
|
||||||
@@ -1821,10 +1823,13 @@ static inline void flushFinal(QStringList *ret,
|
|||||||
ret->append(QString(current.data(), len));
|
ret->append(QString(current.data(), len));
|
||||||
} else if (!pending.isEmpty()) {
|
} else if (!pending.isEmpty()) {
|
||||||
ret->append(pending);
|
ret->append(pending);
|
||||||
|
} else if (joined) {
|
||||||
|
ret->append(QString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList ProFileEvaluator::Private::expandVariableReferences(const QString &str, int *pos)
|
QStringList ProFileEvaluator::Private::expandVariableReferences(
|
||||||
|
const QString &str, int *pos, bool joined)
|
||||||
{
|
{
|
||||||
QStringList ret;
|
QStringList ret;
|
||||||
// if (ok)
|
// if (ok)
|
||||||
@@ -1855,6 +1860,7 @@ QStringList ProFileEvaluator::Private::expandVariableReferences(const QString &s
|
|||||||
QString var, args;
|
QString var, args;
|
||||||
|
|
||||||
bool replaced = false;
|
bool replaced = false;
|
||||||
|
bool putSpace = false;
|
||||||
QString current; // Buffer for successively assembled string segments
|
QString current; // Buffer for successively assembled string segments
|
||||||
current.resize(str.size());
|
current.resize(str.size());
|
||||||
QChar *ptr = current.data();
|
QChar *ptr = current.data();
|
||||||
@@ -1946,13 +1952,18 @@ QStringList ProFileEvaluator::Private::expandVariableReferences(const QString &s
|
|||||||
replacement = values(map(var));
|
replacement = values(map(var));
|
||||||
}
|
}
|
||||||
if (!replacement.isEmpty()) {
|
if (!replacement.isEmpty()) {
|
||||||
if (quote) {
|
if (quote || joined) {
|
||||||
|
if (putSpace) {
|
||||||
|
putSpace = false;
|
||||||
|
if (!replacement.at(0).isEmpty()) // Bizarre, indeed
|
||||||
|
appendChar(' ', ¤t, &ptr, &pending);
|
||||||
|
}
|
||||||
appendString(replacement.join(statics.field_sep),
|
appendString(replacement.join(statics.field_sep),
|
||||||
¤t, &ptr, &pending);
|
¤t, &ptr, &pending);
|
||||||
} else {
|
} else {
|
||||||
appendString(replacement.at(0), ¤t, &ptr, &pending);
|
appendString(replacement.at(0), ¤t, &ptr, &pending);
|
||||||
if (replacement.size() > 1) {
|
if (replacement.size() > 1) {
|
||||||
flushCurrent(&ret, ¤t, &ptr, &pending);
|
flushCurrent(&ret, ¤t, &ptr, &pending, false);
|
||||||
int j = 1;
|
int j = 1;
|
||||||
if (replacement.size() > 2) {
|
if (replacement.size() > 2) {
|
||||||
// FIXME: ret.reserve(ret.size() + replacement.size() - 2);
|
// FIXME: ret.reserve(ret.size() + replacement.size() - 2);
|
||||||
@@ -1983,7 +1994,10 @@ QStringList ProFileEvaluator::Private::expandVariableReferences(const QString &s
|
|||||||
quote = unicode;
|
quote = unicode;
|
||||||
continue;
|
continue;
|
||||||
} else if (unicode == SPACE || unicode == TAB) {
|
} else if (unicode == SPACE || unicode == TAB) {
|
||||||
flushCurrent(&ret, ¤t, &ptr, &pending);
|
if (!joined)
|
||||||
|
flushCurrent(&ret, ¤t, &ptr, &pending, false);
|
||||||
|
else if ((ptr - (QChar*)current.constData()) || !pending.isEmpty())
|
||||||
|
putSpace = true;
|
||||||
continue;
|
continue;
|
||||||
} else if (pos) {
|
} else if (pos) {
|
||||||
if (unicode == LPAREN) {
|
if (unicode == LPAREN) {
|
||||||
@@ -1991,17 +2005,26 @@ QStringList ProFileEvaluator::Private::expandVariableReferences(const QString &s
|
|||||||
} else if (unicode == RPAREN) {
|
} else if (unicode == RPAREN) {
|
||||||
--parens;
|
--parens;
|
||||||
} else if (!parens && unicode == COMMA) {
|
} else if (!parens && unicode == COMMA) {
|
||||||
|
if (!joined) {
|
||||||
*pos = i + 1;
|
*pos = i + 1;
|
||||||
flushFinal(&ret, current, ptr, pending, str, replaced);
|
flushFinal(&ret, current, ptr, pending, str, replaced, false);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
flushCurrent(&ret, ¤t, &ptr, &pending, true);
|
||||||
|
putSpace = false;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (putSpace) {
|
||||||
|
putSpace = false;
|
||||||
|
appendChar(' ', ¤t, &ptr, &pending);
|
||||||
|
}
|
||||||
appendChar(unicode, ¤t, &ptr, &pending);
|
appendChar(unicode, ¤t, &ptr, &pending);
|
||||||
}
|
}
|
||||||
if (pos)
|
if (pos)
|
||||||
*pos = str_len;
|
*pos = str_len;
|
||||||
flushFinal(&ret, current, ptr, pending, str, replaced);
|
flushFinal(&ret, current, ptr, pending, str, replaced, joined);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2100,14 +2123,12 @@ QStringList ProFileEvaluator::Private::evaluateFunction(
|
|||||||
|
|
||||||
QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &func, const QString &arguments)
|
QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &func, const QString &arguments)
|
||||||
{
|
{
|
||||||
QList<QStringList> args_list = prepareFunctionArgs(arguments);
|
|
||||||
|
|
||||||
if (ProFunctionDef *funcPtr = m_functionDefs.replaceFunctions.value(func, 0))
|
if (ProFunctionDef *funcPtr = m_functionDefs.replaceFunctions.value(func, 0))
|
||||||
return evaluateFunction(funcPtr, args_list, 0);
|
return evaluateFunction(funcPtr, prepareFunctionArgs(arguments), 0);
|
||||||
|
|
||||||
QStringList args; //why don't the builtin functions just use args_list? --Sam
|
//why don't the builtin functions just use args_list? --Sam
|
||||||
foreach (const QStringList &arg, args_list)
|
int pos = 0;
|
||||||
args += arg.join(statics.field_sep);
|
QStringList args = expandVariableReferences(arguments, &pos, true);
|
||||||
|
|
||||||
ExpandFunc func_t = ExpandFunc(statics.expands.value(func.toLower()));
|
ExpandFunc func_t = ExpandFunc(statics.expands.value(func.toLower()));
|
||||||
|
|
||||||
@@ -2469,11 +2490,9 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
|
|||||||
ProItem::ProItemReturn ProFileEvaluator::Private::evaluateConditionalFunction(
|
ProItem::ProItemReturn ProFileEvaluator::Private::evaluateConditionalFunction(
|
||||||
const QString &function, const QString &arguments)
|
const QString &function, const QString &arguments)
|
||||||
{
|
{
|
||||||
QList<QStringList> args_list = prepareFunctionArgs(arguments);
|
|
||||||
|
|
||||||
if (ProFunctionDef *funcPtr = m_functionDefs.testFunctions.value(function, 0)) {
|
if (ProFunctionDef *funcPtr = m_functionDefs.testFunctions.value(function, 0)) {
|
||||||
bool ok;
|
bool ok;
|
||||||
QStringList ret = evaluateFunction(funcPtr, args_list, &ok);
|
QStringList ret = evaluateFunction(funcPtr, prepareFunctionArgs(arguments), &ok);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
if (ret.isEmpty()) {
|
if (ret.isEmpty()) {
|
||||||
return ProItem::ReturnTrue;
|
return ProItem::ReturnTrue;
|
||||||
@@ -2498,9 +2517,9 @@ ProItem::ProItemReturn ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
return ProItem::ReturnFalse;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList args; //why don't the builtin functions just use args_list? --Sam
|
//why don't the builtin functions just use args_list? --Sam
|
||||||
foreach (const QStringList &arg, args_list)
|
int pos = 0;
|
||||||
args += arg.join(statics.field_sep);
|
QStringList args = expandVariableReferences(arguments, &pos, true);
|
||||||
|
|
||||||
TestFunc func_t = (TestFunc)statics.functions.value(function);
|
TestFunc func_t = (TestFunc)statics.functions.value(function);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user