Coverage Report

Created: 2026-07-14 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmSourceGroup.cxx
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#include "cmSourceGroup.h"
4
5
#include <utility>
6
7
#include <cm/memory>
8
9
#include "cmGeneratorExpression.h"
10
#include "cmList.h"
11
#include "cmStringAlgorithms.h"
12
13
class cmSourceGroupInternals
14
{
15
public:
16
  SourceGroupVector GroupChildren;
17
};
18
19
cmSourceGroup::cmSourceGroup(std::string name, cm::string_view regex,
20
                             cm::string_view parentName)
21
8
  : Name(std::move(name))
22
8
{
23
8
  this->Internal = cm::make_unique<cmSourceGroupInternals>();
24
8
  this->SetGroupRegex(regex);
25
8
  if (parentName.empty()) {
26
8
    this->FullName = this->Name;
27
8
  } else {
28
0
    this->FullName = cmStrCat(parentName, '\\', this->Name);
29
0
  }
30
8
}
31
32
8
cmSourceGroup::~cmSourceGroup() = default;
33
34
bool cmSourceGroup::SetGroupRegex(cm::string_view regex)
35
15
{
36
15
  if (regex.data()) {
37
15
    return this->GroupRegex.compile(static_cast<std::string>(regex));
38
15
  }
39
0
  return this->GroupRegex.compile("^$");
40
15
}
41
42
void cmSourceGroup::ResolveGenex(cmLocalGenerator* lg,
43
                                 std::string const& config)
44
0
{
45
0
  std::set<std::string> files;
46
47
0
  for (auto& pair : this->GroupFileSets) {
48
0
    files.clear();
49
0
    for (std::string const& fileSet : pair.second) {
50
0
      cmList list{ cmGeneratorExpression::Evaluate(fileSet, lg, config) };
51
0
      files.insert(list.begin(), list.end());
52
0
    }
53
0
    pair.second = std::move(files);
54
0
  }
55
56
0
  files.clear();
57
0
  for (std::string const& file : this->GroupFiles) {
58
0
    cmList list{ cmGeneratorExpression::Evaluate(file, lg, config) };
59
0
    files.insert(list.begin(), list.end());
60
0
  }
61
0
  this->GroupFiles = std::move(files);
62
63
0
  if (!this->Internal) {
64
0
    return;
65
0
  }
66
67
0
  for (auto const& group : this->Internal->GroupChildren) {
68
0
    group->ResolveGenex(lg, config);
69
0
  }
70
0
}
71
72
void cmSourceGroup::AddGroupFile(std::string const& name)
73
0
{
74
0
  this->GroupFiles.insert(name);
75
0
}
76
77
void cmSourceGroup::AddGroupFileSets(std::string const& target,
78
                                     std::set<std::string> const& fileSets)
79
0
{
80
0
  auto& fs = this->GroupFileSets[target];
81
0
  fs.insert(fileSets.begin(), fileSets.end());
82
0
}
83
84
std::string const& cmSourceGroup::GetName() const
85
49
{
86
49
  return this->Name;
87
49
}
88
89
std::string const& cmSourceGroup::GetFullName() const
90
0
{
91
0
  return this->FullName;
92
0
}
93
94
bool cmSourceGroup::MatchesRegex(std::string const& name) const
95
0
{
96
0
  cmsys::RegularExpressionMatch match;
97
0
  return this->GroupRegex.find(name.c_str(), match);
98
0
}
99
100
bool cmSourceGroup::MatchesFiles(std::string const& name) const
101
0
{
102
0
  return this->GroupFiles.find(name) != this->GroupFiles.cend();
103
0
}
104
105
std::set<std::string> const& cmSourceGroup::GetGroupFiles() const
106
0
{
107
0
  return this->GroupFiles;
108
0
}
109
std::map<std::string, std::set<std::string>> const&
110
cmSourceGroup::GetGroupFileSets() const
111
0
{
112
0
  return this->GroupFileSets;
113
0
}
114
115
void cmSourceGroup::AddChild(std::unique_ptr<cmSourceGroup> child)
116
0
{
117
0
  this->Internal->GroupChildren.push_back(std::move(child));
118
0
}
119
120
cmSourceGroup* cmSourceGroup::LookupChild(std::string const& name) const
121
0
{
122
0
  for (auto& group : this->Internal->GroupChildren) {
123
    // look if descendant is the one we're looking for
124
0
    if (group->GetName() == name) {
125
0
      return group.get(); // if so return it
126
0
    }
127
0
  }
128
129
  // if no child with this name was found return NULL
130
0
  return nullptr;
131
0
}
132
133
cmSourceGroup* cmSourceGroup::MatchChildrenFiles(std::string const& name)
134
0
{
135
0
  if (this->MatchesFiles(name)) {
136
0
    return this;
137
0
  }
138
0
  for (auto& group : this->Internal->GroupChildren) {
139
0
    cmSourceGroup* result = group->MatchChildrenFiles(name);
140
0
    if (result) {
141
0
      return result;
142
0
    }
143
0
  }
144
0
  return nullptr;
145
0
}
146
147
cmSourceGroup const* cmSourceGroup::MatchChildrenFiles(
148
  std::string const& name) const
