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