more exact qmake command line parsing

support -after and -config.
this also moves the actual parsing to ProFileOption, where it belongs.
This commit is contained in:
Oswald Buddenhagen
2011-03-18 20:03:22 +01:00
parent 16436a252b
commit 08deb39072
4 changed files with 59 additions and 51 deletions

View File

@@ -34,7 +34,6 @@
#include "qmakestep.h" #include "qmakestep.h"
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <proparser/profileevaluator.h>
#include "qmakeparser.h" #include "qmakeparser.h"
#include "qt4buildconfiguration.h" #include "qt4buildconfiguration.h"
#include "qt4project.h" #include "qt4project.h"
@@ -370,20 +369,9 @@ void QMakeStep::setLinkQmlDebuggingLibrary(bool enable)
QStringList QMakeStep::parserArguments() QStringList QMakeStep::parserArguments()
{ {
QStringList result; QStringList result;
for (Utils::QtcProcess::ConstArgIterator ait(allArguments()); ait.next(); ) { for (Utils::QtcProcess::ConstArgIterator ait(allArguments()); ait.next(); )
const QString &arg = ait.value(); if (ait.isSimple())
if (arg.contains(QLatin1Char('='))) { result << ait.value();
result << arg;
} else {
for (int i = 0; i < ProFileOption::modeMapSize; ++i) {
// Workaround: Apple GCC does not like ProFileOption::modeMap[i], because the array's bounds are not known
if (QLatin1String((&ProFileOption::modeMap[0] + i)->qmakeOption) == arg) {
result << arg;
break;
}
}
}
}
return result; return result;
} }

View File

