/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 | } |