diff options
author | Brad King <brad.king@kitware.com> | 2017-01-16 16:01:38 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2017-01-16 16:01:38 (GMT) |
commit | 35ad12f99e71515f9cc65b1219160b88095a5f6b (patch) | |
tree | 82dfe9cf9f3201f70395f1136feb999dc1d5144c /Source | |
parent | 47d391d71d611c5129c6914ad77b34dc4bb79d75 (diff) | |
parent | b42330be21c0d3046aa0e6fdf046a492bddef520 (diff) | |
download | CMake-35ad12f99e71515f9cc65b1219160b88095a5f6b.zip CMake-35ad12f99e71515f9cc65b1219160b88095a5f6b.tar.gz CMake-35ad12f99e71515f9cc65b1219160b88095a5f6b.tar.bz2 |
Merge topic 'source_group-tree'
b42330be source_group: Add options create groups matching directory tree
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmSourceGroupCommand.cxx | 165 | ||||
-rw-r--r-- | Source/cmSourceGroupCommand.h | 6 |
2 files changed, 171 insertions, 0 deletions
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx index 3f20d4e..5555199 100644 --- a/Source/cmSourceGroupCommand.cxx +++ b/Source/cmSourceGroupCommand.cxx @@ -8,6 +8,99 @@ #include "cmSourceGroup.h" #include "cmSystemTools.h" +namespace { +const size_t RootIndex = 1; +const size_t FilesWithoutPrefixKeywordIndex = 2; +const size_t FilesWithPrefixKeywordIndex = 4; +const size_t PrefixKeywordIdex = 2; + +std::vector<std::string> tokenizePath(const std::string& path) +{ + return cmSystemTools::tokenize(path, "\\/"); +} + +std::string getFullFilePath(const std::string& currentPath, + const std::string& path) +{ + std::string fullPath = path; + + if (!cmSystemTools::FileIsFullPath(path.c_str())) { + fullPath = currentPath; + fullPath += "/"; + fullPath += path; + } + + return cmSystemTools::CollapseFullPath(fullPath); +} + +std::set<std::string> getSourceGroupFilesPaths( + const std::string& currentPath, const std::string& root, + const std::vector<std::string>& files) +{ + std::set<std::string> ret; + const std::string::size_type rootLength = root.length(); + + for (size_t i = 0; i < files.size(); ++i) { + const std::string fullPath = getFullFilePath(currentPath, files[i]); + + ret.insert(fullPath.substr(rootLength + 1)); // +1 to also omnit last '/' + } + + return ret; +} + +cmSourceGroup* addSourceGroup(const std::vector<std::string>& tokenizedPath, + cmMakefile& makefile) +{ + cmSourceGroup* sg; + + sg = makefile.GetSourceGroup(tokenizedPath); + if (!sg) { + makefile.AddSourceGroup(tokenizedPath); + sg = makefile.GetSourceGroup(tokenizedPath); + if (!sg) { + return CM_NULLPTR; + } + } + + return sg; +} + +bool addFilesToItsSourceGroups(const std::set<std::string>& sgFilesPaths, + const std::string& prefix, cmMakefile& makefile, + std::string& errorMsg) +{ + cmSourceGroup* sg; + + for (std::set<std::string>::const_iterator it = sgFilesPaths.begin(); + it != sgFilesPaths.end(); ++it) { + + std::vector<std::string> tokenizedPath; + if (!prefix.empty()) { + tokenizedPath = tokenizePath(prefix + '/' + *it); + } else { + tokenizedPath = tokenizePath(*it); + } + + if (tokenizedPath.size() > 1) { + tokenizedPath.pop_back(); + + sg = addSourceGroup(tokenizedPath, makefile); + + if (!sg) { + errorMsg = "Could not create source group for file: " + *it; + return false; + } + const std::string fullPath = + getFullFilePath(makefile.GetCurrentSourceDirectory(), *it); + sg->AddGroupFile(fullPath); + } + } + + return true; +} +} + class cmExecutionStatus; // cmSourceGroupCommand @@ -19,6 +112,17 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args, return false; } + if (args[0] == "TREE") { + std::string error; + + if (!processTree(args, error)) { + this->SetError(error); + return false; + } + + return true; + } + std::string delimiter = "\\"; if (this->Makefile->GetDefinition("SOURCE_GROUP_DELIMITER")) { delimiter = this->Makefile->GetDefinition("SOURCE_GROUP_DELIMITER"); @@ -82,3 +186,64 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args, return true; } + +bool cmSourceGroupCommand::checkTreeArgumentsPreconditions( + const std::vector<std::string>& args, std::string& errorMsg) const +{ + if (args.size() == 1) { + errorMsg = "TREE argument given without a root."; + return false; + } + + if (args.size() < 3) { + errorMsg = "Missing FILES arguments."; + return false; + } + + if (args[FilesWithoutPrefixKeywordIndex] != "FILES" && + args[PrefixKeywordIdex] != "PREFIX") { + errorMsg = "Unknown argument \"" + args[2] + + "\". Perhaps the FILES keyword is missing.\n"; + return false; + } + + if (args[PrefixKeywordIdex] == "PREFIX" && + (args.size() < 5 || args[FilesWithPrefixKeywordIndex] != "FILES")) { + errorMsg = "Missing FILES arguments."; + return false; + } + + return true; +} + +bool cmSourceGroupCommand::processTree(const std::vector<std::string>& args, + std::string& errorMsg) +{ + if (!checkTreeArgumentsPreconditions(args, errorMsg)) { + return false; + } + + const std::string root = cmSystemTools::CollapseFullPath(args[RootIndex]); + std::string prefix; + size_t filesBegin = FilesWithoutPrefixKeywordIndex + 1; + if (args[PrefixKeywordIdex] == "PREFIX") { + prefix = args[PrefixKeywordIdex + 1]; + filesBegin = FilesWithPrefixKeywordIndex + 1; + } + + const std::vector<std::string> filesVector(args.begin() + filesBegin, + args.end()); + + std::set<std::string> sourceGroupPaths = getSourceGroupFilesPaths( + this->Makefile->GetCurrentSourceDirectory(), root, filesVector); + + addFilesToItsSourceGroups(sourceGroupPaths, prefix, *(this->Makefile), + errorMsg); + + if (!errorMsg.empty()) { + this->SetError(errorMsg); + return false; + } + + return true; +} diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h index f533be1..5549096 100644 --- a/Source/cmSourceGroupCommand.h +++ b/Source/cmSourceGroupCommand.h @@ -36,6 +36,12 @@ public: * The name of the command as specified in CMakeList.txt. */ std::string GetName() const CM_OVERRIDE { return "source_group"; } + +private: + bool processTree(const std::vector<std::string>& args, + std::string& errorMsg); + bool checkTreeArgumentsPreconditions(const std::vector<std::string>& args, + std::string& errorMsg) const; }; #endif |