From 0c09acbb25fd69feb091be6b057d3df3adc54313 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen <oswald.buddenhagen@nokia.com> Date: Fri, 18 Jun 2010 13:30:03 +0200 Subject: [PATCH] refactor ProFileEvaluator, part 1: introduce handler interface externalize the error message and evaluation notification callbacks into an own handler interface. --- .../qt4projectmanager/profilereader.cpp | 49 ++- src/plugins/qt4projectmanager/profilereader.h | 31 +- src/shared/proparser/profileevaluator.cpp | 310 ++++++++---------- src/shared/proparser/profileevaluator.h | 31 +- tests/manual/proparser/main.cpp | 28 +- 5 files changed, 235 insertions(+), 214 deletions(-) diff --git a/src/plugins/qt4projectmanager/profilereader.cpp b/src/plugins/qt4projectmanager/profilereader.cpp index 73257f561d7..f46ca8200fd 100644 --- a/src/plugins/qt4projectmanager/profilereader.cpp +++ b/src/plugins/qt4projectmanager/profilereader.cpp @@ -35,8 +35,38 @@ using namespace Qt4ProjectManager; using namespace Qt4ProjectManager::Internal; +static QString format(const QString &fileName, int lineNo, const QString &msg) +{ + if (lineNo) + return QString::fromLatin1("%1(%2): %3").arg(fileName, QString::number(lineNo), msg); + else + return msg; +} + +void ProMessageHandler::parseError(const QString &fileName, int lineNo, const QString &msg) +{ + emit errorFound(format(fileName, lineNo, msg)); +} + +void ProMessageHandler::configError(const QString &msg) +{ + emit errorFound(msg); +} + +void ProMessageHandler::evalError(const QString &fileName, int lineNo, const QString &msg) +{ + if (m_verbose) + emit errorFound(format(fileName, lineNo, msg)); +} + +void ProMessageHandler::fileMessage(const QString &) +{ + // we ignore these... +} + + ProFileReader::ProFileReader(ProFileOption *option) - : ProFileEvaluator(option) + : ProFileEvaluator(option, this) , m_ignoreLevel(0) { } @@ -79,23 +109,6 @@ QList<ProFile*> ProFileReader::includeFiles() const return m_includeFiles.values(); } -void ProFileReader::fileMessage(const QString &message) -{ - Q_UNUSED(message) - // we ignore these... -} - -void ProFileReader::logMessage(const QString &message) -{ - Q_UNUSED(message) - // we ignore these... -} - -void ProFileReader::errorMessage(const QString &message) -{ - emit errorFound(message); -} - ProFile *ProFileReader::proFileFor(const QString &name) { return m_includeFiles.value(name); diff --git a/src/plugins/qt4projectmanager/profilereader.h b/src/plugins/qt4projectmanager/profilereader.h index 3fec6307f1f..3a96fb019bf 100644 --- a/src/plugins/qt4projectmanager/profilereader.h +++ b/src/plugins/qt4projectmanager/profilereader.h @@ -39,7 +39,30 @@ namespace Qt4ProjectManager { namespace Internal { -class ProFileReader : public QObject, public ProFileEvaluator +class ProMessageHandler : public QObject, + public ProFileEvaluatorHandler +{ + Q_OBJECT + +public: + ProMessageHandler(bool verbose = false) : m_verbose(verbose) {} + virtual ~ProMessageHandler() {} + + virtual void aboutToEval(ProFile *, ProFile *, EvalFileType) {} + virtual void doneWithEval(ProFile *) {} + virtual void parseError(const QString &filename, int lineNo, const QString &msg); + virtual void configError(const QString &msg); + virtual void evalError(const QString &filename, int lineNo, const QString &msg); + virtual void fileMessage(const QString &msg); + +signals: + void errorFound(const QString &error); + +private: + bool m_verbose; +}; + +class ProFileReader : public ProMessageHandler, public ProFileEvaluator { Q_OBJECT @@ -52,15 +75,9 @@ public: QList<ProFile*> includeFiles() const; ProFile *proFileFor(const QString &name); -signals: - void errorFound(const QString &error); -private: virtual void aboutToEval(ProFile *parent, ProFile *proFile, EvalFileType type); virtual void doneWithEval(ProFile *parent); - virtual void logMessage(const QString &msg); - virtual void fileMessage(const QString &msg); - virtual void errorMessage(const QString &msg); private: QMap<QString, ProFile *> m_includeFiles; diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index 200f7ce5ba6..26af3650d1e 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -169,16 +169,18 @@ ProFileOption::~ProFileOption() // /////////////////////////////////////////////////////////////////////// +#define fL1S(s) QString::fromLatin1(s) + class ProFileEvaluator::Private { public: static void initStatics(); - Private(ProFileEvaluator *q_, ProFileOption *option); + Private(ProFileEvaluator *q_, ProFileOption *option, + ProFileEvaluatorHandler *handler); ~Private(); ProFileEvaluator *q; int m_lineNo; // Error reporting - bool m_verbose; /////////////// Reading pro file @@ -254,7 +256,7 @@ public: static ALWAYS_INLINE void skipHashStr(const ushort *&tokPtr); void skipExpression(const ushort *&tokPtr); - VisitReturn visitProFile(ProFile *pro, ProFileEvaluator::EvalFileType type); + VisitReturn visitProFile(ProFile *pro, ProFileEvaluatorHandler::EvalFileType type); VisitReturn visitProBlock(const ushort *tokPtr); VisitReturn visitProLoop(const ProString &variable, const ushort *exprPtr, const ushort *tokPtr); @@ -276,10 +278,8 @@ public: ProStringList evaluateExpandFunction(const ProString &function, const ProString &arguments); ProStringList evaluateExpandFunction(const ProString &function, const ushort *&tokPtr); ProStringList evaluateExpandFunction(const ProString &function, const ProStringList &args); - QString format(const char *format) const; - void logMessage(const QString &msg) const; - void errorMessage(const QString &msg) const; - void fileMessage(const QString &msg) const; + void parseError(const QString &msg) const; + void evalError(const QString &msg) const; QString currentFileName() const; QString currentDirectory() const; @@ -292,11 +292,11 @@ public: VisitReturn evaluateConditionalFunction(const ProString &function, const ProStringList &args); ProFile *parsedProFile(const QString &fileName, bool cache, const QString &contents = QString()); - bool evaluateFileDirect(const QString &fileName, ProFileEvaluator::EvalFileType type); - bool evaluateFile(const QString &fileName, ProFileEvaluator::EvalFileType type); + bool evaluateFileDirect(const QString &fileName, ProFileEvaluatorHandler::EvalFileType type); + bool evaluateFile(const QString &fileName, ProFileEvaluatorHandler::EvalFileType type); bool evaluateFeatureFile(const QString &fileName, QHash<ProString, ProStringList> *values = 0, FunctionDefs *defs = 0); - bool evaluateFileInto(const QString &fileName, ProFileEvaluator::EvalFileType type, + bool evaluateFileInto(const QString &fileName, ProFileEvaluatorHandler::EvalFileType type, QHash<ProString, ProStringList> *values, FunctionDefs *defs); static ALWAYS_INLINE VisitReturn returnBool(bool b) @@ -331,6 +331,7 @@ public: bool m_parsePreAndPostFiles; ProFileOption *m_option; + ProFileEvaluatorHandler *m_handler; enum ExpandFunc { E_MEMBER=1, E_FIRST, E_LAST, E_SIZE, E_CAT, E_FROMFILE, E_EVAL, E_LIST, @@ -540,14 +541,14 @@ ProString ProFileEvaluator::Private::map(const ProString &var) } -ProFileEvaluator::Private::Private(ProFileEvaluator *q_, ProFileOption *option) - : q(q_), m_option(option) +ProFileEvaluator::Private::Private(ProFileEvaluator *q_, ProFileOption *option, + ProFileEvaluatorHandler *handler) + : q(q_), m_option(option), m_handler(handler) { // So that single-threaded apps don't have to call initialize() for now. initStatics(); // Configuration, more or less - m_verbose = true; m_cumulative = true; m_parsePreAndPostFiles = true; @@ -569,7 +570,7 @@ bool ProFileEvaluator::Private::read(ProFile *pro) QFile file(pro->fileName()); if (!file.open(QIODevice::ReadOnly)) { if (IoUtils::exists(pro->fileName())) - errorMessage(format("%1 not readable.").arg(pro->fileName())); + parseError(fL1S("%1 not readable.").arg(pro->fileName())); return false; } @@ -921,7 +922,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in) cur++; checkTerm: if (c != term) { - logMessage(format("Missing %1 terminator [found %2]") + parseError(fL1S("Missing %1 terminator [found %2]") .arg(QChar(term)) .arg(c ? QString(c) : QString::fromLatin1("end-of-line"))); return false; @@ -1006,7 +1007,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in) if (c == '(') { FLUSH_LHS_LITERAL(false); if (ptr == buf) { - logMessage(format("Opening parenthesis without prior test name.")); + parseError(fL1S("Opening parenthesis without prior test name.")); inError = true; goto skip; } @@ -1021,7 +1022,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in) FLUSH_LHS_LITERAL(false); finalizeCond(tokPtr, buf, ptr); if (m_state == StNew) - logMessage(format("And operator without prior condition.")); + parseError(fL1S("And operator without prior condition.")); else m_operator = AndOperator; nextItem: @@ -1032,7 +1033,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in) FLUSH_LHS_LITERAL(false); finalizeCond(tokPtr, buf, ptr); if (m_state != StCond) - logMessage(format("Or operator without prior condition.")); + parseError(fL1S("Or operator without prior condition.")); else m_operator = OrOperator; goto nextItem; @@ -1047,7 +1048,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in) finalizeCond(tokPtr, buf, ptr); flushScopes(tokPtr); if (!m_blockstack.top().braceLevel) { - logMessage(format("Excess closing brace.")); + parseError(fL1S("Excess closing brace.")); } else if (!--m_blockstack.top().braceLevel && m_blockstack.count() != 1) { leaveScope(tokPtr); @@ -1079,7 +1080,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in) flushCond(tokPtr); putLineMarker(tokPtr); if (!(tlen = ptr - buf)) { - logMessage(format("Assignment operator without prior variable name.")); + parseError(fL1S("Assignment operator without prior variable name.")); inError = true; goto skip; } @@ -1118,11 +1119,11 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in) flushLine: FLUSH_LITERAL(false); if (quote) { - logMessage(format("Missing closing %1 quote").arg(QChar(quote))); + parseError(fL1S("Missing closing %1 quote").arg(QChar(quote))); return false; } if (!xprStack.isEmpty()) { - logMessage(format("Missing closing parenthesis in function call")); + parseError(fL1S("Missing closing parenthesis in function call")); return false; } if (context == CtxValue) { @@ -1135,7 +1136,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in) if (!c) { flushScopes(tokPtr); if (m_blockstack.size() > 1) - logMessage(format("Missing closing brace(s).")); + parseError(fL1S("Missing closing brace(s).")); while (m_blockstack.size()) leaveScope(tokPtr); xprBuff.clear(); @@ -1163,7 +1164,7 @@ bool ProFileEvaluator::Private::readInternal(QString *out, const QString &in) #undef FLUSH_RHS_LITERAL extraChars: - logMessage(format("Extra characters after test expression.")); + parseError(fL1S("Extra characters after test expression.")); return false; } @@ -1257,7 +1258,7 @@ void ProFileEvaluator::Private::finalizeCond(ushort *&tokPtr, ushort *uc, ushort m_tmp1.setRawData((QChar *)uc + 4, nlen); if (!m_tmp1.compare(statics.strelse, Qt::CaseInsensitive)) { if (m_invert || m_operator != NoOperator) { - logMessage(format("Unexpected operator in front of else.")); + parseError(fL1S("Unexpected operator in front of else.")); return; } BlockScope &top = m_blockstack.top(); @@ -1279,7 +1280,7 @@ void ProFileEvaluator::Private::finalizeCond(ushort *&tokPtr, ushort *uc, ushort break; leaveScope(tokPtr); } - errorMessage(format("Unexpected 'else'.")); + parseError(fL1S("Unexpected 'else'.")); return; } } @@ -1306,7 +1307,7 @@ void ProFileEvaluator::Private::finalizeCall(ushort *&tokPtr, ushort *uc, ushort putLineMarker(tokPtr); if (m_invert || m_operator == OrOperator) { // '|' could actually work reasonably, but qmake does nonsense here. - logMessage(format("Unexpected operator in front of for().")); + parseError(fL1S("Unexpected operator in front of for().")); return; } if (*uce == TokLiteral) { @@ -1341,7 +1342,7 @@ void ProFileEvaluator::Private::finalizeCall(ushort *&tokPtr, ushort *uc, ushort uc = uce; goto doFor; } - logMessage(format("Syntax is for(var, list), for(var, forever) or for(ever).")); + parseError(fL1S("Syntax is for(var, list), for(var, forever) or for(ever).")); return; } else if (m_tmp1 == statics.strdefineReplace) { defName = &statics.strdefineReplace; @@ -1354,7 +1355,7 @@ void ProFileEvaluator::Private::finalizeCall(ushort *&tokPtr, ushort *uc, ushort flushScopes(tokPtr); putLineMarker(tokPtr); if (m_invert) { - logMessage(format("Unexpected operator in front of function definition.")); + parseError(fL1S("Unexpected operator in front of function definition.")); return; } if (*uce == TokLiteral) { @@ -1371,7 +1372,7 @@ void ProFileEvaluator::Private::finalizeCall(ushort *&tokPtr, ushort *uc, ushort return; } } - logMessage(format("%1(function) requires one literal argument.").arg(*defName)); + parseError(fL1S("%1(function) requires one literal argument.").arg(*defName)); return; } } @@ -1780,7 +1781,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProBlock( case TokCondition: if (!m_skipLevel && okey != or_op) { if (curr.size() != 1) { - logMessage(format("Conditional must expand to exactly one word.")); + evalError(fL1S("Conditional must expand to exactly one word.")); okey = false; } else { okey = isActiveConfig(curr.at(0).toQString(m_tmp2), true) ^ invert; @@ -1793,7 +1794,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProBlock( case TokTestCall: if (!m_skipLevel && okey != or_op) { if (curr.size() != 1) { - logMessage(format("Test name must expand to exactly one word.")); + evalError(fL1S("Test name must expand to exactly one word.")); skipExpression(tokPtr); okey = false; } else { @@ -1858,7 +1859,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProLoop( ProString it_list = expandVariableReferences(exprPtr, 0, true).at(0); if (_variable.isEmpty()) { if (it_list != statics.strever) { - logMessage(format("Invalid loop expression.")); + evalError(fL1S("Invalid loop expression.")); return ReturnFalse; } it_list = ProString(statics.strforever); @@ -1898,7 +1899,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProLoop( if (!variable.isEmpty()) m_valuemapStack.top()[variable] = ProStringList(ProString(QString::number(index++), NoHash)); if (index > 1000) { - errorMessage(format("ran into infinite loop (> 1000 iterations).")); + evalError(fL1S("ran into infinite loop (> 1000 iterations).")); break; } } else { @@ -1941,7 +1942,7 @@ void ProFileEvaluator::Private::visitProVariable( if (curr.size() != 1) { skipExpression(tokPtr); - logMessage(format("Left hand side of assignment must expand to exactly one word.")); + evalError(fL1S("Left hand side of assignment must expand to exactly one word.")); return; } const ProString &varName = map(curr.first()); @@ -1952,13 +1953,13 @@ void ProFileEvaluator::Private::visitProVariable( const ProStringList &varVal = expandVariableReferences(tokPtr, sizeHint, true); const QString &val = varVal.at(0).toQString(m_tmp1); if (val.length() < 4 || val.at(0) != QLatin1Char('s')) { - logMessage(format("the ~= operator can handle only the s/// function.")); + evalError(fL1S("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.")); + evalError(fL1S("the s/// function expects 3 or 4 arguments.")); return; } @@ -2027,9 +2028,9 @@ void ProFileEvaluator::Private::visitProVariable( } ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProFile( - ProFile *pro, ProFileEvaluator::EvalFileType type) + ProFile *pro, ProFileEvaluatorHandler::EvalFileType type) { - q->aboutToEval(currentProFile(), pro, type); + m_handler->aboutToEval(currentProFile(), pro, type); m_lineNo = 0; m_profileStack.push(pro); if (m_profileStack.count() == 1) { @@ -2074,7 +2075,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProFile( if (!qmake_cache.isEmpty()) { qmake_cache = resolvePath(qmake_cache); QHash<ProString, ProStringList> cache_valuemap; - if (evaluateFileInto(qmake_cache, ProFileEvaluator::EvalConfigFile, + if (evaluateFileInto(qmake_cache, ProFileEvaluatorHandler::EvalConfigFile, &cache_valuemap, 0)) { if (m_option->qmakespec.isEmpty()) { const ProStringList &vals = cache_valuemap.value(ProString("QMAKESPEC")); @@ -2099,7 +2100,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProFile( } } if (qmakespec.isEmpty()) { - errorMessage(format("Could not find qmake configuration directory")); + m_handler->configError(fL1S("Could not find qmake configuration directory")); // Unlike in qmake, not finding the spec is not critical ... } } @@ -2120,7 +2121,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProFile( goto cool; } } - errorMessage(format("Could not find qmake configuration file")); + m_handler->configError(fL1S("Could not find qmake configuration file")); // Unlike in qmake, a missing config is not critical ... qmakespec.clear(); cool: ; @@ -2131,11 +2132,12 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProFile( m_option->qmakespec = QDir::cleanPath(qmakespec); QString spec = m_option->qmakespec + QLatin1String("/qmake.conf"); - if (!evaluateFileInto(spec, ProFileEvaluator::EvalConfigFile, + if (!evaluateFileInto(spec, ProFileEvaluatorHandler::EvalConfigFile, &m_option->base_valuemap, &m_option->base_functions)) { - errorMessage(format("Could not read qmake configuration file %1").arg(spec)); + m_handler->configError( + fL1S("Could not read qmake configuration file %1").arg(spec)); } else if (!m_option->cachefile.isEmpty()) { - evaluateFileInto(m_option->cachefile, ProFileEvaluator::EvalConfigFile, + evaluateFileInto(m_option->cachefile, ProFileEvaluatorHandler::EvalConfigFile, &m_option->base_valuemap, &m_option->base_functions); } m_option->qmakespec_name = IoUtils::fileName(m_option->qmakespec).toString(); @@ -2216,7 +2218,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProFile( } } m_profileStack.pop(); - q->doneWithEval(currentProFile()); + m_handler->doneWithEval(currentProFile()); return ReturnTrue; } @@ -2334,7 +2336,7 @@ QString ProFileEvaluator::Private::propertyValue(const QString &name, bool compl if (name == QLatin1String("QMAKE_VERSION")) return QLatin1String("1.0"); //### FIXME if (complain) - logMessage(format("Querying unknown property %1").arg(name)); + evalError(fL1S("Querying unknown property %1").arg(name)); return QString(); } @@ -2530,9 +2532,9 @@ ProStringList ProFileEvaluator::Private::expandVariableReferences( } if (term) { if (unicode != term) { - logMessage(format("Missing %1 terminator [found %2]") - .arg(QChar(term)) - .arg(unicode ? QString(unicode) : QString::fromLatin1(("end-of-line")))); + evalError(fL1S("Missing %1 terminator [found %2]") + .arg(QChar(term)) + .arg(unicode ? QString(unicode) : fL1S("end-of-line"))); // if (ok) // *ok = false; if (pos) @@ -2745,7 +2747,7 @@ ProStringList ProFileEvaluator::Private::evaluateFunction( const ushort *tokPtr = (const ushort *)func.string.constData() + func.offset; if (m_valuemapStack.count() >= 100) { - errorMessage(format("ran into infinite recursion (depth > 100).")); + evalError(fL1S("ran into infinite recursion (depth > 100).")); oki = false; } else { m_valuemapStack.push(QHash<ProString, ProStringList>()); @@ -2791,9 +2793,9 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateBoolFu if (val) return ReturnTrue; } else { - logMessage(format("Unexpected return value from test '%1': %2") - .arg(function.toQString(m_tmp1)) - .arg(ret.join(QLatin1String(" :: ")))); + evalError(fL1S("Unexpected return value from test '%1': %2") + .arg(function.toQString(m_tmp1)) + .arg(ret.join(QLatin1String(" :: ")))); } } } @@ -2843,8 +2845,8 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( int end = -1; if (func_t == E_SECTION) { if (args.count() != 3 && args.count() != 4) { - logMessage(format("%1(var) section(var, sep, begin, end) " - "requires three or four arguments.").arg(func.toQString(m_tmp1))); + evalError(fL1S("%1(var) section(var, sep, begin, end) requires" + " three or four arguments.").arg(func.toQString(m_tmp1))); } else { var = args[0]; sep = args.at(1).toQString(); @@ -2854,8 +2856,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( } } else { if (args.count() != 1) { - logMessage(format("%1(var) requires one argument.") - .arg(func.toQString(m_tmp1))); + evalError(fL1S("%1(var) requires one argument.").arg(func.toQString(m_tmp1))); } else { var = args[0]; regexp = true; @@ -2884,7 +2885,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( } case E_SPRINTF: if(args.count() < 1) { - logMessage(format("sprintf(format, ...) requires at least one argument")); + evalError(fL1S("sprintf(format, ...) requires at least one argument")); } else { QString tmp = args.at(0).toQString(m_tmp1); for (int i = 1; i < args.count(); ++i) @@ -2895,7 +2896,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( break; case E_JOIN: { if (args.count() < 1 || args.count() > 4) { - logMessage(format("join(var, glue, before, after) requires one to four arguments.")); + evalError(fL1S("join(var, glue, before, after) requires one to four arguments.")); } else { QString glue; ProString before, after; @@ -2913,7 +2914,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( } case E_SPLIT: if (args.count() != 2) { - logMessage(format("split(var, sep) requires one or two arguments")); + evalError(fL1S("split(var, sep) requires one or two arguments")); } else { const QString &sep = (args.count() == 2) ? args.at(1).toQString(m_tmp1) : statics.field_sep; foreach (const ProString &var, values(map(args.at(0)))) @@ -2923,7 +2924,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( break; case E_MEMBER: if (args.count() < 1 || args.count() > 3) { - logMessage(format("member(var, start, end) requires one to three arguments.")); + evalError(fL1S("member(var, start, end) requires one to three arguments.")); } else { bool ok = true; const ProStringList &var = values(map(args.at(0))); @@ -2941,15 +2942,15 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( } } if (!ok) - logMessage(format("member() argument 2 (start) '%2' invalid.") - .arg(start_str)); + evalError(fL1S("member() argument 2 (start) '%2' invalid.") + .arg(start_str)); } else { end = start; if (args.count() == 3) end = args.at(2).toQString(m_tmp1).toInt(&ok); if (!ok) - logMessage(format("member() argument 3 (end) '%2' invalid.\n") - .arg(args.at(2).toQString(m_tmp1))); + evalError(fL1S("member() argument 3 (end) '%2' invalid.\n") + .arg(args.at(2).toQString(m_tmp1))); } } if (ok) { @@ -2972,7 +2973,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( case E_FIRST: case E_LAST: if (args.count() != 1) { - logMessage(format("%1(var) requires one argument.").arg(func.toQString(m_tmp1))); + evalError(fL1S("%1(var) requires one argument.").arg(func.toQString(m_tmp1))); } else { const ProStringList &var = values(map(args.at(0))); if (!var.isEmpty()) { @@ -2985,13 +2986,13 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( break; case E_SIZE: if(args.count() != 1) - logMessage(format("size(var) requires one argument.")); + evalError(fL1S("size(var) requires one argument.")); else ret.append(ProString(QString::number(values(map(args.at(0))).size()), NoHash)); break; case E_CAT: if (args.count() < 1 || args.count() > 2) { - logMessage(format("cat(file, singleline=true) requires one or two arguments.")); + evalError(fL1S("cat(file, singleline=true) requires one or two arguments.")); } else { const QString &file = args.at(0).toQString(m_tmp1); @@ -3013,18 +3014,18 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( break; case E_FROMFILE: if (args.count() != 2) { - logMessage(format("fromfile(file, variable) requires two arguments.")); + evalError(fL1S("fromfile(file, variable) requires two arguments.")); } else { QHash<ProString, ProStringList> vars; QString fn = resolvePath(expandEnvVars(args.at(0).toQString(m_tmp1))); fn.detach(); - if (evaluateFileInto(fn, ProFileEvaluator::EvalAuxFile, &vars, 0)) + if (evaluateFileInto(fn, ProFileEvaluatorHandler::EvalAuxFile, &vars, 0)) ret = vars.value(map(args.at(1))); } break; case E_EVAL: if (args.count() != 1) { - logMessage(format("eval(variable) requires one argument")); + evalError(fL1S("eval(variable) requires one argument")); } else { ret += values(map(args.at(0))); } @@ -3040,7 +3041,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( break; } case E_FIND: if (args.count() != 2) { - logMessage(format("find(var, str) requires two arguments.")); + evalError(fL1S("find(var, str) requires two arguments.")); } else { QRegExp regx(args.at(1).toQString()); int t = 0; @@ -3054,7 +3055,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( case E_SYSTEM: if (!m_skipLevel) { if (args.count() < 1 || args.count() > 2) { - logMessage(format("system(execute) requires one or two arguments.")); + evalError(fL1S("system(execute) requires one or two arguments.")); } else { char buff[256]; FILE *proc = QT_POPEN(QString(QLatin1String("cd ") @@ -3083,7 +3084,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( break; case E_UNIQUE: if(args.count() != 1) { - logMessage(format("unique(var) requires one argument.")); + evalError(fL1S("unique(var) requires one argument.")); } else { ret = values(map(args.at(0))); ret.removeDuplicates(); @@ -3141,7 +3142,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( break; case E_FILES: if (args.count() != 1 && args.count() != 2) { - logMessage(format("files(pattern, recursive=false) requires one or two arguments")); + evalError(fL1S("files(pattern, recursive=false) requires one or two arguments")); } else { bool recursive = false; if (args.count() == 2) @@ -3183,7 +3184,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( break; case E_REPLACE: if(args.count() != 3 ) { - logMessage(format("replace(var, before, after) requires three arguments")); + evalError(fL1S("replace(var, before, after) requires three arguments")); } else { const QRegExp before(args.at(1).toQString()); const QString &after(args.at(2).toQString(m_tmp2)); @@ -3196,11 +3197,11 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( } break; case 0: - logMessage(format("'%1' is not a recognized replace function") - .arg(func.toQString(m_tmp1))); + evalError(fL1S("'%1' is not a recognized replace function") + .arg(func.toQString(m_tmp1))); break; default: - logMessage(format("Function '%1' is not implemented").arg(func.toQString(m_tmp1))); + evalError(fL1S("Function '%1' is not implemented").arg(func.toQString(m_tmp1))); break; } @@ -3240,8 +3241,8 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit switch (func_t) { case T_DEFINED: if (args.count() < 1 || args.count() > 2) { - logMessage(format("defined(function, [\"test\"|\"replace\"])" - " requires one or two arguments.")); + evalError(fL1S("defined(function, [\"test\"|\"replace\"])" + " requires one or two arguments.")); return ReturnFalse; } if (args.count() > 1) { @@ -3249,8 +3250,8 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit return returnBool(m_functionDefs.testFunctions.contains(args[0])); else if (args[1] == QLatin1String("replace")) return returnBool(m_functionDefs.replaceFunctions.contains(args[0])); - logMessage(format("defined(function, type):" - " unexpected type [%1].\n").arg(args.at(1).toQString(m_tmp1))); + evalError(fL1S("defined(function, type): unexpected type [%1].\n") + .arg(args.at(1).toQString(m_tmp1))); return ReturnFalse; } return returnBool(m_functionDefs.replaceFunctions.contains(args[0]) @@ -3262,7 +3263,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit if (m_skipLevel || m_cumulative) return ReturnTrue; if (m_valuemapStack.isEmpty()) { - logMessage(format("unexpected return().")); + evalError(fL1S("unexpected return().")); return ReturnFalse; } return ReturnReturn; @@ -3270,7 +3271,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit if (m_skipLevel && !m_cumulative) return ReturnTrue; if (args.count() != 1) { - logMessage(format("export(variable) requires one argument.")); + evalError(fL1S("export(variable) requires one argument.")); return ReturnFalse; } const ProString &var = map(args.at(0)); @@ -3293,12 +3294,12 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit } case T_INFILE: if (args.count() < 2 || args.count() > 3) { - logMessage(format("infile(file, var, [values]) requires two or three arguments.")); + evalError(fL1S("infile(file, var, [values]) requires two or three arguments.")); } else { QHash<ProString, ProStringList> vars; QString fn = resolvePath(expandEnvVars(args.at(0).toQString(m_tmp1))); fn.detach(); - if (!evaluateFileInto(fn, ProFileEvaluator::EvalAuxFile, &vars, 0)) + if (!evaluateFileInto(fn, ProFileEvaluatorHandler::EvalAuxFile, &vars, 0)) return ReturnFalse; if (args.count() == 2) return returnBool(vars.contains(args.at(1))); @@ -3334,20 +3335,20 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit return ReturnFalse; if (m_loopLevel) return ReturnBreak; - logMessage(format("unexpected break().")); + evalError(fL1S("unexpected break().")); return ReturnFalse; case T_NEXT: if (m_skipLevel) return ReturnFalse; if (m_loopLevel) return ReturnNext; - logMessage(format("unexpected next().")); + evalError(fL1S("unexpected next().")); return ReturnFalse; case T_IF: { if (m_skipLevel && !m_cumulative) return ReturnFalse; if (args.count() != 1) { - logMessage(format("if(condition) requires one argument.")); + evalError(fL1S("if(condition) requires one argument.")); return ReturnFalse; } const ProString &cond = args.at(0); @@ -3413,7 +3414,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit } case T_CONFIG: { if (args.count() < 1 || args.count() > 2) { - logMessage(format("CONFIG(config) requires one or two arguments.")); + evalError(fL1S("CONFIG(config) requires one or two arguments.")); return ReturnFalse; } if (args.count() == 1) @@ -3432,7 +3433,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit } case T_CONTAINS: { if (args.count() < 2 || args.count() > 3) { - logMessage(format("contains(var, val) requires two or three arguments.")); + evalError(fL1S("contains(var, val) requires two or three arguments.")); return ReturnFalse; } @@ -3469,7 +3470,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit } case T_COUNT: { if (args.count() != 2 && args.count() != 3) { - logMessage(format("count(var, count, op=\"equals\") requires two or three arguments.")); + evalError(fL1S("count(var, count, op=\"equals\") requires two or three arguments.")); return ReturnFalse; } int cnt = values(map(args.at(0))).count(); @@ -3488,8 +3489,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit || comp == QLatin1String("=") || comp == QLatin1String("==")) { return returnBool(cnt == val); } else { - logMessage(format("unexpected modifier to count(%2)") - .arg(comp.toQString(m_tmp1))); + evalError(fL1S("unexpected modifier to count(%2)").arg(comp.toQString(m_tmp1))); return ReturnFalse; } } @@ -3498,8 +3498,8 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit case T_GREATERTHAN: case T_LESSTHAN: { if (args.count() != 2) { - logMessage(format("%1(variable, value) requires two arguments.") - .arg(function.toQString(m_tmp1))); + evalError(fL1S("%1(variable, value) requires two arguments.") + .arg(function.toQString(m_tmp1))); return ReturnFalse; } const QString &rhs(args.at(1).toQString(m_tmp1)), @@ -3520,8 +3520,8 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit } case T_EQUALS: if (args.count() != 2) { - logMessage(format("%1(variable, value) requires two arguments.") - .arg(function.toQString(m_tmp1))); + evalError(fL1S("%1(variable, value) requires two arguments.") + .arg(function.toQString(m_tmp1))); return ReturnFalse; } return returnBool(values(map(args.at(0))).join(statics.field_sep) @@ -3530,8 +3530,8 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit if (m_skipLevel && !m_cumulative) return ReturnFalse; if (args.count() != 1) { - logMessage(format("%1(variable) requires one argument.") - .arg(function.toQString(m_tmp1))); + evalError(fL1S("%1(variable) requires one argument.") + .arg(function.toQString(m_tmp1))); return ReturnFalse; } QHash<ProString, ProStringList> *hsh; @@ -3549,8 +3549,8 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit if (m_skipLevel && !m_cumulative) return ReturnFalse; if (args.count() != 1) { - logMessage(format("%1(variable) requires one argument.") - .arg(function.toQString(m_tmp1))); + evalError(fL1S("%1(variable) requires one argument.") + .arg(function.toQString(m_tmp1))); return ReturnFalse; } QHash<ProString, ProStringList> *hsh; @@ -3575,17 +3575,17 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit if ((args.count() == 2) || (args.count() == 3) ) { parseInto = args.at(1).toQString(m_tmp2); } else if (args.count() != 1) { - logMessage(format("include(file, into, silent) requires one, two or three arguments.")); + evalError(fL1S("include(file, into, silent) requires one, two or three arguments.")); return ReturnFalse; } QString fn = resolvePath(expandEnvVars(args.at(0).toQString(m_tmp1))); fn.detach(); bool ok; if (parseInto.isEmpty()) { - ok = evaluateFile(fn, ProFileEvaluator::EvalIncludeFile); + ok = evaluateFile(fn, ProFileEvaluatorHandler::EvalIncludeFile); } else { QHash<ProString, ProStringList> symbols; - if ((ok = evaluateFileInto(fn, ProFileEvaluator::EvalIncludeFile, &symbols, 0))) { + if ((ok = evaluateFileInto(fn, ProFileEvaluatorHandler::EvalIncludeFile, &symbols, 0))) { QHash<ProString, ProStringList> newMap; for (QHash<ProString, ProStringList>::ConstIterator it = m_valuemapStack.top().constBegin(), @@ -3615,7 +3615,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit if (args.count() == 2) { ignore_error = isTrue(args.at(1), m_tmp2); } else if (args.count() != 1) { - logMessage(format("load(feature) requires one or two arguments.")); + evalError(fL1S("load(feature) requires one or two arguments.")); return ReturnFalse; } // XXX ignore_error unused @@ -3626,20 +3626,21 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit return ReturnFalse; case T_MESSAGE: { if (args.count() != 1) { - logMessage(format("%1(message) requires one argument.") - .arg(function.toQString(m_tmp1))); + evalError(fL1S("%1(message) requires one argument.") + .arg(function.toQString(m_tmp1))); return ReturnFalse; } const QString &msg = expandEnvVars(args.at(0).toQString(m_tmp2)); - fileMessage(QString::fromLatin1("Project %1: %2") - .arg(function.toQString(m_tmp1).toUpper(), msg)); + if (!m_skipLevel) + m_handler->fileMessage(fL1S("Project %1: %2") + .arg(function.toQString(m_tmp1).toUpper(), msg)); // ### Consider real termination in non-cumulative mode return returnBool(function != QLatin1String("error")); } #if 0 // Way too dangerous to enable. case T_SYSTEM: { if (args.count() != 1) { - logMessage(format("system(exec) requires one argument.")); + evalError(fL1S("system(exec) requires one argument.")); ReturnFalse; } return returnBool(system((QLatin1String("cd ") @@ -3649,7 +3650,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit #endif case T_ISEMPTY: { if (args.count() != 1) { - logMessage(format("isEmpty(var) requires one argument.")); + evalError(fL1S("isEmpty(var) requires one argument.")); return ReturnFalse; } const ProStringList &sl = values(map(args.at(0))); @@ -3664,7 +3665,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit } case T_EXISTS: { if (args.count() != 1) { - logMessage(format("exists(file) requires one argument.")); + evalError(fL1S("exists(file) requires one argument.")); return ReturnFalse; } const QString &file = resolvePath(expandEnvVars(args.at(0).toQString(m_tmp1))); @@ -3683,11 +3684,11 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit return ReturnFalse; } case 0: - logMessage(format("'%1' is not a recognized test function") - .arg(function.toQString(m_tmp1))); + evalError(fL1S("'%1' is not a recognized test function") + .arg(function.toQString(m_tmp1))); return ReturnFalse; default: - logMessage(format("Function '%1' is not implemented").arg(function.toQString(m_tmp1))); + evalError(fL1S("Function '%1' is not implemented").arg(function.toQString(m_tmp1))); return ReturnFalse; } } @@ -3924,7 +3925,7 @@ ProFile *ProFileEvaluator::Private::parsedProFile(const QString &fileName, bool } bool ProFileEvaluator::Private::evaluateFileDirect( - const QString &fileName, ProFileEvaluator::EvalFileType type) + const QString &fileName, ProFileEvaluatorHandler::EvalFileType type) { int lineNo = m_lineNo; if (ProFile *pro = parsedProFile(fileName, true)) { @@ -3939,13 +3940,13 @@ bool ProFileEvaluator::Private::evaluateFileDirect( } bool ProFileEvaluator::Private::evaluateFile( - const QString &fileName, ProFileEvaluator::EvalFileType type) + const QString &fileName, ProFileEvaluatorHandler::EvalFileType type) { if (fileName.isEmpty()) return false; foreach (const ProFile *pf, m_profileStack) if (pf->fileName() == fileName) { - errorMessage(format("circular inclusion of %1").arg(fileName)); + evalError(fL1S("circular inclusion of %1").arg(fileName)); return false; } return evaluateFileDirect(fileName, type); @@ -3991,13 +3992,13 @@ bool ProFileEvaluator::Private::evaluateFeatureFile( } if (values) { - return evaluateFileInto(fn, ProFileEvaluator::EvalFeatureFile, values, funcs); + return evaluateFileInto(fn, ProFileEvaluatorHandler::EvalFeatureFile, values, funcs); } else { bool cumulative = m_cumulative; m_cumulative = false; // The path is fully normalized already. - bool ok = evaluateFileDirect(fn, ProFileEvaluator::EvalFeatureFile); + bool ok = evaluateFileDirect(fn, ProFileEvaluatorHandler::EvalFeatureFile); m_cumulative = cumulative; return ok; @@ -4005,13 +4006,12 @@ bool ProFileEvaluator::Private::evaluateFeatureFile( } bool ProFileEvaluator::Private::evaluateFileInto( - const QString &fileName, ProFileEvaluator::EvalFileType type, + const QString &fileName, ProFileEvaluatorHandler::EvalFileType type, QHash<ProString, ProStringList> *values, FunctionDefs *funcs) { - ProFileEvaluator visitor(m_option); + ProFileEvaluator visitor(m_option, m_handler); visitor.d->m_cumulative = false; visitor.d->m_parsePreAndPostFiles = false; - visitor.d->m_verbose = m_verbose; visitor.d->m_valuemapStack.top() = *values; if (funcs) visitor.d->m_functionDefs = *funcs; @@ -4023,30 +4023,15 @@ bool ProFileEvaluator::Private::evaluateFileInto( return true; } -QString ProFileEvaluator::Private::format(const char *fmt) const -{ - ProFile *pro = currentProFile(); - QString fileName = pro ? pro->fileName() : QLatin1String("Not a file"); - int lineNumber = pro ? m_lineNo : 0; - return QString::fromLatin1("%1(%2):").arg(fileName).arg(lineNumber) + QString::fromAscii(fmt); -} - -void ProFileEvaluator::Private::logMessage(const QString &message) const -{ - if (m_verbose && !m_skipLevel) - q->logMessage(message); -} - -void ProFileEvaluator::Private::fileMessage(const QString &message) const +void ProFileEvaluator::Private::parseError(const QString &message) const { - if (!m_skipLevel) - q->fileMessage(message); + m_handler->parseError(currentFileName(), m_lineNo, message); } -void ProFileEvaluator::Private::errorMessage(const QString &message) const +void ProFileEvaluator::Private::evalError(const QString &message) const { if (!m_skipLevel) - q->errorMessage(message); + m_handler->evalError(currentFileName(), m_lineNo, message); } @@ -4061,8 +4046,9 @@ void ProFileEvaluator::initialize() Private::initStatics(); } -ProFileEvaluator::ProFileEvaluator(ProFileOption *option) - : d(new Private(this, option)) +ProFileEvaluator::ProFileEvaluator(ProFileOption *option, + ProFileEvaluatorHandler *handler) + : d(new Private(this, option, handler)) { } @@ -4185,7 +4171,7 @@ ProFile *ProFileEvaluator::parsedProFile(const QString &fileName, const QString bool ProFileEvaluator::accept(ProFile *pro) { - return d->visitProFile(pro, ProFileEvaluator::EvalProjectFile); + return d->visitProFile(pro, ProFileEvaluatorHandler::EvalProjectFile); } QString ProFileEvaluator::propertyValue(const QString &name) const @@ -4193,34 +4179,6 @@ QString ProFileEvaluator::propertyValue(const QString &name) const return d->propertyValue(name); } -void ProFileEvaluator::aboutToEval(ProFile *, ProFile *, EvalFileType) -{ -} - -void ProFileEvaluator::doneWithEval(ProFile *) -{ -} - -void ProFileEvaluator::logMessage(const QString &message) -{ - qWarning("%s", qPrintable(message)); -} - -void ProFileEvaluator::fileMessage(const QString &message) -{ - qWarning("%s", qPrintable(message)); -} - -void ProFileEvaluator::errorMessage(const QString &message) -{ - qWarning("%s", qPrintable(message)); -} - -void ProFileEvaluator::setVerbose(bool on) -{ - d->m_verbose = on; -} - void ProFileEvaluator::setCumulative(bool on) { d->m_cumulative = on; diff --git a/src/shared/proparser/profileevaluator.h b/src/shared/proparser/profileevaluator.h index 68d11defdfc..1900e7cae5a 100644 --- a/src/shared/proparser/profileevaluator.h +++ b/src/shared/proparser/profileevaluator.h @@ -45,6 +45,24 @@ QT_BEGIN_NAMESPACE struct ProFileOption; +class ProFileEvaluatorHandler +{ +public: + // Some error during parsing + virtual void parseError(const QString &filename, int lineNo, const QString &msg) = 0; + // qmake/project configuration error + virtual void configError(const QString &msg) = 0; + // Some error during evaluation + virtual void evalError(const QString &filename, int lineNo, const QString &msg) = 0; + // error() and message() from .pro file + virtual void fileMessage(const QString &msg) = 0; + + enum EvalFileType { EvalProjectFile, EvalIncludeFile, EvalConfigFile, EvalFeatureFile, EvalAuxFile }; + virtual void aboutToEval(ProFile *parent, ProFile *proFile, EvalFileType type) = 0; + virtual void doneWithEval(ProFile *parent) = 0; +}; + + class ProFileEvaluator { class Private; @@ -71,11 +89,10 @@ public: // Call this from a concurrency-free context static void initialize(); - ProFileEvaluator(ProFileOption *option); - virtual ~ProFileEvaluator(); + ProFileEvaluator(ProFileOption *option, ProFileEvaluatorHandler *handler); + ~ProFileEvaluator(); ProFileEvaluator::TemplateType templateType() const; - void setVerbose(bool on); // Default is false void setCumulative(bool on); // Default is true! void setOutputDir(const QString &dir); // Default is empty @@ -99,14 +116,6 @@ public: const ProFile *pro) const; QString propertyValue(const QString &val) const; - // for our descendents - enum EvalFileType { EvalProjectFile, EvalIncludeFile, EvalConfigFile, EvalFeatureFile, EvalAuxFile }; - virtual void aboutToEval(ProFile *parent, ProFile *proFile, EvalFileType type); - virtual void doneWithEval(ProFile *parent); - virtual void logMessage(const QString &msg); - virtual void errorMessage(const QString &msg); // .pro parse errors - virtual void fileMessage(const QString &msg); // error() and message() from .pro file - private: Private *d; diff --git a/tests/manual/proparser/main.cpp b/tests/manual/proparser/main.cpp index d26b56f241f..f830787aba0 100644 --- a/tests/manual/proparser/main.cpp +++ b/tests/manual/proparser/main.cpp @@ -39,6 +39,31 @@ #include <QtCore/QStringList> #include <QtCore/QTextCodec> +static void print(const QString &fileName, int lineNo, const QString &msg) +{ + if (lineNo) + qWarning("%s(%d): %s", qPrintable(fileName), lineNo, qPrintable(msg)); + else + qWarning("%s", qPrintable(msg)); +} + +class EvalHandler : public ProFileEvaluatorHandler { +public: + virtual void parseError(const QString &fileName, int lineNo, const QString &msg) + { print(fileName, lineNo, msg); } + virtual void configError(const QString &msg) + { qWarning("%s", qPrintable(msg)); } + virtual void evalError(const QString &fileName, int lineNo, const QString &msg) + { print(fileName, lineNo, msg); } + virtual void fileMessage(const QString &msg) + { qWarning("%s", qPrintable(msg)); } + + virtual void aboutToEval(ProFile *, ProFile *, EvalFileType) {} + virtual void doneWithEval(ProFile *) {} +}; + +static EvalHandler evalHandler; + static QString value(ProFileEvaluator &reader, const QString &variable) { QStringList vals = reader.values(variable); @@ -56,8 +81,7 @@ static int evaluate(const QString &fileName, const QString &in_pwd, const QStrin return 0; visited.insert(fileName); - ProFileEvaluator visitor(option); - visitor.setVerbose(true); + ProFileEvaluator visitor(option, &evalHandler); visitor.setCumulative(cumulative); visitor.setOutputDir(out_pwd); -- GitLab