/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file LICENSE.rst or https://cmake.org/licensing for details. */ #include "cmSourceGroup.h" #include #include #include "cmGeneratorExpression.h" #include "cmSourceFile.h" #include "cmStringAlgorithms.h" class cmSourceGroupInternals { public: SourceGroupVector GroupChildren; }; cmSourceGroup::cmSourceGroup(std::string name, char const* regex, char const* parentName) : Name(std::move(name)) { this->Internal = cm::make_unique(); this->SetGroupRegex(regex); if (parentName) { this->FullName = cmStrCat(parentName, '\\'); } this->FullName += this->Name; } cmSourceGroup::~cmSourceGroup() = default; void cmSourceGroup::SetGroupRegex(char const* regex) { if (regex) { this->GroupRegex.compile(regex); } else { this->GroupRegex.compile("^$"); } } void cmSourceGroup::ResolveGenex(cmLocalGenerator* lg, std::string const& config) { std::set files; for (std::string const& file : this->GroupFiles) { files.emplace(cmGeneratorExpression::Evaluate(file, lg, config)); } this->GroupFiles = std::move(files); if (!this->Internal) { return; } for (auto const& group : this->Internal->GroupChildren) { group->ResolveGenex(lg, config); } } void cmSourceGroup::AddGroupFile(std::string const& name) { this->GroupFiles.insert(name); } std::string const& cmSourceGroup::GetName() const { return this->Name; } std::string const& cmSourceGroup::GetFullName() const { return this->FullName; } bool cmSourceGroup::MatchesRegex(std::string const& name) const { cmsys::RegularExpressionMatch match; return this->GroupRegex.find(name.c_str(), match); } bool cmSourceGroup::MatchesFiles(std::string const& name) const { return this->GroupFiles.find(name) != this->GroupFiles.cend(); } void cmSourceGroup::AssignSource(cmSourceFile const* sf) { this->SourceFiles.push_back(sf); } std::set const& cmSourceGroup::GetGroupFiles() const { return this->GroupFiles; } std::vector const& cmSourceGroup::GetSourceFiles() const { return this->SourceFiles; } void cmSourceGroup::AddChild(std::unique_ptr child) { this->Internal->GroupChildren.push_back(std::move(child)); } cmSourceGroup* cmSourceGroup::LookupChild(std::string const& name) const { for (auto& group : this->Internal->GroupChildren) { // look if descendant is the one we're looking for if (group->GetName() == name) { return group.get(); // if so return it } } // if no child with this name was found return NULL return nullptr; } cmSourceGroup* cmSourceGroup::MatchChildrenFiles(std::string const& name) { if (this->MatchesFiles(name)) { return this; } for (auto& group : this->Internal->GroupChildren) { cmSourceGroup* result = group->MatchChildrenFiles(name); if (result) { return result; } } return nullptr; } cmSourceGroup const* cmSourceGroup::MatchChildrenFiles( std::string const& name) const { if (this->MatchesFiles(name)) { return this; } for (auto const& group : this->Internal->GroupChildren) { cmSourceGroup const* result = group->MatchChildrenFiles(name); if (result) { return result; } } return nullptr; } cmSourceGroup* cmSourceGroup::MatchChildrenRegex(std::string const& name) const { for (auto& group : this->Internal->GroupChildren) { cmSourceGroup* result = group->MatchChildrenRegex(name); if (result) { return result; } } if (this->MatchesRegex(name)) { return const_cast(this); } return nullptr; } SourceGroupVector const& cmSourceGroup::GetGroupChildren() const { return this->Internal->GroupChildren; } /** * Find a source group whose regular expression matches the filename * part of the given source name. Search backward through the list of * source groups, and take the first matching group found. This way * non-inherited SOURCE_GROUP commands will have precedence over * inherited ones. */ cmSourceGroup* cmSourceGroup::FindSourceGroup(std::string const& source, SourceGroupVector const& groups) { // First search for a group that lists the file explicitly. for (auto sg = groups.rbegin(); sg != groups.rend(); ++sg) { cmSourceGroup* result = (*sg)->MatchChildrenFiles(source); if (result) { return result; } } // Now search for a group whose regex matches the file. for (auto sg = groups.rbegin(); sg != groups.rend(); ++sg) { cmSourceGroup* result = (*sg)->MatchChildrenRegex(source); if (result) { return result; } } // Shouldn't get here, but just in case, return the default group. return groups.data()->get(); }