diff options
author | Sebastian Holtermann <sebholt@xwmw.org> | 2017-02-15 18:19:37 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2017-02-21 15:12:51 (GMT) |
commit | 815a05cf12499b42acea70b5a9534e10e1701417 (patch) | |
tree | 62f6e647e22600e510582427287438bf2dd00a3b /Source/cmQtAutoGenerators.cxx | |
parent | 3270091210c0cfdddb133209b232a1d0a1fa48da (diff) | |
download | CMake-815a05cf12499b42acea70b5a9534e10e1701417.zip CMake-815a05cf12499b42acea70b5a9534e10e1701417.tar.gz CMake-815a05cf12499b42acea70b5a9534e10e1701417.tar.bz2 |
Autogen: Overhaul FindMatchingHeader function
Diffstat (limited to 'Source/cmQtAutoGenerators.cxx')
-rw-r--r-- | Source/cmQtAutoGenerators.cxx | 147 |
1 files changed, 76 insertions, 71 deletions
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 580265b..97d1299 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -74,42 +74,6 @@ static void SettingWrite(std::ostream& ostr, const char* key, } } -static std::string FindMatchingHeader( - const std::string& absPath, const std::string& mocSubDir, - const std::string& basename, - const std::vector<std::string>& headerExtensions) -{ - std::string header; - for (std::vector<std::string>::const_iterator ext = headerExtensions.begin(); - ext != headerExtensions.end(); ++ext) { - std::string sourceFilePath = absPath + basename + "." + (*ext); - if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) { - header = sourceFilePath; - break; - } - // Try subdirectory instead - if (!mocSubDir.empty()) { - sourceFilePath = mocSubDir + basename + "." + (*ext); - if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) { - header = sourceFilePath; - break; - } - } - } - - return header; -} - -static std::string ExtractSubDir(const std::string& absPath, - const std::string& currentMoc) -{ - std::string subDir; - if (currentMoc.find_first_of('/') != std::string::npos) { - subDir = absPath + cmsys::SystemTools::GetFilenamePath(currentMoc) + '/'; - } - return subDir; -} - static bool FileNameIsUnique(const std::string& filePath, const std::map<std::string, std::string>& fileMap) { @@ -807,38 +771,38 @@ bool cmQtAutoGenerators::ParseContentForMoc( if (strstr(contentChars, "moc") != CM_NULLPTR) { // Iterate over all included moc files while (this->RegExpMocInclude.find(contentChars)) { - const std::string currentMoc = this->RegExpMocInclude.match(1); - // Basename of the current moc include - std::string basename = - cmsys::SystemTools::GetFilenameWithoutLastExtension(currentMoc); + const std::string incString = this->RegExpMocInclude.match(1); + // Basename of the moc include + const std::string incBasename = + cmsys::SystemTools::GetFilenameWithoutLastExtension(incString); + std::string incSubDir; + if (incString.find_first_of('/') != std::string::npos) { + incSubDir = cmsys::SystemTools::GetFilenamePath(incString) + '/'; + } // If the moc include is of the moc_foo.cpp style we expect // the Q_OBJECT class declaration in a header file. // If the moc include is of the foo.moc style we need to look for // a Q_OBJECT macro in the current source file, if it contains the // macro we generate the moc file from the source file. - if (cmHasLiteralPrefix(basename, "moc_")) { + if (cmHasLiteralPrefix(incBasename, "moc_")) { // Include: moc_FOO.cxx - // basename should be the part of the moc filename used for - // finding the correct header, so we need to remove the moc_ part - basename = basename.substr(4); - const std::string mocSubDir = - ExtractSubDir(scannedFileAbsPath, currentMoc); + // Remove the moc_ part + const std::string incRealBasename = incBasename.substr(4); const std::string headerToMoc = FindMatchingHeader( - scannedFileAbsPath, mocSubDir, basename, headerExtensions); - + scannedFileAbsPath, incRealBasename, incSubDir, headerExtensions); if (!headerToMoc.empty()) { - mocsIncluded[headerToMoc] = currentMoc; - if (relaxed && (basename == scannedFileBasename)) { + mocsIncluded[headerToMoc] = incString; + if (relaxed && (incRealBasename == scannedFileBasename)) { ownMocUnderscoreIncluded = true; - ownMocUnderscoreFile = currentMoc; + ownMocUnderscoreFile = incString; ownMocHeaderFile = headerToMoc; } } else { std::ostringstream err; err << "AutoMoc: Error: " << absFilename << "\n" - << "The file includes the moc file \"" << currentMoc - << "\", but could not find header \"" << basename << '{' + << "The file includes the moc file \"" << incString + << "\", but could not find header \"" << incRealBasename << '{' << JoinExts(headerExtensions) << "}\"\n"; this->LogError(err.str()); return false; @@ -848,31 +812,31 @@ bool cmQtAutoGenerators::ParseContentForMoc( std::string fileToMoc; if (relaxed) { // Mode: Relaxed - if (!requiresMoc || basename != scannedFileBasename) { - const std::string mocSubDir = - ExtractSubDir(scannedFileAbsPath, currentMoc); + if (!requiresMoc || (incBasename != scannedFileBasename)) { const std::string headerToMoc = FindMatchingHeader( - scannedFileAbsPath, mocSubDir, basename, headerExtensions); + scannedFileAbsPath, incBasename, incSubDir, headerExtensions); if (!headerToMoc.empty()) { // This is for KDE4 compatibility: fileToMoc = headerToMoc; - if (!requiresMoc && basename == scannedFileBasename) { + if (!requiresMoc && (incBasename == scannedFileBasename)) { std::ostringstream err; err << "AutoMoc: Warning: " << absFilename << "\n" - << "The file includes the moc file \"" << currentMoc + << "The file includes the moc file \"" << incString << "\", but does not contain a " << macroName << " macro. Running moc on " - << "\"" << headerToMoc << "\" ! Include \"moc_" << basename + << "\"" << headerToMoc << "\" ! Include \"moc_" + << incBasename << ".cpp\" for a compatibility with " "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n"; this->LogWarning(err.str()); } else { std::ostringstream err; err << "AutoMoc: Warning: " << absFilename << "\n" - << "The file includes the moc file \"" << currentMoc - << "\" instead of \"moc_" << basename + << "The file includes the moc file \"" << incString + << "\" instead of \"moc_" << incBasename << ".cpp\". Running moc on " - << "\"" << headerToMoc << "\" ! Include \"moc_" << basename + << "\"" << headerToMoc << "\" ! Include \"moc_" + << incBasename << ".cpp\" for compatibility with " "strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n"; this->LogWarning(err.str()); @@ -880,7 +844,7 @@ bool cmQtAutoGenerators::ParseContentForMoc( } else { std::ostringstream err; err << "AutoMoc: Error: " << absFilename << "\n" - << "The file includes the moc file \"" << currentMoc + << "The file includes the moc file \"" << incString << "\", which seems to be the moc file from a different " "source file. CMake also could not find a matching " "header.\n"; @@ -894,7 +858,7 @@ bool cmQtAutoGenerators::ParseContentForMoc( } } else { // Mode: Strict - if (basename == scannedFileBasename) { + if (incBasename == scannedFileBasename) { // Include self fileToMoc = absFilename; ownDotMocIncluded = true; @@ -902,7 +866,7 @@ bool cmQtAutoGenerators::ParseContentForMoc( // Don't allow FOO.moc include other than self in strict mode std::ostringstream err; err << "AutoMoc: Error: " << absFilename << "\n" - << "The file includes the moc file \"" << currentMoc + << "The file includes the moc file \"" << incString << "\", which seems to be the moc file from a different " "source file. This is not supported. Include \"" << scannedFileBasename @@ -912,7 +876,7 @@ bool cmQtAutoGenerators::ParseContentForMoc( } } if (!fileToMoc.empty()) { - mocsIncluded[fileToMoc] = currentMoc; + mocsIncluded[fileToMoc] = incString; } } // Forward content pointer @@ -920,11 +884,11 @@ bool cmQtAutoGenerators::ParseContentForMoc( } } - // In this case, check whether the scanned file itself contains a Q_OBJECT. - // If this is the case, the moc_foo.cpp should probably be generated from - // foo.cpp instead of foo.h, because otherwise it won't build. - // But warn, since this is not how it is supposed to be used. if (requiresMoc && !ownDotMocIncluded) { + // In this case, check whether the scanned file itself contains a Q_OBJECT. + // If this is the case, the moc_foo.cpp should probably be generated from + // foo.cpp instead of foo.h, because otherwise it won't build. + // But warn, since this is not how it is supposed to be used. if (relaxed && ownMocUnderscoreIncluded) { // This is for KDE4 compatibility: std::ostringstream err; @@ -1620,6 +1584,47 @@ std::string cmQtAutoGenerators::ChecksumedPath(const std::string& sourceFile, } /** + * @brief Tries to find the header file to the given file base path by + * appending different header extensions + * @return True on success + */ +bool cmQtAutoGenerators::FindHeader( + std::string& header, const std::string& testBasePath, + const std::vector<std::string>& headerExtensions) const +{ + for (std::vector<std::string>::const_iterator ext = headerExtensions.begin(); + ext != headerExtensions.end(); ++ext) { + std::string testFilePath(testBasePath); + testFilePath += '.'; + testFilePath += (*ext); + if (cmsys::SystemTools::FileExists(testFilePath.c_str())) { + header = testFilePath; + return true; + } + } + return false; +} + +std::string cmQtAutoGenerators::FindMatchingHeader( + const std::string& basePath, const std::string& baseName, + const std::string& subDir, + const std::vector<std::string>& headerExtensions) const +{ + std::string header; + do { + if (!subDir.empty()) { + if (FindHeader(header, basePath + subDir + baseName, headerExtensions)) { + break; + } + } + if (FindHeader(header, basePath + baseName, headerExtensions)) { + break; + } + } while (false); + return header; +} + +/** * @brief Generates the parent directory of the given file on demand * @return True on success */ |