Coverage Report

Created: 2026-04-29 07:01

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