revamp command line argument parsing

the command line parser can be now integrated with a parser which
understands more options.

Change-Id: Ib9de352376b2f03dd466d577435f680702d1e2b9
Reviewed-by: Daniel Teske <daniel.teske@nokia.com>
This commit is contained in:
Oswald Buddenhagen
2012-08-15 18:11:54 +02:00
parent 6f254b37a6
commit 07a7cad50b
4 changed files with 113 additions and 51 deletions

View File

@@ -967,7 +967,7 @@ QtSupport::ProFileReader *Qt4Project::createProFileReader(Qt4ProFileNode *qt4Pro
for (; eit != eend; ++eit) for (; eit != eend; ++eit)
m_qmakeGlobals->environment.insert(env.key(eit), env.value(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(); QtSupport::ProFileCacheManager::instance()->incRefCount();
} }

View File

@@ -109,43 +109,67 @@ QMakeGlobals::~QMakeGlobals()
qDeleteAll(baseEnvs); qDeleteAll(baseEnvs);
} }
void QMakeGlobals::setCommandLineArguments(const QStringList &args) QMakeGlobals::ArgumentReturn QMakeGlobals::addCommandLineArguments(
QMakeCmdLineParserState &state, QStringList &args, int *pos)
{ {
QStringList _precmds, _preconfigs, _postcmds, _postconfigs; enum { ArgNone, ArgConfig } argState = ArgNone;
bool after = false; for (; *pos < args.count(); (*pos)++) {
QString arg = args.at(*pos);
bool isConf = false; switch (argState) {
foreach (const QString &arg, args) { case ArgConfig:
if (isConf) { if (state.after)
isConf = false; state.postconfigs << arg;
if (after)
_postconfigs << arg;
else else
_preconfigs << arg; state.preconfigs << arg;
} else if (arg.startsWith(QLatin1Char('-'))) { break;
if (arg == QLatin1String("-after")) { default:
after = true; if (arg.startsWith(QLatin1Char('-'))) {
} else if (arg == QLatin1String("-config")) { if (arg == QLatin1String("-after")) {
isConf = true; state.after = true;
} else if (arg == QLatin1String("-win32")) { } else if (arg == QLatin1String("-config")) {
dir_sep = QLatin1Char('\\'); argState = ArgConfig;
} else if (arg == QLatin1String("-unix")) { } else if (arg == QLatin1String("-win32")) {
dir_sep = QLatin1Char('/'); 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('='))) { continue;
if (after)
_postcmds << arg;
else
_precmds << arg;
} }
argState = ArgNone;
} }
if (argState != ArgNone)
return ArgumentMalformed;
return ArgumentsOk;
}
if (!_preconfigs.isEmpty()) void QMakeGlobals::commitCommandLineArguments(QMakeCmdLineParserState &state)
_precmds << (fL1S("CONFIG += ") + _preconfigs.join(fL1S(" "))); {
precmds = _precmds.join(fL1S("\n")); if (!state.preconfigs.isEmpty())
if (!_postconfigs.isEmpty()) state.precmds << (fL1S("CONFIG += ") + state.preconfigs.join(fL1S(" ")));
_postcmds << (fL1S("CONFIG += ") + _postconfigs.join(fL1S(" "))); precmds = state.precmds.join(fL1S("\n"));
postcmds = _postcmds.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) void QMakeGlobals::setDirectories(const QString &input_dir, const QString &output_dir)

View File

@@ -77,6 +77,15 @@ public:
QMakeEvaluator *evaluator; 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 class QMAKE_EXPORT QMakeGlobals
{ {
public: public:
@@ -96,9 +105,11 @@ public:
QString qmake_abslocation; QString qmake_abslocation;
QString user_template, user_template_prefix; QString user_template, user_template_prefix;
// -nocache, -cache, -spec, QMAKESPEC enum ArgumentReturn { ArgumentUnknown, ArgumentMalformed, ArgumentsOk };
// -set persistent value ArgumentReturn addCommandLineArguments(QMakeCmdLineParserState &state,
void setCommandLineArguments(const QStringList &args); 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); void setDirectories(const QString &input_dir, const QString &output_dir);
#ifdef PROEVALUATOR_INIT_PROPS #ifdef PROEVALUATOR_INIT_PROPS
bool initProperties(); bool initProperties();

View File

@@ -141,30 +141,57 @@ int main(int argc, char **argv)
{ {
QCoreApplication app(argc, 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] <cumulative?> <filenme> [<out_pwd> [<qmake options>]]");
QMakeGlobals option; QMakeGlobals option;
QString qmake = QString::fromLocal8Bit(qgetenv("TESTREADER_QMAKE")); QString qmake = QString::fromLocal8Bit(qgetenv("TESTREADER_QMAKE"));
if (qmake.isEmpty()) if (qmake.isEmpty())
qmake = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/qmake"); qmake = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/qmake");
option.qmake_abslocation = QDir::cleanPath(qmake); option.qmake_abslocation = QDir::cleanPath(qmake);
option.initProperties(); option.initProperties();
if (args.count() >= 4)
option.setCommandLineArguments(args.mid(3));
QMakeParser parser(0, &evalHandler);
bool cumulative = args[0] == QLatin1String("true"); QStringList args = app.arguments();
QFileInfo infi(args[1]); args.removeFirst();
QString file = infi.absoluteFilePath(); int level = -1; // verbose
QString in_pwd = infi.absolutePath(); bool cumulative = false;
QString out_pwd = (args.count() > 2) ? QFileInfo(args[2]).absoluteFilePath() : in_pwd; 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] <filenme> [<out_pwd>] [<variable assignments>]");
return 3;
}
if (out_pwd.isEmpty())
out_pwd = in_pwd;
option.setDirectories(in_pwd, out_pwd); option.setDirectories(in_pwd, out_pwd);
QMakeParser parser(0, &evalHandler);
return evaluate(file, in_pwd, out_pwd, cumulative, &option, &parser, level); return evaluate(file, in_pwd, out_pwd, cumulative, &option, &parser, level);
} }