Coverage Report

Created: 2026-02-09 06:05

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 "cmMessageType.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.IssueMessage(
52
0
            MessageType::AUTHOR_WARNING,
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
  if (!this->DefaultComponentName.empty()) {
104
0
    return this->DefaultComponentName;
105
0
  }
106
0
  static std::string unspecifiedComponent = "Unspecified";
107
0
  return unspecifiedComponent;
108
0
}
109
110
std::string const& cmInstallCommandArguments::GetNamelinkComponent() const
111
0
{
112
0
  if (!this->NamelinkComponent.empty()) {
113
0
    return this->NamelinkComponent;
114
0
  }
115
0
  return this->GetComponent();
116
0
}
117
118
std::string const& cmInstallCommandArguments::GetRename() const
119
0
{
120
0
  if (!this->Rename.empty()) {
121
0
    return this->Rename;
122
0
  }
123
0
  if (this->GenericArguments) {
124
0
    return this->GenericArguments->GetRename();
125
0
  }
126
0
  return EmptyString;
127
0
}
128
129
std::string const& cmInstallCommandArguments::GetPermissions() const
130
0
{
131
0
  if (!this->PermissionsString.empty()) {
132
0
    return this->PermissionsString;
133
0
  }
134
0
  if (this->GenericArguments) {
135
0
    return this->GenericArguments->GetPermissions();
136
0
  }
137
0
  return EmptyString;
138
0
}
139
140
bool cmInstallCommandArguments::GetOptional() const
141
0
{
142
0
  if (this->Optional) {
143
0
    return true;
144
0
  }
145
0
  if (this->GenericArguments) {
146
0
    return this->GenericArguments->GetOptional();
147
0
  }
148
0
  return false;
149
0
}
150
151
bool cmInstallCommandArguments::GetExcludeFromAll() const
152
0
{
153
0
  if (this->ExcludeFromAll) {
154
0
    return true;
155
0
  }
156
0
  if (this->GenericArguments) {
157
0
    return this->GenericArguments->GetExcludeFromAll();
158
0
  }
159
0
  return false;
160
0
}
161
162
bool cmInstallCommandArguments::GetNamelinkOnly() const
163
0
{
164
0
  if (this->NamelinkOnly) {
165
0
    return true;
166
0
  }
167
0
  if (this->GenericArguments) {
168
0
    return this->GenericArguments->GetNamelinkOnly();
169
0
  }
170
0
  return false;
171
0
}
172
173
bool cmInstallCommandArguments::GetNamelinkSkip() const
174
0
{
175
0
  if (this->NamelinkSkip) {
176
0
    return true;
177
0
  }
178
0
  if (this->GenericArguments) {
179
0
    return this->GenericArguments->GetNamelinkSkip();
180
0
  }
181
0
  return false;
182
0
}
183
184
bool cmInstallCommandArguments::HasNamelinkComponent() const
185
0
{
186
0
  if (!this->NamelinkComponent.empty()) {
187
0
    return true;
188
0
  }
189
0
  if (this->GenericArguments) {
190
0
    return this->GenericArguments->HasNamelinkComponent();
191
0
  }
192
0
  return false;
193
0
}
194
195
std::string const& cmInstallCommandArguments::GetType() const
196
0
{
197
0
  return this->Type;
198
0
}
199
200
std::string const& cmInstallCommandArguments::GetDefaultComponent() const
201
0
{
202
0
  return this->DefaultComponentName;
203
0
}
204
205
std::vector<std::string> const& cmInstallCommandArguments::GetConfigurations()
206
  const
207
0
{
208
0
  if (!this->Configurations.empty()) {
209
0
    return this->Configurations;
210
0
  }
211
0
  if (this->GenericArguments) {
212
0
    return this->GenericArguments->GetConfigurations();
213
0
  }
214
0
  return this->Configurations;
215
0
}
216
217
bool cmInstallCommandArguments::Finalize()
218
0
{
219
0
  if (!this->CheckPermissions()) {
220
0
    return false;
221
0
  }
222
0
  this->DestinationString = this->Destination;
223
0
  cmSystemTools::ConvertToUnixSlashes(this->DestinationString);
224
0
  return true;
225
0
}
226
227
bool cmInstallCommandArguments::CheckPermissions()
228
0
{
229
0
  this->PermissionsString.clear();
230
0
  return std::all_of(this->Permissions.begin(), this->Permissions.end(),
231
0
                     [this](std::string const& perm) -> bool {
232
0
                       return cmInstallCommandArguments::CheckPermissions(
233
0
                         perm, this->PermissionsString);
234
0
                     });
235
0
}
236
237
bool cmInstallCommandArguments::CheckPermissions(
238
  std::string const& onePermission, std::string& permissions)
239
0
{
240
  // Check the permission against the table.
241
0
  for (char const** valid = cmInstallCommandArguments::PermissionsTable;
242
0
       *valid; ++valid) {
243
0
    if (onePermission == *valid) {
244
      // This is a valid permission.
245
0
      permissions += " ";
246
0
      permissions += onePermission;
247
0
      return true;
248
0
    }
249
0
  }
250
  // This is not a valid permission.
251
0
  return false;
252
0
}
253
254
0
cmInstallCommandIncludesArgument::cmInstallCommandIncludesArgument() = default;
255
256
std::vector<std::string> const&
257
cmInstallCommandIncludesArgument::GetIncludeDirs() const
258
0
{
259
0
  return this->IncludeDirs;
260
0
}
261
262
void cmInstallCommandIncludesArgument::Parse(
263
  std::vector<std::string> const* args, std::vector<std::string>*)
264
0
{
265
0
  if (args->empty()) {
266
0
    return;
267
0
  }
268
0
  for (std::string dir : cmMakeRange(*args).advance(1)) {
269
0
    cmSystemTools::ConvertToUnixSlashes(dir);
270
0
    this->IncludeDirs.push_back(std::move(dir));
271
0
  }
272
0
}
273
274
cmInstallCommandFileSetArguments::cmInstallCommandFileSetArguments(
275
  std::string defaultComponent, cmMakefile& makefile)
276
0
  : cmInstallCommandArguments(std::move(defaultComponent), makefile)
277
0
{
278
0
  this->Bind("FILE_SET"_s, this->FileSet);
279
0
}
280
281
void cmInstallCommandFileSetArguments::Parse(
282
  std::vector<std::string> args, std::vector<std::string>* unconsumedArgs)
283
0
{
284
0
  args.insert(args.begin(), "FILE_SET");
285
0
  this->cmInstallCommandArguments::Parse(args, unconsumedArgs);
286
0
}