Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmCMakePolicyCommand.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 "cmCMakePolicyCommand.h"
4
5
#include "cmExecutionStatus.h"
6
#include "cmMakefile.h"
7
#include "cmPolicies.h"
8
#include "cmStringAlgorithms.h"
9
10
namespace {
11
bool HandleSetMode(std::vector<std::string> const& args,
12
                   cmExecutionStatus& status);
13
bool HandleGetMode(std::vector<std::string> const& args,
14
                   cmExecutionStatus& status);
15
bool HandleVersionMode(std::vector<std::string> const& args,
16
                       cmExecutionStatus& status);
17
bool HandleGetWarningMode(std::vector<std::string> const& args,
18
                          cmExecutionStatus& status);
19
}
20
21
// cmCMakePolicyCommand
22
bool cmCMakePolicyCommand(std::vector<std::string> const& args,
23
                          cmExecutionStatus& status)
24
0
{
25
0
  if (args.empty()) {
26
0
    status.SetError("requires at least one argument.");
27
0
    return false;
28
0
  }
29
30
0
  if (args[0] == "SET") {
31
0
    return HandleSetMode(args, status);
32
0
  }
33
0
  if (args[0] == "GET") {
34
0
    return HandleGetMode(args, status);
35
0
  }
36
0
  if (args[0] == "PUSH") {
37
0
    if (args.size() > 1) {
38
0
      status.SetError("PUSH may not be given additional arguments.");
39
0
      return false;
40
0
    }
41
0
    status.GetMakefile().PushPolicy();
42
0
    return true;
43
0
  }
44
0
  if (args[0] == "POP") {
45
0
    if (args.size() > 1) {
46
0
      status.SetError("POP may not be given additional arguments.");
47
0
      return false;
48
0
    }
49
0
    status.GetMakefile().PopPolicy();
50
0
    return true;
51
0
  }
52
0
  if (args[0] == "VERSION") {
53
0
    return HandleVersionMode(args, status);
54
0
  }
55
0
  if (args[0] == "GET_WARNING") {
56
0
    return HandleGetWarningMode(args, status);
57
0
  }
58
59
0
  status.SetError(cmStrCat("given unknown first argument \"", args[0], '"'));
60
0
  return false;
61
0
}
62
63
namespace {
64
65
bool HandleSetMode(std::vector<std::string> const& args,
66
                   cmExecutionStatus& status)
67
0
{
68
0
  if (args.size() != 3) {
69
0
    status.SetError("SET must be given exactly 2 additional arguments.");
70
0
    return false;
71
0
  }
72
73
0
  cmPolicies::PolicyStatus policyStatus;
74
0
  if (args[2] == "OLD") {
75
0
    policyStatus = cmPolicies::OLD;
76
0
  } else if (args[2] == "NEW") {
77
0
    policyStatus = cmPolicies::NEW;
78
0
  } else {
79
0
    status.SetError(
80
0
      cmStrCat("SET given unrecognized policy status \"", args[2], '"'));
81
0
    return false;
82
0
  }
83
84
0
  if (!status.GetMakefile().SetPolicy(args[1].c_str(), policyStatus)) {
85
0
    status.SetError("SET failed to set policy.");
86
0
    return false;
87
0
  }
88
0
  return true;
89
0
}
90
91
bool HandleGetMode(std::vector<std::string> const& args,
92
                   cmExecutionStatus& status)
93
0
{
94
0
  bool parent_scope = false;
95
0
  if (args.size() == 4 && args[3] == "PARENT_SCOPE") {
96
    // Undocumented PARENT_SCOPE option for use within CMake.
97
0
    parent_scope = true;
98
0
  } else if (args.size() != 3) {
99
0
    status.SetError("GET must be given exactly 2 additional arguments.");
100
0
    return false;
101
0
  }
102
103
  // Get arguments.
104
0
  std::string const& id = args[1];
105
0
  std::string const& var = args[2];
106
107
  // Lookup the policy number.
108
0
  cmPolicies::PolicyID pid;
109
0
  if (!cmPolicies::GetPolicyID(id.c_str(), pid)) {
110
0
    status.SetError(
111
0
      cmStrCat("GET given policy \"", id,
112
0
               "\" which is not known to this version of CMake."));
113
0
    return false;
114
0
  }
115
116
  // Lookup the policy setting.
117
0
  cmPolicies::PolicyStatus policyStatus =
118
0
    status.GetMakefile().GetPolicyStatus(pid, parent_scope);
119
0
  switch (policyStatus) {
120
0
    case cmPolicies::OLD:
121
      // Report that the policy is set to OLD.
122
0
      status.GetMakefile().AddDefinition(var, "OLD");
123
0
      break;
124
0
    case cmPolicies::WARN:
125
      // Report that the policy is not set.
126
0
      status.GetMakefile().AddDefinition(var, "");
127
0
      break;
128
0
    case cmPolicies::NEW:
129
      // Report that the policy is set to NEW.
130
0
      status.GetMakefile().AddDefinition(var, "NEW");
131
0
      break;
132
0
  }
133
134
0
  return true;
135
0
}
136
137
bool HandleVersionMode(std::vector<std::string> const& args,
138
                       cmExecutionStatus& status)
139
0
{
140
0
  if (args.size() <= 1) {
141
0
    status.SetError("VERSION not given an argument");
142
0
    return false;
143
0
  }
144
0
  if (args.size() >= 3) {
145
0
    status.SetError("VERSION given too many arguments");
146
0
    return false;
147
0
  }
148
0
  std::string const& version_string = args[1];
149
150
  // Separate the <min> version and any trailing ...<max> component.
151
0
  std::string::size_type const dd = version_string.find("...");
152
0
  std::string const version_min = version_string.substr(0, dd);
153
0
  std::string const version_max = dd != std::string::npos
154
0
    ? version_string.substr(dd + 3, std::string::npos)
155
0
    : std::string();
156
0
  if (dd != std::string::npos &&
157
0
      (version_min.empty() || version_max.empty())) {
158
0
    status.SetError(
159
0
      cmStrCat("VERSION \"", version_string,
160
0
               R"(" does not have a version on both sides of "...".)"));
161
0
    return false;
162
0
  }
163
164
0
  return status.GetMakefile().SetPolicyVersion(version_min, version_max);
165
0
}
166
167
bool HandleGetWarningMode(std::vector<std::string> const& args,
168
                          cmExecutionStatus& status)
169
0
{
170
0
  if (args.size() != 3) {
171
0
    status.SetError(
172
0
      "GET_WARNING must be given exactly 2 additional arguments.");
173
0
    return false;
174
0
  }
175
176
  // Get arguments.
177
0
  std::string const& id = args[1];
178
0
  std::string const& var = args[2];
179
180
  // Lookup the policy number.
181
0
  cmPolicies::PolicyID pid;
182
0
  if (!cmPolicies::GetPolicyID(id.c_str(), pid)) {
183
0
    status.SetError(
184
0
      cmStrCat("GET_WARNING given policy \"", id,
185
0
               "\" which is not known to this version of CMake."));
186
0
    return false;
187
0
  }
188
189
  // Lookup the policy warning.
190
0
  status.GetMakefile().AddDefinition(var, cmPolicies::GetPolicyWarning(pid));
191
192
0
  return true;
193
0
}
194
}