Coverage Report

Created: 2026-06-15 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmInstallCommandArguments.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 "cmInstallCommandArguments.h"
4
5
#include <algorithm>
6
#include <functional>
7
#include <utility>
8
9
#include <cm/string_view>
10
#include <cmext/string_view>
11
12
#include "cmCMakePath.h"
13
#include "cmGeneratorExpression.h"
14
#include "cmMakefile.h"
15
#include "cmPolicies.h"
16
#include "cmRange.h"
17
#include "cmStringAlgorithms.h"
18
#include "cmSystemTools.h"
19
20
// Table of valid permissions.
21
char const* cmInstallCommandArguments::PermissionsTable[] = {
22
  "OWNER_READ",    "OWNER_WRITE",   "OWNER_EXECUTE", "GROUP_READ",
23
  "GROUP_WRITE",   "GROUP_EXECUTE", "WORLD_READ",    "WORLD_WRITE",
24
  "WORLD_EXECUTE", "SETUID",        "SETGID",        nullptr
25
};
26
27
std::string const cmInstallCommandArguments::EmptyString;
28
29
cmInstallCommandArguments::cmInstallCommandArguments(
30
  std::string defaultComponent, cmMakefile& makefile)
31
0
  : DefaultComponentName(std::move(defaultComponent))
32
0
{
33
0
  std::function<ArgumentParser::Continue(cm::string_view)> normalizeDest;
34
35
0
  switch (makefile.GetPolicyStatus(cmPolicies::CMP0177)) {
36
0
    case cmPolicies::OLD:
37
0
      normalizeDest = [this](cm::string_view arg) -> ArgumentParser::Continue {
38
0
        this->Destination = std::string(arg.begin(), arg.end());
39
0
        return ArgumentParser::Continue::No;
40
0
      };
41
0
      break;
42
0
    case cmPolicies::WARN:
43
0
      normalizeDest =
44
0
        [this, &makefile](cm::string_view arg) -> ArgumentParser::Continue {
45
0
        this->Destination = std::string(arg.begin(), arg.end());
46
        // We can't be certain if a warning is appropriate if there are any
47
        // generator expressions
48
0
        if (cmGeneratorExpression::Find(arg) == cm::string_view::npos &&
49
0
            arg != cmCMakePath(arg).Normal().String()) {
50
0
          makefile.IssuePolicyWarning(cmPolicies::CMP0177);
51
0
        }
52
0
        return ArgumentParser::Continue::No;
53
0
      };
54
0
      break;
55
0
    case cmPolicies::NEW:
56
0
      normalizeDest = [this](cm::string_view arg) -> ArgumentParser::Continue {
57
0
        if (cmGeneratorExpression::Find(arg) == cm::string_view::npos) {
58
0
          this->Destination = cmCMakePath(arg).Normal().String();
59
0
        } else {
60
0
          this->Destination =
61
0
            cmStrCat("$<PATH:CMAKE_PATH,NORMALIZE,", arg, '>');
62
0
        }
63
0
        return ArgumentParser::Continue::No;
64
0
      };
65
0
      break;
66
0
  }
67
68
0
  this->Bind("DESTINATION"_s, normalizeDest);
69
0
  this->Bind("COMPONENT"_s, this->Component);
70
0
  this->Bind("NAMELINK_COMPONENT"_s, this->NamelinkComponent);
71
0
  this->Bind("EXCLUDE_FROM_ALL"_s, this->ExcludeFromAll);
72
0
  this->Bind("RENAME"_s, this->Rename);
73
0
  this->Bind("PERMISSIONS"_s, this->Permissions);
74
0
  this->Bind("CONFIGURATIONS"_s, this->Configurations);
75
0
  this->Bind("OPTIONAL"_s, this->Optional);
76
0
  this->Bind("NAMELINK_ONLY"_s, this->NamelinkOnly);
77
0
  this->Bind("NAMELINK_SKIP"_s, this->NamelinkSkip);
78
0
  this->Bind("TYPE"_s, this->Type);
79
0
}
80
81
std::string const& cmInstallCommandArguments::GetDestination() const
82
0
{
83
0
  if (!this->DestinationString.empty()) {
84
0
    return this->DestinationString;
85
0
  }
86
0
  if (this->GenericArguments) {
87
0
    return this->GenericArguments->GetDestination();
88
0
  }
89
0
  return EmptyString;
90
0
}
91
92
std::string const& cmInstallCommandArguments::GetComponent() const
93
0
{
94
0
  if (!this->Component.empty()) {
95
0
    return this->Component;
96
0
  }
97
0
  if (this->GenericArguments) {
98
0
    return this->GenericArguments->GetComponent();
99
0
  }
100
0
  return this->DefaultComponentName;
101
0
}
102
103
std::string const& cmInstallCommandArguments::GetNamelinkComponent() const
104
0
{
105
0
  if (!this->NamelinkComponent.empty()) {
106
0
    return this->NamelinkComponent;
107
0
  }
108
0
  return this->GetComponent();
109
0
}
110
111
std::string const& cmInstallCommandArguments::GetRename() const
112
0
{
113
0
  if (!this->Rename.empty()) {
114
0
    return this->Rename;
115
0
  }
116
0
  if (this->GenericArguments) {
117
0
    return this->GenericArguments->GetRename();
118
0
  }
119
0
  return EmptyString;
120
0
}
121
122
std::string const& cmInstallCommandArguments::GetPermissions() const
123
0
{
124
0
  if (!this->PermissionsString.empty()) {
125
0
    return this->PermissionsString;
126
0
  }
127
0
  if (this->GenericArguments) {
128
0
    return this->GenericArguments->GetPermissions();
129
0
  }
130
0
  return EmptyString;
131
0
}
132
133
bool cmInstallCommandArguments::GetOptional() const
134
0
{
135
0
  if (this->Optional) {
136
0
    return true;
137
0
  }
138
0
  if (this->GenericArguments) {
139
0
    return this->GenericArguments->GetOptional();
140
0
  }
141
0
  return false;
142
0
}
143
144
bool cmInstallCommandArguments::GetExcludeFromAll() const
145
0
{
146
0
  if (this->ExcludeFromAll) {
147
0
    return true;
148
0
  }
149
0
  if (this->GenericArguments) {
150
0
    return this->GenericArguments->GetExcludeFromAll();
151
0
  }
152
0
  return false;
153
0
}
154
155
bool cmInstallCommandArguments::GetNamelinkOnly() const
156
0
{
157
0
  if (this->NamelinkOnly) {
158
0
    return true;
159
0
  }
160
0
  if (this->GenericArguments) {
161
0
    return this->GenericArguments->GetNamelinkOnly();
162
0
  }
163
0
  return false;
164
0
}
165
166
bool cmInstallCommandArguments::GetNamelinkSkip() const
167
0
{
168
0
  if (this->NamelinkSkip) {
169
0
    return true;
170
0
  }
171
0
  if (this->GenericArguments) {
172
0
    return this->GenericArguments->GetNamelinkSkip();
173
0
  }
174
0
  return false;
175
0
}
176
177
bool cmInstallCommandArguments::HasNamelinkComponent() const
178
0
{
179
0
  if (!this->NamelinkComponent.empty()) {
180
0
    return true;
181
0
  }
182
0
  if (this->GenericArguments) {
183
0
    return this->GenericArguments->HasNamelinkComponent();
184
0
  }
185
0
  return false;
186
0
}
187
188
std::string const& cmInstallCommandArguments::GetType() const
189
0
{
190
0
  return this->Type;
191
0
}
192
193
std::string const& cmInstallCommandArguments::GetDefaultComponent() const
194
0
{
195
0
  return this->DefaultComponentName;
196
0
}
197
198
std::vector<std::string> const& cmInstallCommandArguments::GetConfigurations()
199
  const
