diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index f8b1ebf6b05a5d7819c22661cac82b5e68a7e02a..a6a5dd3eb12e41ca822a5b61f0e295861945328b 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -945,6 +945,7 @@ QtSupport::ProFileReader *Qt4Project::createProFileReader(Qt4ProFileNode *qt4Pro m_qmakeGlobals->qmake_abslocation = QDir::cleanPath(qtVersion->qmakeCommand().toString()); m_qmakeGlobals->setProperties(qtVersion->versionInfo()); } + m_qmakeGlobals->setDirectories(m_rootProjectNode->sourceDir(), m_rootProjectNode->buildDir()); m_qmakeGlobals->sysroot = systemRoot; Utils::Environment::const_iterator eit = env.constBegin(), eend = env.constEnd(); diff --git a/src/shared/proparser/qmakebuiltins.cpp b/src/shared/proparser/qmakebuiltins.cpp index bf6023b9ff93a4dbc85e61107849211213eabd0a..630d1fb0805fceff42975280cd7325a49258bb9e 100644 --- a/src/shared/proparser/qmakebuiltins.cpp +++ b/src/shared/proparser/qmakebuiltins.cpp @@ -76,7 +76,8 @@ enum ExpandFunc { E_SPRINTF, E_FORMAT_NUMBER, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION, E_FIND, E_SYSTEM, E_UNIQUE, E_REVERSE, E_QUOTE, E_ESCAPE_EXPAND, E_UPPER, E_LOWER, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE, - E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS + E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS, + E_SHADOWED }; enum TestFunc { @@ -123,6 +124,7 @@ void QMakeEvaluator::initFunctionStatics() { "sort_depends", E_SORT_DEPENDS }, { "resolve_depends", E_RESOLVE_DEPENDS }, { "enumerate_vars", E_ENUMERATE_VARS }, + { "shadowed", E_SHADOWED }, }; for (unsigned i = 0; i < sizeof(expandInits)/sizeof(expandInits[0]); ++i) statics.expands.insert(ProString(expandInits[i].name), expandInits[i].func); @@ -819,6 +821,21 @@ ProStringList QMakeEvaluator::evaluateExpandFunction( foreach (const ProString &key, keys) ret << key; break; } + case E_SHADOWED: + if (args.count() != 1) { + evalError(fL1S("shadowed(path) requires one argument.")); + } else { + QString val = resolvePath(args.at(0).toQString(m_tmp1)); + if (m_option->source_root.isEmpty()) { + ret += ProString(val, NoHash); + } else if (val.startsWith(m_option->source_root) + && (val.length() == m_option->source_root.length() + || val.at(m_option->source_root.length()) == QLatin1Char('/'))) { + ret += ProString(m_option->build_root + val.mid(m_option->source_root.length()), + NoHash).setSource(args.at(0)); + } + } + break; case E_INVALID: evalError(fL1S("'%1' is not a recognized replace function.") .arg(func.toQString(m_tmp1))); diff --git a/src/shared/proparser/qmakeglobals.cpp b/src/shared/proparser/qmakeglobals.cpp index b06e34f457add56dcc7f60e0714c8a8ff04d9446..0c112870cde38e3cb112f1e7d878cef659f1dffc 100644 --- a/src/shared/proparser/qmakeglobals.cpp +++ b/src/shared/proparser/qmakeglobals.cpp @@ -148,6 +148,26 @@ void QMakeGlobals::setCommandLineArguments(const QStringList &args) postcmds = _postcmds.join(fL1S("\n")); } +void QMakeGlobals::setDirectories(const QString &input_dir, const QString &output_dir) +{ + if (input_dir != output_dir && !output_dir.isEmpty()) { + QString srcpath = input_dir; + if (!srcpath.endsWith(QLatin1Char('/'))) + srcpath += QLatin1Char('/'); + QString dstpath = output_dir; + if (!dstpath.endsWith(QLatin1Char('/'))) + dstpath += QLatin1Char('/'); + int srcLen = srcpath.length(); + int dstLen = dstpath.length(); + int lastSl = -1; + while (++lastSl, srcpath.at(--srcLen) == dstpath.at(--dstLen)) + if (srcpath.at(srcLen) == QLatin1Char('/')) + lastSl = 0; + source_root = srcpath.left(srcLen + lastSl); + build_root = dstpath.left(dstLen + lastSl); + } +} + QString QMakeGlobals::getEnv(const QString &var) const { #ifndef QT_BOOTSTRAPPED diff --git a/src/shared/proparser/qmakeglobals.h b/src/shared/proparser/qmakeglobals.h index 8ca220aac4e4c3f5d32d48982ca1d2581ab7b608..38044f21a6a165493acff86a08d4ea1865b59adf 100644 --- a/src/shared/proparser/qmakeglobals.h +++ b/src/shared/proparser/qmakeglobals.h @@ -99,6 +99,7 @@ public: // -nocache, -cache, -spec, QMAKESPEC // -set persistent value void setCommandLineArguments(const QStringList &args); + void setDirectories(const QString &input_dir, const QString &output_dir); #ifdef PROEVALUATOR_INIT_PROPS bool initProperties(); #else @@ -112,6 +113,8 @@ private: QString getEnv(const QString &) const; QStringList getPathListEnv(const QString &var) const; + QString source_root, build_root; + QString precmds, postcmds; QHash<ProString, ProString> properties; diff --git a/tests/manual/proparser/main.cpp b/tests/manual/proparser/main.cpp index b686672104cda424a805a1b56c032e3989cea7c6..110e1f0f98aa7673a7e5f2e0c4b4f0f0c6cd678d 100644 --- a/tests/manual/proparser/main.cpp +++ b/tests/manual/proparser/main.cpp @@ -168,6 +168,7 @@ int main(int argc, char **argv) QString file = infi.absoluteFilePath(); QString in_pwd = infi.absolutePath(); QString out_pwd = (args.count() > 2) ? QFileInfo(args[2]).absoluteFilePath() : in_pwd; + option.setDirectories(in_pwd, out_pwd); return evaluate(file, in_pwd, out_pwd, cumulative, &option, &parser, level); }