mirror of
https://github.com/Kitware/CMake.git
synced 2026-04-24 15:18:26 -05:00
Merge topic 'command-arg-parser-result'
8a18e82e95cmCMakePathCommand: Report keyword errors via argument parser results7e4a9afa1acmCMakeHost*Command: Report keyword errors via argument parser results74ec6b63c2cmFileCommand: Report keyword errors via argument parser resultse56108f629cmExecuteProcessCommand: Report keyword errors via argument parser resultsb7c82b26b0cmArgumentParser: Capture keyword errors in parse results50876f6b9acmArgumentParser: Add structure to capture operational results5955ec1992cmArgumentParser: Store keyword action map with explicit name119e1f7fbccmArgumentParser: Factor out common static/dynamic implementation ... Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !7488
This commit is contained in:
+42
-19
@@ -5,10 +5,13 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "cmArgumentParserTypes.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
|
||||
namespace ArgumentParser {
|
||||
|
||||
auto ActionMap::Emplace(cm::string_view name, Action action)
|
||||
auto KeywordActionMap::Emplace(cm::string_view name, KeywordAction action)
|
||||
-> std::pair<iterator, bool>
|
||||
{
|
||||
auto const it =
|
||||
@@ -21,7 +24,7 @@ auto ActionMap::Emplace(cm::string_view name, Action action)
|
||||
: std::make_pair(this->emplace(it, name, std::move(action)), true);
|
||||
}
|
||||
|
||||
auto ActionMap::Find(cm::string_view name) const -> const_iterator
|
||||
auto KeywordActionMap::Find(cm::string_view name) const -> const_iterator
|
||||
{
|
||||
auto const it =
|
||||
std::lower_bound(this->begin(), this->end(), name,
|
||||
@@ -74,20 +77,16 @@ void Instance::Bind(std::vector<std::vector<std::string>>& val)
|
||||
this->ExpectValue = false;
|
||||
}
|
||||
|
||||
void Instance::Consume(cm::string_view arg, void* result,
|
||||
std::vector<std::string>* unparsedArguments,
|
||||
std::vector<cm::string_view>* keywordsMissingValue,
|
||||
std::vector<cm::string_view>* parsedKeywords)
|
||||
void Instance::Consume(cm::string_view arg)
|
||||
{
|
||||
auto const it = this->Bindings.Find(arg);
|
||||
if (it != this->Bindings.end()) {
|
||||
if (parsedKeywords != nullptr) {
|
||||
parsedKeywords->emplace_back(it->first);
|
||||
}
|
||||
it->second(*this, result);
|
||||
if (this->ExpectValue && keywordsMissingValue != nullptr) {
|
||||
keywordsMissingValue->emplace_back(it->first);
|
||||
auto const it = this->Bindings.Keywords.Find(arg);
|
||||
if (it != this->Bindings.Keywords.end()) {
|
||||
this->FinishKeyword();
|
||||
this->Keyword = it->first;
|
||||
if (this->ParsedKeywords != nullptr) {
|
||||
this->ParsedKeywords->emplace_back(it->first);
|
||||
}
|
||||
it->second(*this);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -97,16 +96,40 @@ void Instance::Consume(cm::string_view arg, void* result,
|
||||
this->CurrentList = nullptr;
|
||||
} else if (this->CurrentList != nullptr) {
|
||||
this->CurrentList->emplace_back(arg);
|
||||
} else if (unparsedArguments != nullptr) {
|
||||
unparsedArguments->emplace_back(arg);
|
||||
} else if (this->UnparsedArguments != nullptr) {
|
||||
this->UnparsedArguments->emplace_back(arg);
|
||||
}
|
||||
|
||||
this->ExpectValue = false;
|
||||
}
|
||||
|
||||
void Instance::FinishKeyword()
|
||||
{
|
||||
if (this->Keyword.empty()) {
|
||||
return;
|
||||
}
|
||||
if (this->ExpectValue) {
|
||||
if (keywordsMissingValue != nullptr) {
|
||||
keywordsMissingValue->pop_back();
|
||||
if (this->ParseResults != nullptr) {
|
||||
this->ParseResults->AddKeywordError(this->Keyword,
|
||||
" missing required value\n");
|
||||
}
|
||||
if (this->KeywordsMissingValue != nullptr) {
|
||||
this->KeywordsMissingValue->emplace_back(this->Keyword);
|
||||
}
|
||||
this->ExpectValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ParseResult::MaybeReportError(cmMakefile& mf) const
|
||||
{
|
||||
if (*this) {
|
||||
return false;
|
||||
}
|
||||
std::string e;
|
||||
for (auto const& ke : this->KeywordErrors) {
|
||||
e = cmStrCat(e, "Error after keyword \"", ke.first, "\":\n", ke.second);
|
||||
}
|
||||
mf.IssueMessage(MessageType::FATAL_ERROR, e);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ArgumentParser
|
||||
|
||||
+133
-48
@@ -6,34 +6,116 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <cm/optional>
|
||||
#include <cm/string_view>
|
||||
#include <cm/type_traits>
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmArgumentParserTypes.h" // IWYU pragma: keep
|
||||
|
||||
template <typename Result>
|
||||
class cmArgumentParser; // IWYU pragma: keep
|
||||
|
||||
class cmMakefile;
|
||||
|
||||
namespace ArgumentParser {
|
||||
|
||||
class Instance;
|
||||
using Action = std::function<void(Instance&, void*)>;
|
||||
class ParseResult
|
||||
{
|
||||
std::map<cm::string_view, std::string> KeywordErrors;
|
||||
|
||||
// using ActionMap = cm::flat_map<cm::string_view, Action>;
|
||||
class ActionMap : public std::vector<std::pair<cm::string_view, Action>>
|
||||
public:
|
||||
explicit operator bool() const { return this->KeywordErrors.empty(); }
|
||||
|
||||
void AddKeywordError(cm::string_view key, cm::string_view text)
|
||||
|
||||
{
|
||||
this->KeywordErrors[key] += text;
|
||||
}
|
||||
|
||||
std::map<cm::string_view, std::string> const& GetKeywordErrors() const
|
||||
{
|
||||
return this->KeywordErrors;
|
||||
}
|
||||
|
||||
bool MaybeReportError(cmMakefile& mf) const;
|
||||
};
|
||||
|
||||
template <typename Result>
|
||||
typename std::enable_if<std::is_base_of<ParseResult, Result>::value,
|
||||
ParseResult*>::type
|
||||
AsParseResultPtr(Result& result)
|
||||
{
|
||||
return &result;
|
||||
}
|
||||
|
||||
template <typename Result>
|
||||
typename std::enable_if<!std::is_base_of<ParseResult, Result>::value,
|
||||
ParseResult*>::type
|
||||
AsParseResultPtr(Result&)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
class Instance;
|
||||
using KeywordAction = std::function<void(Instance&)>;
|
||||
|
||||
// using KeywordActionMap = cm::flat_map<cm::string_view, KeywordAction>;
|
||||
class KeywordActionMap
|
||||
: public std::vector<std::pair<cm::string_view, KeywordAction>>
|
||||
{
|
||||
public:
|
||||
std::pair<iterator, bool> Emplace(cm::string_view name, Action action);
|
||||
std::pair<iterator, bool> Emplace(cm::string_view name,
|
||||
KeywordAction action);
|
||||
const_iterator Find(cm::string_view name) const;
|
||||
};
|
||||
|
||||
class ActionMap
|
||||
{
|
||||
public:
|
||||
KeywordActionMap Keywords;
|
||||
};
|
||||
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
using Instance = ArgumentParser::Instance;
|
||||
using ParseResult = ArgumentParser::ParseResult;
|
||||
|
||||
ArgumentParser::ActionMap Bindings;
|
||||
|
||||
bool MaybeBind(cm::string_view name, KeywordAction action)
|
||||
{
|
||||
return this->Bindings.Keywords.Emplace(name, std::move(action)).second;
|
||||
}
|
||||
|
||||
void Bind(cm::string_view name, KeywordAction action)
|
||||
{
|
||||
bool const inserted = this->MaybeBind(name, std::move(action));
|
||||
assert(inserted);
|
||||
static_cast<void>(inserted);
|
||||
}
|
||||
};
|
||||
|
||||
class Instance
|
||||
{
|
||||
public:
|
||||
Instance(ActionMap const& bindings)
|
||||
Instance(ActionMap const& bindings, ParseResult* parseResult,
|
||||
std::vector<std::string>* unparsedArguments,
|
||||
std::vector<cm::string_view>* keywordsMissingValue,
|
||||
std::vector<cm::string_view>* parsedKeywords,
|
||||
void* result = nullptr)
|
||||
: Bindings(bindings)
|
||||
, ParseResults(parseResult)
|
||||
, UnparsedArguments(unparsedArguments)
|
||||
, KeywordsMissingValue(keywordsMissingValue)
|
||||
, ParsedKeywords(parsedKeywords)
|
||||
, Result(result)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -54,22 +136,39 @@ public:
|
||||
this->Bind(*optVal);
|
||||
}
|
||||
|
||||
void Consume(cm::string_view arg, void* result,
|
||||
std::vector<std::string>* unparsedArguments,
|
||||
std::vector<cm::string_view>* keywordsMissingValue,
|
||||
std::vector<cm::string_view>* parsedKeywords);
|
||||
template <typename Range>
|
||||
void Parse(Range const& args)
|
||||
{
|
||||
for (cm::string_view arg : args) {
|
||||
this->Consume(arg);
|
||||
}
|
||||
this->FinishKeyword();
|
||||
}
|
||||
|
||||
private:
|
||||
ActionMap const& Bindings;
|
||||
ParseResult* ParseResults = nullptr;
|
||||
std::vector<std::string>* UnparsedArguments = nullptr;
|
||||
std::vector<cm::string_view>* KeywordsMissingValue = nullptr;
|
||||
std::vector<cm::string_view>* ParsedKeywords = nullptr;
|
||||
void* Result = nullptr;
|
||||
|
||||
cm::string_view Keyword;
|
||||
std::string* CurrentString = nullptr;
|
||||
std::vector<std::string>* CurrentList = nullptr;
|
||||
bool ExpectValue = false;
|
||||
|
||||
void Consume(cm::string_view arg);
|
||||
void FinishKeyword();
|
||||
|
||||
template <typename Result>
|
||||
friend class ::cmArgumentParser;
|
||||
};
|
||||
|
||||
} // namespace ArgumentParser
|
||||
|
||||
template <typename Result>
|
||||
class cmArgumentParser
|
||||
class cmArgumentParser : private ArgumentParser::Base
|
||||
{
|
||||
public:
|
||||
// I *think* this function could be made `constexpr` when the code is
|
||||
@@ -77,28 +176,24 @@ public:
|
||||
template <typename T>
|
||||
cmArgumentParser& Bind(cm::static_string_view name, T Result::*member)
|
||||
{
|
||||
bool const inserted =
|
||||
this->Bindings
|
||||
.Emplace(name,
|
||||
[member](ArgumentParser::Instance& instance, void* result) {
|
||||
instance.Bind(static_cast<Result*>(result)->*member);
|
||||
})
|
||||
.second;
|
||||
assert(inserted), (void)inserted;
|
||||
this->Base::Bind(name, [member](Instance& instance) {
|
||||
instance.Bind(static_cast<Result*>(instance.Result)->*member);
|
||||
});
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
void Parse(Result& result, Range const& args,
|
||||
bool Parse(Result& result, Range const& args,
|
||||
std::vector<std::string>* unparsedArguments,
|
||||
std::vector<cm::string_view>* keywordsMissingValue = nullptr,
|
||||
std::vector<cm::string_view>* parsedKeywords = nullptr) const
|
||||
{
|
||||
ArgumentParser::Instance instance(this->Bindings);
|
||||
for (cm::string_view arg : args) {
|
||||
instance.Consume(arg, &result, unparsedArguments, keywordsMissingValue,
|
||||
parsedKeywords);
|
||||
}
|
||||
using ArgumentParser::AsParseResultPtr;
|
||||
ParseResult* parseResultPtr = AsParseResultPtr(result);
|
||||
Instance instance(this->Bindings, parseResultPtr, unparsedArguments,
|
||||
keywordsMissingValue, parsedKeywords, &result);
|
||||
instance.Parse(args);
|
||||
return parseResultPtr ? static_cast<bool>(*parseResultPtr) : true;
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
@@ -111,47 +206,37 @@ public:
|
||||
parsedKeywords);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
ArgumentParser::ActionMap Bindings;
|
||||
};
|
||||
|
||||
template <>
|
||||
class cmArgumentParser<void>
|
||||
class cmArgumentParser<void> : private ArgumentParser::Base
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
cmArgumentParser& Bind(cm::static_string_view name, T& ref)
|
||||
{
|
||||
bool const inserted = this->Bind(cm::string_view(name), ref);
|
||||
assert(inserted), (void)inserted;
|
||||
this->Base::Bind(name, [&ref](Instance& instance) { instance.Bind(ref); });
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
void Parse(Range const& args, std::vector<std::string>* unparsedArguments,
|
||||
std::vector<cm::string_view>* keywordsMissingValue = nullptr,
|
||||
std::vector<cm::string_view>* parsedKeywords = nullptr) const
|
||||
ParseResult Parse(
|
||||
Range const& args, std::vector<std::string>* unparsedArguments,
|
||||
std::vector<cm::string_view>* keywordsMissingValue = nullptr,
|
||||
std::vector<cm::string_view>* parsedKeywords = nullptr) const
|
||||
{
|
||||
ArgumentParser::Instance instance(this->Bindings);
|
||||
for (cm::string_view arg : args) {
|
||||
instance.Consume(arg, nullptr, unparsedArguments, keywordsMissingValue,
|
||||
parsedKeywords);
|
||||
}
|
||||
ParseResult parseResult;
|
||||
Instance instance(this->Bindings, &parseResult, unparsedArguments,
|
||||
keywordsMissingValue, parsedKeywords);
|
||||
instance.Parse(args);
|
||||
return parseResult;
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename T>
|
||||
bool Bind(cm::string_view name, T& ref)
|
||||
{
|
||||
return this->Bindings
|
||||
.Emplace(name,
|
||||
[&ref](ArgumentParser::Instance& instance, void*) {
|
||||
instance.Bind(ref);
|
||||
})
|
||||
.second;
|
||||
return this->MaybeBind(name,
|
||||
[&ref](Instance& instance) { instance.Bind(ref); });
|
||||
}
|
||||
|
||||
private:
|
||||
ArgumentParser::ActionMap Bindings;
|
||||
};
|
||||
|
||||
@@ -474,7 +474,7 @@ bool QueryWindowsRegistry(Range args, cmExecutionStatus& status,
|
||||
}
|
||||
std::string const& key = *args.begin();
|
||||
|
||||
struct Arguments
|
||||
struct Arguments : public ArgumentParser::ParseResult
|
||||
{
|
||||
std::string ValueName;
|
||||
bool ValueNames = false;
|
||||
@@ -491,19 +491,15 @@ bool QueryWindowsRegistry(Range args, cmExecutionStatus& status,
|
||||
.Bind("SEPARATOR"_s, &Arguments::Separator)
|
||||
.Bind("ERROR_VARIABLE"_s, &Arguments::ErrorVariable);
|
||||
std::vector<std::string> invalidArgs;
|
||||
std::vector<cm::string_view> keywordsMissingValue;
|
||||
|
||||
Arguments const arguments =
|
||||
parser.Parse(args.advance(1), &invalidArgs, &keywordsMissingValue);
|
||||
Arguments const arguments = parser.Parse(args.advance(1), &invalidArgs);
|
||||
if (!invalidArgs.empty()) {
|
||||
status.SetError(cmStrCat("given invalid argument(s) \"",
|
||||
cmJoin(invalidArgs, ", "_s), "\"."));
|
||||
return false;
|
||||
}
|
||||
if (!keywordsMissingValue.empty()) {
|
||||
status.SetError(cmStrCat("missing expected value for argument(s) \"",
|
||||
cmJoin(keywordsMissingValue, ", "_s), "\"."));
|
||||
return false;
|
||||
if (arguments.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
if ((!arguments.ValueName.empty() &&
|
||||
(arguments.ValueNames || arguments.SubKeys)) ||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmCMakePathCommand.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
@@ -11,6 +10,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <cm/optional>
|
||||
#include <cm/string_view>
|
||||
#include <cmext/string_view>
|
||||
|
||||
@@ -43,15 +43,12 @@ public:
|
||||
}
|
||||
|
||||
template <int Advance = 2>
|
||||
Result Parse(std::vector<std::string> const& args,
|
||||
std::vector<cm::string_view>* keywordsMissingValue = nullptr,
|
||||
std::vector<cm::string_view>* parsedKeywords = nullptr) const
|
||||
Result Parse(std::vector<std::string> const& args) const
|
||||
{
|
||||
this->Inputs.clear();
|
||||
|
||||
return this->cmArgumentParser<Result>::Parse(
|
||||
cmMakeRange(args).advance(Advance), &this->Inputs, keywordsMissingValue,
|
||||
parsedKeywords);
|
||||
cmMakeRange(args).advance(Advance), &this->Inputs);
|
||||
}
|
||||
|
||||
const std::vector<std::string>& GetInputs() const { return this->Inputs; }
|
||||
@@ -82,52 +79,25 @@ public:
|
||||
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<cm::string_view>& GetKeywordsMissingValue() const
|
||||
{
|
||||
return this->KeywordsMissingValue;
|
||||
}
|
||||
const std::vector<cm::string_view>& GetParsedKeywords() const
|
||||
{
|
||||
return this->ParsedKeywords;
|
||||
args);
|
||||
}
|
||||
|
||||
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()) {
|
||||
if (arguments.Output && arguments.Output->empty()) {
|
||||
status.SetError("Invalid name for output variable.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::vector<cm::string_view> KeywordsMissingValue;
|
||||
mutable std::vector<cm::string_view> ParsedKeywords;
|
||||
};
|
||||
|
||||
struct OutputVariable
|
||||
struct OutputVariable : public ArgumentParser::ParseResult
|
||||
{
|
||||
std::string Output;
|
||||
cm::optional<std::string> Output;
|
||||
};
|
||||
// Usable when OUTPUT_VARIABLE is the only option
|
||||
class OutputVariableParser
|
||||
@@ -297,6 +267,9 @@ bool HandleAppendCommand(std::vector<std::string> const& args,
|
||||
|
||||
const auto arguments = parser.Parse(args);
|
||||
|
||||
if (arguments.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
if (!parser.checkOutputVariable(arguments, status)) {
|
||||
return false;
|
||||
}
|
||||
@@ -307,7 +280,7 @@ bool HandleAppendCommand(std::vector<std::string> const& args,
|
||||
}
|
||||
|
||||
status.GetMakefile().AddDefinition(
|
||||
arguments.Output.empty() ? args[1] : arguments.Output, path.String());
|
||||
arguments.Output ? *arguments.Output : args[1], path.String());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -319,6 +292,9 @@ bool HandleAppendStringCommand(std::vector<std::string> const& args,
|
||||
|
||||
const auto arguments = parser.Parse(args);
|
||||
|
||||
if (arguments.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
if (!parser.checkOutputVariable(arguments, status)) {
|
||||
return false;
|
||||
}
|
||||
@@ -334,7 +310,7 @@ bool HandleAppendStringCommand(std::vector<std::string> const& args,
|
||||
}
|
||||
|
||||
status.GetMakefile().AddDefinition(
|
||||
arguments.Output.empty() ? args[1] : arguments.Output, path.String());
|
||||
arguments.Output ? *arguments.Output : args[1], path.String());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -346,6 +322,9 @@ bool HandleRemoveFilenameCommand(std::vector<std::string> const& args,
|
||||
|
||||
const auto arguments = parser.Parse(args);
|
||||
|
||||
if (arguments.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
if (!parser.checkOutputVariable(arguments, status)) {
|
||||
return false;
|
||||
}
|
||||
@@ -364,7 +343,7 @@ bool HandleRemoveFilenameCommand(std::vector<std::string> const& args,
|
||||
path.RemoveFileName();
|
||||
|
||||
status.GetMakefile().AddDefinition(
|
||||
arguments.Output.empty() ? args[1] : arguments.Output, path.String());
|
||||
arguments.Output ? *arguments.Output : args[1], path.String());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -376,6 +355,9 @@ bool HandleReplaceFilenameCommand(std::vector<std::string> const& args,
|
||||
|
||||
const auto arguments = parser.Parse(args);
|
||||
|
||||
if (arguments.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
if (!parser.checkOutputVariable(arguments, status)) {
|
||||
return false;
|
||||
}
|
||||
@@ -395,7 +377,7 @@ bool HandleReplaceFilenameCommand(std::vector<std::string> const& args,
|
||||
parser.GetInputs().empty() ? "" : parser.GetInputs().front());
|
||||
|
||||
status.GetMakefile().AddDefinition(
|
||||
arguments.Output.empty() ? args[1] : arguments.Output, path.String());
|
||||
arguments.Output ? *arguments.Output : args[1], path.String());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -403,9 +385,9 @@ bool HandleReplaceFilenameCommand(std::vector<std::string> const& args,
|
||||
bool HandleRemoveExtensionCommand(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
struct Arguments
|
||||
struct Arguments : public ArgumentParser::ParseResult
|
||||
{
|
||||
std::string Output;
|
||||
cm::optional<std::string> Output;
|
||||
bool LastOnly = false;
|
||||
};
|
||||
|
||||
@@ -415,6 +397,9 @@ bool HandleRemoveExtensionCommand(std::vector<std::string> const& args,
|
||||
|
||||
Arguments const arguments = parser.Parse(args);
|
||||
|
||||
if (arguments.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
if (!parser.checkOutputVariable(arguments, status)) {
|
||||
return false;
|
||||
}
|
||||
@@ -438,7 +423,7 @@ bool HandleRemoveExtensionCommand(std::vector<std::string> const& args,
|
||||
}
|
||||
|
||||
status.GetMakefile().AddDefinition(
|
||||
arguments.Output.empty() ? args[1] : arguments.Output, path.String());
|
||||
arguments.Output ? *arguments.Output : args[1], path.String());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -446,9 +431,9 @@ bool HandleRemoveExtensionCommand(std::vector<std::string> const& args,
|
||||
bool HandleReplaceExtensionCommand(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
struct Arguments
|
||||
struct Arguments : public ArgumentParser::ParseResult
|
||||
{
|
||||
std::string Output;
|
||||
cm::optional<std::string> Output;
|
||||
bool LastOnly = false;
|
||||
};
|
||||
|
||||
@@ -458,6 +443,9 @@ bool HandleReplaceExtensionCommand(std::vector<std::string> const& args,
|
||||
|
||||
Arguments const arguments = parser.Parse(args);
|
||||
|
||||
if (arguments.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
if (!parser.checkOutputVariable(arguments, status)) {
|
||||
return false;
|
||||
}
|
||||
@@ -483,7 +471,7 @@ bool HandleReplaceExtensionCommand(std::vector<std::string> const& args,
|
||||
}
|
||||
|
||||
status.GetMakefile().AddDefinition(
|
||||
arguments.Output.empty() ? args[1] : arguments.Output, path.String());
|
||||
arguments.Output ? *arguments.Output : args[1], path.String());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -495,6 +483,9 @@ bool HandleNormalPathCommand(std::vector<std::string> const& args,
|
||||
|
||||
const auto arguments = parser.Parse(args);
|
||||
|
||||
if (arguments.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
if (!parser.checkOutputVariable(arguments, status)) {
|
||||
return false;
|
||||
}
|
||||
@@ -512,7 +503,7 @@ bool HandleNormalPathCommand(std::vector<std::string> const& args,
|
||||
auto path = cmCMakePath(inputPath).Normal();
|
||||
|
||||
status.GetMakefile().AddDefinition(
|
||||
arguments.Output.empty() ? args[1] : arguments.Output, path.String());
|
||||
arguments.Output ? *arguments.Output : args[1], path.String());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -523,10 +514,10 @@ bool HandleTransformPathCommand(
|
||||
const std::string& base)>& transform,
|
||||
bool normalizeOption = false)
|
||||
{
|
||||
struct Arguments
|
||||
struct Arguments : public ArgumentParser::ParseResult
|
||||
{
|
||||
std::string Output;
|
||||
std::string BaseDirectory;
|
||||
cm::optional<std::string> Output;
|
||||
cm::optional<std::string> BaseDirectory;
|
||||
bool Normalize = false;
|
||||
};
|
||||
|
||||
@@ -538,6 +529,9 @@ bool HandleTransformPathCommand(
|
||||
|
||||
Arguments arguments = parser.Parse(args);
|
||||
|
||||
if (arguments.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
if (!parser.checkOutputVariable(arguments, status)) {
|
||||
return false;
|
||||
}
|
||||
@@ -547,17 +541,11 @@ bool HandleTransformPathCommand(
|
||||
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 baseDirectory;
|
||||
if (arguments.BaseDirectory) {
|
||||
baseDirectory = *arguments.BaseDirectory;
|
||||
} else {
|
||||
baseDirectory = status.GetMakefile().GetCurrentSourceDirectory();
|
||||
}
|
||||
|
||||
std::string inputPath;
|
||||
@@ -565,13 +553,13 @@ bool HandleTransformPathCommand(
|
||||
return false;
|
||||
}
|
||||
|
||||
auto path = transform(cmCMakePath(inputPath), arguments.BaseDirectory);
|
||||
auto path = transform(cmCMakePath(inputPath), baseDirectory);
|
||||
if (arguments.Normalize) {
|
||||
path = path.Normal();
|
||||
}
|
||||
|
||||
status.GetMakefile().AddDefinition(
|
||||
arguments.Output.empty() ? args[1] : arguments.Output, path.String());
|
||||
arguments.Output ? *arguments.Output : args[1], path.String());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
|
||||
return false;
|
||||
}
|
||||
|
||||
struct Arguments
|
||||
struct Arguments : public ArgumentParser::ParseResult
|
||||
{
|
||||
std::vector<std::vector<std::string>> Commands;
|
||||
std::string OutputVariable;
|
||||
@@ -95,14 +95,10 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
|
||||
.Bind("COMMAND_ERROR_IS_FATAL"_s, &Arguments::CommandErrorIsFatal);
|
||||
|
||||
std::vector<std::string> unparsedArguments;
|
||||
std::vector<cm::string_view> keywordsMissingValue;
|
||||
Arguments const arguments =
|
||||
parser.Parse(args, &unparsedArguments, &keywordsMissingValue);
|
||||
Arguments const arguments = parser.Parse(args, &unparsedArguments);
|
||||
|
||||
if (!keywordsMissingValue.empty()) {
|
||||
status.SetError(cmStrCat(" called with no value for ",
|
||||
keywordsMissingValue.front(), "."));
|
||||
return false;
|
||||
if (arguments.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
if (!unparsedArguments.empty()) {
|
||||
status.SetError(" given unknown argument \"" + unparsedArguments.front() +
|
||||
|
||||
+82
-126
@@ -954,42 +954,34 @@ bool HandleRPathChangeCommand(std::vector<std::string> const& args,
|
||||
{
|
||||
// Evaluate arguments.
|
||||
std::string file;
|
||||
std::string oldRPath;
|
||||
std::string newRPath;
|
||||
cm::optional<std::string> oldRPath;
|
||||
cm::optional<std::string> newRPath;
|
||||
bool removeEnvironmentRPath = false;
|
||||
cmArgumentParser<void> parser;
|
||||
std::vector<std::string> unknownArgs;
|
||||
std::vector<cm::string_view> missingArgs;
|
||||
std::vector<cm::string_view> parsedArgs;
|
||||
parser.Bind("FILE"_s, file)
|
||||
.Bind("OLD_RPATH"_s, oldRPath)
|
||||
.Bind("NEW_RPATH"_s, newRPath)
|
||||
.Bind("INSTALL_REMOVE_ENVIRONMENT_RPATH"_s, removeEnvironmentRPath);
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unknownArgs, &missingArgs,
|
||||
&parsedArgs);
|
||||
ArgumentParser::ParseResult parseResult =
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
|
||||
if (!unknownArgs.empty()) {
|
||||
status.SetError(
|
||||
cmStrCat("RPATH_CHANGE given unknown argument ", unknownArgs.front()));
|
||||
return false;
|
||||
}
|
||||
if (!missingArgs.empty()) {
|
||||
status.SetError(cmStrCat("RPATH_CHANGE \"", missingArgs.front(),
|
||||
"\" argument not given value."));
|
||||
return false;
|
||||
if (parseResult.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
if (file.empty()) {
|
||||
status.SetError("RPATH_CHANGE not given FILE option.");
|
||||
return false;
|
||||
}
|
||||
if (oldRPath.empty() &&
|
||||
std::find(parsedArgs.begin(), parsedArgs.end(), "OLD_RPATH") ==
|
||||
parsedArgs.end()) {
|
||||
if (!oldRPath) {
|
||||
status.SetError("RPATH_CHANGE not given OLD_RPATH option.");
|
||||
return false;
|
||||
}
|
||||
if (newRPath.empty() &&
|
||||
std::find(parsedArgs.begin(), parsedArgs.end(), "NEW_RPATH") ==
|
||||
parsedArgs.end()) {
|
||||
if (!newRPath) {
|
||||
status.SetError("RPATH_CHANGE not given NEW_RPATH option.");
|
||||
return false;
|
||||
}
|
||||
@@ -1003,17 +995,17 @@ bool HandleRPathChangeCommand(std::vector<std::string> const& args,
|
||||
std::string emsg;
|
||||
bool changed;
|
||||
|
||||
if (!cmSystemTools::ChangeRPath(file, oldRPath, newRPath,
|
||||
if (!cmSystemTools::ChangeRPath(file, *oldRPath, *newRPath,
|
||||
removeEnvironmentRPath, &emsg, &changed)) {
|
||||
status.SetError(cmStrCat("RPATH_CHANGE could not write new RPATH:\n ",
|
||||
newRPath, "\nto the file:\n ", file, "\n",
|
||||
*newRPath, "\nto the file:\n ", file, "\n",
|
||||
emsg));
|
||||
success = false;
|
||||
}
|
||||
if (success) {
|
||||
if (changed) {
|
||||
std::string message =
|
||||
cmStrCat("Set runtime path of \"", file, "\" to \"", newRPath, '"');
|
||||
cmStrCat("Set runtime path of \"", file, "\" to \"", *newRPath, '"');
|
||||
status.GetMakefile().DisplayStatus(message, -1);
|
||||
}
|
||||
ft.Store(file);
|
||||
@@ -1026,31 +1018,25 @@ bool HandleRPathSetCommand(std::vector<std::string> const& args,
|
||||
{
|
||||
// Evaluate arguments.
|
||||
std::string file;
|
||||
std::string newRPath;
|
||||
cm::optional<std::string> newRPath;
|
||||
cmArgumentParser<void> parser;
|
||||
std::vector<std::string> unknownArgs;
|
||||
std::vector<cm::string_view> missingArgs;
|
||||
std::vector<cm::string_view> parsedArgs;
|
||||
parser.Bind("FILE"_s, file).Bind("NEW_RPATH"_s, newRPath);
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unknownArgs, &missingArgs,
|
||||
&parsedArgs);
|
||||
ArgumentParser::ParseResult parseResult =
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
|
||||
if (!unknownArgs.empty()) {
|
||||
status.SetError(cmStrCat("RPATH_SET given unrecognized argument \"",
|
||||
unknownArgs.front(), "\"."));
|
||||
return false;
|
||||
}
|
||||
if (!missingArgs.empty()) {
|
||||
status.SetError(cmStrCat("RPATH_SET \"", missingArgs.front(),
|
||||
"\" argument not given value."));
|
||||
return false;
|
||||
if (parseResult.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
if (file.empty()) {
|
||||
status.SetError("RPATH_SET not given FILE option.");
|
||||
return false;
|
||||
}
|
||||
if (newRPath.empty() &&
|
||||
std::find(parsedArgs.begin(), parsedArgs.end(), "NEW_RPATH") ==
|
||||
parsedArgs.end()) {
|
||||
if (!newRPath) {
|
||||
status.SetError("RPATH_SET not given NEW_RPATH option.");
|
||||
return false;
|
||||
}
|
||||
@@ -1064,16 +1050,16 @@ bool HandleRPathSetCommand(std::vector<std::string> const& args,
|
||||
std::string emsg;
|
||||
bool changed;
|
||||
|
||||
if (!cmSystemTools::SetRPath(file, newRPath, &emsg, &changed)) {
|
||||
if (!cmSystemTools::SetRPath(file, *newRPath, &emsg, &changed)) {
|
||||
status.SetError(cmStrCat("RPATH_SET could not write new RPATH:\n ",
|
||||
newRPath, "\nto the file:\n ", file, "\n",
|
||||
*newRPath, "\nto the file:\n ", file, "\n",
|
||||
emsg));
|
||||
success = false;
|
||||
}
|
||||
if (success) {
|
||||
if (changed) {
|
||||
std::string message =
|
||||
cmStrCat("Set runtime path of \"", file, "\" to \"", newRPath, '"');
|
||||
cmStrCat("Set runtime path of \"", file, "\" to \"", *newRPath, '"');
|
||||
status.GetMakefile().DisplayStatus(message, -1);
|
||||
}
|
||||
ft.Store(file);
|
||||
@@ -1088,18 +1074,16 @@ bool HandleRPathRemoveCommand(std::vector<std::string> const& args,
|
||||
std::string file;
|
||||
cmArgumentParser<void> parser;
|
||||
std::vector<std::string> unknownArgs;
|
||||
std::vector<cm::string_view> missingArgs;
|
||||
parser.Bind("FILE"_s, file);
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unknownArgs, &missingArgs);
|
||||
ArgumentParser::ParseResult parseResult =
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
|
||||
if (!unknownArgs.empty()) {
|
||||
status.SetError(
|
||||
cmStrCat("RPATH_REMOVE given unknown argument ", unknownArgs.front()));
|
||||
return false;
|
||||
}
|
||||
if (!missingArgs.empty()) {
|
||||
status.SetError(cmStrCat("RPATH_REMOVE \"", missingArgs.front(),
|
||||
"\" argument not given value."));
|
||||
return false;
|
||||
if (parseResult.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
if (file.empty()) {
|
||||
status.SetError("RPATH_REMOVE not given FILE option.");
|
||||
@@ -1136,31 +1120,25 @@ bool HandleRPathCheckCommand(std::vector<std::string> const& args,
|
||||
{
|
||||
// Evaluate arguments.
|
||||
std::string file;
|
||||
std::string rpath;
|
||||
cm::optional<std::string> rpath;
|
||||
cmArgumentParser<void> parser;
|
||||
std::vector<std::string> unknownArgs;
|
||||
std::vector<cm::string_view> missingArgs;
|
||||
std::vector<cm::string_view> parsedArgs;
|
||||
parser.Bind("FILE"_s, file).Bind("RPATH"_s, rpath);
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unknownArgs, &missingArgs,
|
||||
&parsedArgs);
|
||||
ArgumentParser::ParseResult parseResult =
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
|
||||
if (!unknownArgs.empty()) {
|
||||
status.SetError(
|
||||
cmStrCat("RPATH_CHECK given unknown argument ", unknownArgs.front()));
|
||||
return false;
|
||||
}
|
||||
if (!missingArgs.empty()) {
|
||||
status.SetError(cmStrCat("RPATH_CHECK \"", missingArgs.front(),
|
||||
"\" argument not given value."));
|
||||
return false;
|
||||
if (parseResult.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
if (file.empty()) {
|
||||
status.SetError("RPATH_CHECK not given FILE option.");
|
||||
return false;
|
||||
}
|
||||
if (rpath.empty() &&
|
||||
std::find(parsedArgs.begin(), parsedArgs.end(), "RPATH") ==
|
||||
parsedArgs.end()) {
|
||||
if (!rpath) {
|
||||
status.SetError("RPATH_CHECK not given RPATH option.");
|
||||
return false;
|
||||
}
|
||||
@@ -1169,7 +1147,7 @@ bool HandleRPathCheckCommand(std::vector<std::string> const& args,
|
||||
// delete it. This is used during installation to re-install a file
|
||||
// if its RPath will change.
|
||||
if (cmSystemTools::FileExists(file, true) &&
|
||||
!cmSystemTools::CheckRPath(file, rpath)) {
|
||||
!cmSystemTools::CheckRPath(file, *rpath)) {
|
||||
cmSystemTools::RemoveFile(file);
|
||||
}
|
||||
|
||||
@@ -1252,7 +1230,7 @@ bool HandleRealPathCommand(std::vector<std::string> const& args,
|
||||
return false;
|
||||
}
|
||||
|
||||
struct Arguments
|
||||
struct Arguments : public ArgumentParser::ParseResult
|
||||
{
|
||||
cm::optional<std::string> BaseDirectory;
|
||||
bool ExpandTilde = false;
|
||||
@@ -1263,17 +1241,15 @@ bool HandleRealPathCommand(std::vector<std::string> const& args,
|
||||
.Bind("EXPAND_TILDE"_s, &Arguments::ExpandTilde);
|
||||
|
||||
std::vector<std::string> unparsedArguments;
|
||||
std::vector<cm::string_view> keywordsMissingValue;
|
||||
auto arguments = parser.Parse(cmMakeRange(args).advance(3),
|
||||
&unparsedArguments, &keywordsMissingValue);
|
||||
auto arguments =
|
||||
parser.Parse(cmMakeRange(args).advance(3), &unparsedArguments);
|
||||
|
||||
if (!unparsedArguments.empty()) {
|
||||
status.SetError("REAL_PATH called with unexpected arguments");
|
||||
return false;
|
||||
}
|
||||
if (!keywordsMissingValue.empty()) {
|
||||
status.SetError("BASE_DIRECTORY requires a value");
|
||||
return false;
|
||||
if (arguments.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!arguments.BaseDirectory) {
|
||||
@@ -2495,7 +2471,7 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
|
||||
return false;
|
||||
}
|
||||
|
||||
struct Arguments
|
||||
struct Arguments : public ArgumentParser::ParseResult
|
||||
{
|
||||
cm::optional<std::string> Output;
|
||||
cm::optional<std::string> Input;
|
||||
@@ -2521,17 +2497,13 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
|
||||
.Bind("NEWLINE_STYLE"_s, &Arguments::NewLineStyle);
|
||||
|
||||
std::vector<std::string> unparsedArguments;
|
||||
std::vector<cm::string_view> keywordsMissingValues;
|
||||
std::vector<cm::string_view> parsedKeywords;
|
||||
Arguments const arguments =
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unparsedArguments,
|
||||
&keywordsMissingValues, &parsedKeywords);
|
||||
/*keywordsMissingValue=*/nullptr, &parsedKeywords);
|
||||
|
||||
if (!keywordsMissingValues.empty()) {
|
||||
status.SetError(
|
||||
cmStrCat("GENERATE keywords missing values:\n ",
|
||||
cmJoin(cmMakeRange(keywordsMissingValues), "\n ")));
|
||||
return false;
|
||||
if (arguments.MaybeReportError(status.GetMakefile())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!unparsedArguments.empty()) {
|
||||
@@ -3045,7 +3017,7 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
|
||||
"\n ]])");
|
||||
}
|
||||
|
||||
struct Arguments
|
||||
struct Arguments : public ArgumentParser::ParseResult
|
||||
{
|
||||
std::string ResolvedDependenciesVar;
|
||||
std::string UnresolvedDependenciesVar;
|
||||
@@ -3088,10 +3060,8 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
|
||||
.Bind("POST_EXCLUDE_FILES_STRICT"_s, &Arguments::PostExcludeFilesStrict);
|
||||
|
||||
std::vector<std::string> unrecognizedArguments;
|
||||
std::vector<cm::string_view> keywordsMissingValues;
|
||||
auto parsedArgs =
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
|
||||
&keywordsMissingValues);
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
|
||||
auto argIt = unrecognizedArguments.begin();
|
||||
if (argIt != unrecognizedArguments.end()) {
|
||||
status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
|
||||
@@ -3099,12 +3069,9 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!keywordsMissingValues.empty()) {
|
||||
status.SetError(
|
||||
cmStrCat("Keywords missing values:\n ",
|
||||
cmJoin(cmMakeRange(keywordsMissingValues), "\n ")));
|
||||
if (parsedArgs.MaybeReportError(status.GetMakefile())) {
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
cmRuntimeDependencyArchive archive(
|
||||
@@ -3204,7 +3171,7 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
|
||||
bool HandleConfigureCommand(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
struct Arguments
|
||||
struct Arguments : public ArgumentParser::ParseResult
|
||||
{
|
||||
cm::optional<std::string> Output;
|
||||
cm::optional<std::string> Content;
|
||||
@@ -3223,10 +3190,8 @@ bool HandleConfigureCommand(std::vector<std::string> const& args,
|
||||
.Bind("NEWLINE_STYLE"_s, &Arguments::NewlineStyle);
|
||||
|
||||
std::vector<std::string> unrecognizedArguments;
|
||||
std::vector<cm::string_view> keywordsMissingValues;
|
||||
auto parsedArgs =
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
|
||||
&keywordsMissingValues);
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
|
||||
|
||||
auto argIt = unrecognizedArguments.begin();
|
||||
if (argIt != unrecognizedArguments.end()) {
|
||||
@@ -3236,12 +3201,9 @@ bool HandleConfigureCommand(std::vector<std::string> const& args,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!keywordsMissingValues.empty()) {
|
||||
status.SetError(
|
||||
cmStrCat("CONFIGURE keywords missing values:\n ",
|
||||
cmJoin(cmMakeRange(keywordsMissingValues), "\n ")));
|
||||
if (parsedArgs.MaybeReportError(status.GetMakefile())) {
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!parsedArgs.Output) {
|
||||
@@ -3336,7 +3298,7 @@ bool HandleConfigureCommand(std::vector<std::string> const& args,
|
||||
bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
struct Arguments
|
||||
struct Arguments : public ArgumentParser::ParseResult
|
||||
{
|
||||
std::string Output;
|
||||
std::string Format;
|
||||
@@ -3362,10 +3324,8 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
|
||||
.Bind("PATHS"_s, &Arguments::Paths);
|
||||
|
||||
std::vector<std::string> unrecognizedArguments;
|
||||
std::vector<cm::string_view> keywordsMissingValues;
|
||||
auto parsedArgs =
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
|
||||
&keywordsMissingValues);
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
|
||||
auto argIt = unrecognizedArguments.begin();
|
||||
if (argIt != unrecognizedArguments.end()) {
|
||||
status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
|
||||
@@ -3373,12 +3333,9 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!keywordsMissingValues.empty()) {
|
||||
status.SetError(
|
||||
cmStrCat("Keywords missing values:\n ",
|
||||
cmJoin(cmMakeRange(keywordsMissingValues), "\n ")));
|
||||
if (parsedArgs.MaybeReportError(status.GetMakefile())) {
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* knownFormats[] = {
|
||||
@@ -3467,7 +3424,7 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
|
||||
bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
struct Arguments
|
||||
struct Arguments : public ArgumentParser::ParseResult
|
||||
{
|
||||
std::string Input;
|
||||
bool Verbose = false;
|
||||
@@ -3486,10 +3443,8 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
|
||||
.Bind("TOUCH"_s, &Arguments::Touch);
|
||||
|
||||
std::vector<std::string> unrecognizedArguments;
|
||||
std::vector<cm::string_view> keywordsMissingValues;
|
||||
auto parsedArgs =
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
|
||||
&keywordsMissingValues);
|
||||
parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
|
||||
auto argIt = unrecognizedArguments.begin();
|
||||
if (argIt != unrecognizedArguments.end()) {
|
||||
status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
|
||||
@@ -3497,12 +3452,9 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!keywordsMissingValues.empty()) {
|
||||
status.SetError(
|
||||
cmStrCat("Keywords missing values:\n ",
|
||||
cmJoin(cmMakeRange(keywordsMissingValues), "\n ")));
|
||||
if (parsedArgs.MaybeReportError(status.GetMakefile())) {
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string inFile = parsedArgs.Input;
|
||||
@@ -3557,10 +3509,15 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValidateAndConvertPermissions(const std::vector<std::string>& permissions,
|
||||
mode_t& perms, cmExecutionStatus& status)
|
||||
bool ValidateAndConvertPermissions(
|
||||
cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> const&
|
||||
permissions,
|
||||
mode_t& perms, cmExecutionStatus& status)
|
||||
{
|
||||
for (const auto& i : permissions) {
|
||||
if (!permissions) {
|
||||
return true;
|
||||
}
|
||||
for (const auto& i : *permissions) {
|
||||
if (!cmFSPermissions::stringToModeT(i, perms)) {
|
||||
status.SetError(i + " is an invalid permission specifier");
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
@@ -3592,11 +3549,14 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
|
||||
globber.SetRecurse(recurse);
|
||||
globber.SetRecurseListDirs(recurse);
|
||||
|
||||
struct Arguments
|
||||
struct Arguments : public ArgumentParser::ParseResult
|
||||
{
|
||||
ArgumentParser::NonEmpty<std::vector<std::string>> Permissions;
|
||||
ArgumentParser::NonEmpty<std::vector<std::string>> FilePermissions;
|
||||
ArgumentParser::NonEmpty<std::vector<std::string>> DirectoryPermissions;
|
||||
cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
|
||||
Permissions;
|
||||
cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
|
||||
FilePermissions;
|
||||
cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
|
||||
DirectoryPermissions;
|
||||
};
|
||||
|
||||
static auto const parser =
|
||||
@@ -3606,21 +3566,20 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
|
||||
.Bind("DIRECTORY_PERMISSIONS"_s, &Arguments::DirectoryPermissions);
|
||||
|
||||
std::vector<std::string> pathEntries;
|
||||
std::vector<cm::string_view> keywordsMissingValues;
|
||||
Arguments parsedArgs = parser.Parse(cmMakeRange(args).advance(1),
|
||||
&pathEntries, &keywordsMissingValues);
|
||||
Arguments parsedArgs =
|
||||
parser.Parse(cmMakeRange(args).advance(1), &pathEntries);
|
||||
|
||||
// check validity of arguments
|
||||
if (parsedArgs.Permissions.empty() && parsedArgs.FilePermissions.empty() &&
|
||||
parsedArgs.DirectoryPermissions.empty()) // no permissions given
|
||||
if (!parsedArgs.Permissions && !parsedArgs.FilePermissions &&
|
||||
!parsedArgs.DirectoryPermissions) // no permissions given
|
||||
{
|
||||
status.SetError("No permissions given");
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parsedArgs.Permissions.empty() && !parsedArgs.FilePermissions.empty() &&
|
||||
!parsedArgs.DirectoryPermissions.empty()) // all keywords are used
|
||||
if (parsedArgs.Permissions && parsedArgs.FilePermissions &&
|
||||
parsedArgs.DirectoryPermissions) // all keywords are used
|
||||
{
|
||||
status.SetError("Remove either PERMISSIONS or FILE_PERMISSIONS or "
|
||||
"DIRECTORY_PERMISSIONS from the invocation");
|
||||
@@ -3628,12 +3587,9 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!keywordsMissingValues.empty()) {
|
||||
for (const auto& i : keywordsMissingValues) {
|
||||
status.SetError(cmStrCat(i, " is not given any arguments"));
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
}
|
||||
return false;
|
||||
if (parsedArgs.MaybeReportError(status.GetMakefile())) {
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
return true;
|
||||
}
|
||||
|
||||
// validate permissions
|
||||
@@ -3677,7 +3633,7 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
|
||||
if (cmSystemTools::FileExists(i, true)) {
|
||||
bool success = true;
|
||||
const mode_t& filePermissions =
|
||||
parsedArgs.FilePermissions.empty() ? perms : fperms;
|
||||
parsedArgs.FilePermissions ? fperms : perms;
|
||||
if (filePermissions) {
|
||||
success = SetPermissions(i, filePermissions, status);
|
||||
}
|
||||
@@ -3689,7 +3645,7 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
|
||||
else if (cmSystemTools::FileIsDirectory(i)) {
|
||||
bool success = true;
|
||||
const mode_t& directoryPermissions =
|
||||
parsedArgs.DirectoryPermissions.empty() ? perms : dperms;
|
||||
parsedArgs.DirectoryPermissions ? dperms : perms;
|
||||
if (directoryPermissions) {
|
||||
success = SetPermissions(i, directoryPermissions, status);
|
||||
}
|
||||
|
||||
@@ -2160,11 +2160,9 @@ bool HandleRuntimeDependencySetMode(std::vector<std::string> const& args,
|
||||
// These generic args also contain the runtime dependency set
|
||||
std::string runtimeDependencySetArg;
|
||||
std::vector<std::string> runtimeDependencyArgVector;
|
||||
std::vector<cm::string_view> parsedArgs;
|
||||
cmInstallCommandArguments genericArgs(helper.DefaultComponentName);
|
||||
genericArgs.Bind("RUNTIME_DEPENDENCY_SET"_s, runtimeDependencySetArg);
|
||||
genericArgs.Parse(genericArgVector, &runtimeDependencyArgVector, nullptr,
|
||||
&parsedArgs);
|
||||
genericArgs.Parse(genericArgVector, &runtimeDependencyArgVector);
|
||||
bool success = genericArgs.Finalize();
|
||||
|
||||
cmInstallCommandArguments libraryArgs(helper.DefaultComponentName);
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
#include <initializer_list>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <cm/optional>
|
||||
@@ -15,7 +17,7 @@
|
||||
|
||||
namespace {
|
||||
|
||||
struct Result
|
||||
struct Result : public ArgumentParser::ParseResult
|
||||
{
|
||||
bool Option1 = false;
|
||||
bool Option2 = false;
|
||||
@@ -69,6 +71,11 @@ bool verifyResult(Result const& result,
|
||||
static std::vector<cm::string_view> const missing = { "STRING_1"_s,
|
||||
"LIST_1"_s,
|
||||
"LIST_4"_s };
|
||||
static std::map<cm::string_view, std::string> const keywordErrors = {
|
||||
{ "STRING_1"_s, " missing required value\n" },
|
||||
{ "LIST_1"_s, " missing required value\n" },
|
||||
{ "LIST_4"_s, " missing required value\n" }
|
||||
};
|
||||
|
||||
#define ASSERT_TRUE(x) \
|
||||
do { \
|
||||
@@ -78,6 +85,8 @@ bool verifyResult(Result const& result,
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
ASSERT_TRUE(!result);
|
||||
|
||||
ASSERT_TRUE(result.Option1);
|
||||
ASSERT_TRUE(!result.Option2);
|
||||
|
||||
@@ -110,6 +119,13 @@ bool verifyResult(Result const& result,
|
||||
ASSERT_TRUE(unparsedArguments[0] == "bar");
|
||||
ASSERT_TRUE(keywordsMissingValue == missing);
|
||||
|
||||
ASSERT_TRUE(result.GetKeywordErrors().size() == keywordErrors.size());
|
||||
for (auto const& ke : result.GetKeywordErrors()) {
|
||||
auto const ki = keywordErrors.find(ke.first);
|
||||
ASSERT_TRUE(ki != keywordErrors.end());
|
||||
ASSERT_TRUE(ke.second == ki->second);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -119,54 +135,65 @@ bool testArgumentParserDynamic()
|
||||
std::vector<std::string> unparsedArguments;
|
||||
std::vector<cm::string_view> keywordsMissingValue;
|
||||
|
||||
cmArgumentParser<void>{}
|
||||
.Bind("OPTION_1"_s, result.Option1)
|
||||
.Bind("OPTION_2"_s, result.Option2)
|
||||
.Bind("STRING_1"_s, result.String1)
|
||||
.Bind("STRING_2"_s, result.String2)
|
||||
.Bind("STRING_3"_s, result.String3)
|
||||
.Bind("STRING_4"_s, result.String4)
|
||||
.Bind("LIST_1"_s, result.List1)
|
||||
.Bind("LIST_2"_s, result.List2)
|
||||
.Bind("LIST_3"_s, result.List3)
|
||||
.Bind("LIST_4"_s, result.List4)
|
||||
.Bind("LIST_5"_s, result.List5)
|
||||
.Bind("LIST_6"_s, result.List6)
|
||||
.Bind("MULTI_1"_s, result.Multi1)
|
||||
.Bind("MULTI_2"_s, result.Multi2)
|
||||
.Bind("MULTI_3"_s, result.Multi3)
|
||||
.Bind("MULTI_4"_s, result.Multi4)
|
||||
.Parse(args, &unparsedArguments, &keywordsMissingValue);
|
||||
static_cast<ArgumentParser::ParseResult&>(result) =
|
||||
cmArgumentParser<void>{}
|
||||
.Bind("OPTION_1"_s, result.Option1)
|
||||
.Bind("OPTION_2"_s, result.Option2)
|
||||
.Bind("STRING_1"_s, result.String1)
|
||||
.Bind("STRING_2"_s, result.String2)
|
||||
.Bind("STRING_3"_s, result.String3)
|
||||
.Bind("STRING_4"_s, result.String4)
|
||||
.Bind("LIST_1"_s, result.List1)
|
||||
.Bind("LIST_2"_s, result.List2)
|
||||
.Bind("LIST_3"_s, result.List3)
|
||||
.Bind("LIST_4"_s, result.List4)
|
||||
.Bind("LIST_5"_s, result.List5)
|
||||
.Bind("LIST_6"_s, result.List6)
|
||||
.Bind("MULTI_1"_s, result.Multi1)
|
||||
.Bind("MULTI_2"_s, result.Multi2)
|
||||
.Bind("MULTI_3"_s, result.Multi3)
|
||||
.Bind("MULTI_4"_s, result.Multi4)
|
||||
.Parse(args, &unparsedArguments, &keywordsMissingValue);
|
||||
|
||||
return verifyResult(result, unparsedArguments, keywordsMissingValue);
|
||||
}
|
||||
|
||||
static auto const parserStatic = //
|
||||
cmArgumentParser<Result>{}
|
||||
.Bind("OPTION_1"_s, &Result::Option1)
|
||||
.Bind("OPTION_2"_s, &Result::Option2)
|
||||
.Bind("STRING_1"_s, &Result::String1)
|
||||
.Bind("STRING_2"_s, &Result::String2)
|
||||
.Bind("STRING_3"_s, &Result::String3)
|
||||
.Bind("STRING_4"_s, &Result::String4)
|
||||
.Bind("LIST_1"_s, &Result::List1)
|
||||
.Bind("LIST_2"_s, &Result::List2)
|
||||
.Bind("LIST_3"_s, &Result::List3)
|
||||
.Bind("LIST_4"_s, &Result::List4)
|
||||
.Bind("LIST_5"_s, &Result::List5)
|
||||
.Bind("LIST_6"_s, &Result::List6)
|
||||
.Bind("MULTI_1"_s, &Result::Multi1)
|
||||
.Bind("MULTI_2"_s, &Result::Multi2)
|
||||
.Bind("MULTI_3"_s, &Result::Multi3)
|
||||
.Bind("MULTI_4"_s, &Result::Multi4)
|
||||
/* keep semicolon on own line */;
|
||||
|
||||
bool testArgumentParserStatic()
|
||||
{
|
||||
static auto const parser = //
|
||||
cmArgumentParser<Result>{}
|
||||
.Bind("OPTION_1"_s, &Result::Option1)
|
||||
.Bind("OPTION_2"_s, &Result::Option2)
|
||||
.Bind("STRING_1"_s, &Result::String1)
|
||||
.Bind("STRING_2"_s, &Result::String2)
|
||||
.Bind("STRING_3"_s, &Result::String3)
|
||||
.Bind("STRING_4"_s, &Result::String4)
|
||||
.Bind("LIST_1"_s, &Result::List1)
|
||||
.Bind("LIST_2"_s, &Result::List2)
|
||||
.Bind("LIST_3"_s, &Result::List3)
|
||||
.Bind("LIST_4"_s, &Result::List4)
|
||||
.Bind("LIST_5"_s, &Result::List5)
|
||||
.Bind("LIST_6"_s, &Result::List6)
|
||||
.Bind("MULTI_1"_s, &Result::Multi1)
|
||||
.Bind("MULTI_2"_s, &Result::Multi2)
|
||||
.Bind("MULTI_3"_s, &Result::Multi3)
|
||||
.Bind("MULTI_4"_s, &Result::Multi4);
|
||||
|
||||
std::vector<std::string> unparsedArguments;
|
||||
std::vector<cm::string_view> keywordsMissingValue;
|
||||
Result const result =
|
||||
parser.Parse(args, &unparsedArguments, &keywordsMissingValue);
|
||||
parserStatic.Parse(args, &unparsedArguments, &keywordsMissingValue);
|
||||
return verifyResult(result, unparsedArguments, keywordsMissingValue);
|
||||
}
|
||||
|
||||
bool testArgumentParserStaticBool()
|
||||
{
|
||||
std::vector<std::string> unparsedArguments;
|
||||
std::vector<cm::string_view> keywordsMissingValue;
|
||||
Result result;
|
||||
ASSERT_TRUE(parserStatic.Parse(result, args, &unparsedArguments,
|
||||
&keywordsMissingValue) == false);
|
||||
return verifyResult(result, unparsedArguments, keywordsMissingValue);
|
||||
}
|
||||
|
||||
@@ -184,5 +211,10 @@ int testArgumentParser(int /*unused*/, char* /*unused*/ [])
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!testArgumentParserStaticBool()) {
|
||||
std::cout << "While executing testArgumentParserStaticBool().\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
^CMake Error at create-missing-args.cmake:[0-9]+ \(file\):
|
||||
file Keywords missing values:
|
||||
Error after keyword "COMPRESSION":
|
||||
|
||||
missing required value
|
||||
|
||||
Error after keyword "COMPRESSION_LEVEL":
|
||||
|
||||
missing required value
|
||||
|
||||
Error after keyword "FORMAT":
|
||||
|
||||
missing required value
|
||||
|
||||
Error after keyword "OUTPUT":
|
||||
|
||||
missing required value
|
||||
|
||||
OUTPUT
|
||||
FORMAT
|
||||
COMPRESSION
|
||||
COMPRESSION_LEVEL
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)$
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
^CMake Error at extract-missing-args.cmake:[0-9]+ \(file\):
|
||||
file Keywords missing values:
|
||||
Error after keyword "DESTINATION":
|
||||
|
||||
missing required value
|
||||
|
||||
Error after keyword "INPUT":
|
||||
|
||||
missing required value
|
||||
|
||||
INPUT
|
||||
DESTINATION
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)$
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
CMake Error at BadArgContent.cmake:[0-9]+ \(file\):
|
||||
file CONFIGURE keywords missing values:
|
||||
Error after keyword "CONTENT":
|
||||
|
||||
missing required value
|
||||
|
||||
CONTENT
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
CMake Error at BadArgOutput.cmake:[0-9]+ \(file\):
|
||||
file CONFIGURE keywords missing values:
|
||||
Error after keyword "OUTPUT":
|
||||
|
||||
missing required value
|
||||
|
||||
OUTPUT
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
CMake Error at EmptyCondition1.cmake:2 \(file\):
|
||||
file GENERATE keywords missing values:
|
||||
Error after keyword "CONDITION":
|
||||
|
||||
missing required value
|
||||
|
||||
CONDITION
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
CMake Error at NewLineStyle-NoArg.cmake:[0-9]+ \(file\):
|
||||
file GENERATE keywords missing values:
|
||||
Error after keyword "NEWLINE_STYLE":
|
||||
|
||||
missing required value
|
||||
|
||||
NEWLINE_STYLE
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
CMake Error at Registry_BadQuery2.cmake:[0-9]+ \(cmake_host_system_information\):
|
||||
cmake_host_system_information missing expected value for argument\(s\)
|
||||
"VALUE".
|
||||
Error after keyword "VALUE":
|
||||
|
||||
missing required value
|
||||
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
CMake Error at Registry_BadView1.cmake:[0-9]+ \(cmake_host_system_information\):
|
||||
cmake_host_system_information missing expected value for argument\(s\)
|
||||
"VIEW".
|
||||
Error after keyword "VIEW":
|
||||
|
||||
missing required value
|
||||
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
CMake Error at .+/cmake_path/call-cmake_path.cmake:[0-9]+ \(cmake_path\):
|
||||
Error after keyword "BASE_DIRECTORY":
|
||||
|
||||
missing required value
|
||||
@@ -1,2 +1,4 @@
|
||||
CMake Error at .+/cmake_path/call-cmake_path.cmake:[0-9]+ \(cmake_path\):
|
||||
cmake_path OUTPUT_VARIABLE requires an argument.
|
||||
Error after keyword "OUTPUT_VARIABLE":
|
||||
|
||||
missing required value
|
||||
|
||||
@@ -74,6 +74,14 @@ foreach (command IN ITEMS APPEND APPEND_STRING REMOVE_FILENAME REPLACE_FILENAME
|
||||
endforeach()
|
||||
|
||||
|
||||
## BASE_DIRECTORY without argument
|
||||
set (RunCMake-stderr-file "BASE_DIRECTORY-no-arg-stderr.txt")
|
||||
|
||||
foreach (command IN ITEMS RELATIVE_PATH ABSOLUTE_PATH)
|
||||
run_cmake_command (${command}-OUTPUT_VARIABLE-no-arg "${CMAKE_COMMAND}" "-DCMAKE_PATH_ARGUMENTS=${command} path BASE_DIRECTORY" -P "${RunCMake_SOURCE_DIR}/call-cmake_path.cmake")
|
||||
endforeach()
|
||||
|
||||
|
||||
## Invalid output variable
|
||||
set (RunCMake-stderr-file "invalid-output-var-stderr.txt")
|
||||
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
CMake Error at .*EchoCommand.cmake:.*\(execute_process\):
|
||||
execute_process called with no value for COMMAND_ECHO.
|
||||
Error after keyword "COMMAND_ECHO":
|
||||
|
||||
missing required value
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
^CMake Error at EncodingMissing.cmake:[0-9]+ \(execute_process\):
|
||||
execute_process called with no value for ENCODING.
|
||||
Error after keyword "ENCODING":
|
||||
|
||||
missing required value
|
||||
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)$
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
CMake Error at CHMOD-all-perms\.cmake:[0-9]+ \(file\):
|
||||
file Remove either PERMISSIONS or FILE_PERMISSIONS or DIRECTORY_PERMISSIONS
|
||||
from the invocation
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
@@ -1,6 +0,0 @@
|
||||
file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a)
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS OWNER_READ
|
||||
FILE_PERMISSIONS OWNER_READ DIRECTORY_PERMISSIONS OWNER_READ)
|
||||
@@ -1,6 +0,0 @@
|
||||
CMake Error at CHMOD-invalid-path\.cmake:[0-9]+ \(file\):
|
||||
file does not exist:
|
||||
|
||||
.*/chmod-tests/I_dont_exist
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
@@ -1,4 +0,0 @@
|
||||
file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/I_dont_exist PERMISSIONS OWNER_READ)
|
||||
@@ -1,4 +0,0 @@
|
||||
CMake Error at CHMOD-invalid-perms\.cmake:[0-9]+ \(file\):
|
||||
file INVALID_PERMISSION is an invalid permission specifier
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
@@ -1,5 +0,0 @@
|
||||
file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a)
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS INVALID_PERMISSION)
|
||||
@@ -1,4 +0,0 @@
|
||||
CMake Error at CHMOD-no-keyword\.cmake:[0-9]+ \(file\):
|
||||
file No permissions given
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
@@ -1,5 +0,0 @@
|
||||
file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a)
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a)
|
||||
@@ -1,4 +0,0 @@
|
||||
CMake Error at CHMOD-no-perms\.cmake:[0-9]+ \(file\):
|
||||
file No permissions given
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
@@ -1,5 +0,0 @@
|
||||
file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a)
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS)
|
||||
@@ -1,5 +0,0 @@
|
||||
file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a)
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS OWNER_READ)
|
||||
@@ -1,6 +0,0 @@
|
||||
file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a)
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS OWNER_READ
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||
@@ -1,6 +0,0 @@
|
||||
CMake Error at CHMOD-write-only\.cmake:[0-9]+ \(file\):
|
||||
file failed to open for reading \(Permission denied\):
|
||||
|
||||
.*/chmod-tests/a
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
@@ -1,6 +0,0 @@
|
||||
file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
|
||||
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a "CONTENT")
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS OWNER_WRITE)
|
||||
file(READ ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a content)
|
||||
@@ -1,12 +1,14 @@
|
||||
include(RunCMake)
|
||||
|
||||
run_cmake(CHMOD-no-perms)
|
||||
run_cmake(CHMOD-no-keyword)
|
||||
run_cmake(CHMOD-all-perms)
|
||||
run_cmake(CHMOD-invalid-perms)
|
||||
run_cmake(CHMOD-invalid-path)
|
||||
run_cmake(CHMOD-ok)
|
||||
run_cmake(CHMOD-override)
|
||||
run_cmake_script(no-perms)
|
||||
run_cmake_script(missing-perms)
|
||||
run_cmake_script(missing-file-perms)
|
||||
run_cmake_script(missing-dir-perms)
|
||||
run_cmake_script(all-perms)
|
||||
run_cmake_script(invalid-perms)
|
||||
run_cmake_script(invalid-path)
|
||||
run_cmake_script(ok)
|
||||
run_cmake_script(override)
|
||||
|
||||
if(UNIX)
|
||||
execute_process(COMMAND id -u $ENV{USER}
|
||||
@@ -15,5 +17,5 @@ if(UNIX)
|
||||
endif()
|
||||
|
||||
if(NOT WIN32 AND NOT MSYS AND NOT "${uid}" STREQUAL "0")
|
||||
run_cmake(CHMOD-write-only)
|
||||
run_cmake_script(write-only)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
^CMake Error at [^
|
||||
]*/all-perms\.cmake:[0-9]+ \(file\):
|
||||
file Remove either PERMISSIONS or FILE_PERMISSIONS or DIRECTORY_PERMISSIONS
|
||||
from the invocation$
|
||||
@@ -0,0 +1,3 @@
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a PERMISSIONS OWNER_READ
|
||||
FILE_PERMISSIONS OWNER_READ DIRECTORY_PERMISSIONS OWNER_READ)
|
||||
@@ -0,0 +1,6 @@
|
||||
^CMake Error at [^
|
||||
]*/invalid-path\.cmake:[0-9]+ \(file\):
|
||||
file does not exist:
|
||||
|
||||
[^
|
||||
]*/Tests/RunCMake/file-CHMOD/invalid-path-build/I_dont_exist$
|
||||
@@ -0,0 +1 @@
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/I_dont_exist PERMISSIONS OWNER_READ)
|
||||
@@ -0,0 +1,3 @@
|
||||
^CMake Error at [^
|
||||
]*/invalid-perms\.cmake:[0-9]+ \(file\):
|
||||
file INVALID_PERMISSION is an invalid permission specifier$
|
||||
@@ -0,0 +1,2 @@
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a PERMISSIONS INVALID_PERMISSION)
|
||||
@@ -0,0 +1,5 @@
|
||||
^CMake Error at [^
|
||||
]*/missing-dir-perms.cmake:[0-9]+ \(file\):
|
||||
Error after keyword "DIRECTORY_PERMISSIONS":
|
||||
|
||||
missing required value$
|
||||
@@ -0,0 +1,2 @@
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a PERMISSIONS OWNER_READ DIRECTORY_PERMISSIONS)
|
||||
@@ -0,0 +1,5 @@
|
||||
^CMake Error at [^
|
||||
]*/missing-file-perms.cmake:[0-9]+ \(file\):
|
||||
Error after keyword "FILE_PERMISSIONS":
|
||||
|
||||
missing required value$
|
||||
@@ -0,0 +1,2 @@
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a PERMISSIONS OWNER_READ FILE_PERMISSIONS)
|
||||
@@ -0,0 +1,5 @@
|
||||
^CMake Error at [^
|
||||
]*/missing-perms.cmake:[0-9]+ \(file\):
|
||||
Error after keyword "PERMISSIONS":
|
||||
|
||||
missing required value$
|
||||
@@ -0,0 +1,2 @@
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a FILE_PERMISSIONS OWNER_READ PERMISSIONS)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,3 @@
|
||||
^CMake Error at [^
|
||||
]*/no-perms\.cmake:[0-9]+ \(file\):
|
||||
file No permissions given$
|
||||
@@ -0,0 +1,2 @@
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a)
|
||||
@@ -0,0 +1,2 @@
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a PERMISSIONS OWNER_READ)
|
||||
@@ -0,0 +1,3 @@
|
||||
file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a PERMISSIONS OWNER_READ
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,6 @@
|
||||
^CMake Error at [^
|
||||
]*/write-only\.cmake:[0-9]+ \(file\):
|
||||
file failed to open for reading \(Permission denied\):
|
||||
|
||||
[^
|
||||
]*/Tests/RunCMake/file-CHMOD/write-only-build/a$
|
||||
@@ -0,0 +1,3 @@
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/a "CONTENT")
|
||||
file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a PERMISSIONS OWNER_WRITE)
|
||||
file(READ ${CMAKE_CURRENT_BINARY_DIR}/a content)
|
||||
@@ -13,11 +13,21 @@ Call Stack \(most recent call first\):
|
||||
This warning is for project developers\. Use -Wno-dev to suppress it\.
|
||||
|
||||
CMake Error at badargs2\.cmake:[0-9]+ \(file\):
|
||||
file Keywords missing values:
|
||||
Error after keyword "BUNDLE_EXECUTABLE":
|
||||
|
||||
missing required value
|
||||
|
||||
Error after keyword "CONFLICTING_DEPENDENCIES_PREFIX":
|
||||
|
||||
missing required value
|
||||
|
||||
Error after keyword "RESOLVED_DEPENDENCIES_VAR":
|
||||
|
||||
missing required value
|
||||
|
||||
Error after keyword "UNRESOLVED_DEPENDENCIES_VAR":
|
||||
|
||||
missing required value
|
||||
|
||||
RESOLVED_DEPENDENCIES_VAR
|
||||
UNRESOLVED_DEPENDENCIES_VAR
|
||||
CONFLICTING_DEPENDENCIES_PREFIX
|
||||
BUNDLE_EXECUTABLE
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)$
|
||||
|
||||
@@ -1,2 +1,7 @@
|
||||
CMake Error at REAL_PATH-no-base-dir.cmake:[0-9]+ \(file\):
|
||||
file BASE_DIRECTORY requires a value
|
||||
^CMake Error at REAL_PATH-no-base-dir.cmake:[0-9]+ \(file\):
|
||||
Error after keyword "BASE_DIRECTORY":
|
||||
|
||||
missing required value
|
||||
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)$
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
{ symbol: [ "std::__decay_and_strip<cmFindPackageCommand::PathLabel &>::__type", private, "\"cmConfigure.h\"", public ] },
|
||||
{ symbol: [ "std::__decay_and_strip<cmGlobalNinjaGenerator::TargetAlias &>::__type", private, "\"cmConfigure.h\"", public ] },
|
||||
{ symbol: [ "std::__decay_and_strip<__gnu_cxx::__normal_iterator<const cmCTestTestHandler::cmCTestTestProperties *, std::vector<cmCTestTestHandler::cmCTestTestProperties, std::allocator<cmCTestTestHandler::cmCTestTestProperties> > > &>::__type", private, "\"cmConfigure.h\"", public ] },
|
||||
{ symbol: [ "std::__decay_and_strip<const __gnu_cxx::__normal_iterator<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &, void *)> > *, std::vector<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &, void *)> >, std::allocator<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &, void *)> > > > > &>::__type", private, "\"cmConfigure.h\"", public ] },
|
||||
{ symbol: [ "std::__decay_and_strip<const __gnu_cxx::__normal_iterator<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &)> > *, std::vector<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &)> >, std::allocator<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &)> > > > > &>::__type", private, "\"cmConfigure.h\"", public ] },
|
||||
{ symbol: [ "std::__success_type<std::chrono::duration<double, std::ratio<1, 1> > >::type", private, "\"cmConfigure.h\"", public ] },
|
||||
{ symbol: [ "std::__success_type<std::chrono::duration<long, std::ratio<1, 1000000000> > >::type", private, "\"cmConfigure.h\"", public ] },
|
||||
{ symbol: [ "std::enable_if<true, std::chrono::duration<long, std::ratio<1, 1> > >::type", private, "\"cmConfigure.h\"", public ] },
|
||||
|
||||
Reference in New Issue
Block a user