200
0
{
201
0
  if (!this->Configurations.empty()) {
202
0
    return this->Configurations;
203
0
  }
204
0
  if (this->GenericArguments) {
205
0
    return this->GenericArguments->GetConfigurations();
206
0
  }
207
0
  return this->Configurations;
208
0
}
209
210
bool cmInstallCommandArguments::Finalize()
211
0
{
212
0
  if (!this->CheckPermissions()) {
213
0
    return false;
214
0
  }
215
0
  this->DestinationString = this->Destination;
216
0
  cmSystemTools::ConvertToUnixSlashes(this->DestinationString);
217
0
  return true;
218
0
}
219
220
bool cmInstallCommandArguments::CheckPermissions()
221
0
{
222
0
  this->PermissionsString.clear();
223
0
  return std::all_of(this->Permissions.begin(), this->Permissions.end(),
224
0
                     [this](std::string const& perm) -> bool {
225
0
                       return cmInstallCommandArguments::CheckPermissions(
226
0
                         perm, this->PermissionsString);
227
0
                     });
228
0
}
229
230
bool cmInstallCommandArguments::CheckPermissions(
231
  std::string const& onePermission, std::string& permissions)
232
0
{
233
  // Check the permission against the table.
234
0
  for (char const** valid = cmInstallCommandArguments::PermissionsTable;
235
0
       *valid; ++valid) {
236
0
    if (onePermission == *valid) {
237
      // This is a valid permission.
238
0
      permissions += " ";
239
0
      permissions += onePermission;
240
0
      return true;
241
0
    }
242
0
  }
243
  // This is not a valid permission.
244
0
  return false;
245
0
}
246
247
0
cmInstallCommandIncludesArgument::cmInstallCommandIncludesArgument() = default;
248
249
std::vector<std::string> const&
250
cmInstallCommandIncludesArgument::GetIncludeDirs() const
251
0
{
252
0
  return this->IncludeDirs;
253
0
}
254
255
void cmInstallCommandIncludesArgument::Parse(
256
  std::vector<std::string> const* args, std::vector<std::string>*)
257
0
{
258
0
  if (args->empty()) {
259
0
    return;
260
0
  }
261
0
  for (std::string dir : cmMakeRange(*args).advance(1)) {
262
0
    cmSystemTools::ConvertToUnixSlashes(dir);
263
0
    this->IncludeDirs.push_back(std::move(dir));
264
0
  }
265
0
}
266
267
cmInstallCommandFileSetArguments::cmInstallCommandFileSetArguments(
268
  std::string defaultComponent, cmMakefile& makefile)
269
0
  : cmInstallCommandArguments(std::move(defaultComponent), makefile)
270
0
{
271
0
  this->Bind("FILE_SET"_s, this->FileSet);
272
0
}
273
274
void cmInstallCommandFileSetArguments::Parse(
275
  std::vector<std::string> args, std::vector<std::string>* unconsumedArgs)
276
0
{
277
0
  args.insert(args.begin(), "FILE_SET");
278
0
  this->cmInstallCommandArguments::Parse(args, unconsumedArgs);
279
0
}