diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index 4e061af1e6b..adbcb112a64 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -967,7 +967,7 @@ QtSupport::ProFileReader *Qt4Project::createProFileReader(Qt4ProFileNode *qt4Pro for (; eit != eend; ++eit) m_qmakeGlobals->environment.insert(env.key(eit), env.value(eit)); - m_qmakeGlobals->setCommandLineArguments(qmakeArgs); + m_qmakeGlobals->setCommandLineArguments(m_rootProjectNode->buildDir(), qmakeArgs); QtSupport::ProFileCacheManager::instance()->incRefCount(); } diff --git a/src/shared/proparser/qmakeglobals.cpp b/src/shared/proparser/qmakeglobals.cpp index ea2dde36890..d78283bd769 100644 --- a/src/shared/proparser/qmakeglobals.cpp +++ b/src/shared/proparser/qmakeglobals.cpp @@ -109,43 +109,67 @@ QMakeGlobals::~QMakeGlobals() qDeleteAll(baseEnvs); } -void QMakeGlobals::setCommandLineArguments(const QStringList &args) +QMakeGlobals::ArgumentReturn QMakeGlobals::addCommandLineArguments( + QMakeCmdLineParserState &state, QStringList &args, int *pos) { - QStringList _precmds, _preconfigs, _postcmds, _postconfigs; - bool after = false; - - bool isConf = false; - foreach (const QString &arg, args) { - if (isConf) { - isConf = false; - if (after) - _postconfigs << arg; + enum { ArgNone, ArgConfig } argState = ArgNone; + for (; *pos < args.count(); (*pos)++) { + QString arg = args.at(*pos); + switch (argState) { + case ArgConfig: + if (state.after) + state.postconfigs << arg; else - _preconfigs << arg; - } else if (arg.startsWith(QLatin1Char('-'))) { - if (arg == QLatin1String("-after")) { - after = true; - } else if (arg == QLatin1String("-config")) { - isConf = true; - } else if (arg == QLatin1String("-win32")) { - dir_sep = QLatin1Char('\\'); - } else if (arg == QLatin1String("-unix")) { - dir_sep = QLatin1Char('/'); + state.preconfigs << arg; + break; + default: + if (arg.startsWith(QLatin1Char('-'))) { + if (arg == QLatin1String("-after")) { + state.after = true; + } else if (arg == QLatin1String("-config")) { + argState = ArgConfig; + } else if (arg == QLatin1String("-win32")) { + dir_sep = QLatin1Char('\\'); + } else if (arg == QLatin1String("-unix")) { + dir_sep = QLatin1Char('/'); + } else { + return ArgumentUnknown; + } + } else if (arg.contains(QLatin1Char('='))) { + if (state.after) + state.postcmds << arg; + else + state.precmds << arg; + } else { + return ArgumentUnknown; } - } else if (arg.contains(QLatin1Char('='))) { - if (after) - _postcmds << arg; - else - _precmds << arg; + continue; } + argState = ArgNone; } + if (argState != ArgNone) + return ArgumentMalformed; + return ArgumentsOk; +} - if (!_preconfigs.isEmpty()) - _precmds << (fL1S("CONFIG += ") + _preconfigs.join(fL1S(" "))); - precmds = _precmds.join(fL1S("\n")); - if (!_postconfigs.isEmpty()) - _postcmds << (fL1S("CONFIG += ") + _postconfigs.join(fL1S(" "))); - postcmds = _postcmds.join(fL1S("\n")); +void QMakeGlobals::commitCommandLineArguments(QMakeCmdLineParserState &state) +{ + if (!state.preconfigs.isEmpty()) + state.precmds << (fL1S("CONFIG += ") + state.preconfigs.join(fL1S(" "))); + precmds = state.precmds.join(fL1S("\n")); + if (!state.postconfigs.isEmpty()) + state.postcmds << (fL1S("CONFIG += ") + state.postconfigs.join(fL1S(" "))); + postcmds = state.postcmds.join(fL1S("\n")); +} + +void QMakeGlobals::setCommandLineArguments(const QString &pwd, const QStringList &_args) +{ + QStringList args = _args; + + QMakeCmdLineParserState state(pwd); + for (int pos = 0; pos < args.size(); pos++) + addCommandLineArguments(state, args, &pos); + commitCommandLineArguments(state); } void QMakeGlobals::setDirectories(const QString &input_dir, const QString &output_dir) diff --git a/src/shared/proparser/qmakeglobals.h b/src/shared/proparser/qmakeglobals.h index 08d07eac31f..dcdec544dae 100644 --- a/src/shared/proparser/qmakeglobals.h +++ b/src/shared/proparser/qmakeglobals.h @@ -77,6 +77,15 @@ public: QMakeEvaluator *evaluator; }; +class QMAKE_EXPORT QMakeCmdLineParserState +{ +public: + QMakeCmdLineParserState(const QString &_pwd) : pwd(_pwd), after(false) {} + QString pwd; + QStringList precmds, preconfigs, postcmds, postconfigs; + bool after; +}; + class QMAKE_EXPORT QMakeGlobals { public: @@ -96,9 +105,11 @@ public: QString qmake_abslocation; QString user_template, user_template_prefix; - // -nocache, -cache, -spec, QMAKESPEC - // -set persistent value - void setCommandLineArguments(const QStringList &args); + enum ArgumentReturn { ArgumentUnknown, ArgumentMalformed, ArgumentsOk }; + ArgumentReturn addCommandLineArguments(QMakeCmdLineParserState &state, + QStringList &args, int *pos); + void commitCommandLineArguments(QMakeCmdLineParserState &state); + void setCommandLineArguments(const QString &pwd, const QStringList &args); void setDirectories(const QString &input_dir, const QString &output_dir); #ifdef PROEVALUATOR_INIT_PROPS bool initProperties(); diff --git a/tests/manual/proparser/main.cpp b/tests/manual/proparser/main.cpp index 94f1f4069fe..f42fbb61241 100644 --- a/tests/manual/proparser/main.cpp +++ b/tests/manual/proparser/main.cpp @@ -141,30 +141,57 @@ int main(int argc, char **argv) { QCoreApplication app(argc, argv); - QStringList args = app.arguments(); - args.removeFirst(); - int level = -1; // verbose - if (args.count() && args.first() == QLatin1String("-v")) - level = 0, args.removeFirst(); - if (args.count() < 2) - qFatal("need at least two arguments: [-v] [ []]"); - QMakeGlobals option; QString qmake = QString::fromLocal8Bit(qgetenv("TESTREADER_QMAKE")); if (qmake.isEmpty()) qmake = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/qmake"); option.qmake_abslocation = QDir::cleanPath(qmake); option.initProperties(); - if (args.count() >= 4) - option.setCommandLineArguments(args.mid(3)); - QMakeParser parser(0, &evalHandler); - bool cumulative = args[0] == QLatin1String("true"); - QFileInfo infi(args[1]); - QString file = infi.absoluteFilePath(); - QString in_pwd = infi.absolutePath(); - QString out_pwd = (args.count() > 2) ? QFileInfo(args[2]).absoluteFilePath() : in_pwd; + QStringList args = app.arguments(); + args.removeFirst(); + int level = -1; // verbose + bool cumulative = false; + QString file; + QString in_pwd; + QString out_pwd; + QMakeCmdLineParserState state(QDir::currentPath()); + for (int pos = 0; ; ) { + QMakeGlobals::ArgumentReturn cmdRet = option.addCommandLineArguments(state, args, &pos); + if (cmdRet == QMakeGlobals::ArgumentsOk) + break; + if (cmdRet == QMakeGlobals::ArgumentMalformed) { + qCritical("argument %s needs a parameter", qPrintable(args.at(pos - 1))); + return 3; + } + Q_ASSERT(cmdRet == QMakeGlobals::ArgumentUnknown); + QString arg = args.at(pos++); + if (arg == QLatin1String("-v")) { + level = 0; + } else if (arg == QLatin1String("-c")) { + cumulative = true; + } else if (arg.startsWith(QLatin1Char('-'))) { + qCritical("unrecognized option %s", qPrintable(arg)); + return 3; + } else if (file.isEmpty()) { + QFileInfo infi(arg); + file = QDir::cleanPath(infi.absoluteFilePath()); + in_pwd = QDir::cleanPath(infi.absolutePath()); + } else if (out_pwd.isEmpty()) { + out_pwd = QDir::cleanPath(QFileInfo(arg).absoluteFilePath()); + } else { + qCritical("excess argument '%s'", qPrintable(arg)); + return 3; + } + } + if (file.isEmpty()) { + qCritical("usage: testreader [-v] [-c] [] []"); + return 3; + } + if (out_pwd.isEmpty()) + out_pwd = in_pwd; option.setDirectories(in_pwd, out_pwd); + QMakeParser parser(0, &evalHandler); return evaluate(file, in_pwd, out_pwd, cumulative, &option, &parser, level); }