From adee8336bbc1365149dbcd33b0e05a2096c4dfa8 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 25 Aug 2013 22:42:37 +0300 Subject: C++: Custom directory list for Switch Header/Source Some projects use separate directories for sources and headers. An example tree: * |-- src |-- foo.cpp |-- include |-- foo.h Allow the user to specify directories for finding out-of-project related header/source files, in addition to current directory Task-number: QTCREATORBUG-8883 Change-Id: I57215c8f2feffcc246d0d161798290861bcfcdd4 Reviewed-by: Nikolai Kosjar --- src/plugins/cpptools/cpptoolsplugin.cpp | 57 +++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 9 deletions(-) (limited to 'src/plugins/cpptools/cpptoolsplugin.cpp') diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp index 066bc93e07..2d027ad091 100644 --- a/src/plugins/cpptools/cpptoolsplugin.cpp +++ b/src/plugins/cpptools/cpptoolsplugin.cpp @@ -52,6 +52,9 @@ #include #include +#ifdef Q_OS_WIN +#include +#endif #include #include @@ -88,6 +91,21 @@ CppToolsPlugin *CppToolsPlugin::instance() return m_instance; } +void CppToolsPlugin::clearHeaderSourceCache() +{ + m_headerSourceMapping.clear(); +} + +const QStringList &CppToolsPlugin::headerSearchPaths() +{ + return m_instance->m_fileSettings->headerSearchPaths; +} + +const QStringList &CppToolsPlugin::sourceSearchPaths() +{ + return m_instance->m_fileSettings->sourceSearchPaths; +} + bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error) { Q_UNUSED(arguments) @@ -231,6 +249,14 @@ static QStringList baseNameWithAllSuffixes(const QString &baseName, const QStrin return result; } +static QStringList baseDirWithAllDirectories(const QDir &baseDir, const QStringList &directories) +{ + QStringList result; + foreach (const QString &dir, directories) + result << QDir::cleanPath(baseDir.absoluteFilePath(dir)); + return result; +} + static int commonStringLength(const QString &s1, const QString &s2) { int length = qMin(s1.length(), s2.length()); @@ -307,15 +333,28 @@ QString correspondingHeaderOrSource(const QString &fileName, bool *wasHeader) } const QDir absoluteDir = fi.absoluteDir(); - - // Try to find a file in the same directory first - foreach (const QString &candidateFileName, candidateFileNames) { - const QFileInfo candidateFi(absoluteDir, candidateFileName); - if (candidateFi.isFile()) { - m_headerSourceMapping[fi.absoluteFilePath()] = candidateFi.absoluteFilePath(); - if (!isHeader || !baseName.endsWith(privateHeaderSuffix)) - m_headerSourceMapping[candidateFi.absoluteFilePath()] = fi.absoluteFilePath(); - return candidateFi.absoluteFilePath(); + QStringList candidateDirs(absoluteDir.absolutePath()); + // If directory is not root, try matching against its siblings + const QStringList searchPaths = isHeader ? m_instance->sourceSearchPaths() + : m_instance->headerSearchPaths(); + candidateDirs += baseDirWithAllDirectories(absoluteDir, searchPaths); + + // Try to find a file in the same or sibling directories first + foreach (const QString &candidateDir, candidateDirs) { + foreach (const QString &candidateFileName, candidateFileNames) { + const QString candidateFilePath = candidateDir + QLatin1Char('/') + candidateFileName; +#ifdef Q_OS_WIN + const QString normalized = Utils::normalizePathName(candidateFilePath); +#else + const QString normalized = candidateFilePath; +#endif + const QFileInfo candidateFi(normalized); + if (candidateFi.isFile()) { + m_headerSourceMapping[fi.absoluteFilePath()] = candidateFi.absoluteFilePath(); + if (!isHeader || !baseName.endsWith(privateHeaderSuffix)) + m_headerSourceMapping[candidateFi.absoluteFilePath()] = fi.absoluteFilePath(); + return candidateFi.absoluteFilePath(); + } } } -- cgit v1.2.1