149
0
{
150
0
  if (this->MatchesFiles(name)) {
151
0
    return this;
152
0
  }
153
0
  for (auto const& group : this->Internal->GroupChildren) {
154
0
    cmSourceGroup const* result = group->MatchChildrenFiles(name);
155
0
    if (result) {
156
0
      return result;
157
0
    }
158
0
  }
159
0
  return nullptr;
160
0
}
161
162
cmSourceGroup* cmSourceGroup::MatchChildrenRegex(std::string const& name) const
163
0
{
164
0
  for (auto& group : this->Internal->GroupChildren) {
165
0
    cmSourceGroup* result = group->MatchChildrenRegex(name);
166
0
    if (result) {
167
0
      return result;
168
0
    }
169
0
  }
170
0
  if (this->MatchesRegex(name)) {
171
0
    return const_cast<cmSourceGroup*>(this);
172
0
  }
173
174
0
  return nullptr;
175
0
}
176
177
cmSourceGroup* cmSourceGroup::MatchChildrenFileSets(std::string const& target,
178
                                                    std::string const& fileSet)
179
0
{
180
0
  auto item = this->GroupFileSets.find(target);
181
0
  if (item != this->GroupFileSets.end() &&
182
0
      item->second.find(fileSet) != item->second.end()) {
183
0
    return this;
184
0
  }
185
0
  for (auto const& group : this->Internal->GroupChildren) {
186
0
    if (cmSourceGroup* result =
187
0
          group->MatchChildrenFileSets(target, fileSet)) {
188
0
      return result;
189
0
    }
190
0
  }
191
0
  return nullptr;
192
0
}
193
194
SourceGroupVector const& cmSourceGroup::GetGroupChildren() const
195
0
{
196
0
  return this->Internal->GroupChildren;
197
0
}
198
199
/**
200
 * Find a source group whose regular expression matches the filename
201
 * part of the given source name.  Search backward through the list of
202
 * source groups, and take the first matching group found.  This way
203
 * non-inherited source_group() commands will have precedence over
204
 * inherited ones.
205
 */
206
cmSourceGroup* cmSourceGroup::FindSourceGroup(std::string const& source,
207
                                              SourceGroupVector const& groups)
208
0
{
209
  // First search for a group that lists the file explicitly.
210
0
  for (auto sg = groups.rbegin(); sg != groups.rend(); ++sg) {
211
0
    cmSourceGroup* result = (*sg)->MatchChildrenFiles(source);
212
0
    if (result) {
213
0
      return result;
214
0
    }
215
0
  }
216
217
  // Now search for a group whose regex matches the file.
218
0
  for (auto sg = groups.rbegin(); sg != groups.rend(); ++sg) {
219
0
    cmSourceGroup* result = (*sg)->MatchChildrenRegex(source);
220
0
    if (result) {
221
0
      return result;
222
0
    }
223
0
  }
224
225
  // Shouldn't get here, but just in case, return the default group.
226
0
  return groups.data()->get();
227
0
}
228
229
/**
230
 * Find a source group whose matches the target and file set.
231
 * Search backward through the list of source groups, and take the first
232
 * matching group found.  This way non-inherited source_group() commands will
233
 * have precedence over inherited ones.
234
 */
235
cmSourceGroup* cmSourceGroup::FindSourceGroup(std::string const& target,
236
                                              std::string const& fileSet,
237
                                              SourceGroupVector const& groups)
238
0
{
239
  // First search for a group that lists the file set explicitly.
240
0
  for (auto sg = groups.rbegin(); sg != groups.rend(); ++sg) {
241
0
    if (cmSourceGroup* result =
242
0
          (*sg)->MatchChildrenFileSets(target, fileSet)) {
243
0
      return result;
244
0
    }
245
0
  }
246
247
0
  return nullptr;
248
0
}
249
250
void cmSourceGroupFiles::Add(cmSourceGroup const* sg, cmSourceFile const* sf)
251
0
{
252
0
  this->SourceFiles[sg].push_back(sf);
253
0
}
254
255
std::vector<cmSourceFile const*> const& cmSourceGroupFiles::GetSourceFiles(
256
  cmSourceGroup const* sg) const
257
0
{
258
0
  auto i = this->SourceFiles.find(sg);
259
0
  if (i != this->SourceFiles.end()) {
260
0
    return i->second;
261
0
  }
262
0
  static std::vector<cmSourceFile const*> const empty;
263
0
  return empty;
264
0
}