Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmCMakePathCommand.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 "cmCMakePathCommand.h"
4
5
#include <functional>
6
#include <iomanip>
7
#include <map>
8
#include <sstream>
9
#include <string>
10
#include <utility>
11
#include <vector>
12
13
#include <cm/optional>
14
#include <cm/string_view>
15
#include <cmext/string_view>
16
17
#include "cmArgumentParser.h"
18
#include "cmArgumentParserTypes.h"
19
#include "cmCMakePath.h"
20
#include "cmExecutionStatus.h"
21
#include "cmList.h"
22
#include "cmMakefile.h"
23
#include "cmRange.h"
24
#include "cmStringAlgorithms.h"
25
#include "cmSubcommandTable.h"
26
#include "cmSystemTools.h"
27
#include "cmValue.h"
28
29
namespace {
30
// Helper classes for argument parsing
31
template <typename Result>
32
class CMakePathArgumentParser : public cmArgumentParser<Result>
33
{
34
public:
35
  CMakePathArgumentParser()
36
0
    : cmArgumentParser<Result>()
37
0
  {
38
0
  }
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::HandleGetCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::CMakePathArgumentParser()
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::NormalizeOption>::CMakePathArgumentParser()
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::OutputVariable>::CMakePathArgumentParser()
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::HandleRemoveExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::CMakePathArgumentParser()
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::HandleReplaceExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::CMakePathArgumentParser()
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments>::CMakePathArgumentParser()
39
40
  template <typename T>
41
  CMakePathArgumentParser& Bind(cm::static_string_view name, T Result::*member)
42
0
  {
43
0
    this->cmArgumentParser<Result>::Bind(name, member);
44
0
    return *this;
45
0
  }
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::HandleGetCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>& (anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::HandleGetCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::Bind<bool>(cm::static_string_view, bool (anonymous namespace)::HandleGetCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments::*)
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::NormalizeOption>& (anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::NormalizeOption>::Bind<bool>(cm::static_string_view, bool (anonymous namespace)::NormalizeOption::*)
46
47
  template <int Advance = 2>
48
  Result Parse(std::vector<std::string> const& args) const
49
0
  {
50
0
    this->Inputs.clear();
51
52
0
    return this->cmArgumentParser<Result>::Parse(
53
0
      cmMakeRange(args).advance(Advance), &this->Inputs);
54
0
  }
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::HandleGetCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments (anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::HandleGetCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::Parse<3>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) const
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::NormalizeOption (anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::NormalizeOption>::Parse<2>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) const
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::OutputVariable (anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::OutputVariable>::Parse<2>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) const
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::HandleRemoveExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments (anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::HandleRemoveExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::Parse<2>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) const
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::HandleReplaceExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments (anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::HandleReplaceExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::Parse<2>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) const
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments (anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments>::Parse<2>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) const
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::NormalizeOption (anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::NormalizeOption>::Parse<4>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) const
55
56
0
  std::vector<std::string> const& GetInputs() const { return this->Inputs; }
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::HandleGetCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::GetInputs() const
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::NormalizeOption>::GetInputs() const
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::OutputVariable>::GetInputs() const
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::HandleRemoveExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::GetInputs() const
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::HandleReplaceExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::GetInputs() const
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::CMakePathArgumentParser<(anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments>::GetInputs() const
57
58
protected:
59
  mutable std::vector<std::string> Inputs;
60
};
61
62
// OUTPUT_VARIABLE is expected
63
template <typename Result>
64
class ArgumentParserWithOutputVariable : public CMakePathArgumentParser<Result>
65
{
66
public:
67
  ArgumentParserWithOutputVariable()
68
0
    : CMakePathArgumentParser<Result>()
69
0
  {
70
0
    this->Bind("OUTPUT_VARIABLE"_s, &Result::Output);
71
0
  }
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::OutputVariable>::ArgumentParserWithOutputVariable()
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleRemoveExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::ArgumentParserWithOutputVariable()
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleReplaceExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::ArgumentParserWithOutputVariable()
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments>::ArgumentParserWithOutputVariable()
72
73
  template <typename T>
74
  ArgumentParserWithOutputVariable& Bind(cm::static_string_view name,
75
                                         T Result::*member)
76
0
  {
77
0
    this->cmArgumentParser<Result>::Bind(name, member);
78
0
    return *this;
79
0
  }
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::OutputVariable>& (anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::OutputVariable>::Bind<std::__1::optional<ArgumentParser::NonEmpty<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(cm::static_string_view, std::__1::optional<ArgumentParser::NonEmpty<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > (anonymous namespace)::OutputVariable::*)
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleRemoveExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>& (anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleRemoveExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::Bind<std::__1::optional<ArgumentParser::NonEmpty<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(cm::static_string_view, std::__1::optional<ArgumentParser::NonEmpty<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > (anonymous namespace)::HandleRemoveExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments::*)
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleRemoveExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>& (anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleRemoveExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::Bind<bool>(cm::static_string_view, bool (anonymous namespace)::HandleRemoveExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments::*)
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleReplaceExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>& (anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleReplaceExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::Bind<std::__1::optional<ArgumentParser::NonEmpty<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(cm::static_string_view, std::__1::optional<ArgumentParser::NonEmpty<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > (anonymous namespace)::HandleReplaceExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments::*)
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleReplaceExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>& (anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleReplaceExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::Bind<bool>(cm::static_string_view, bool (anonymous namespace)::HandleReplaceExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments::*)
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments>& (anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments>::Bind<std::__1::optional<ArgumentParser::NonEmpty<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(cm::static_string_view, std::__1::optional<ArgumentParser::NonEmpty<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > (anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments::*)
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments>& (anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments>::Bind<std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >(cm::static_string_view, std::__1::optional<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > (anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments::*)
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments>& (anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments>::Bind<bool>(cm::static_string_view, bool (anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments::*)
80
81
  template <int Advance = 2>
82
  Result Parse(std::vector<std::string> const& args) const
83
0
  {
84
0
    return this->CMakePathArgumentParser<Result>::template Parse<Advance>(
85
0
      args);
86
0
  }
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::OutputVariable (anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::OutputVariable>::Parse<2>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) const
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::HandleRemoveExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments (anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleRemoveExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::Parse<2>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) const
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::HandleReplaceExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments (anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleReplaceExtensionCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&)::Arguments>::Parse<2>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) const
Unexecuted instantiation: cmCMakePathCommand.cxx:(anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments (anonymous namespace)::ArgumentParserWithOutputVariable<(anonymous namespace)::HandleTransformPathCommand(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, cmExecutionStatus&, std::__1::function<cmCMakePath (cmCMakePath const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)> const&, bool)::Arguments>::Parse<2>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) const
87
};
88
89
struct OutputVariable : public ArgumentParser::ParseResult
90
{
91
  cm::optional<ArgumentParser::NonEmpty<std::string>> Output;
92
};
93
// Usable when OUTPUT_VARIABLE is the only option
94
class OutputVariableParser
95
  : public ArgumentParserWithOutputVariable<OutputVariable>
96
{
97
};
98
99
struct NormalizeOption
100
{
101
  bool Normalize = false;
102
};
103
// Usable when NORMALIZE is the only option
104
class NormalizeParser : public CMakePathArgumentParser<NormalizeOption>
105
{
106
public:
107
0
  NormalizeParser() { this->Bind("NORMALIZE"_s, &NormalizeOption::Normalize); }
108
};
109
110
// retrieve value of input path from specified variable
111
bool getInputPath(std::string const& arg, cmExecutionStatus& status,
112
                  std::string& path)
113
0
{
114
0
  cmValue def = status.GetMakefile().GetDefinition(arg);
115
0
  if (!def) {
116
0
    status.SetError("undefined variable for input path.");
117
0
    return false;
118
0
  }
119
120
0
  path = *def;
121
0
  return true;
122
0
}
123
124
bool HandleGetCommand(std::vector<std::string> const& args,
125
                      cmExecutionStatus& status)
126
0
{
127
0
  static std::map<cm::string_view,
128
0
                  std::function<cmCMakePath(cmCMakePath const&, bool)>> const
129
0
    actions{ { "ROOT_NAME"_s,
130
0
               [](cmCMakePath const& path, bool) -> cmCMakePath {
131
0
                 return path.GetRootName();
132
0
               } },
133
0
             { "ROOT_DIRECTORY"_s,
134
0
               [](cmCMakePath const& path, bool) -> cmCMakePath {
135
0
                 return path.GetRootDirectory();
136
0
               } },
137
0
             { "ROOT_PATH"_s,
138
0
               [](cmCMakePath const& path, bool) -> cmCMakePath {
139
0
                 return path.GetRootPath();
140
0
               } },
141
0
             { "FILENAME"_s,
142
0
               [](cmCMakePath const& path, bool) -> cmCMakePath {
143
0
                 return path.GetFileName();
144
0
               } },
145
0
             { "EXTENSION"_s,
146
0
               [](cmCMakePath const& path, bool last_only) -> cmCMakePath {
147
0
                 if (last_only) {
148
0
                   return path.GetExtension();
149
0
                 }
150
0
                 return path.GetWideExtension();
151
0
               } },
152
0
             { "STEM"_s,
153
0
               [](cmCMakePath const& path, bool last_only) -> cmCMakePath {
154
0
                 if (last_only) {
155
0
                   return path.GetStem();
156
0
                 }
157
0
                 return path.GetNarrowStem();
158
0
               } },
159
0
             { "RELATIVE_PART"_s,
160
0
               [](cmCMakePath const& path, bool) -> cmCMakePath {
161
0
                 return path.GetRelativePath();
162
0
               } },
163
0
             { "PARENT_PATH"_s,
164
0
               [](cmCMakePath const& path, bool) -> cmCMakePath {
165
0
                 return path.GetParentPath();
166
0
               } } };
167
168
0
  if (args.size() < 4) {
169
0
    status.SetError("GET must be called with at least three arguments.");
170
0
    return false;
171
0
  }
172
173
0
  auto const& action = args[2];
174
175
0
  if (actions.find(action) == actions.end()) {
176
0
    status.SetError(
177
0
      cmStrCat("GET called with an unknown action: ", action, '.'));
178
0
    return false;
179
0
  }
180
181
0
  struct Arguments
182
0
  {
183
0
    bool LastOnly = false;
184
0
  };
185
186
0
  CMakePathArgumentParser<Arguments> parser;
187
0
  if ((action == "EXTENSION"_s || action == "STEM"_s)) {
188
0
    parser.Bind("LAST_ONLY"_s, &Arguments::LastOnly);
189
0
  }
190
191
0
  Arguments const arguments = parser.Parse<3>(args);
192
193
0
  if (parser.GetInputs().size() != 1) {
194
0
    status.SetError("GET called with unexpected arguments.");
195
0
    return false;
196
0
  }
197
0
  if (parser.GetInputs().front().empty()) {
198
0
    status.SetError("Invalid name for output variable.");
199
0
    return false;
200
0
  }
201
202
0
  std::string path;
203
0
  if (!getInputPath(args[1], status, path)) {
204
0
    return false;
205
0
  }
206
207
0
  auto result = actions.at(action)(path, arguments.LastOnly);
208
209
0
  status.GetMakefile().AddDefinition(parser.GetInputs().front(),
210
0
                                     result.String());
211
212
0
  return true;
213
0
}
214
215
bool HandleSetCommand(std::vector<std::string> const& args,
216
                      cmExecutionStatus& status)
217
0
{
218
0
  if (args.size() < 3 || args.size() > 4) {
219
0
    status.SetError("SET must be called with two or three arguments.");
220
0
    return false;
221
0
  }
222
223
0
  if (args[1].empty()) {
224
0
    status.SetError("Invalid name for path variable.");
225
0
    return false;
226
0
  }
227
228
0
  static NormalizeParser const parser;
229
230
0
  auto const arguments = parser.Parse(args);
231
232
0
  if (parser.GetInputs().size() != 1) {
233
0
    status.SetError("SET called with unexpected arguments.");
234
0
    return false;
235
0
  }
236
237
0
  auto path =
238
0
    cmCMakePath(parser.GetInputs().front(), cmCMakePath::native_format);
239
240
0
  if (arguments.Normalize) {
241
0
    path = path.Normal();
242
0
  }
243
244
0
  status.GetMakefile().AddDefinition(args[1], path.GenericString());
245
246
0
  return true;
247
0
}
248
249
bool HandleAppendCommand(std::vector<std::string> const& args,
250
                         cmExecutionStatus& status)
251
0
{
252
0
  if (args[1].empty()) {
253
0
    status.SetError("Invalid name for path variable.");
254
0
    return false;
255
0
  }
256
257
0
  static OutputVariableParser const parser{};
258
259
0
  auto const arguments = parser.Parse(args);
260
261
0
  if (arguments.MaybeReportError(status.GetMakefile())) {
262
0
    return true;
263
0
  }
264
265
0
  cmCMakePath path(status.GetMakefile().GetSafeDefinition(args[1]));
266
0
  for (auto const& input : parser.GetInputs()) {
267
0
    path /= input;
268
0
  }
269
270
0
  status.GetMakefile().AddDefinition(
271
0
    arguments.Output ? *arguments.Output : args[1], path.String());
272
273
0
  return true;
274
0
}
275
276
bool HandleAppendStringCommand(std::vector<std::string> const& args,
277
                               cmExecutionStatus& status)
278
0
{
279
0
  static OutputVariableParser const parser{};
280
281
0
  auto const arguments = parser.Parse(args);
282
283
0
  if (arguments.MaybeReportError(status.GetMakefile())) {
284
0
    return true;
285
0
  }
286
287
0
  std::string inputPath;
288
0
  if (!getInputPath(args[1], status, inputPath)) {
289
0
    return false;
290
0
  }
291
292
0
  cmCMakePath path(inputPath);
293
0
  for (auto const& input : parser.GetInputs()) {
294
0
    path += input;
295
0
  }
296
297
0
  status.GetMakefile().AddDefinition(
298
0
    arguments.Output ? *arguments.Output : args[1], path.String());
299
300
0
  return true;
301
0
}
302
303
bool HandleRemoveFilenameCommand(std::vector<std::string> const& args,
304
                                 cmExecutionStatus& status)
305
0
{
306
0
  static OutputVariableParser const parser{};
307
308
0
  auto const arguments = parser.Parse(args);
309
310
0
  if (arguments.MaybeReportError(status.GetMakefile())) {
311
0
    return true;
312
0
  }
313
314
0
  if (!parser.GetInputs().empty()) {
315
0
    status.SetError("REMOVE_FILENAME called with unexpected arguments.");
316
0
    return false;
317
0
  }
318
319
0
  std::string inputPath;
320
0
  if (!getInputPath(args[1], status, inputPath)) {
321
0
    return false;
322
0
  }
323
324
0
  cmCMakePath path(inputPath);
325
0
  path.RemoveFileName();
326
327
0
  status.GetMakefile().AddDefinition(
328
0
    arguments.Output ? *arguments.Output : args[1], path.String());
329
330
0
  return true;
331
0
}
332
333
bool HandleReplaceFilenameCommand(std::vector<std::string> const& args,
334
                                  cmExecutionStatus& status)
335
0
{
336
0
  static OutputVariableParser const parser{};
337
338
0
  auto const arguments = parser.Parse(args);
339
340
0
  if (arguments.MaybeReportError(status.GetMakefile())) {
341
0
    return true;
342
0
  }
343
344
0
  if (parser.GetInputs().size() > 1) {
345
0
    status.SetError("REPLACE_FILENAME called with unexpected arguments.");
346
0
    return false;
347
0
  }
348
349
0
  std::string inputPath;
350
0
  if (!getInputPath(args[1], status, inputPath)) {
351
0
    return false;
352
0
  }
353
354
0
  cmCMakePath path(inputPath);
355
0
  path.ReplaceFileName(
356
0
    parser.GetInputs().empty() ? "" : parser.GetInputs().front());
357
358
0
  status.GetMakefile().AddDefinition(
359
0
    arguments.Output ? *arguments.Output : args[1], path.String());
360
361
0
  return true;
362
0
}
363
364
bool HandleRemoveExtensionCommand(std::vector<std::string> const& args,
365
                                  cmExecutionStatus& status)
366
0
{
367
0
  struct Arguments : public ArgumentParser::ParseResult
368
0
  {
369
0
    cm::optional<ArgumentParser::NonEmpty<std::string>> Output;
370
0
    bool LastOnly = false;
371
0
  };
372
373
0
  static auto const parser =
374
0
    ArgumentParserWithOutputVariable<Arguments>{}.Bind("LAST_ONLY"_s,
375
0
                                                       &Arguments::LastOnly);
376
377
0
  Arguments const arguments = parser.Parse(args);
378
379
0
  if (arguments.MaybeReportError(status.GetMakefile())) {
380
0
    return true;
381
0
  }
382
383
0
  if (!parser.GetInputs().empty()) {
384
0
    status.SetError("REMOVE_EXTENSION called with unexpected arguments.");
385
0
    return false;
386
0
  }
387
388
0
  std::string inputPath;
389
0
  if (!getInputPath(args[1], status, inputPath)) {
390
0
    return false;
391
0
  }
392
393
0
  cmCMakePath path(inputPath);
394
395
0
  if (arguments.LastOnly) {
396
0
    path.RemoveExtension();
397
0
  } else {
398
0
    path.RemoveWideExtension();
399
0
  }
400
401
0
  status.GetMakefile().AddDefinition(
402
0
    arguments.Output ? *arguments.Output : args[1], path.String());
403
404
0
  return true;
405
0
}
406
407
bool HandleReplaceExtensionCommand(std::vector<std::string> const& args,
408
                                   cmExecutionStatus& status)
409
0
{
410
0
  struct Arguments : public ArgumentParser::ParseResult
411
0
  {
412
0
    cm::optional<ArgumentParser::NonEmpty<std::string>> Output;
413
0
    bool LastOnly = false;
414
0
  };
415
416
0
  static auto const parser =
417
0
    ArgumentParserWithOutputVariable<Arguments>{}.Bind("LAST_ONLY"_s,
418
0
                                                       &Arguments::LastOnly);
419
420
0
  Arguments const arguments = parser.Parse(args);
421
422
0
  if (arguments.MaybeReportError(status.GetMakefile())) {
423
0
    return true;
424
0
  }
425
426
0
  if (parser.GetInputs().size() > 1) {
427
0
    status.SetError("REPLACE_EXTENSION called with unexpected arguments.");
428
0
    return false;
429
0
  }
430
431
0
  std::string inputPath;
432
0
  if (!getInputPath(args[1], status, inputPath)) {
433
0
    return false;
434
0
  }
435
436
0
  cmCMakePath path(inputPath);
437
0
  cmCMakePath extension(
438
0
    parser.GetInputs().empty() ? "" : parser.GetInputs().front());
439
440
0
  if (arguments.LastOnly) {
441
0
    path.ReplaceExtension(extension);
442
0
  } else {
443
0
    path.ReplaceWideExtension(extension);
444
0
  }
445
446
0
  status.GetMakefile().AddDefinition(
447
0
    arguments.Output ? *arguments.Output : args[1], path.String());
448
449
0
  return true;
450
0
}
451
452
bool HandleNormalPathCommand(std::vector<std::string> const& args,
453
                             cmExecutionStatus& status)
454
0
{
455
0
  static OutputVariableParser const parser{};
456
457
0
  auto const arguments = parser.Parse(args);
458
459
0
  if (arguments.MaybeReportError(status.GetMakefile())) {
460
0
    return true;
461
0
  }
462
463
0
  if (!parser.GetInputs().empty()) {
464
0
    status.SetError("NORMAL_PATH called with unexpected arguments.");
465
0
    return false;
466
0
  }
467
468
0
  std::string inputPath;
469
0
  if (!getInputPath(args[1], status, inputPath)) {
470
0
    return false;
471
0
  }
472
473
0
  auto path = cmCMakePath(inputPath).Normal();
474
475
0
  status.GetMakefile().AddDefinition(
476
0
    arguments.Output ? *arguments.Output : args[1], path.String());
477
478
0
  return true;
479
0
}
480
481
bool HandleTransformPathCommand(
482
  std::vector<std::string> const& args, cmExecutionStatus& status,
483
  std::function<cmCMakePath(cmCMakePath const&,
484
                            std::string const& base)> const& transform,
485
  bool normalizeOption = false)
486
0
{
487
0
  struct Arguments : public ArgumentParser::ParseResult
488
0
  {
489
0
    cm::optional<ArgumentParser::NonEmpty<std::string>> Output;
490
0
    cm::optional<std::string> BaseDirectory;
491
0
    bool Normalize = false;
492
0
  };
493
494
0
  auto parser = ArgumentParserWithOutputVariable<Arguments>{}.Bind(
495
0
    "BASE_DIRECTORY"_s, &Arguments::BaseDirectory);
496
0
  if (normalizeOption) {
497
0
    parser.Bind("NORMALIZE"_s, &Arguments::Normalize);
498
0
  }
499
500
0
  Arguments arguments = parser.Parse(args);
501
502
0
  if (arguments.MaybeReportError(status.GetMakefile())) {
503
0
    return true;
504
0
  }
505
506
0
  if (!parser.GetInputs().empty()) {
507
0
    status.SetError(cmStrCat(args[0], " called with unexpected arguments."));
508
0
    return false;
509
0
  }
510
511
0
  std::string baseDirectory;
512
0
  if (arguments.BaseDirectory) {
513
0
    baseDirectory = *arguments.BaseDirectory;
514
0
  } else {
515
0
    baseDirectory = status.GetMakefile().GetCurrentSourceDirectory();
516
0
  }
517
518
0
  std::string inputPath;
519
0
  if (!getInputPath(args[1], status, inputPath)) {
520
0
    return false;
521
0
  }
522
523
0
  auto path = transform(cmCMakePath(inputPath), baseDirectory);
524
0
  if (arguments.Normalize) {
525
0
    path = path.Normal();
526
0
  }
527
528
0
  status.GetMakefile().AddDefinition(
529
0
    arguments.Output ? *arguments.Output : args[1], path.String());
530
531
0
  return true;
532
0
}
533
534
bool HandleRelativePathCommand(std::vector<std::string> const& args,
535
                               cmExecutionStatus& status)
536
0
{
537
0
  return HandleTransformPathCommand(
538
0
    args, status,
539
0
    [](cmCMakePath const& path, std::string const& base) -> cmCMakePath {
540
0
      return path.Relative(base);
541
0
    });
542
0
}
543
544
bool HandleAbsolutePathCommand(std::vector<std::string> const& args,
545
                               cmExecutionStatus& status)
546
0
{
547
0
  return HandleTransformPathCommand(
548
0
    args, status,
549
0
    [](cmCMakePath const& path, std::string const& base) -> cmCMakePath {
550
0
      return path.Absolute(base);
551
0
    },
552
0
    true);
553
0
}
554
555
bool HandleNativePathCommand(std::vector<std::string> const& args,
556
                             cmExecutionStatus& status)
557
0
{
558
0
  if (args.size() < 3 || args.size() > 4) {
559
0
    status.SetError("NATIVE_PATH must be called with two or three arguments.");
560
0
    return false;
561
0
  }
562
563
0
  static NormalizeParser const parser;
564
565
0
  auto const arguments = parser.Parse(args);
566
567
0
  if (parser.GetInputs().size() != 1) {
568
0
    status.SetError("NATIVE_PATH called with unexpected arguments.");
569
0
    return false;
570
0
  }
571
0
  if (parser.GetInputs().front().empty()) {
572
0
    status.SetError("Invalid name for output variable.");
573
0
    return false;
574
0
  }
575
576
0
  std::string inputPath;
577
0
  if (!getInputPath(args[1], status, inputPath)) {
578
0
    return false;
579
0
  }
580
581
0
  cmCMakePath path(inputPath);
582
0
  if (arguments.Normalize) {
583
0
    path = path.Normal();
584
0
  }
585
586
0
  status.GetMakefile().AddDefinition(parser.GetInputs().front(),
587
0
                                     path.NativeString());
588
589
0
  return true;
590
0
}
591
592
bool HandleConvertCommand(std::vector<std::string> const& args,
593
                          cmExecutionStatus& status)
594
0
{
595
#if defined(_WIN32) && !defined(__CYGWIN__)
596
  auto const pathSep = ";"_s;
597
#else
598
0
  auto const pathSep = ":"_s;
599
0
#endif
600
0
  auto const cmakePath = "TO_CMAKE_PATH_LIST"_s;
601
0
  auto const nativePath = "TO_NATIVE_PATH_LIST"_s;
602
603
0
  if (args.size() < 4 || args.size() > 5) {
604
0
    status.SetError("CONVERT must be called with three or four arguments.");
605
0
    return false;
606
0
  }
607
608
0
  auto const& action = args[2];
609
610
0
  if (action != cmakePath && action != nativePath) {
611
0
    status.SetError(
612
0
      cmStrCat("CONVERT called with an unknown action: ", action, '.'));
613
0
    return false;
614
0
  }
615
616
0
  if (args[3].empty()) {
617
0
    status.SetError("Invalid name for output variable.");
618
0
    return false;
619
0
  }
620
621
0
  static NormalizeParser const parser;
622
623
0
  auto const arguments = parser.Parse<4>(args);
624
625
0
  if (!parser.GetInputs().empty()) {
626
0
    status.SetError("CONVERT called with unexpected arguments.");
627
0
    return false;
628
0
  }
629
630
0
  cmList paths;
631
632
0
  if (action == cmakePath) {
633
0
    paths = cmSystemTools::SplitString(args[1], pathSep.front());
634
0
  } else {
635
0
    paths.assign(args[1]);
636
0
  }
637
638
0
  for (auto& path : paths) {
639
0
    auto p = cmCMakePath(path,
640
0
                         action == cmakePath ? cmCMakePath::native_format
641
0
                                             : cmCMakePath::generic_format);
642
0
    if (arguments.Normalize) {
643
0
      p = p.Normal();
644
0
    }
645
0
    if (action == cmakePath) {
646
0
      path = p.GenericString();
647
0
    } else {
648
0
      path = p.NativeString();
649
0
    }
650
0
  }
651
652
0
  auto value = action == cmakePath ? paths.to_string() : paths.join(pathSep);
653
0
  status.GetMakefile().AddDefinition(args[3], value);
654
655
0
  return true;
656
0
}
657
658
bool HandleCompareCommand(std::vector<std::string> const& args,
659
                          cmExecutionStatus& status)
660
0
{
661
0
  if (args.size() != 5) {
662
0
    status.SetError("COMPARE must be called with four arguments.");
663
0
    return false;
664
0
  }
665
666
0
  static std::map<cm::string_view,
667
0
                  std::function<bool(cmCMakePath const&,
668
0
                                     cmCMakePath const&)>> const operators{
669
0
    { "EQUAL"_s,
670
0
      [](cmCMakePath const& path1, cmCMakePath const& path2) -> bool {
671
0
        return path1 == path2;
672
0
      } },
673
0
    { "NOT_EQUAL"_s,
674
0
      [](cmCMakePath const& path1, cmCMakePath const& path2) -> bool {
675
0
        return path1 != path2;
676
0
      } }
677
0
  };
678
679
0
  auto const op = operators.find(args[2]);
680
0
  if (op == operators.end()) {
681
0
    status.SetError(cmStrCat(
682
0
      "COMPARE called with an unknown comparison operator: ", args[2], '.'));
683
0
    return false;
684
0
  }
685
686
0
  if (args[4].empty()) {
687
0
    status.SetError("Invalid name for output variable.");
688
0
    return false;
689
0
  }
690
691
0
  cmCMakePath path1(args[1]);
692
0
  cmCMakePath path2(args[3]);
693
0
  auto result = op->second(path1, path2);
694
695
0
  status.GetMakefile().AddDefinitionBool(args[4], result);
696
697
0
  return true;
698
0
}
699
700
bool HandleHasItemCommand(
701
  std::vector<std::string> const& args, cmExecutionStatus& status,
702
  std::function<bool(cmCMakePath const&)> const& has_item)
703
0
{
704
0
  if (args.size() != 3) {
705
0
    status.SetError(
706
0
      cmStrCat(args.front(), " must be called with two arguments."));
707
0
    return false;
708
0
  }
709
710
0
  std::string inputPath;
711
0
  if (!getInputPath(args[1], status, inputPath)) {
712
0
    return false;
713
0
  }
714
715
0
  if (args[2].empty()) {
716
0
    status.SetError("Invalid name for output variable.");
717
0
    return false;
718
0
  }
719
720
0
  cmCMakePath path(inputPath);
721
0
  auto result = has_item(path);
722
723
0
  status.GetMakefile().AddDefinitionBool(args[2], result);
724
725
0
  return true;
726
0
}
727
728
bool HandleHasRootNameCommand(std::vector<std::string> const& args,
729
                              cmExecutionStatus& status)
730
0
{
731
0
  return HandleHasItemCommand(
732
0
    args, status,
733
0
    [](cmCMakePath const& path) -> bool { return path.HasRootName(); });
734
0
}
735
736
bool HandleHasRootDirectoryCommand(std::vector<std::string> const& args,
737
                                   cmExecutionStatus& status)
738
0
{
739
0
  return HandleHasItemCommand(
740
0
    args, status,
741
0
    [](cmCMakePath const& path) -> bool { return path.HasRootDirectory(); });
742
0
}
743
744
bool HandleHasRootPathCommand(std::vector<std::string> const& args,
745
                              cmExecutionStatus& status)
746
0
{
747
0
  return HandleHasItemCommand(
748
0
    args, status,
749
0
    [](cmCMakePath const& path) -> bool { return path.HasRootPath(); });
750
0
}
751
752
bool HandleHasFilenameCommand(std::vector<std::string> const& args,
753
                              cmExecutionStatus& status)
754
0
{
755
0
  return HandleHasItemCommand(
756
0
    args, status,
757
0
    [](cmCMakePath const& path) -> bool { return path.HasFileName(); });
758
0
}
759
760
bool HandleHasExtensionCommand(std::vector<std::string> const& args,
761
                               cmExecutionStatus& status)
762
0
{
763
0
  return HandleHasItemCommand(
764
0
    args, status,
765
0
    [](cmCMakePath const& path) -> bool { return path.HasExtension(); });
766
0
}
767
768
bool HandleHasStemCommand(std::vector<std::string> const& args,
769
                          cmExecutionStatus& status)
770
0
{
771
0
  return HandleHasItemCommand(
772
0
    args, status,
773
0
    [](cmCMakePath const& path) -> bool { return path.HasStem(); });
774
0
}
775
776
bool HandleHasRelativePartCommand(std::vector<std::string> const& args,
777
                                  cmExecutionStatus& status)
778
0
{
779
0
  return HandleHasItemCommand(
780
0
    args, status,
781
0
    [](cmCMakePath const& path) -> bool { return path.HasRelativePath(); });
782
0
}
783
784
bool HandleHasParentPathCommand(std::vector<std::string> const& args,
785
                                cmExecutionStatus& status)
786
0
{
787
0
  return HandleHasItemCommand(
788
0
    args, status,
789
0
    [](cmCMakePath const& path) -> bool { return path.HasParentPath(); });
790
0
}
791
792
bool HandleIsAbsoluteCommand(std::vector<std::string> const& args,
793
                             cmExecutionStatus& status)
794
0
{
795
0
  if (args.size() != 3) {
796
0
    status.SetError("IS_ABSOLUTE must be called with two arguments.");
797
0
    return false;
798
0
  }
799
800
0
  std::string inputPath;
801
0
  if (!getInputPath(args[1], status, inputPath)) {
802
0
    return false;
803
0
  }
804
805
0
  if (args[2].empty()) {
806
0
    status.SetError("Invalid name for output variable.");
807
0
    return false;
808
0
  }
809
810
0
  bool isAbsolute = cmCMakePath(inputPath).IsAbsolute();
811
812
0
  status.GetMakefile().AddDefinitionBool(args[2], isAbsolute);
813
814
0
  return true;
815
0
}
816
817
bool HandleIsRelativeCommand(std::vector<std::string> const& args,
818
                             cmExecutionStatus& status)
819
0
{
820
0
  if (args.size() != 3) {
821
0
    status.SetError("IS_RELATIVE must be called with two arguments.");
822
0
    return false;
823
0
  }
824
825
0
  std::string inputPath;
826
0
  if (!getInputPath(args[1], status, inputPath)) {
827
0
    return false;
828
0
  }
829
830
0
  if (args[2].empty()) {
831
0
    status.SetError("Invalid name for output variable.");
832
0
    return false;
833
0
  }
834
835
0
  bool isRelative = cmCMakePath(inputPath).IsRelative();
836
837
0
  status.GetMakefile().AddDefinitionBool(args[2], isRelative);
838
839
0
  return true;
840
0
}
841
842
bool HandleIsPrefixCommand(std::vector<std::string> const& args,
843
                           cmExecutionStatus& status)
844
0
{
845
0
  if (args.size() < 4 || args.size() > 5) {
846
0
    status.SetError("IS_PREFIX must be called with three or four arguments.");
847
0
    return false;
848
0
  }
849
850
0
  static NormalizeParser const parser;
851
852
0
  auto const arguments = parser.Parse(args);
853
854
0
  if (parser.GetInputs().size() != 2) {
855
0
    status.SetError("IS_PREFIX called with unexpected arguments.");
856
0
    return false;
857
0
  }
858
859
0
  std::string inputPath;
860
0
  if (!getInputPath(args[1], status, inputPath)) {
861
0
    return false;
862
0
  }
863
864
0
  auto const& input = parser.GetInputs().front();
865
0
  auto const& output = parser.GetInputs().back();
866
867
0
  if (output.empty()) {
868
0
    status.SetError("Invalid name for output variable.");
869
0
    return false;
870
0
  }
871
872
0
  bool isPrefix;
873
0
  if (arguments.Normalize) {
874
0
    isPrefix =
875
0
      cmCMakePath(inputPath).Normal().IsPrefix(cmCMakePath(input).Normal());
876
0
  } else {
877
0
    isPrefix = cmCMakePath(inputPath).IsPrefix(input);
878
0
  }
879
880
0
  status.GetMakefile().AddDefinitionBool(output, isPrefix);
881
882
0
  return true;
883
0
}
884
885
bool HandleHashCommand(std::vector<std::string> const& args,
886
                       cmExecutionStatus& status)
887
0
{
888
0
  if (args.size() != 3) {
889
0
    status.SetError("HASH must be called with two arguments.");
890
0
    return false;
891
0
  }
892
893
0
  std::string inputPath;
894
0
  if (!getInputPath(args[1], status, inputPath)) {
895
0
    return false;
896
0
  }
897
898
0
  auto const& output = args[2];
899
900
0
  if (output.empty()) {
901
0
    status.SetError("Invalid name for output variable.");
902
0
    return false;
903
0
  }
904
905
0
  auto hash = hash_value(cmCMakePath(inputPath).Normal());
906
907
0
  std::ostringstream out;
908
0
  out << std::setbase(16) << hash;
909
910
0
  status.GetMakefile().AddDefinition(output, out.str());
911
912
0
  return true;
913
0
}
914
} // anonymous namespace
915
916
bool cmCMakePathCommand(std::vector<std::string> const& args,
917
                        cmExecutionStatus& status)
918
0
{
919
0
  if (args.size() < 2) {
920
0
    status.SetError("must be called with at least two arguments.");
921
0
    return false;
922
0
  }
923
924
0
  static cmSubcommandTable const subcommand{
925
0
    { "GET"_s, HandleGetCommand },
926
0
    { "SET"_s, HandleSetCommand },
927
0
    { "APPEND"_s, HandleAppendCommand },
928
0
    { "APPEND_STRING"_s, HandleAppendStringCommand },
929
0
    { "REMOVE_FILENAME"_s, HandleRemoveFilenameCommand },
930
0
    { "REPLACE_FILENAME"_s, HandleReplaceFilenameCommand },
931
0
    { "REMOVE_EXTENSION"_s, HandleRemoveExtensionCommand },
932
0
    { "REPLACE_EXTENSION"_s, HandleReplaceExtensionCommand },
933
0
    { "NORMAL_PATH"_s, HandleNormalPathCommand },
934
0
    { "RELATIVE_PATH"_s, HandleRelativePathCommand },
935
0
    { "ABSOLUTE_PATH"_s, HandleAbsolutePathCommand },
936
0
    { "NATIVE_PATH"_s, HandleNativePathCommand },
937
0
    { "CONVERT"_s, HandleConvertCommand },
938
0
    { "COMPARE"_s, HandleCompareCommand },
939
0
    { "HAS_ROOT_NAME"_s, HandleHasRootNameCommand },
940
0
    { "HAS_ROOT_DIRECTORY"_s, HandleHasRootDirectoryCommand },
941
0
    { "HAS_ROOT_PATH"_s, HandleHasRootPathCommand },
942
0
    { "HAS_FILENAME"_s, HandleHasFilenameCommand },
943
0
    { "HAS_EXTENSION"_s, HandleHasExtensionCommand },
944
0
    { "HAS_STEM"_s, HandleHasStemCommand },
945
0
    { "HAS_RELATIVE_PART"_s, HandleHasRelativePartCommand },
946
0
    { "HAS_PARENT_PATH"_s, HandleHasParentPathCommand },
947
0
    { "IS_ABSOLUTE"_s, HandleIsAbsoluteCommand },
948
0
    { "IS_RELATIVE"_s, HandleIsRelativeCommand },
949
0
    { "IS_PREFIX"_s, HandleIsPrefixCommand },
950
0
    { "HASH"_s, HandleHashCommand }
951
0
  };
952
953
0
  return subcommand(args[0], args, status);
954
0
}