forked from qt-creator/qt-creator
don't pre-split RHS of variable assignments
creating tons of items is a tad allocation-intensive and thus slow. this is probably slower for often-included files, as now the splitting is done in every evaluation pass.
This commit is contained in:
@@ -44,13 +44,10 @@ struct AbstractProItemVisitor
|
|||||||
virtual ProItem::ProItemReturn visitProLoopIteration() = 0;
|
virtual ProItem::ProItemReturn visitProLoopIteration() = 0;
|
||||||
virtual void visitProLoopCleanup() = 0;
|
virtual void visitProLoopCleanup() = 0;
|
||||||
|
|
||||||
virtual void visitBeginProVariable(ProVariable *variable) = 0;
|
|
||||||
virtual void visitEndProVariable(ProVariable *variable) = 0;
|
|
||||||
|
|
||||||
virtual ProItem::ProItemReturn visitBeginProFile(ProFile *value) = 0;
|
virtual ProItem::ProItemReturn visitBeginProFile(ProFile *value) = 0;
|
||||||
virtual ProItem::ProItemReturn visitEndProFile(ProFile *value) = 0;
|
virtual ProItem::ProItemReturn visitEndProFile(ProFile *value) = 0;
|
||||||
|
|
||||||
virtual void visitProValue(ProValue *value) = 0;
|
virtual void visitProVariable(ProVariable *variable) = 0;
|
||||||
virtual ProItem::ProItemReturn visitProFunction(ProFunction *function) = 0;
|
virtual ProItem::ProItemReturn visitProFunction(ProFunction *function) = 0;
|
||||||
virtual void visitProOperator(ProOperator *function) = 0;
|
virtual void visitProOperator(ProOperator *function) = 0;
|
||||||
virtual void visitProCondition(ProCondition *function) = 0;
|
virtual void visitProCondition(ProCondition *function) = 0;
|
||||||
|
|||||||
@@ -196,7 +196,8 @@ public:
|
|||||||
ProBlock *currentBlock();
|
ProBlock *currentBlock();
|
||||||
void updateItem(ushort *ptr);
|
void updateItem(ushort *ptr);
|
||||||
void updateItem2();
|
void updateItem2();
|
||||||
bool insertVariable(ushort *ptr, bool *doSplit, bool *doSemicolon);
|
ProVariable *startVariable(ushort *ptr);
|
||||||
|
void finalizeVariable(ProVariable *var);
|
||||||
void insertOperator(const char op);
|
void insertOperator(const char op);
|
||||||
void enterScope(bool multiLine);
|
void enterScope(bool multiLine);
|
||||||
void leaveScope();
|
void leaveScope();
|
||||||
@@ -214,11 +215,9 @@ public:
|
|||||||
void visitEndProBlock(ProBlock *block);
|
void visitEndProBlock(ProBlock *block);
|
||||||
ProItem::ProItemReturn visitProLoopIteration();
|
ProItem::ProItemReturn visitProLoopIteration();
|
||||||
void visitProLoopCleanup();
|
void visitProLoopCleanup();
|
||||||
void visitBeginProVariable(ProVariable *variable);
|
|
||||||
void visitEndProVariable(ProVariable *variable);
|
|
||||||
ProItem::ProItemReturn visitBeginProFile(ProFile *value);
|
ProItem::ProItemReturn visitBeginProFile(ProFile *value);
|
||||||
ProItem::ProItemReturn visitEndProFile(ProFile *value);
|
ProItem::ProItemReturn visitEndProFile(ProFile *value);
|
||||||
void visitProValue(ProValue *value);
|
void visitProVariable(ProVariable *variable);
|
||||||
ProItem::ProItemReturn visitProFunction(ProFunction *function);
|
ProItem::ProItemReturn visitProFunction(ProFunction *function);
|
||||||
void visitProOperator(ProOperator *oper);
|
void visitProOperator(ProOperator *oper);
|
||||||
void visitProCondition(ProCondition *condition);
|
void visitProCondition(ProCondition *condition);
|
||||||
@@ -230,8 +229,8 @@ public:
|
|||||||
const ProFile *pro) const;
|
const ProFile *pro) const;
|
||||||
QString propertyValue(const QString &val, bool complain = true) const;
|
QString propertyValue(const QString &val, bool complain = true) const;
|
||||||
|
|
||||||
QStringList split_value_list(const QString &vals, bool do_semicolon = false);
|
static QStringList split_value_list(const QString &vals, bool do_semicolon = false);
|
||||||
QStringList split_arg_list(const QString ¶ms);
|
static QStringList split_arg_list(const QString ¶ms);
|
||||||
bool isActiveConfig(const QString &config, bool regex = false);
|
bool isActiveConfig(const QString &config, bool regex = false);
|
||||||
QStringList expandVariableReferences(const QString &value);
|
QStringList expandVariableReferences(const QString &value);
|
||||||
void doVariableReplace(QString *str);
|
void doVariableReplace(QString *str);
|
||||||
@@ -266,7 +265,6 @@ public:
|
|||||||
struct State {
|
struct State {
|
||||||
bool condition;
|
bool condition;
|
||||||
bool prevCondition;
|
bool prevCondition;
|
||||||
QStringList varVal;
|
|
||||||
} m_sts;
|
} m_sts;
|
||||||
bool m_invertNext; // Short-lived, so not in State
|
bool m_invertNext; // Short-lived, so not in State
|
||||||
bool m_hadCondition; // Nested calls set it on return, so no need for it to be in State
|
bool m_hadCondition; // Nested calls set it on return, so no need for it to be in State
|
||||||
@@ -358,11 +356,9 @@ bool ProFileEvaluator::Private::read(ProBlock *pro, QTextStream *ts)
|
|||||||
m_blockstack.push(pro);
|
m_blockstack.push(pro);
|
||||||
|
|
||||||
freshLine:
|
freshLine:
|
||||||
|
ProVariable *currAssignment = 0;
|
||||||
int parens = 0;
|
int parens = 0;
|
||||||
bool inError = false;
|
bool inError = false;
|
||||||
bool inAssignment = false;
|
|
||||||
bool doSplit = false;
|
|
||||||
bool doSemicolon = false;
|
|
||||||
bool putSpace = false;
|
bool putSpace = false;
|
||||||
ushort quote = 0;
|
ushort quote = 0;
|
||||||
while (!ts->atEnd()) {
|
while (!ts->atEnd()) {
|
||||||
@@ -374,7 +370,12 @@ bool ProFileEvaluator::Private::read(ProBlock *pro, QTextStream *ts)
|
|||||||
// First, skip leading whitespace
|
// First, skip leading whitespace
|
||||||
forever {
|
forever {
|
||||||
if (cur == end) { // Entirely empty line (sans whitespace)
|
if (cur == end) { // Entirely empty line (sans whitespace)
|
||||||
updateItem2();
|
if (currAssignment) {
|
||||||
|
finalizeVariable(currAssignment);
|
||||||
|
currAssignment = 0;
|
||||||
|
} else {
|
||||||
|
updateItem2();
|
||||||
|
}
|
||||||
finalizeBlock();
|
finalizeBlock();
|
||||||
++m_lineNo;
|
++m_lineNo;
|
||||||
goto freshLine;
|
goto freshLine;
|
||||||
@@ -419,7 +420,7 @@ bool ProFileEvaluator::Private::read(ProBlock *pro, QTextStream *ts)
|
|||||||
m_proitem.reserve(m_proitem.length() + (end - cur));
|
m_proitem.reserve(m_proitem.length() + (end - cur));
|
||||||
|
|
||||||
// Finally, do the tokenization
|
// Finally, do the tokenization
|
||||||
if (!inAssignment) {
|
if (!currAssignment) {
|
||||||
newItem:
|
newItem:
|
||||||
ptr = (ushort *)m_proitem.unicode() + m_proitem.length();
|
ptr = (ushort *)m_proitem.unicode() + m_proitem.length();
|
||||||
do {
|
do {
|
||||||
@@ -454,8 +455,7 @@ bool ProFileEvaluator::Private::read(ProBlock *pro, QTextStream *ts)
|
|||||||
goto nextItem;
|
goto nextItem;
|
||||||
}
|
}
|
||||||
if (c == '=') {
|
if (c == '=') {
|
||||||
if (insertVariable(ptr, &doSplit, &doSemicolon)) {
|
if ((currAssignment = startVariable(ptr))) {
|
||||||
inAssignment = true;
|
|
||||||
putSpace = false;
|
putSpace = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -485,97 +485,41 @@ bool ProFileEvaluator::Private::read(ProBlock *pro, QTextStream *ts)
|
|||||||
putSpace = true;
|
putSpace = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // !inAssignment
|
} // !currAssignment
|
||||||
|
|
||||||
nextVal:
|
|
||||||
ptr = (ushort *)m_proitem.unicode() + m_proitem.length();
|
ptr = (ushort *)m_proitem.unicode() + m_proitem.length();
|
||||||
do {
|
do {
|
||||||
if (cur == end)
|
if (cur == end)
|
||||||
goto lineEnd;
|
goto lineEnd;
|
||||||
c = *cur++;
|
c = *cur++;
|
||||||
} while (c == ' ' || c == '\t');
|
} while (c == ' ' || c == '\t');
|
||||||
if (doSplit) {
|
forever {
|
||||||
// Qmake's parser supports truly bizarre quote nesting here, but later
|
if (putSpace) {
|
||||||
// stages (in qmake) don't grok it anyway. So make it simple instead.
|
putSpace = false;
|
||||||
forever {
|
*ptr++ = ' ';
|
||||||
if (c == '\\') {
|
|
||||||
ushort ec;
|
|
||||||
if (cur != end && ((ec = *cur) == '"' || ec == '\'')) {
|
|
||||||
++cur;
|
|
||||||
if (putSpace) {
|
|
||||||
putSpace = false;
|
|
||||||
*ptr++ = ' ';
|
|
||||||
}
|
|
||||||
*ptr++ = '\\';
|
|
||||||
*ptr++ = ec;
|
|
||||||
goto getNext;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (quote) {
|
|
||||||
if (c == quote) {
|
|
||||||
quote = 0;
|
|
||||||
} else if (c == ' ' || c == '\t') {
|
|
||||||
putSpace = true;
|
|
||||||
goto getNext;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (c == '"' || c == '\'') {
|
|
||||||
quote = c;
|
|
||||||
} else if (c == ')') {
|
|
||||||
--parens;
|
|
||||||
} else if (c == '(') {
|
|
||||||
++parens;
|
|
||||||
} else if (c == ' ' || c == '\t') {
|
|
||||||
if (parens) {
|
|
||||||
putSpace = true;
|
|
||||||
goto getNext;
|
|
||||||
}
|
|
||||||
updateItem(ptr);
|
|
||||||
// assert(!putSpace);
|
|
||||||
goto nextVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (putSpace) {
|
|
||||||
putSpace = false;
|
|
||||||
*ptr++ = ' ';
|
|
||||||
}
|
|
||||||
*ptr++ = c;
|
|
||||||
|
|
||||||
getNext:
|
|
||||||
if (cur == end) {
|
|
||||||
if (!quote && !parens)
|
|
||||||
goto flushItem;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
c = *cur++;
|
|
||||||
}
|
}
|
||||||
} else { // doSplit
|
*ptr++ = c;
|
||||||
forever {
|
|
||||||
if (putSpace) {
|
|
||||||
putSpace = false;
|
|
||||||
*ptr++ = ' ';
|
|
||||||
}
|
|
||||||
*ptr++ = c;
|
|
||||||
|
|
||||||
forever {
|
forever {
|
||||||
if (cur == end)
|
if (cur == end)
|
||||||
goto lineEnd;
|
goto lineEnd;
|
||||||
c = *cur++;
|
c = *cur++;
|
||||||
if (c != ' ' && c != '\t')
|
if (c != ' ' && c != '\t')
|
||||||
break;
|
break;
|
||||||
putSpace = true;
|
putSpace = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lineEnd:
|
lineEnd:
|
||||||
|
m_proitem.resize(ptr - (ushort *)m_proitem.unicode());
|
||||||
if (lineCont) {
|
if (lineCont) {
|
||||||
m_proitem.resize(ptr - (ushort *)m_proitem.unicode());
|
|
||||||
putSpace = !m_proitem.isEmpty();
|
putSpace = !m_proitem.isEmpty();
|
||||||
} else {
|
} else {
|
||||||
flushItem:
|
if (currAssignment) {
|
||||||
updateItem(ptr);
|
finalizeVariable(currAssignment);
|
||||||
|
currAssignment = 0;
|
||||||
|
} else {
|
||||||
|
updateItem2();
|
||||||
|
}
|
||||||
putSpace = false;
|
putSpace = false;
|
||||||
}
|
}
|
||||||
} // !inError
|
} // !inError
|
||||||
@@ -599,13 +543,13 @@ void ProFileEvaluator::Private::finalizeBlock()
|
|||||||
m_block = 0;
|
m_block = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProFileEvaluator::Private::insertVariable(ushort *ptr, bool *doSplit, bool *doSemicolon)
|
ProVariable *ProFileEvaluator::Private::startVariable(ushort *ptr)
|
||||||
{
|
{
|
||||||
ProVariable::VariableOperator opkind;
|
ProVariable::VariableOperator opkind;
|
||||||
ushort *uc = (ushort *)m_proitem.unicode();
|
ushort *uc = (ushort *)m_proitem.unicode();
|
||||||
|
|
||||||
if (ptr == uc) // Line starting with '=', like a conflict marker
|
if (ptr == uc) // Line starting with '=', like a conflict marker
|
||||||
return false;
|
return 0;
|
||||||
|
|
||||||
switch (*(ptr - 1)) {
|
switch (*(ptr - 1)) {
|
||||||
case '+':
|
case '+':
|
||||||
@@ -630,7 +574,7 @@ bool ProFileEvaluator::Private::insertVariable(ushort *ptr, bool *doSplit, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ptr == uc) // Line starting with manipulation operator
|
if (ptr == uc) // Line starting with manipulation operator
|
||||||
return false;
|
return 0;
|
||||||
if (*(ptr - 1) == ' ')
|
if (*(ptr - 1) == ' ')
|
||||||
--ptr;
|
--ptr;
|
||||||
|
|
||||||
@@ -638,20 +582,23 @@ bool ProFileEvaluator::Private::insertVariable(ushort *ptr, bool *doSplit, bool
|
|||||||
m_proitem.resize(ptr - uc);
|
m_proitem.resize(ptr - uc);
|
||||||
QString proVar = m_proitem;
|
QString proVar = m_proitem;
|
||||||
proVar.detach();
|
proVar.detach();
|
||||||
|
|
||||||
ProBlock *block = m_blockstack.top();
|
|
||||||
ProVariable *variable = new ProVariable(proVar, block);
|
|
||||||
variable->setLineNumber(m_lineNo);
|
|
||||||
variable->setVariableOperator(opkind);
|
|
||||||
block->appendItem(variable);
|
|
||||||
m_block = variable;
|
|
||||||
|
|
||||||
m_proitem.resize(0);
|
m_proitem.resize(0);
|
||||||
|
|
||||||
*doSplit = (opkind != ProVariable::ReplaceOperator);
|
ProVariable *variable = new ProVariable(proVar);
|
||||||
*doSemicolon = (proVar == QLatin1String("DEPENDPATH")
|
variable->setLineNumber(m_lineNo);
|
||||||
|| proVar == QLatin1String("INCLUDEPATH"));
|
variable->setVariableOperator(opkind);
|
||||||
return true;
|
return variable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProFileEvaluator::Private::finalizeVariable(ProVariable *variable)
|
||||||
|
{
|
||||||
|
QString proItem = m_proitem;
|
||||||
|
proItem.detach();
|
||||||
|
m_proitem.resize(0);
|
||||||
|
variable->setValue(proItem);
|
||||||
|
|
||||||
|
ProBlock *block = m_blockstack.top();
|
||||||
|
block->appendItem(variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProFileEvaluator::Private::insertOperator(const char op)
|
void ProFileEvaluator::Private::insertOperator(const char op)
|
||||||
@@ -730,9 +677,7 @@ void ProFileEvaluator::Private::updateItem2()
|
|||||||
|
|
||||||
ProBlock *block = currentBlock();
|
ProBlock *block = currentBlock();
|
||||||
ProItem *item;
|
ProItem *item;
|
||||||
if (block->blockKind() & ProBlock::VariableKind) {
|
if (proItem.endsWith(QLatin1Char(')'))) {
|
||||||
item = new ProValue(proItem, static_cast<ProVariable*>(block));
|
|
||||||
} else if (proItem.endsWith(QLatin1Char(')'))) {
|
|
||||||
item = new ProFunction(proItem);
|
item = new ProFunction(proItem);
|
||||||
} else {
|
} else {
|
||||||
item = new ProCondition(proItem);
|
item = new ProCondition(proItem);
|
||||||
@@ -1001,89 +946,91 @@ void ProFileEvaluator::Private::visitProLoopCleanup()
|
|||||||
m_loopStack.pop_back();
|
m_loopStack.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProFileEvaluator::Private::visitBeginProVariable(ProVariable *)
|
void ProFileEvaluator::Private::visitProVariable(ProVariable *var)
|
||||||
{
|
{
|
||||||
m_sts.varVal.clear();
|
m_lineNo = var->lineNumber();
|
||||||
}
|
const QString &varName = var->variable();
|
||||||
|
|
||||||
void ProFileEvaluator::Private::visitEndProVariable(ProVariable *variable)
|
if (var->variableOperator() == ProVariable::ReplaceOperator) { // ~=
|
||||||
{
|
// DEFINES ~= s/a/b/?[gqi]
|
||||||
QString varName = variable->variable();
|
|
||||||
|
|
||||||
switch (variable->variableOperator()) {
|
QString val = var->value();
|
||||||
|
doVariableReplace(&val);
|
||||||
|
if (val.length() < 4 || val.at(0) != QLatin1Char('s')) {
|
||||||
|
logMessage(format("the ~= operator can handle only the s/// function."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QChar sep = val.at(1);
|
||||||
|
QStringList func = val.split(sep);
|
||||||
|
if (func.count() < 3 || func.count() > 4) {
|
||||||
|
logMessage(format("the s/// function expects 3 or 4 arguments."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool global = false, quote = false, case_sense = false;
|
||||||
|
if (func.count() == 4) {
|
||||||
|
global = func[3].indexOf(QLatin1Char('g')) != -1;
|
||||||
|
case_sense = func[3].indexOf(QLatin1Char('i')) == -1;
|
||||||
|
quote = func[3].indexOf(QLatin1Char('q')) != -1;
|
||||||
|
}
|
||||||
|
QString pattern = func[1];
|
||||||
|
QString replace = func[2];
|
||||||
|
if (quote)
|
||||||
|
pattern = QRegExp::escape(pattern);
|
||||||
|
|
||||||
|
QRegExp regexp(pattern, case_sense ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
||||||
|
|
||||||
|
if (!m_skipLevel || m_cumulative) {
|
||||||
|
// We could make a union of modified and unmodified values,
|
||||||
|
// but this will break just as much as it fixes, so leave it as is.
|
||||||
|
replaceInList(&m_valuemap[varName], regexp, replace, global);
|
||||||
|
replaceInList(&m_filevaluemap[currentProFile()][varName], regexp, replace, global);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
static const QString deppath(QLatin1String("DEPENDPATH"));
|
||||||
|
static const QString incpath(QLatin1String("INCLUDEPATH"));
|
||||||
|
bool doSemicolon = (varName == deppath || varName == incpath);
|
||||||
|
QStringList varVal;
|
||||||
|
foreach (const QString &arg, split_value_list(var->value(), doSemicolon))
|
||||||
|
varVal += expandVariableReferences(arg);
|
||||||
|
|
||||||
|
switch (var->variableOperator()) {
|
||||||
|
default: // ReplaceOperator - cannot happen
|
||||||
case ProVariable::SetOperator: // =
|
case ProVariable::SetOperator: // =
|
||||||
if (!m_cumulative) {
|
if (!m_cumulative) {
|
||||||
if (!m_skipLevel) {
|
if (!m_skipLevel) {
|
||||||
m_valuemap[varName] = m_sts.varVal;
|
m_valuemap[varName] = varVal;
|
||||||
m_filevaluemap[currentProFile()][varName] = m_sts.varVal;
|
m_filevaluemap[currentProFile()][varName] = varVal;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We are greedy for values.
|
// We are greedy for values.
|
||||||
m_valuemap[varName] += m_sts.varVal;
|
m_valuemap[varName] += varVal;
|
||||||
m_filevaluemap[currentProFile()][varName] += m_sts.varVal;
|
m_filevaluemap[currentProFile()][varName] += varVal;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ProVariable::UniqueAddOperator: // *=
|
case ProVariable::UniqueAddOperator: // *=
|
||||||
if (!m_skipLevel || m_cumulative) {
|
if (!m_skipLevel || m_cumulative) {
|
||||||
insertUnique(&m_valuemap, varName, m_sts.varVal);
|
insertUnique(&m_valuemap, varName, varVal);
|
||||||
insertUnique(&m_filevaluemap[currentProFile()], varName, m_sts.varVal);
|
insertUnique(&m_filevaluemap[currentProFile()], varName, varVal);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ProVariable::AddOperator: // +=
|
case ProVariable::AddOperator: // +=
|
||||||
if (!m_skipLevel || m_cumulative) {
|
if (!m_skipLevel || m_cumulative) {
|
||||||
m_valuemap[varName] += m_sts.varVal;
|
m_valuemap[varName] += varVal;
|
||||||
m_filevaluemap[currentProFile()][varName] += m_sts.varVal;
|
m_filevaluemap[currentProFile()][varName] += varVal;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ProVariable::RemoveOperator: // -=
|
case ProVariable::RemoveOperator: // -=
|
||||||
if (!m_cumulative) {
|
if (!m_cumulative) {
|
||||||
if (!m_skipLevel) {
|
if (!m_skipLevel) {
|
||||||
removeEach(&m_valuemap, varName, m_sts.varVal);
|
removeEach(&m_valuemap, varName, varVal);
|
||||||
removeEach(&m_filevaluemap[currentProFile()], varName, m_sts.varVal);
|
removeEach(&m_filevaluemap[currentProFile()], varName, varVal);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We are stingy with our values, too.
|
// We are stingy with our values, too.
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ProVariable::ReplaceOperator: // ~=
|
}
|
||||||
{
|
|
||||||
// DEFINES ~= s/a/b/?[gqi]
|
|
||||||
|
|
||||||
QString val = m_sts.varVal.first();
|
|
||||||
doVariableReplace(&val);
|
|
||||||
if (val.length() < 4 || val.at(0) != QLatin1Char('s')) {
|
|
||||||
logMessage(format("the ~= operator can handle only the s/// function."));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
QChar sep = val.at(1);
|
|
||||||
QStringList func = val.split(sep);
|
|
||||||
if (func.count() < 3 || func.count() > 4) {
|
|
||||||
logMessage(format("the s/// function expects 3 or 4 arguments."));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool global = false, quote = false, case_sense = false;
|
|
||||||
if (func.count() == 4) {
|
|
||||||
global = func[3].indexOf(QLatin1Char('g')) != -1;
|
|
||||||
case_sense = func[3].indexOf(QLatin1Char('i')) == -1;
|
|
||||||
quote = func[3].indexOf(QLatin1Char('q')) != -1;
|
|
||||||
}
|
|
||||||
QString pattern = func[1];
|
|
||||||
QString replace = func[2];
|
|
||||||
if (quote)
|
|
||||||
pattern = QRegExp::escape(pattern);
|
|
||||||
|
|
||||||
QRegExp regexp(pattern, case_sense ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
|
||||||
|
|
||||||
if (!m_skipLevel || m_cumulative) {
|
|
||||||
// We could make a union of modified and unmodified values,
|
|
||||||
// but this will break just as much as it fixes, so leave it as is.
|
|
||||||
replaceInList(&m_valuemap[varName], regexp, replace, global);
|
|
||||||
replaceInList(&m_filevaluemap[currentProFile()][varName], regexp, replace, global);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1266,12 +1213,6 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitEndProFile(ProFile * pro)
|
|||||||
return returnBool(QDir::setCurrent(m_oldPathStack.pop()));
|
return returnBool(QDir::setCurrent(m_oldPathStack.pop()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProFileEvaluator::Private::visitProValue(ProValue *value)
|
|
||||||
{
|
|
||||||
m_lineNo = value->lineNumber();
|
|
||||||
m_sts.varVal += expandVariableReferences(value->value());
|
|
||||||
}
|
|
||||||
|
|
||||||
ProItem::ProItemReturn ProFileEvaluator::Private::visitProFunction(ProFunction *func)
|
ProItem::ProItemReturn ProFileEvaluator::Private::visitProFunction(ProFunction *func)
|
||||||
{
|
{
|
||||||
// Make sure that called subblocks don't inherit & destroy the state
|
// Make sure that called subblocks don't inherit & destroy the state
|
||||||
|
|||||||
@@ -126,10 +126,8 @@ ProItem::ProItemReturn ProBlock::Accept(AbstractProItemVisitor *visitor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --------------- ProVariable ----------------
|
// --------------- ProVariable ----------------
|
||||||
ProVariable::ProVariable(const QString &name, ProBlock *parent)
|
ProVariable::ProVariable(const QString &name)
|
||||||
: ProBlock(parent)
|
|
||||||
{
|
{
|
||||||
setBlockKind(ProBlock::VariableKind);
|
|
||||||
m_variable = name;
|
m_variable = name;
|
||||||
m_variableKind = SetOperator;
|
m_variableKind = SetOperator;
|
||||||
}
|
}
|
||||||
@@ -154,50 +152,24 @@ QString ProVariable::variable() const
|
|||||||
return m_variable;
|
return m_variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProItem::ProItemReturn ProVariable::Accept(AbstractProItemVisitor *visitor)
|
void ProVariable::setValue(const QString &val)
|
||||||
{
|
{
|
||||||
visitor->visitBeginProVariable(this);
|
m_value = val;
|
||||||
foreach (ProItem *item, m_proitems)
|
|
||||||
item->Accept(visitor); // cannot fail
|
|
||||||
visitor->visitEndProVariable(this);
|
|
||||||
return ReturnTrue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------- ProValue ----------------
|
QString ProVariable::value() const
|
||||||
ProValue::ProValue(const QString &value, ProVariable *variable)
|
|
||||||
{
|
|
||||||
m_variable = variable;
|
|
||||||
m_value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProValue::setValue(const QString &value)
|
|
||||||
{
|
|
||||||
m_value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ProValue::value() const
|
|
||||||
{
|
{
|
||||||
return m_value;
|
return m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProValue::setVariable(ProVariable *variable)
|
ProItem::ProItemKind ProVariable::kind() const
|
||||||
{
|
{
|
||||||
m_variable = variable;
|
return ProItem::VariableKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProVariable *ProValue::variable() const
|
ProItem::ProItemReturn ProVariable::Accept(AbstractProItemVisitor *visitor)
|
||||||
{
|
{
|
||||||
return m_variable;
|
visitor->visitProVariable(this);
|
||||||
}
|
|
||||||
|
|
||||||
ProItem::ProItemKind ProValue::kind() const
|
|
||||||
{
|
|
||||||
return ProItem::ValueKind;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProItem::ProItemReturn ProValue::Accept(AbstractProItemVisitor *visitor)
|
|
||||||
{
|
|
||||||
visitor->visitProValue(this);
|
|
||||||
return ReturnTrue;
|
return ReturnTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ public:
|
|||||||
FunctionKind,
|
FunctionKind,
|
||||||
ConditionKind,
|
ConditionKind,
|
||||||
OperatorKind,
|
OperatorKind,
|
||||||
|
VariableKind,
|
||||||
BlockKind
|
BlockKind
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -78,7 +79,6 @@ public:
|
|||||||
NormalKind = 0x00,
|
NormalKind = 0x00,
|
||||||
ScopeKind = 0x01,
|
ScopeKind = 0x01,
|
||||||
ScopeContentsKind = 0x02,
|
ScopeContentsKind = 0x02,
|
||||||
VariableKind = 0x04,
|
|
||||||
ProFileKind = 0x08,
|
ProFileKind = 0x08,
|
||||||
FunctionBodyKind = 0x10,
|
FunctionBodyKind = 0x10,
|
||||||
SingleLine = 0x80
|
SingleLine = 0x80
|
||||||
@@ -111,7 +111,7 @@ private:
|
|||||||
int m_refCount;
|
int m_refCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ProVariable : public ProBlock
|
class ProVariable : public ProItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum VariableOperator {
|
enum VariableOperator {
|
||||||
@@ -122,7 +122,7 @@ public:
|
|||||||
UniqueAddOperator = 4
|
UniqueAddOperator = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
ProVariable(const QString &name, ProBlock *parent);
|
ProVariable(const QString &name);
|
||||||
|
|
||||||
void setVariableOperator(VariableOperator variableKind);
|
void setVariableOperator(VariableOperator variableKind);
|
||||||
VariableOperator variableOperator() const;
|
VariableOperator variableOperator() const;
|
||||||
@@ -130,29 +130,16 @@ public:
|
|||||||
void setVariable(const QString &name);
|
void setVariable(const QString &name);
|
||||||
QString variable() const;
|
QString variable() const;
|
||||||
|
|
||||||
virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
|
|
||||||
private:
|
|
||||||
VariableOperator m_variableKind;
|
|
||||||
QString m_variable;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ProValue : public ProItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ProValue(const QString &value, ProVariable *variable);
|
|
||||||
|
|
||||||
void setValue(const QString &value);
|
void setValue(const QString &value);
|
||||||
QString value() const;
|
QString value() const;
|
||||||
|
|
||||||
void setVariable(ProVariable *variable);
|
|
||||||
ProVariable *variable() const;
|
|
||||||
|
|
||||||
ProItem::ProItemKind kind() const;
|
ProItem::ProItemKind kind() const;
|
||||||
|
|
||||||
virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
|
virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
|
||||||
private:
|
private:
|
||||||
|
VariableOperator m_variableKind;
|
||||||
|
QString m_variable;
|
||||||
QString m_value;
|
QString m_value;
|
||||||
ProVariable *m_variable;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ProFunction : public ProItem
|
class ProFunction : public ProItem
|
||||||
|
|||||||
@@ -41,41 +41,38 @@ void ProWriter::addFiles(ProFile *profile, QStringList *lines,
|
|||||||
{
|
{
|
||||||
// Check if variable item exists as child of root item
|
// Check if variable item exists as child of root item
|
||||||
foreach (ProItem *item, profile->items()) {
|
foreach (ProItem *item, profile->items()) {
|
||||||
if (item->kind() == ProItem::BlockKind) {
|
if (item->kind() == ProItem::VariableKind) {
|
||||||
ProBlock *block = static_cast<ProBlock *>(item);
|
ProVariable *proVar = static_cast<ProVariable*>(item);
|
||||||
if (block->blockKind() == ProBlock::VariableKind) {
|
if (vars.contains(proVar->variable())
|
||||||
ProVariable *proVar = static_cast<ProVariable*>(block);
|
&& proVar->variableOperator() != ProVariable::RemoveOperator
|
||||||
if (vars.contains(proVar->variable())
|
&& proVar->variableOperator() != ProVariable::ReplaceOperator) {
|
||||||
&& proVar->variableOperator() != ProVariable::RemoveOperator
|
|
||||||
&& proVar->variableOperator() != ProVariable::ReplaceOperator) {
|
|
||||||
|
|
||||||
int lineNo = proVar->lineNumber() - 1;
|
int lineNo = proVar->lineNumber() - 1;
|
||||||
for (; lineNo < lines->count(); lineNo++) {
|
for (; lineNo < lines->count(); lineNo++) {
|
||||||
QString line = lines->at(lineNo);
|
QString line = lines->at(lineNo);
|
||||||
int idx = line.indexOf(QLatin1Char('#'));
|
int idx = line.indexOf(QLatin1Char('#'));
|
||||||
|
if (idx >= 0)
|
||||||
|
line.truncate(idx);
|
||||||
|
while (line.endsWith(QLatin1Char(' ')) || line.endsWith(QLatin1Char('\t')))
|
||||||
|
line.chop(1);
|
||||||
|
if (line.isEmpty()) {
|
||||||
if (idx >= 0)
|
if (idx >= 0)
|
||||||
line.truncate(idx);
|
continue;
|
||||||
while (line.endsWith(QLatin1Char(' ')) || line.endsWith(QLatin1Char('\t')))
|
break;
|
||||||
line.chop(1);
|
}
|
||||||
if (line.isEmpty()) {
|
if (!line.endsWith(QLatin1Char('\\'))) {
|
||||||
if (idx >= 0)
|
(*lines)[lineNo].insert(line.length(), QLatin1String(" \\"));
|
||||||
continue;
|
lineNo++;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if (!line.endsWith(QLatin1Char('\\'))) {
|
|
||||||
(*lines)[lineNo].insert(line.length(), QLatin1String(" \\"));
|
|
||||||
lineNo++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
QString added;
|
|
||||||
foreach (const QString &filePath, filePaths)
|
|
||||||
added += QLatin1String(" ") + proFileDir.relativeFilePath(filePath)
|
|
||||||
+ QLatin1String(" \\\n");
|
|
||||||
added.chop(3);
|
|
||||||
lines->insert(lineNo, added);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
QString added;
|
||||||
|
foreach (const QString &filePath, filePaths)
|
||||||
|
added += QLatin1String(" ") + proFileDir.relativeFilePath(filePath)
|
||||||
|
+ QLatin1String(" \\\n");
|
||||||
|
added.chop(3);
|
||||||
|
lines->insert(lineNo, added);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,14 +89,11 @@ static void findProVariables(ProBlock *block, const QStringList &vars,
|
|||||||
{
|
{
|
||||||
foreach (ProItem *item, block->items()) {
|
foreach (ProItem *item, block->items()) {
|
||||||
if (item->kind() == ProItem::BlockKind) {
|
if (item->kind() == ProItem::BlockKind) {
|
||||||
ProBlock *subBlock = static_cast<ProBlock *>(item);
|
findProVariables(static_cast<ProBlock*>(item), vars, proVars);
|
||||||
if (subBlock->blockKind() == ProBlock::VariableKind) {
|
} else if (item->kind() == ProItem::VariableKind) {
|
||||||
ProVariable *proVar = static_cast<ProVariable*>(subBlock);
|
ProVariable *proVar = static_cast<ProVariable*>(item);
|
||||||
if (vars.contains(proVar->variable()))
|
if (vars.contains(proVar->variable()))
|
||||||
*proVars << proVar;
|
*proVars << proVar;
|
||||||
} else {
|
|
||||||
findProVariables(subBlock, vars, proVars);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user