| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmCMakePathCommand.h"
- #include <algorithm>
- #include <functional>
- #include <iomanip>
- #include <map>
- #include <sstream>
- #include <string>
- #include <utility>
- #include <vector>
- #include <cm/string_view>
- #include <cmext/string_view>
- #include "cmArgumentParser.h"
- #include "cmCMakePath.h"
- #include "cmExecutionStatus.h"
- #include "cmMakefile.h"
- #include "cmProperty.h"
- #include "cmRange.h"
- #include "cmStringAlgorithms.h"
- #include "cmSubcommandTable.h"
- #include "cmSystemTools.h"
- namespace {
- // Helper classes for argument parsing
- template <typename Result>
- class CMakePathArgumentParser : public cmArgumentParser<Result>
- {
- public:
- CMakePathArgumentParser()
- : cmArgumentParser<Result>()
- {
- }
- template <typename T>
- CMakePathArgumentParser& Bind(cm::static_string_view name, T Result::*member)
- {
- this->cmArgumentParser<Result>::Bind(name, member);
- return *this;
- }
- template <int Advance = 2>
- Result Parse(std::vector<std::string> const& args,
- std::vector<std::string>* keywordsMissingValue = nullptr,
- std::vector<std::string>* parsedKeywords = nullptr) const
- {
- this->Inputs.clear();
- return this->cmArgumentParser<Result>::Parse(
- cmMakeRange(args).advance(Advance), &this->Inputs, keywordsMissingValue,
- parsedKeywords);
- }
- const std::vector<std::string>& GetInputs() const { return this->Inputs; }
- protected:
- mutable std::vector<std::string> Inputs;
- };
- // OUTPUT_VARIABLE is expected
- template <typename Result>
- class ArgumentParserWithOutputVariable : public CMakePathArgumentParser<Result>
- {
- public:
- ArgumentParserWithOutputVariable()
- : CMakePathArgumentParser<Result>()
- {
- this->Bind("OUTPUT_VARIABLE"_s, &Result::Output);
- }
- template <typename T>
- ArgumentParserWithOutputVariable& Bind(cm::static_string_view name,
- T Result::*member)
- {
- this->cmArgumentParser<Result>::Bind(name, member);
- return *this;
- }
- template <int Advance = 2>
- Result Parse(std::vector<std::string> const& args) const
- {
- this->KeywordsMissingValue.clear();
- this->ParsedKeywords.clear();
- return this->CMakePathArgumentParser<Result>::template Parse<Advance>(
- args, &this->KeywordsMissingValue, &this->ParsedKeywords);
- }
- const std::vector<std::string>& GetKeywordsMissingValue() const
- {
- return this->KeywordsMissingValue;
- }
- const std::vector<std::string>& GetParsedKeywords() const
- {
- return this->ParsedKeywords;
- }
- bool checkOutputVariable(const Result& arguments,
- cmExecutionStatus& status) const
- {
- if (std::find(this->GetKeywordsMissingValue().begin(),
- this->GetKeywordsMissingValue().end(),
- "OUTPUT_VARIABLE"_s) !=
- this->GetKeywordsMissingValue().end()) {
- status.SetError("OUTPUT_VARIABLE requires an argument.");
- return false;
- }
- if (std::find(this->GetParsedKeywords().begin(),
- this->GetParsedKeywords().end(),
- "OUTPUT_VARIABLE"_s) != this->GetParsedKeywords().end() &&
- arguments.Output.empty()) {
- status.SetError("Invalid name for output variable.");
- return false;
- }
- return true;
- }
- private:
- mutable std::vector<std::string> KeywordsMissingValue;
- mutable std::vector<std::string> ParsedKeywords;
- };
- struct OutputVariable
- {
- std::string Output;
- };
- // Usable when OUTPUT_VARIABLE is the only option
- class OutputVariableParser
- : public ArgumentParserWithOutputVariable<OutputVariable>
- {
- };
- struct NormalizeOption
- {
- bool Normalize = false;
- };
- // Usable when NORMALIZE is the only option
- class NormalizeParser : public CMakePathArgumentParser<NormalizeOption>
- {
- public:
- NormalizeParser() { this->Bind("NORMALIZE"_s, &NormalizeOption::Normalize); }
- };
- // retrieve value of input path from specified variable
- bool getInputPath(const std::string& arg, cmExecutionStatus& status,
- std::string& path)
- {
- cmProp def = status.GetMakefile().GetDefinition(arg);
- if (!def) {
- status.SetError("undefined variable for input path.");
- return false;
- }
- path = *def;
- return true;
- }
- bool HandleGetCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- static std::map<cm::string_view,
- std::function<cmCMakePath(const cmCMakePath&, bool)>> const
- actions{ { "ROOT_NAME"_s,
- [](const cmCMakePath& path, bool) -> cmCMakePath {
- return path.GetRootName();
- } },
- { "ROOT_DIRECTORY"_s,
- [](const cmCMakePath& path, bool) -> cmCMakePath {
- return path.GetRootDirectory();
- } },
- { "ROOT_PATH"_s,
- [](const cmCMakePath& path, bool) -> cmCMakePath {
- return path.GetRootPath();
- } },
- { "FILENAME"_s,
- [](const cmCMakePath& path, bool) -> cmCMakePath {
- return path.GetFileName();
- } },
- { "EXTENSION"_s,
- [](const cmCMakePath& path, bool last_only) -> cmCMakePath {
- if (last_only) {
- return path.GetExtension();
- }
- return path.GetWideExtension();
- } },
- { "STEM"_s,
- [](const cmCMakePath& path, bool last_only) -> cmCMakePath {
- if (last_only) {
- return path.GetStem();
- }
- return path.GetNarrowStem();
- } },
- { "RELATIVE_PART"_s,
- [](const cmCMakePath& path, bool) -> cmCMakePath {
- return path.GetRelativePath();
- } },
- { "PARENT_PATH"_s,
- [](const cmCMakePath& path, bool) -> cmCMakePath {
- return path.GetParentPath();
- } } };
- if (args.size() < 4) {
- status.SetError("GET must be called with at least three arguments.");
- return false;
- }
- const auto& action = args[2];
- if (actions.find(action) == actions.end()) {
- status.SetError(
- cmStrCat("GET called with an unknown action: ", action, "."));
- return false;
- }
- struct Arguments
- {
- bool LastOnly = false;
- };
- CMakePathArgumentParser<Arguments> parser;
- if ((action == "EXTENSION"_s || action == "STEM"_s)) {
- parser.Bind("LAST_ONLY"_s, &Arguments::LastOnly);
- }
- Arguments const arguments = parser.Parse<3>(args);
- if (parser.GetInputs().size() != 1) {
- status.SetError("GET called with unexpected arguments.");
- return false;
- }
- if (parser.GetInputs().front().empty()) {
- status.SetError("Invalid name for output variable.");
- return false;
- }
- std::string path;
- if (!getInputPath(args[1], status, path)) {
- return false;
- }
- auto result = actions.at(action)(path, arguments.LastOnly);
- status.GetMakefile().AddDefinition(parser.GetInputs().front(),
- result.String());
- return true;
- }
- bool HandleSetCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- if (args.size() < 3 || args.size() > 4) {
- status.SetError("SET must be called with two or three arguments.");
- return false;
- }
- if (args[1].empty()) {
- status.SetError("Invalid name for path variable.");
- return false;
- }
- static NormalizeParser const parser;
- const auto arguments = parser.Parse(args);
- if (parser.GetInputs().size() != 1) {
- status.SetError("SET called with unexpected arguments.");
- return false;
- }
- auto path =
- cmCMakePath(parser.GetInputs().front(), cmCMakePath::native_format);
- if (arguments.Normalize) {
- path = path.Normal();
- }
- status.GetMakefile().AddDefinition(args[1], path.GenericString());
- return true;
- }
- bool HandleAppendCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- if (args[1].empty()) {
- status.SetError("Invalid name for path variable.");
- return false;
- }
- static OutputVariableParser const parser{};
- const auto arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
- }
- cmCMakePath path(status.GetMakefile().GetSafeDefinition(args[1]));
- for (const auto& input : parser.GetInputs()) {
- path /= input;
- }
- status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
- return true;
- }
- bool HandleAppendStringCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- static OutputVariableParser const parser{};
- const auto arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
- }
- std::string inputPath;
- if (!getInputPath(args[1], status, inputPath)) {
- return false;
- }
- cmCMakePath path(inputPath);
- for (const auto& input : parser.GetInputs()) {
- path += input;
- }
- status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
- return true;
- }
- bool HandleRemoveFilenameCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- static OutputVariableParser const parser{};
- const auto arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
- }
- if (!parser.GetInputs().empty()) {
- status.SetError("REMOVE_FILENAME called with unexpected arguments.");
- return false;
- }
- std::string inputPath;
- if (!getInputPath(args[1], status, inputPath)) {
- return false;
- }
- cmCMakePath path(inputPath);
- path.RemoveFileName();
- status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
- return true;
- }
- bool HandleReplaceFilenameCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- static OutputVariableParser const parser{};
- const auto arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
- }
- if (parser.GetInputs().size() > 1) {
- status.SetError("REPLACE_FILENAME called with unexpected arguments.");
- return false;
- }
- std::string inputPath;
- if (!getInputPath(args[1], status, inputPath)) {
- return false;
- }
- cmCMakePath path(inputPath);
- path.ReplaceFileName(
- parser.GetInputs().empty() ? "" : parser.GetInputs().front());
- status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
- return true;
- }
- bool HandleRemoveExtensionCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- struct Arguments
- {
- std::string Output;
- bool LastOnly = false;
- };
- static auto const parser =
- ArgumentParserWithOutputVariable<Arguments>{}.Bind("LAST_ONLY"_s,
- &Arguments::LastOnly);
- Arguments const arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
- }
- if (!parser.GetInputs().empty()) {
- status.SetError("REMOVE_EXTENSION called with unexpected arguments.");
- return false;
- }
- std::string inputPath;
- if (!getInputPath(args[1], status, inputPath)) {
- return false;
- }
- cmCMakePath path(inputPath);
- if (arguments.LastOnly) {
- path.RemoveExtension();
- } else {
- path.RemoveWideExtension();
- }
- status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
- return true;
- }
- bool HandleReplaceExtensionCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- struct Arguments
- {
- std::string Output;
- bool LastOnly = false;
- };
- static auto const parser =
- ArgumentParserWithOutputVariable<Arguments>{}.Bind("LAST_ONLY"_s,
- &Arguments::LastOnly);
- Arguments const arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
- }
- if (parser.GetInputs().size() > 1) {
- status.SetError("REPLACE_EXTENSION called with unexpected arguments.");
- return false;
- }
- std::string inputPath;
- if (!getInputPath(args[1], status, inputPath)) {
- return false;
- }
- cmCMakePath path(inputPath);
- cmCMakePath extension(
- parser.GetInputs().empty() ? "" : parser.GetInputs().front());
- if (arguments.LastOnly) {
- path.ReplaceExtension(extension);
- } else {
- path.ReplaceWideExtension(extension);
- }
- status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
- return true;
- }
- bool HandleNormalPathCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- static OutputVariableParser const parser{};
- const auto arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
- }
- if (!parser.GetInputs().empty()) {
- status.SetError("NORMAL_PATH called with unexpected arguments.");
- return false;
- }
- std::string inputPath;
- if (!getInputPath(args[1], status, inputPath)) {
- return false;
- }
- auto path = cmCMakePath(inputPath).Normal();
- status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
- return true;
- }
- bool HandleTransformPathCommand(
- std::vector<std::string> const& args, cmExecutionStatus& status,
- const std::function<cmCMakePath(const cmCMakePath&,
- const std::string& base)>& transform,
- bool normalizeOption = false)
- {
- struct Arguments
- {
- std::string Output;
- std::string BaseDirectory;
- bool Normalize = false;
- };
- auto parser = ArgumentParserWithOutputVariable<Arguments>{}.Bind(
- "BASE_DIRECTORY"_s, &Arguments::BaseDirectory);
- if (normalizeOption) {
- parser.Bind("NORMALIZE"_s, &Arguments::Normalize);
- }
- Arguments arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
- }
- if (!parser.GetInputs().empty()) {
- status.SetError(cmStrCat(args[0], " called with unexpected arguments."));
- return false;
- }
- if (std::find(parser.GetKeywordsMissingValue().begin(),
- parser.GetKeywordsMissingValue().end(), "BASE_DIRECTORY"_s) !=
- parser.GetKeywordsMissingValue().end()) {
- status.SetError("BASE_DIRECTORY requires an argument.");
- return false;
- }
- if (std::find(parser.GetParsedKeywords().begin(),
- parser.GetParsedKeywords().end(),
- "BASE_DIRECTORY"_s) == parser.GetParsedKeywords().end()) {
- arguments.BaseDirectory = status.GetMakefile().GetCurrentSourceDirectory();
- }
- std::string inputPath;
- if (!getInputPath(args[1], status, inputPath)) {
- return false;
- }
- auto path = transform(cmCMakePath(inputPath), arguments.BaseDirectory);
- if (arguments.Normalize) {
- path = path.Normal();
- }
- status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
- return true;
- }
- bool HandleRelativePathCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- return HandleTransformPathCommand(
- args, status,
- [](const cmCMakePath& path, const std::string& base) -> cmCMakePath {
- return path.Relative(base);
- });
- }
- bool HandleAbsolutePathCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- return HandleTransformPathCommand(
- args, status,
- [](const cmCMakePath& path, const std::string& base) -> cmCMakePath {
- return path.Absolute(base);
- },
- true);
- }
- bool HandleNativePathCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- if (args.size() < 3 || args.size() > 4) {
- status.SetError("NATIVE_PATH must be called with two or three arguments.");
- return false;
- }
- static NormalizeParser const parser;
- const auto arguments = parser.Parse(args);
- if (parser.GetInputs().size() != 1) {
- status.SetError("NATIVE_PATH called with unexpected arguments.");
- return false;
- }
- if (parser.GetInputs().front().empty()) {
- status.SetError("Invalid name for output variable.");
- return false;
- }
- std::string inputPath;
- if (!getInputPath(args[1], status, inputPath)) {
- return false;
- }
- cmCMakePath path(inputPath);
- if (arguments.Normalize) {
- path = path.Normal();
- }
- status.GetMakefile().AddDefinition(parser.GetInputs().front(),
- path.NativeString());
- return true;
- }
- bool HandleConvertCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- #if defined(_WIN32) && !defined(__CYGWIN__)
- const auto pathSep = ";"_s;
- #else
- const auto pathSep = ":"_s;
- #endif
- const auto cmakePath = "TO_CMAKE_PATH_LIST"_s;
- const auto nativePath = "TO_NATIVE_PATH_LIST"_s;
- if (args.size() < 4 || args.size() > 5) {
- status.SetError("CONVERT must be called with three or four arguments.");
- return false;
- }
- const auto& action = args[2];
- if (action != cmakePath && action != nativePath) {
- status.SetError(
- cmStrCat("CONVERT called with an unknown action: ", action, "."));
- return false;
- }
- if (args[3].empty()) {
- status.SetError("Invalid name for output variable.");
- return false;
- }
- static NormalizeParser const parser;
- const auto arguments = parser.Parse<4>(args);
- if (!parser.GetInputs().empty()) {
- status.SetError("CONVERT called with unexpected arguments.");
- return false;
- }
- std::vector<std::string> paths;
- if (action == cmakePath) {
- paths = cmSystemTools::SplitString(args[1], pathSep.front());
- } else {
- cmExpandList(args[1], paths);
- }
- for (auto& path : paths) {
- auto p = cmCMakePath(path,
- action == cmakePath ? cmCMakePath::native_format
- : cmCMakePath::generic_format);
- if (arguments.Normalize) {
- p = p.Normal();
- }
- if (action == cmakePath) {
- path = p.GenericString();
- } else {
- path = p.NativeString();
- }
- }
- auto value = cmJoin(paths, action == cmakePath ? ";"_s : pathSep);
- status.GetMakefile().AddDefinition(args[3], value);
- return true;
- }
- bool HandleCompareCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- if (args.size() != 5) {
- status.SetError("COMPARE must be called with four arguments.");
- return false;
- }
- static std::map<cm::string_view,
- std::function<bool(const cmCMakePath&,
- const cmCMakePath&)>> const operators{
- { "EQUAL"_s,
- [](const cmCMakePath& path1, const cmCMakePath& path2) -> bool {
- return path1 == path2;
- } },
- { "NOT_EQUAL"_s,
- [](const cmCMakePath& path1, const cmCMakePath& path2) -> bool {
- return path1 != path2;
- } }
- };
- const auto op = operators.find(args[2]);
- if (op == operators.end()) {
- status.SetError(cmStrCat(
- "COMPARE called with an unknown comparison operator: ", args[2], "."));
- return false;
- }
- if (args[4].empty()) {
- status.SetError("Invalid name for output variable.");
- return false;
- }
- cmCMakePath path1(args[1]);
- cmCMakePath path2(args[3]);
- auto result = op->second(path1, path2);
- status.GetMakefile().AddDefinitionBool(args[4], result);
- return true;
- }
- bool HandleHasItemCommand(
- std::vector<std::string> const& args, cmExecutionStatus& status,
- const std::function<bool(const cmCMakePath&)>& has_item)
- {
- if (args.size() != 3) {
- status.SetError(
- cmStrCat(args.front(), " must be called with two arguments."));
- return false;
- }
- std::string inputPath;
- if (!getInputPath(args[1], status, inputPath)) {
- return false;
- }
- if (args[2].empty()) {
- status.SetError("Invalid name for output variable.");
- return false;
- }
- cmCMakePath path(inputPath);
- auto result = has_item(path);
- status.GetMakefile().AddDefinitionBool(args[2], result);
- return true;
- }
- bool HandleHasRootNameCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- return HandleHasItemCommand(
- args, status,
- [](const cmCMakePath& path) -> bool { return path.HasRootName(); });
- }
- bool HandleHasRootDirectoryCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- return HandleHasItemCommand(
- args, status,
- [](const cmCMakePath& path) -> bool { return path.HasRootDirectory(); });
- }
- bool HandleHasRootPathCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- return HandleHasItemCommand(
- args, status,
- [](const cmCMakePath& path) -> bool { return path.HasRootPath(); });
- }
- bool HandleHasFilenameCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- return HandleHasItemCommand(
- args, status,
- [](const cmCMakePath& path) -> bool { return path.HasFileName(); });
- }
- bool HandleHasExtensionCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- return HandleHasItemCommand(
- args, status,
- [](const cmCMakePath& path) -> bool { return path.HasExtension(); });
- }
- bool HandleHasStemCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- return HandleHasItemCommand(
- args, status,
- [](const cmCMakePath& path) -> bool { return path.HasStem(); });
- }
- bool HandleHasRelativePartCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- return HandleHasItemCommand(
- args, status,
- [](const cmCMakePath& path) -> bool { return path.HasRelativePath(); });
- }
- bool HandleHasParentPathCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- return HandleHasItemCommand(
- args, status,
- [](const cmCMakePath& path) -> bool { return path.HasParentPath(); });
- }
- bool HandleIsAbsoluteCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- if (args.size() != 3) {
- status.SetError("IS_ABSOLUTE must be called with two arguments.");
- return false;
- }
- std::string inputPath;
- if (!getInputPath(args[1], status, inputPath)) {
- return false;
- }
- if (args[2].empty()) {
- status.SetError("Invalid name for output variable.");
- return false;
- }
- bool isAbsolute = cmCMakePath(inputPath).IsAbsolute();
- status.GetMakefile().AddDefinitionBool(args[2], isAbsolute);
- return true;
- }
- bool HandleIsRelativeCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- if (args.size() != 3) {
- status.SetError("IS_RELATIVE must be called with two arguments.");
- return false;
- }
- std::string inputPath;
- if (!getInputPath(args[1], status, inputPath)) {
- return false;
- }
- if (args[2].empty()) {
- status.SetError("Invalid name for output variable.");
- return false;
- }
- bool isRelative = cmCMakePath(inputPath).IsRelative();
- status.GetMakefile().AddDefinitionBool(args[2], isRelative);
- return true;
- }
- bool HandleIsPrefixCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- if (args.size() < 4 || args.size() > 5) {
- status.SetError("IS_PREFIX must be called with three or four arguments.");
- return false;
- }
- static NormalizeParser const parser;
- const auto arguments = parser.Parse(args);
- if (parser.GetInputs().size() != 2) {
- status.SetError("IS_PREFIX called with unexpected arguments.");
- return false;
- }
- std::string inputPath;
- if (!getInputPath(args[1], status, inputPath)) {
- return false;
- }
- const auto& input = parser.GetInputs().front();
- const auto& output = parser.GetInputs().back();
- if (output.empty()) {
- status.SetError("Invalid name for output variable.");
- return false;
- }
- bool isPrefix;
- if (arguments.Normalize) {
- isPrefix =
- cmCMakePath(inputPath).Normal().IsPrefix(cmCMakePath(input).Normal());
- } else {
- isPrefix = cmCMakePath(inputPath).IsPrefix(input);
- }
- status.GetMakefile().AddDefinitionBool(output, isPrefix);
- return true;
- }
- bool HandleHashCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- if (args.size() != 3) {
- status.SetError("HASH must be called with two arguments.");
- return false;
- }
- std::string inputPath;
- if (!getInputPath(args[1], status, inputPath)) {
- return false;
- }
- const auto& output = args[2];
- if (output.empty()) {
- status.SetError("Invalid name for output variable.");
- return false;
- }
- auto hash = hash_value(cmCMakePath(inputPath).Normal());
- std::ostringstream out;
- out << std::setbase(16) << hash;
- status.GetMakefile().AddDefinition(output, out.str());
- return true;
- }
- } // anonymous namespace
- bool cmCMakePathCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- if (args.size() < 2) {
- status.SetError("must be called with at least two arguments.");
- return false;
- }
- static cmSubcommandTable const subcommand{
- { "GET"_s, HandleGetCommand },
- { "SET"_s, HandleSetCommand },
- { "APPEND"_s, HandleAppendCommand },
- { "APPEND_STRING"_s, HandleAppendStringCommand },
- { "REMOVE_FILENAME"_s, HandleRemoveFilenameCommand },
- { "REPLACE_FILENAME"_s, HandleReplaceFilenameCommand },
- { "REMOVE_EXTENSION"_s, HandleRemoveExtensionCommand },
- { "REPLACE_EXTENSION"_s, HandleReplaceExtensionCommand },
- { "NORMAL_PATH"_s, HandleNormalPathCommand },
- { "RELATIVE_PATH"_s, HandleRelativePathCommand },
- { "ABSOLUTE_PATH"_s, HandleAbsolutePathCommand },
- { "NATIVE_PATH"_s, HandleNativePathCommand },
- { "CONVERT"_s, HandleConvertCommand },
- { "COMPARE"_s, HandleCompareCommand },
- { "HAS_ROOT_NAME"_s, HandleHasRootNameCommand },
- { "HAS_ROOT_DIRECTORY"_s, HandleHasRootDirectoryCommand },
- { "HAS_ROOT_PATH"_s, HandleHasRootPathCommand },
- { "HAS_FILENAME"_s, HandleHasFilenameCommand },
- { "HAS_EXTENSION"_s, HandleHasExtensionCommand },
- { "HAS_STEM"_s, HandleHasStemCommand },
- { "HAS_RELATIVE_PART"_s, HandleHasRelativePartCommand },
- { "HAS_PARENT_PATH"_s, HandleHasParentPathCommand },
- { "IS_ABSOLUTE"_s, HandleIsAbsoluteCommand },
- { "IS_RELATIVE"_s, HandleIsRelativeCommand },
- { "IS_PREFIX"_s, HandleIsPrefixCommand },
- { "HASH"_s, HandleHashCommand }
- };
- return subcommand(args[0], args, status);
- }
|