@@ -77,6 +77,8 @@ QT_BEGIN_NAMESPACE
using namespace ProStringConstants; using namespace ProStringConstants;
#define fL1S(s) QString::fromLatin1(s)
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// //
// ProFileOption // ProFileOption
@@ -106,20 +108,45 @@ ProFileOption::~ProFileOption()
void ProFileOption::setCommandLineArguments(const QStringList &args) void ProFileOption::setCommandLineArguments(const QStringList &args)
{ {
cmdargs = args; QStringList _precmds, _preconfigs, _postcmds, _postconfigs;
bool after = false;
setHostTargetMode(); setHostTargetMode();
bool targetModeSet = false;
for (int i = args.count() - 1; !targetModeSet && i >= 0; --i) { bool isConf = false;
for (int j = 0; j < modeMapSize; ++j) { foreach (const QString &arg, args) {
const TargetModeMapElement &mapElem = modeMap[j]; if (isConf) {
if (args.at(i) == QLatin1String(mapElem.qmakeOption)) { isConf = false;
target_mode = mapElem.targetMode; if (after)
targetModeSet = true; _postconfigs << arg;
break; 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")) {
target_mode = TARG_WIN_MODE;
} else if (arg == QLatin1String("-unix")) {
target_mode = TARG_UNIX_MODE;
} else if (arg == QLatin1String("-macx")) {
target_mode = TARG_MACX_MODE;
} }
} else if (arg.contains(QLatin1Char('='))) {
if (after)
_postcmds << arg;
else
_precmds << arg;
} }
} }
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 ProFileOption::setHostTargetMode() void ProFileOption::setHostTargetMode()
@@ -135,22 +162,12 @@ void ProFileOption::setHostTargetMode()
#endif #endif
} }
const struct ProFileOption::TargetModeMapElement ProFileOption::modeMap[] = {
{ "-unix", TARG_UNIX_MODE },
{ "-macx", TARG_MACX_MODE },
{ "-win32", TARG_WIN_MODE }
};
const int ProFileOption::modeMapSize
= sizeof ProFileOption::modeMap / sizeof ProFileOption::modeMap[0];
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// //
// ProFileEvaluator::Private // ProFileEvaluator::Private
// //
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
#define fL1S(s) QString::fromLatin1(s)
class ProFileEvaluator::Private class ProFileEvaluator::Private
{ {
public: public:
@@ -177,6 +194,7 @@ public:
static ALWAYS_INLINE void skipHashStr(const ushort *&tokPtr); static ALWAYS_INLINE void skipHashStr(const ushort *&tokPtr);
void skipExpression(const ushort *&tokPtr); void skipExpression(const ushort *&tokPtr);
void visitCmdLine(const QString &cmds);
VisitReturn visitProFile(ProFile *pro, ProFileEvaluatorHandler::EvalFileType type, VisitReturn visitProFile(ProFile *pro, ProFileEvaluatorHandler::EvalFileType type,
ProFileEvaluator::LoadFlags flags); ProFileEvaluator::LoadFlags flags);
VisitReturn visitProBlock(ProFile *pro, const ushort *tokPtr); VisitReturn visitProBlock(ProFile *pro, const ushort *tokPtr);
@@ -1149,6 +1167,18 @@ void ProFileEvaluator::Private::visitProVariable(
} }
} }
void ProFileEvaluator::Private::visitCmdLine(const QString &cmds)
{
if (!cmds.isEmpty()) {
if (ProFile *pro = m_parser->parsedProBlock(fL1S("(command line)"), cmds)) {
m_locationStack.push(m_current);
visitProBlock(pro, pro->tokPtr());
m_current = m_locationStack.pop();
pro->deref();
}
}
}
ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProFile( ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProFile(
ProFile *pro, ProFileEvaluatorHandler::EvalFileType type, ProFile *pro, ProFileEvaluatorHandler::EvalFileType type,
ProFileEvaluator::LoadFlags flags) ProFileEvaluator::LoadFlags flags)
@@ -1310,20 +1340,14 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProFile(
if (tgt.isEmpty()) if (tgt.isEmpty())
tgt.append(ProString(QFileInfo(pro->fileName()).baseName(), NoHash)); tgt.append(ProString(QFileInfo(pro->fileName()).baseName(), NoHash));
if (!m_option->cmdargs.isEmpty()) { visitCmdLine(m_option->precmds);
if (ProFile *pro = m_parser->parsedProBlock(
fL1S("(command line)"), m_option->cmdargs.join(fL1S("\n")))) {
m_locationStack.push(m_current);
visitProBlock(pro, pro->tokPtr());
m_current = m_locationStack.pop();
pro->deref();
}
}
} }
visitProBlock(pro, pro->tokPtr()); visitProBlock(pro, pro->tokPtr());
if (flags & LoadPostFiles) { if (flags & LoadPostFiles) {
visitCmdLine(m_option->postcmds);
evaluateFeatureFile(QLatin1String("default_post.prf")); evaluateFeatureFile(QLatin1String("default_post.prf"));
QSet<QString> processed; QSet<QString> processed;

View File

@@ -176,12 +176,6 @@ struct ProFileOption
//QString pro_ext; //QString pro_ext;
//QString res_ext; //QString res_ext;
static const struct TargetModeMapElement {
const char * const qmakeOption;
const TARG_MODE targetMode;
} modeMap[];
static const int modeMapSize;
// -nocache, -cache, -spec, QMAKESPEC // -nocache, -cache, -spec, QMAKESPEC
// -set persistent value // -set persistent value
void setCommandLineArguments(const QStringList &args); void setCommandLineArguments(const QStringList &args);
@@ -195,7 +189,7 @@ struct ProFileOption
ProFileEvaluator::FunctionDefs base_functions; ProFileEvaluator::FunctionDefs base_functions;
QStringList feature_roots; QStringList feature_roots;
QString qmakespec_name; QString qmakespec_name;
QStringList cmdargs; QString precmds, postcmds;
#ifdef PROEVALUATOR_THREAD_SAFE #ifdef PROEVALUATOR_THREAD_SAFE
QMutex mutex; QMutex mutex;
QWaitCondition cond; QWaitCondition cond;

View File

@@ -156,9 +156,11 @@ int main(int argc, char **argv)
if (args.count() && args.first() == QLatin1String("-v")) if (args.count() && args.first() == QLatin1String("-v"))
level = 0, args.removeFirst(); level = 0, args.removeFirst();
if (args.count() < 2) if (args.count() < 2)
qFatal("need at least two arguments: [-v] <cumulative?> <filenme> [<out_pwd>]"); qFatal("need at least two arguments: [-v] <cumulative?> <filenme> [<out_pwd> [<qmake options>]]");
ProFileOption option; ProFileOption option;
if (args.count() >= 4)
option.setCommandLineArguments(args.mid(3));
ProFileParser parser(0, &parseHandler); ProFileParser parser(0, &parseHandler);
static const struct { static const struct {