forked from qt-creator/qt-creator
support custom functions: implement defineTest(), defineReplace(), defined(), return() & export()
This commit is contained in:
@@ -37,17 +37,18 @@ QT_BEGIN_NAMESPACE
|
|||||||
struct AbstractProItemVisitor
|
struct AbstractProItemVisitor
|
||||||
{
|
{
|
||||||
virtual ~AbstractProItemVisitor() {}
|
virtual ~AbstractProItemVisitor() {}
|
||||||
virtual void visitBeginProBlock(ProBlock *block) = 0;
|
|
||||||
|
virtual ProItem::ProItemReturn visitBeginProBlock(ProBlock *block) = 0;
|
||||||
virtual void visitEndProBlock(ProBlock *block) = 0;
|
virtual void visitEndProBlock(ProBlock *block) = 0;
|
||||||
|
|
||||||
virtual void visitBeginProVariable(ProVariable *variable) = 0;
|
virtual void visitBeginProVariable(ProVariable *variable) = 0;
|
||||||
virtual void visitEndProVariable(ProVariable *variable) = 0;
|
virtual void visitEndProVariable(ProVariable *variable) = 0;
|
||||||
|
|
||||||
virtual bool visitBeginProFile(ProFile *value) = 0;
|
virtual ProItem::ProItemReturn visitBeginProFile(ProFile *value) = 0;
|
||||||
virtual bool visitEndProFile(ProFile *value) = 0;
|
virtual ProItem::ProItemReturn visitEndProFile(ProFile *value) = 0;
|
||||||
|
|
||||||
virtual void visitProValue(ProValue *value) = 0;
|
virtual void visitProValue(ProValue *value) = 0;
|
||||||
virtual void 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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -157,14 +157,14 @@ public:
|
|||||||
/////////////// Evaluating pro file contents
|
/////////////// Evaluating pro file contents
|
||||||
|
|
||||||
// implementation of AbstractProItemVisitor
|
// implementation of AbstractProItemVisitor
|
||||||
void visitBeginProBlock(ProBlock *block);
|
ProItem::ProItemReturn visitBeginProBlock(ProBlock *block);
|
||||||
void visitEndProBlock(ProBlock *block);
|
void visitEndProBlock(ProBlock *block);
|
||||||
void visitBeginProVariable(ProVariable *variable);
|
void visitBeginProVariable(ProVariable *variable);
|
||||||
void visitEndProVariable(ProVariable *variable);
|
void visitEndProVariable(ProVariable *variable);
|
||||||
bool visitBeginProFile(ProFile *value);
|
ProItem::ProItemReturn visitBeginProFile(ProFile *value);
|
||||||
bool visitEndProFile(ProFile *value);
|
ProItem::ProItemReturn visitEndProFile(ProFile *value);
|
||||||
void visitProValue(ProValue *value);
|
void visitProValue(ProValue *value);
|
||||||
void visitProFunction(ProFunction *function);
|
ProItem::ProItemReturn visitProFunction(ProFunction *function);
|
||||||
void visitProOperator(ProOperator *oper);
|
void visitProOperator(ProOperator *oper);
|
||||||
void visitProCondition(ProCondition *condition);
|
void visitProCondition(ProCondition *condition);
|
||||||
|
|
||||||
@@ -187,10 +187,15 @@ public:
|
|||||||
QString currentDirectory() const;
|
QString currentDirectory() const;
|
||||||
ProFile *currentProFile() const;
|
ProFile *currentProFile() const;
|
||||||
|
|
||||||
bool evaluateConditionalFunction(const QString &function, const QString &arguments);
|
ProItem::ProItemReturn evaluateConditionalFunction(const QString &function, const QString &arguments);
|
||||||
bool evaluateFile(const QString &fileName);
|
bool evaluateFile(const QString &fileName);
|
||||||
bool evaluateFeatureFile(const QString &fileName);
|
bool evaluateFeatureFile(const QString &fileName);
|
||||||
|
|
||||||
|
static inline ProItem::ProItemReturn returnBool(bool b)
|
||||||
|
{ return b ? ProItem::ReturnTrue : ProItem::ReturnFalse; }
|
||||||
|
|
||||||
|
QStringList evaluateFunction(ProBlock *funcPtr, const QStringList &argumentsList, bool *ok);
|
||||||
|
|
||||||
QStringList qmakeFeaturePaths();
|
QStringList qmakeFeaturePaths();
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
@@ -217,6 +222,14 @@ public:
|
|||||||
QHash<QString, QString> m_properties;
|
QHash<QString, QString> m_properties;
|
||||||
QString m_outputDir;
|
QString m_outputDir;
|
||||||
|
|
||||||
|
bool m_definingTest;
|
||||||
|
QString m_definingFunc;
|
||||||
|
QHash<QString, ProBlock *> m_testFunctions;
|
||||||
|
QHash<QString, ProBlock *> m_replaceFunctions;
|
||||||
|
QStringList m_returnValue;
|
||||||
|
QStack<QHash<QString, QStringList> > m_valuemapStack;
|
||||||
|
QStack<QHash<const ProFile*, QHash<QString, QStringList> > > m_filevaluemapStack;
|
||||||
|
|
||||||
int m_prevLineNo; // Checking whether we're assigning the same TARGET
|
int m_prevLineNo; // Checking whether we're assigning the same TARGET
|
||||||
ProFile *m_prevProFile; // See m_prevLineNo
|
ProFile *m_prevProFile; // See m_prevLineNo
|
||||||
QStringList m_addUserConfigCmdArgs;
|
QStringList m_addUserConfigCmdArgs;
|
||||||
@@ -236,6 +249,7 @@ ProFileEvaluator::Private::Private(ProFileEvaluator *q_)
|
|||||||
// Configuration, more or less
|
// Configuration, more or less
|
||||||
m_verbose = true;
|
m_verbose = true;
|
||||||
m_cumulative = true;
|
m_cumulative = true;
|
||||||
|
m_parsePreAndPostFiles = true;
|
||||||
|
|
||||||
// Evaluator state
|
// Evaluator state
|
||||||
m_sts.condition = false;
|
m_sts.condition = false;
|
||||||
@@ -243,7 +257,7 @@ ProFileEvaluator::Private::Private(ProFileEvaluator *q_)
|
|||||||
m_invertNext = false;
|
m_invertNext = false;
|
||||||
m_skipLevel = 0;
|
m_skipLevel = 0;
|
||||||
m_isFirstVariableValue = true;
|
m_isFirstVariableValue = true;
|
||||||
m_parsePreAndPostFiles = true;
|
m_definingFunc.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProFileEvaluator::Private::read(ProFile *pro)
|
bool ProFileEvaluator::Private::read(ProFile *pro)
|
||||||
@@ -555,13 +569,27 @@ void ProFileEvaluator::Private::updateItem()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ProFileEvaluator::Private::visitBeginProBlock(ProBlock *block)
|
ProItem::ProItemReturn ProFileEvaluator::Private::visitBeginProBlock(ProBlock *block)
|
||||||
{
|
{
|
||||||
if (block->blockKind() & ProBlock::ScopeContentsKind) {
|
if (block->blockKind() & ProBlock::ScopeContentsKind) {
|
||||||
if (!m_sts.condition)
|
if (!m_definingFunc.isEmpty()) {
|
||||||
++m_skipLevel;
|
if (!m_skipLevel || m_cumulative) {
|
||||||
else
|
QHash<QString, ProBlock *> *hash =
|
||||||
Q_ASSERT(!m_skipLevel);
|
(m_definingTest ? &m_testFunctions : &m_replaceFunctions);
|
||||||
|
if (ProBlock *def = hash->value(m_definingFunc))
|
||||||
|
def->deref();
|
||||||
|
hash->insert(m_definingFunc, block);
|
||||||
|
block->ref();
|
||||||
|
block->setBlockKind(block->blockKind() | ProBlock::FunctionBodyKind);
|
||||||
|
}
|
||||||
|
m_definingFunc.clear();
|
||||||
|
return ProItem::ReturnSkip;
|
||||||
|
} else if (!(block->blockKind() & ProBlock::FunctionBodyKind)) {
|
||||||
|
if (!m_sts.condition)
|
||||||
|
++m_skipLevel;
|
||||||
|
else
|
||||||
|
Q_ASSERT(!m_skipLevel);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!m_skipLevel) {
|
if (!m_skipLevel) {
|
||||||
if (m_sts.condition) {
|
if (m_sts.condition) {
|
||||||
@@ -572,11 +600,13 @@ void ProFileEvaluator::Private::visitBeginProBlock(ProBlock *block)
|
|||||||
Q_ASSERT(!m_sts.condition);
|
Q_ASSERT(!m_sts.condition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ProItem::ReturnTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProFileEvaluator::Private::visitEndProBlock(ProBlock *block)
|
void ProFileEvaluator::Private::visitEndProBlock(ProBlock *block)
|
||||||
{
|
{
|
||||||
if (block->blockKind() & ProBlock::ScopeContentsKind) {
|
if ((block->blockKind() & ProBlock::ScopeContentsKind)
|
||||||
|
&& !(block->blockKind() & ProBlock::FunctionBodyKind)) {
|
||||||
if (m_skipLevel) {
|
if (m_skipLevel) {
|
||||||
Q_ASSERT(!m_sts.condition);
|
Q_ASSERT(!m_sts.condition);
|
||||||
--m_skipLevel;
|
--m_skipLevel;
|
||||||
@@ -624,10 +654,9 @@ void ProFileEvaluator::Private::visitProCondition(ProCondition *cond)
|
|||||||
m_invertNext = false;
|
m_invertNext = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProFileEvaluator::Private::visitBeginProFile(ProFile * pro)
|
ProItem::ProItemReturn ProFileEvaluator::Private::visitBeginProFile(ProFile * pro)
|
||||||
{
|
{
|
||||||
PRE(pro);
|
PRE(pro);
|
||||||
bool ok = true;
|
|
||||||
m_lineNo = pro->lineNumber();
|
m_lineNo = pro->lineNumber();
|
||||||
if (m_origfile.isEmpty())
|
if (m_origfile.isEmpty())
|
||||||
m_origfile = pro->fileName();
|
m_origfile = pro->fileName();
|
||||||
@@ -655,16 +684,15 @@ bool ProFileEvaluator::Private::visitBeginProFile(ProFile * pro)
|
|||||||
m_cumulative = cumulative;
|
m_cumulative = cumulative;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = QDir::setCurrent(pro->directoryName());
|
return returnBool(QDir::setCurrent(pro->directoryName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok;
|
return ProItem::ReturnTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProFileEvaluator::Private::visitEndProFile(ProFile * pro)
|
ProItem::ProItemReturn ProFileEvaluator::Private::visitEndProFile(ProFile * pro)
|
||||||
{
|
{
|
||||||
PRE(pro);
|
PRE(pro);
|
||||||
bool ok = true;
|
|
||||||
m_lineNo = pro->lineNumber();
|
m_lineNo = pro->lineNumber();
|
||||||
if (m_profileStack.count() == 1 && !m_oldPath.isEmpty()) {
|
if (m_profileStack.count() == 1 && !m_oldPath.isEmpty()) {
|
||||||
const QString &mkspecDirectory = propertyValue(QLatin1String("QMAKE_MKSPECS"));
|
const QString &mkspecDirectory = propertyValue(QLatin1String("QMAKE_MKSPECS"));
|
||||||
@@ -693,13 +721,21 @@ bool ProFileEvaluator::Private::visitEndProFile(ProFile * pro)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (ProBlock *itm, m_replaceFunctions)
|
||||||
|
itm->deref();
|
||||||
|
m_replaceFunctions.clear();
|
||||||
|
foreach (ProBlock *itm, m_testFunctions)
|
||||||
|
itm->deref();
|
||||||
|
m_testFunctions.clear();
|
||||||
|
|
||||||
m_cumulative = cumulative;
|
m_cumulative = cumulative;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_profileStack.pop();
|
m_profileStack.pop();
|
||||||
ok = QDir::setCurrent(m_oldPath);
|
return returnBool(QDir::setCurrent(m_oldPath));
|
||||||
}
|
}
|
||||||
return ok;
|
|
||||||
|
return ProItem::ReturnTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void replaceInList(QStringList *varlist,
|
static void replaceInList(QStringList *varlist,
|
||||||
@@ -854,7 +890,7 @@ void ProFileEvaluator::Private::visitProValue(ProValue *value)
|
|||||||
m_isFirstVariableValue = false;
|
m_isFirstVariableValue = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void 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
|
||||||
bool invertThis = m_invertNext;
|
bool invertThis = m_invertNext;
|
||||||
@@ -869,10 +905,13 @@ void ProFileEvaluator::Private::visitProFunction(ProFunction *func)
|
|||||||
QString arguments = text.mid(lparen + 1, rparen - lparen - 1);
|
QString arguments = text.mid(lparen + 1, rparen - lparen - 1);
|
||||||
QString funcName = text.left(lparen);
|
QString funcName = text.left(lparen);
|
||||||
m_lineNo = func->lineNumber();
|
m_lineNo = func->lineNumber();
|
||||||
bool result = evaluateConditionalFunction(funcName.trimmed(), arguments);
|
ProItem::ProItemReturn result = evaluateConditionalFunction(funcName.trimmed(), arguments);
|
||||||
if (!m_skipLevel && (result ^ invertThis))
|
if (result != ProItem::ReturnFalse && result != ProItem::ReturnTrue)
|
||||||
|
return result;
|
||||||
|
if (!m_skipLevel && ((result == ProItem::ReturnTrue) ^ invertThis))
|
||||||
m_sts.condition = true;
|
m_sts.condition = true;
|
||||||
}
|
}
|
||||||
|
return ProItem::ReturnTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1212,10 +1251,49 @@ bool ProFileEvaluator::Private::isActiveConfig(const QString &config, bool regex
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList ProFileEvaluator::Private::evaluateFunction(
|
||||||
|
ProBlock *funcPtr, const QStringList &argumentsList, bool *ok)
|
||||||
|
{
|
||||||
|
bool oki;
|
||||||
|
QStringList ret;
|
||||||
|
|
||||||
|
if (m_valuemapStack.count() >= 100) {
|
||||||
|
q->errorMessage(format("ran into infinite recursion (depth > 100)."));
|
||||||
|
ok = false;
|
||||||
|
} else {
|
||||||
|
State sts = m_sts;
|
||||||
|
m_valuemapStack.push(m_valuemap);
|
||||||
|
m_filevaluemapStack.push(m_filevaluemap);
|
||||||
|
|
||||||
|
QStringList args;
|
||||||
|
for (int i = 0; i < argumentsList.count(); ++i) {
|
||||||
|
QStringList theArgs = expandVariableReferences(argumentsList[i]);
|
||||||
|
args += theArgs;
|
||||||
|
m_valuemap[QString::number(i+1)] = theArgs;
|
||||||
|
}
|
||||||
|
m_valuemap[QLatin1String("ARGS")] = args;
|
||||||
|
oki = (funcPtr->Accept(this) != ProItem::ReturnFalse); // True || Return
|
||||||
|
ret = m_returnValue;
|
||||||
|
m_returnValue.clear();
|
||||||
|
|
||||||
|
m_valuemap = m_valuemapStack.pop();
|
||||||
|
m_filevaluemap = m_filevaluemapStack.pop();
|
||||||
|
m_sts = sts;
|
||||||
|
}
|
||||||
|
if (ok)
|
||||||
|
*ok = oki;
|
||||||
|
if (oki)
|
||||||
|
return ret;
|
||||||
|
return QStringList();
|
||||||
|
}
|
||||||
|
|
||||||
QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &func, const QString &arguments)
|
QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &func, const QString &arguments)
|
||||||
{
|
{
|
||||||
QStringList argumentsList = split_arg_list(arguments);
|
QStringList argumentsList = split_arg_list(arguments);
|
||||||
|
|
||||||
|
if (ProBlock *funcPtr = m_replaceFunctions.value(func, 0))
|
||||||
|
return evaluateFunction(funcPtr, argumentsList, 0);
|
||||||
|
|
||||||
QStringList args;
|
QStringList args;
|
||||||
for (int i = 0; i < argumentsList.count(); ++i)
|
for (int i = 0; i < argumentsList.count(); ++i)
|
||||||
args += expandVariableReferences(argumentsList[i]).join(Option::field_sep);
|
args += expandVariableReferences(argumentsList[i]).join(Option::field_sep);
|
||||||
@@ -1618,13 +1696,40 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProFileEvaluator::Private::evaluateConditionalFunction(
|
ProItem::ProItemReturn ProFileEvaluator::Private::evaluateConditionalFunction(
|
||||||
const QString &function, const QString &arguments)
|
const QString &function, const QString &arguments)
|
||||||
{
|
{
|
||||||
QStringList argumentsList = split_arg_list(arguments);
|
QStringList argumentsList = split_arg_list(arguments);
|
||||||
|
|
||||||
|
if (ProBlock *funcPtr = m_testFunctions.value(function, 0)) {
|
||||||
|
bool ok;
|
||||||
|
QStringList ret = evaluateFunction(funcPtr, argumentsList, &ok);
|
||||||
|
if (ok) {
|
||||||
|
if (ret.isEmpty()) {
|
||||||
|
return ProItem::ReturnTrue;
|
||||||
|
} else {
|
||||||
|
if (ret.first() != QLatin1String("false")) {
|
||||||
|
if (ret.first() == QLatin1String("true")) {
|
||||||
|
return ProItem::ReturnTrue;
|
||||||
|
} else {
|
||||||
|
bool ok;
|
||||||
|
int val = ret.first().toInt(&ok);
|
||||||
|
if (ok) {
|
||||||
|
if (val)
|
||||||
|
return ProItem::ReturnTrue;
|
||||||
|
} else {
|
||||||
|
q->logMessage(format("Unexpected return value from test '%1': %2")
|
||||||
|
.arg(function).arg(ret.join(QLatin1String(" :: "))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ProItem::ReturnFalse;
|
||||||
|
}
|
||||||
|
|
||||||
QString sep;
|
QString sep;
|
||||||
sep.append(Option::field_sep);
|
sep.append(Option::field_sep);
|
||||||
|
|
||||||
QStringList args;
|
QStringList args;
|
||||||
for (int i = 0; i < argumentsList.count(); ++i)
|
for (int i = 0; i < argumentsList.count(); ++i)
|
||||||
args += expandVariableReferences(argumentsList[i]).join(sep);
|
args += expandVariableReferences(argumentsList[i]).join(sep);
|
||||||
@@ -1632,7 +1737,8 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
enum TestFunc { T_REQUIRES=1, T_GREATERTHAN, T_LESSTHAN, T_EQUALS,
|
enum TestFunc { T_REQUIRES=1, T_GREATERTHAN, T_LESSTHAN, T_EQUALS,
|
||||||
T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM,
|
T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM,
|
||||||
T_RETURN, T_BREAK, T_NEXT, T_DEFINED, T_CONTAINS, T_INFILE,
|
T_RETURN, T_BREAK, T_NEXT, T_DEFINED, T_CONTAINS, T_INFILE,
|
||||||
T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_MESSAGE, T_IF };
|
T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_MESSAGE, T_IF,
|
||||||
|
T_DEFINE_TEST, T_DEFINE_REPLACE };
|
||||||
|
|
||||||
static QHash<QString, int> *functions = 0;
|
static QHash<QString, int> *functions = 0;
|
||||||
if (!functions) {
|
if (!functions) {
|
||||||
@@ -1665,35 +1771,87 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
functions->insert(QLatin1String("message"), T_MESSAGE); //v
|
functions->insert(QLatin1String("message"), T_MESSAGE); //v
|
||||||
functions->insert(QLatin1String("warning"), T_MESSAGE); //v
|
functions->insert(QLatin1String("warning"), T_MESSAGE); //v
|
||||||
functions->insert(QLatin1String("error"), T_MESSAGE); //v
|
functions->insert(QLatin1String("error"), T_MESSAGE); //v
|
||||||
|
functions->insert(QLatin1String("defineTest"), T_DEFINE_TEST); //v
|
||||||
|
functions->insert(QLatin1String("defineReplace"), T_DEFINE_REPLACE); //v
|
||||||
}
|
}
|
||||||
|
|
||||||
TestFunc func_t = (TestFunc)functions->value(function);
|
TestFunc func_t = (TestFunc)functions->value(function);
|
||||||
|
|
||||||
switch (func_t) {
|
switch (func_t) {
|
||||||
|
case T_DEFINE_TEST:
|
||||||
|
m_definingTest = true;
|
||||||
|
goto defineFunc;
|
||||||
|
case T_DEFINE_REPLACE:
|
||||||
|
m_definingTest = false;
|
||||||
|
defineFunc:
|
||||||
|
if (args.count() != 1) {
|
||||||
|
q->logMessage(format("%s(function) requires one argument.").arg(function));
|
||||||
|
return ProItem::ReturnFalse;
|
||||||
|
}
|
||||||
|
m_definingFunc = args.first();
|
||||||
|
return ProItem::ReturnTrue;
|
||||||
|
case T_DEFINED:
|
||||||
|
if (args.count() < 1 || args.count() > 2) {
|
||||||
|
q->logMessage(format("defined(function, [\"test\"|\"replace\"])"
|
||||||
|
" requires one or two arguments."));
|
||||||
|
return ProItem::ReturnFalse;
|
||||||
|
}
|
||||||
|
if (args.count() > 1) {
|
||||||
|
if (args[1] == QLatin1String("test"))
|
||||||
|
return returnBool(m_testFunctions.contains(args[0]));
|
||||||
|
else if (args[1] == QLatin1String("replace"))
|
||||||
|
return returnBool(m_replaceFunctions.contains(args[0]));
|
||||||
|
q->logMessage(format("defined(function, type):"
|
||||||
|
" unexpected type [%1].\n").arg(args[1]));
|
||||||
|
return ProItem::ReturnFalse;
|
||||||
|
}
|
||||||
|
return returnBool(m_replaceFunctions.contains(args[0])
|
||||||
|
|| m_testFunctions.contains(args[0]));
|
||||||
|
case T_RETURN:
|
||||||
|
m_returnValue = args;
|
||||||
|
// It is "safe" to ignore returns - due to qmake brokeness
|
||||||
|
// they cannot be used to terminate loops anyway.
|
||||||
|
if (m_skipLevel || m_cumulative)
|
||||||
|
return ProItem::ReturnTrue;
|
||||||
|
if (m_valuemapStack.isEmpty()) {
|
||||||
|
q->logMessage(format("unexpected return()."));
|
||||||
|
return ProItem::ReturnFalse;
|
||||||
|
}
|
||||||
|
return ProItem::ReturnReturn;
|
||||||
|
case T_EXPORT:
|
||||||
|
if (m_skipLevel && !m_cumulative)
|
||||||
|
return ProItem::ReturnTrue;
|
||||||
|
if (args.count() != 1) {
|
||||||
|
q->logMessage(format("export(variable) requires one argument."));
|
||||||
|
return ProItem::ReturnFalse;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < m_valuemapStack.size(); ++i) {
|
||||||
|
m_valuemapStack[i][args[0]] = m_valuemap[args[0]];
|
||||||
|
m_filevaluemapStack[i][currentProFile()][args[0]] =
|
||||||
|
m_filevaluemap[currentProFile()][args[0]];
|
||||||
|
}
|
||||||
|
return ProItem::ReturnTrue;
|
||||||
#if 0
|
#if 0
|
||||||
case T_INFILE:
|
case T_INFILE:
|
||||||
case T_REQUIRES:
|
case T_REQUIRES:
|
||||||
case T_GREATERTHAN:
|
case T_GREATERTHAN:
|
||||||
case T_LESSTHAN:
|
case T_LESSTHAN:
|
||||||
case T_EQUALS:
|
case T_EQUALS:
|
||||||
case T_EXPORT:
|
|
||||||
case T_CLEAR:
|
case T_CLEAR:
|
||||||
case T_UNSET:
|
case T_UNSET:
|
||||||
case T_EVAL:
|
case T_EVAL:
|
||||||
case T_IF:
|
case T_IF:
|
||||||
case T_RETURN:
|
|
||||||
case T_BREAK:
|
case T_BREAK:
|
||||||
case T_NEXT:
|
case T_NEXT:
|
||||||
case T_DEFINED:
|
|
||||||
#endif
|
#endif
|
||||||
case T_CONFIG: {
|
case T_CONFIG: {
|
||||||
if (args.count() < 1 || args.count() > 2) {
|
if (args.count() < 1 || args.count() > 2) {
|
||||||
q->logMessage(format("CONFIG(config) requires one or two arguments."));
|
q->logMessage(format("CONFIG(config) requires one or two arguments."));
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
if (args.count() == 1) {
|
if (args.count() == 1) {
|
||||||
//cond = isActiveConfig(args.first()); XXX
|
//cond = isActiveConfig(args.first()); XXX
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
const QStringList mutuals = args[1].split(QLatin1Char('|'));
|
const QStringList mutuals = args[1].split(QLatin1Char('|'));
|
||||||
const QStringList &configs = valuesDirect(QLatin1String("CONFIG"));
|
const QStringList &configs = valuesDirect(QLatin1String("CONFIG"));
|
||||||
@@ -1701,16 +1859,16 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
for (int i = configs.size() - 1; i >= 0; i--) {
|
for (int i = configs.size() - 1; i >= 0; i--) {
|
||||||
for (int mut = 0; mut < mutuals.count(); mut++) {
|
for (int mut = 0; mut < mutuals.count(); mut++) {
|
||||||
if (configs[i] == mutuals[mut].trimmed()) {
|
if (configs[i] == mutuals[mut].trimmed()) {
|
||||||
return (configs[i] == args[0]);
|
return returnBool(configs[i] == args[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
case T_CONTAINS: {
|
case T_CONTAINS: {
|
||||||
if (args.count() < 2 || args.count() > 3) {
|
if (args.count() < 2 || args.count() > 3) {
|
||||||
q->logMessage(format("contains(var, val) requires two or three arguments."));
|
q->logMessage(format("contains(var, val) requires two or three arguments."));
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRegExp regx(args[1]);
|
QRegExp regx(args[1]);
|
||||||
@@ -1719,7 +1877,7 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
for (int i = 0; i < l.size(); ++i) {
|
for (int i = 0; i < l.size(); ++i) {
|
||||||
const QString val = l[i];
|
const QString val = l[i];
|
||||||
if (regx.exactMatch(val) || val == args[1]) {
|
if (regx.exactMatch(val) || val == args[1]) {
|
||||||
return true;
|
return ProItem::ReturnTrue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1728,47 +1886,47 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
const QString val = l[i];
|
const QString val = l[i];
|
||||||
for (int mut = 0; mut < mutuals.count(); mut++) {
|
for (int mut = 0; mut < mutuals.count(); mut++) {
|
||||||
if (val == mutuals[mut].trimmed()) {
|
if (val == mutuals[mut].trimmed()) {
|
||||||
return (regx.exactMatch(val) || val == args[1]);
|
return returnBool(regx.exactMatch(val) || val == args[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
case T_COUNT: {
|
case T_COUNT: {
|
||||||
if (args.count() != 2 && args.count() != 3) {
|
if (args.count() != 2 && args.count() != 3) {
|
||||||
q->logMessage(format("count(var, count, op=\"equals\") requires two or three arguments."));
|
q->logMessage(format("count(var, count, op=\"equals\") requires two or three arguments."));
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
if (args.count() == 3) {
|
if (args.count() == 3) {
|
||||||
QString comp = args[2];
|
QString comp = args[2];
|
||||||
if (comp == QLatin1String(">") || comp == QLatin1String("greaterThan")) {
|
if (comp == QLatin1String(">") || comp == QLatin1String("greaterThan")) {
|
||||||
return (values(args.first()).count() > args[1].toInt());
|
return returnBool(values(args.first()).count() > args[1].toInt());
|
||||||
} else if (comp == QLatin1String(">=")) {
|
} else if (comp == QLatin1String(">=")) {
|
||||||
return (values(args.first()).count() >= args[1].toInt());
|
return returnBool(values(args.first()).count() >= args[1].toInt());
|
||||||
} else if (comp == QLatin1String("<") || comp == QLatin1String("lessThan")) {
|
} else if (comp == QLatin1String("<") || comp == QLatin1String("lessThan")) {
|
||||||
return (values(args.first()).count() < args[1].toInt());
|
return returnBool(values(args.first()).count() < args[1].toInt());
|
||||||
} else if (comp == QLatin1String("<=")) {
|
} else if (comp == QLatin1String("<=")) {
|
||||||
return (values(args.first()).count() <= args[1].toInt());
|
return returnBool(values(args.first()).count() <= args[1].toInt());
|
||||||
} else if (comp == QLatin1String("equals") || comp == QLatin1String("isEqual")
|
} else if (comp == QLatin1String("equals") || comp == QLatin1String("isEqual")
|
||||||
|| comp == QLatin1String("=") || comp == QLatin1String("==")) {
|
|| comp == QLatin1String("=") || comp == QLatin1String("==")) {
|
||||||
return (values(args.first()).count() == args[1].toInt());
|
return returnBool(values(args.first()).count() == args[1].toInt());
|
||||||
} else {
|
} else {
|
||||||
q->logMessage(format("unexpected modifier to count(%2)").arg(comp));
|
q->logMessage(format("unexpected modifier to count(%2)").arg(comp));
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (values(args.first()).count() == args[1].toInt());
|
return returnBool(values(args.first()).count() == args[1].toInt());
|
||||||
}
|
}
|
||||||
case T_INCLUDE: {
|
case T_INCLUDE: {
|
||||||
if (m_skipLevel && !m_cumulative)
|
if (m_skipLevel && !m_cumulative)
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
QString parseInto;
|
QString parseInto;
|
||||||
if (args.count() == 2) {
|
if (args.count() == 2) {
|
||||||
parseInto = args[1];
|
parseInto = args[1];
|
||||||
} else if (args.count() != 1) {
|
} else if (args.count() != 1) {
|
||||||
q->logMessage(format("include(file) requires one or two arguments."));
|
q->logMessage(format("include(file) requires one or two arguments."));
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
QString fileName = args.first();
|
QString fileName = args.first();
|
||||||
// ### this breaks if we have include(c:/reallystupid.pri) but IMHO that's really bad style.
|
// ### this breaks if we have include(c:/reallystupid.pri) but IMHO that's really bad style.
|
||||||
@@ -1777,11 +1935,11 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
State sts = m_sts;
|
State sts = m_sts;
|
||||||
bool ok = evaluateFile(fileName);
|
bool ok = evaluateFile(fileName);
|
||||||
m_sts = sts;
|
m_sts = sts;
|
||||||
return ok;
|
return returnBool(ok);
|
||||||
}
|
}
|
||||||
case T_LOAD: {
|
case T_LOAD: {
|
||||||
if (m_skipLevel && !m_cumulative)
|
if (m_skipLevel && !m_cumulative)
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
QString parseInto;
|
QString parseInto;
|
||||||
bool ignore_error = false;
|
bool ignore_error = false;
|
||||||
if (args.count() == 2) {
|
if (args.count() == 2) {
|
||||||
@@ -1789,18 +1947,18 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
ignore_error = (sarg.toLower() == QLatin1String("true") || sarg.toInt());
|
ignore_error = (sarg.toLower() == QLatin1String("true") || sarg.toInt());
|
||||||
} else if (args.count() != 1) {
|
} else if (args.count() != 1) {
|
||||||
q->logMessage(format("load(feature) requires one or two arguments."));
|
q->logMessage(format("load(feature) requires one or two arguments."));
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
// XXX ignore_error unused
|
// XXX ignore_error unused
|
||||||
return evaluateFeatureFile(args.first());
|
return returnBool(evaluateFeatureFile(args.first()));
|
||||||
}
|
}
|
||||||
case T_DEBUG:
|
case T_DEBUG:
|
||||||
// Yup - do nothing. Nothing is going to enable debug output anyway.
|
// Yup - do nothing. Nothing is going to enable debug output anyway.
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
case T_MESSAGE: {
|
case T_MESSAGE: {
|
||||||
if (args.count() != 1) {
|
if (args.count() != 1) {
|
||||||
q->logMessage(format("%1(message) requires one argument.").arg(function));
|
q->logMessage(format("%1(message) requires one argument.").arg(function));
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
QString msg = fixEnvVariables(args.first());
|
QString msg = fixEnvVariables(args.first());
|
||||||
if (function == QLatin1String("error")) {
|
if (function == QLatin1String("error")) {
|
||||||
@@ -1817,42 +1975,42 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
} else {
|
} else {
|
||||||
q->fileMessage(format("Project MESSAGE: %1").arg(msg));
|
q->fileMessage(format("Project MESSAGE: %1").arg(msg));
|
||||||
}
|
}
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
#if 0 // Way too dangerous to enable.
|
#if 0 // Way too dangerous to enable.
|
||||||
case T_SYSTEM: {
|
case T_SYSTEM: {
|
||||||
if (args.count() != 1) {
|
if (args.count() != 1) {
|
||||||
q->logMessage(format("system(exec) requires one argument."));
|
q->logMessage(format("system(exec) requires one argument."));
|
||||||
false;
|
ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
return (system(args.first().toLatin1().constData()) == 0);
|
return returnBool(system(args.first().toLatin1().constData()) == 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
case T_ISEMPTY: {
|
case T_ISEMPTY: {
|
||||||
if (args.count() != 1) {
|
if (args.count() != 1) {
|
||||||
q->logMessage(format("isEmpty(var) requires one argument."));
|
q->logMessage(format("isEmpty(var) requires one argument."));
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
QStringList sl = values(args.first());
|
QStringList sl = values(args.first());
|
||||||
if (sl.count() == 0) {
|
if (sl.count() == 0) {
|
||||||
return true;
|
return ProItem::ReturnTrue;
|
||||||
} else if (sl.count() > 0) {
|
} else if (sl.count() > 0) {
|
||||||
QString var = sl.first();
|
QString var = sl.first();
|
||||||
if (var.isEmpty())
|
if (var.isEmpty())
|
||||||
return true;
|
return ProItem::ReturnTrue;
|
||||||
}
|
}
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
case T_EXISTS: {
|
case T_EXISTS: {
|
||||||
if (args.count() != 1) {
|
if (args.count() != 1) {
|
||||||
q->logMessage(format("exists(file) requires one argument."));
|
q->logMessage(format("exists(file) requires one argument."));
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
QString file = args.first();
|
QString file = args.first();
|
||||||
file = Option::fixPathToLocalOS(file);
|
file = Option::fixPathToLocalOS(file);
|
||||||
|
|
||||||
if (QFile::exists(file)) {
|
if (QFile::exists(file)) {
|
||||||
return true;
|
return ProItem::ReturnTrue;
|
||||||
}
|
}
|
||||||
//regular expression I guess
|
//regular expression I guess
|
||||||
QString dirstr = currentDirectory();
|
QString dirstr = currentDirectory();
|
||||||
@@ -1863,17 +2021,16 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(
|
|||||||
}
|
}
|
||||||
if (file.contains(QLatin1Char('*')) || file.contains(QLatin1Char('?')))
|
if (file.contains(QLatin1Char('*')) || file.contains(QLatin1Char('?')))
|
||||||
if (!QDir(dirstr).entryList(QStringList(file)).isEmpty())
|
if (!QDir(dirstr).entryList(QStringList(file)).isEmpty())
|
||||||
return true;
|
return ProItem::ReturnTrue;
|
||||||
|
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
case 0:
|
case 0:
|
||||||
// This is too chatty currently (missing defineTest and defineReplace)
|
q->logMessage(format("'%1' is not a recognized test function").arg(function));
|
||||||
//q->logMessage(format("'%1' is not a recognized test function").arg(function));
|
return ProItem::ReturnFalse;
|
||||||
return false;
|
|
||||||
default:
|
default:
|
||||||
q->logMessage(format("Function '%1' is not implemented").arg(function));
|
q->logMessage(format("Function '%1' is not implemented").arg(function));
|
||||||
return false;
|
return ProItem::ReturnFalse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2032,7 +2189,7 @@ bool ProFileEvaluator::Private::evaluateFile(const QString &fileName)
|
|||||||
ProFile *pro = q->parsedProFile(fileName);
|
ProFile *pro = q->parsedProFile(fileName);
|
||||||
if (pro) {
|
if (pro) {
|
||||||
m_profileStack.push(pro);
|
m_profileStack.push(pro);
|
||||||
bool ok = pro->Accept(this);
|
bool ok = (pro->Accept(this) == ProItem::ReturnTrue);
|
||||||
m_profileStack.pop();
|
m_profileStack.pop();
|
||||||
q->releaseParsedProFile(pro);
|
q->releaseParsedProFile(pro);
|
||||||
return ok;
|
return ok;
|
||||||
|
|||||||
@@ -46,15 +46,21 @@ QString ProItem::comment() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --------------- ProBlock ----------------
|
// --------------- ProBlock ----------------
|
||||||
|
|
||||||
ProBlock::ProBlock(ProBlock *parent)
|
ProBlock::ProBlock(ProBlock *parent)
|
||||||
{
|
{
|
||||||
m_blockKind = 0;
|
m_blockKind = 0;
|
||||||
m_parent = parent;
|
m_parent = parent;
|
||||||
|
m_refCount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProBlock::~ProBlock()
|
ProBlock::~ProBlock()
|
||||||
{
|
{
|
||||||
qDeleteAll(m_proitems);
|
foreach (ProItem *itm, m_proitems)
|
||||||
|
if (itm->kind() == BlockKind)
|
||||||
|
static_cast<ProBlock *>(itm)->deref();
|
||||||
|
else
|
||||||
|
delete itm;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProBlock::appendItem(ProItem *proitem)
|
void ProBlock::appendItem(ProItem *proitem)
|
||||||
@@ -97,15 +103,16 @@ ProItem::ProItemKind ProBlock::kind() const
|
|||||||
return ProItem::BlockKind;
|
return ProItem::BlockKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProBlock::Accept(AbstractProItemVisitor *visitor)
|
ProItem::ProItemReturn ProBlock::Accept(AbstractProItemVisitor *visitor)
|
||||||
{
|
{
|
||||||
visitor->visitBeginProBlock(this);
|
if (visitor->visitBeginProBlock(this) == ReturnSkip)
|
||||||
foreach (ProItem *item, m_proitems) {
|
return ReturnTrue;
|
||||||
if (!item->Accept(visitor))
|
ProItemReturn rt = ReturnTrue;
|
||||||
return false;
|
foreach (ProItem *item, m_proitems)
|
||||||
}
|
if ((rt = item->Accept(visitor)) != ReturnTrue && rt != ReturnFalse)
|
||||||
|
break;
|
||||||
visitor->visitEndProBlock(this);
|
visitor->visitEndProBlock(this);
|
||||||
return true;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------- ProVariable ----------------
|
// --------------- ProVariable ----------------
|
||||||
@@ -137,15 +144,13 @@ QString ProVariable::variable() const
|
|||||||
return m_variable;
|
return m_variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProVariable::Accept(AbstractProItemVisitor *visitor)
|
ProItem::ProItemReturn ProVariable::Accept(AbstractProItemVisitor *visitor)
|
||||||
{
|
{
|
||||||
visitor->visitBeginProVariable(this);
|
visitor->visitBeginProVariable(this);
|
||||||
foreach (ProItem *item, m_proitems) {
|
foreach (ProItem *item, m_proitems)
|
||||||
if (!item->Accept(visitor))
|
item->Accept(visitor); // cannot fail
|
||||||
return false;
|
|
||||||
}
|
|
||||||
visitor->visitEndProVariable(this);
|
visitor->visitEndProVariable(this);
|
||||||
return true;
|
return ReturnTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------- ProValue ----------------
|
// --------------- ProValue ----------------
|
||||||
@@ -180,10 +185,10 @@ ProItem::ProItemKind ProValue::kind() const
|
|||||||
return ProItem::ValueKind;
|
return ProItem::ValueKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProValue::Accept(AbstractProItemVisitor *visitor)
|
ProItem::ProItemReturn ProValue::Accept(AbstractProItemVisitor *visitor)
|
||||||
{
|
{
|
||||||
visitor->visitProValue(this);
|
visitor->visitProValue(this);
|
||||||
return true;
|
return ReturnTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------- ProFunction ----------------
|
// --------------- ProFunction ----------------
|
||||||
@@ -207,10 +212,9 @@ ProItem::ProItemKind ProFunction::kind() const
|
|||||||
return ProItem::FunctionKind;
|
return ProItem::FunctionKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProFunction::Accept(AbstractProItemVisitor *visitor)
|
ProItem::ProItemReturn ProFunction::Accept(AbstractProItemVisitor *visitor)
|
||||||
{
|
{
|
||||||
visitor->visitProFunction(this);
|
return visitor->visitProFunction(this);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------- ProCondition ----------------
|
// --------------- ProCondition ----------------
|
||||||
@@ -234,10 +238,10 @@ ProItem::ProItemKind ProCondition::kind() const
|
|||||||
return ProItem::ConditionKind;
|
return ProItem::ConditionKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProCondition::Accept(AbstractProItemVisitor *visitor)
|
ProItem::ProItemReturn ProCondition::Accept(AbstractProItemVisitor *visitor)
|
||||||
{
|
{
|
||||||
visitor->visitProCondition(this);
|
visitor->visitProCondition(this);
|
||||||
return true;
|
return ReturnTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------- ProOperator ----------------
|
// --------------- ProOperator ----------------
|
||||||
@@ -261,10 +265,10 @@ ProItem::ProItemKind ProOperator::kind() const
|
|||||||
return ProItem::OperatorKind;
|
return ProItem::OperatorKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProOperator::Accept(AbstractProItemVisitor *visitor)
|
ProItem::ProItemReturn ProOperator::Accept(AbstractProItemVisitor *visitor)
|
||||||
{
|
{
|
||||||
visitor->visitProOperator(this);
|
visitor->visitProOperator(this);
|
||||||
return true;
|
return ReturnTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------- ProFile ----------------
|
// --------------- ProFile ----------------
|
||||||
@@ -309,13 +313,12 @@ bool ProFile::isModified() const
|
|||||||
return m_modified;
|
return m_modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProFile::Accept(AbstractProItemVisitor *visitor)
|
ProItem::ProItemReturn ProFile::Accept(AbstractProItemVisitor *visitor)
|
||||||
{
|
{
|
||||||
visitor->visitBeginProFile(this);
|
ProItemReturn rt;
|
||||||
foreach (ProItem *item, m_proitems) {
|
if ((rt = visitor->visitBeginProFile(this)) != ReturnTrue)
|
||||||
if (!item->Accept(visitor))
|
return rt;
|
||||||
return false;
|
ProBlock::Accept(visitor); // cannot fail
|
||||||
}
|
|
||||||
return visitor->visitEndProFile(this);
|
return visitor->visitEndProFile(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,13 @@ public:
|
|||||||
BlockKind
|
BlockKind
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ProItemReturn {
|
||||||
|
ReturnFalse,
|
||||||
|
ReturnTrue,
|
||||||
|
ReturnSkip,
|
||||||
|
ReturnReturn
|
||||||
|
};
|
||||||
|
|
||||||
ProItem() : m_lineNumber(0) {}
|
ProItem() : m_lineNumber(0) {}
|
||||||
virtual ~ProItem() {}
|
virtual ~ProItem() {}
|
||||||
|
|
||||||
@@ -57,7 +64,7 @@ public:
|
|||||||
void setComment(const QString &comment);
|
void setComment(const QString &comment);
|
||||||
QString comment() const;
|
QString comment() const;
|
||||||
|
|
||||||
virtual bool Accept(AbstractProItemVisitor *visitor) = 0;
|
virtual ProItemReturn Accept(AbstractProItemVisitor *visitor) = 0;
|
||||||
int lineNumber() const { return m_lineNumber; }
|
int lineNumber() const { return m_lineNumber; }
|
||||||
void setLineNumber(int lineNumber) { m_lineNumber = lineNumber; }
|
void setLineNumber(int lineNumber) { m_lineNumber = lineNumber; }
|
||||||
|
|
||||||
@@ -75,7 +82,8 @@ public:
|
|||||||
ScopeContentsKind = 0x02,
|
ScopeContentsKind = 0x02,
|
||||||
VariableKind = 0x04,
|
VariableKind = 0x04,
|
||||||
ProFileKind = 0x08,
|
ProFileKind = 0x08,
|
||||||
SingleLine = 0x10
|
FunctionBodyKind = 0x10,
|
||||||
|
SingleLine = 0x80
|
||||||
};
|
};
|
||||||
|
|
||||||
ProBlock(ProBlock *parent);
|
ProBlock(ProBlock *parent);
|
||||||
@@ -91,14 +99,18 @@ public:
|
|||||||
void setParent(ProBlock *parent);
|
void setParent(ProBlock *parent);
|
||||||
ProBlock *parent() const;
|
ProBlock *parent() const;
|
||||||
|
|
||||||
|
void ref() { ++m_refCount; }
|
||||||
|
void deref() { if (!--m_refCount) delete this; }
|
||||||
|
|
||||||
ProItem::ProItemKind kind() const;
|
ProItem::ProItemKind kind() const;
|
||||||
|
|
||||||
virtual bool Accept(AbstractProItemVisitor *visitor);
|
virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
|
||||||
protected:
|
protected:
|
||||||
QList<ProItem *> m_proitems;
|
QList<ProItem *> m_proitems;
|
||||||
private:
|
private:
|
||||||
ProBlock *m_parent;
|
ProBlock *m_parent;
|
||||||
int m_blockKind;
|
int m_blockKind;
|
||||||
|
int m_refCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ProVariable : public ProBlock
|
class ProVariable : public ProBlock
|
||||||
@@ -120,7 +132,7 @@ public:
|
|||||||
void setVariable(const QString &name);
|
void setVariable(const QString &name);
|
||||||
QString variable() const;
|
QString variable() const;
|
||||||
|
|
||||||
virtual bool Accept(AbstractProItemVisitor *visitor);
|
virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
|
||||||
private:
|
private:
|
||||||
VariableOperator m_variableKind;
|
VariableOperator m_variableKind;
|
||||||
QString m_variable;
|
QString m_variable;
|
||||||
@@ -139,7 +151,7 @@ public:
|
|||||||
|
|
||||||
ProItem::ProItemKind kind() const;
|
ProItem::ProItemKind kind() const;
|
||||||
|
|
||||||
virtual bool Accept(AbstractProItemVisitor *visitor);
|
virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
|
||||||
private:
|
private:
|
||||||
QString m_value;
|
QString m_value;
|
||||||
ProVariable *m_variable;
|
ProVariable *m_variable;
|
||||||
@@ -155,7 +167,7 @@ public:
|
|||||||
|
|
||||||
ProItem::ProItemKind kind() const;
|
ProItem::ProItemKind kind() const;
|
||||||
|
|
||||||
virtual bool Accept(AbstractProItemVisitor *visitor);
|
virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
|
||||||
private:
|
private:
|
||||||
QString m_text;
|
QString m_text;
|
||||||
};
|
};
|
||||||
@@ -170,7 +182,7 @@ public:
|
|||||||
|
|
||||||
ProItem::ProItemKind kind() const;
|
ProItem::ProItemKind kind() const;
|
||||||
|
|
||||||
virtual bool Accept(AbstractProItemVisitor *visitor);
|
virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
|
||||||
private:
|
private:
|
||||||
QString m_text;
|
QString m_text;
|
||||||
};
|
};
|
||||||
@@ -190,7 +202,7 @@ public:
|
|||||||
|
|
||||||
ProItem::ProItemKind kind() const;
|
ProItem::ProItemKind kind() const;
|
||||||
|
|
||||||
virtual bool Accept(AbstractProItemVisitor *visitor);
|
virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
|
||||||
private:
|
private:
|
||||||
OperatorKind m_operatorKind;
|
OperatorKind m_operatorKind;
|
||||||
};
|
};
|
||||||
@@ -210,7 +222,7 @@ public:
|
|||||||
void setModified(bool modified);
|
void setModified(bool modified);
|
||||||
bool isModified() const;
|
bool isModified() const;
|
||||||
|
|
||||||
virtual bool Accept(AbstractProItemVisitor *visitor);
|
virtual ProItemReturn Accept(AbstractProItemVisitor *visitor);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_fileName;
|
QString m_fileName;
|
||||||
|
|||||||
Reference in New Issue
Block a user