mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-11 00:11:07 -06:00
cmArgumentParser: Model maybe-empty and non-empty lists with wrapper types
Previously bindings to `std::vector<std::string>` required at least one value. Some clients have been filtering `keywordsMissingValue` to support keywords followed by empty lists. Instead, require clients to specify whether a keyword's list can be empty as part of the binding type.
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <cm/memory>
|
||||
#include <cm/optional>
|
||||
|
||||
#include "cmArgumentParserTypes.h" // IWYU pragma: keep
|
||||
#include "cmCTestHandlerCommand.h"
|
||||
#include "cmCommand.h"
|
||||
|
||||
@@ -44,5 +45,5 @@ protected:
|
||||
void BindArguments() override;
|
||||
cmCTestGenericHandler* InitializeHandler() override;
|
||||
|
||||
cm::optional<std::vector<std::string>> Labels;
|
||||
cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Labels;
|
||||
};
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <cm/optional>
|
||||
|
||||
#include "cmArgumentParserTypes.h"
|
||||
#include "cmCTestHandlerCommand.h"
|
||||
|
||||
class cmCommand;
|
||||
@@ -50,7 +51,7 @@ protected:
|
||||
std::string RetryDelay;
|
||||
std::string SubmitURL;
|
||||
|
||||
cm::optional<std::vector<std::string>> Files;
|
||||
std::vector<std::string> HttpHeaders;
|
||||
cm::optional<std::vector<std::string>> Parts;
|
||||
cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Files;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> HttpHeaders;
|
||||
cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Parts;
|
||||
};
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <cm/memory>
|
||||
|
||||
#include "cmArgumentParserTypes.h"
|
||||
#include "cmCTestHandlerCommand.h"
|
||||
#include "cmCommand.h"
|
||||
|
||||
@@ -45,5 +46,5 @@ protected:
|
||||
void CheckArguments() override;
|
||||
cmCTestGenericHandler* InitializeHandler() override;
|
||||
|
||||
std::vector<std::string> Files;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Files;
|
||||
};
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "cmArgumentParserTypes.h"
|
||||
|
||||
namespace ArgumentParser {
|
||||
|
||||
auto ActionMap::Emplace(cm::string_view name, Action action)
|
||||
@@ -44,7 +46,14 @@ void Instance::Bind(std::string& val)
|
||||
this->ExpectValue = true;
|
||||
}
|
||||
|
||||
void Instance::Bind(std::vector<std::string>& val)
|
||||
void Instance::Bind(MaybeEmpty<std::vector<std::string>>& val)
|
||||
{
|
||||
this->CurrentString = nullptr;
|
||||
this->CurrentList = &val;
|
||||
this->ExpectValue = false;
|
||||
}
|
||||
|
||||
void Instance::Bind(NonEmpty<std::vector<std::string>>& val)
|
||||
{
|
||||
this->CurrentString = nullptr;
|
||||
this->CurrentList = &val;
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <cm/string_view>
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmArgumentParserTypes.h" // IWYU pragma: keep
|
||||
|
||||
namespace ArgumentParser {
|
||||
|
||||
class Instance;
|
||||
@@ -37,7 +39,8 @@ public:
|
||||
|
||||
void Bind(bool& val);
|
||||
void Bind(std::string& val);
|
||||
void Bind(std::vector<std::string>& val);
|
||||
void Bind(MaybeEmpty<std::vector<std::string>>& val);
|
||||
void Bind(NonEmpty<std::vector<std::string>>& val);
|
||||
void Bind(std::vector<std::vector<std::string>>& val);
|
||||
|
||||
// cm::optional<> records the presence the keyword to which it binds.
|
||||
|
||||
19
Source/cmArgumentParserTypes.h
Normal file
19
Source/cmArgumentParserTypes.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
namespace ArgumentParser {
|
||||
|
||||
template <typename T>
|
||||
struct MaybeEmpty : public T
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct NonEmpty : public T
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace ArgumentParser
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmArgumentParser.h"
|
||||
#include "cmArgumentParserTypes.h"
|
||||
#include "cmDependencyProvider.h"
|
||||
#include "cmExecutionStatus.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
@@ -237,7 +238,7 @@ bool cmCMakeLanguageCommandSET_DEPENDENCY_PROVIDER(
|
||||
struct SetProviderArgs
|
||||
{
|
||||
std::string Command;
|
||||
std::vector<std::string> Methods;
|
||||
ArgumentParser::NonEmpty<std::vector<std::string>> Methods;
|
||||
};
|
||||
|
||||
auto const ArgsParser =
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmArgumentParser.h"
|
||||
#include "cmArgumentParserTypes.h"
|
||||
#include "cmExecutionStatus.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmProperty.h"
|
||||
@@ -51,8 +52,8 @@ bool cmDefinePropertyCommand(std::vector<std::string> const& args,
|
||||
// Parse remaining arguments.
|
||||
bool inherited = false;
|
||||
std::string PropertyName;
|
||||
std::vector<std::string> BriefDocs;
|
||||
std::vector<std::string> FullDocs;
|
||||
ArgumentParser::NonEmpty<std::vector<std::string>> BriefDocs;
|
||||
ArgumentParser::NonEmpty<std::vector<std::string>> FullDocs;
|
||||
std::string initializeFromVariable;
|
||||
|
||||
cmArgumentParser<void> parser;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "cmsys/RegularExpression.hxx"
|
||||
|
||||
#include "cmArgumentParser.h"
|
||||
#include "cmArgumentParserTypes.h"
|
||||
#include "cmExecutionStatus.h"
|
||||
#include "cmExperimental.h"
|
||||
#include "cmExportBuildAndroidMKGenerator.h"
|
||||
@@ -58,7 +59,7 @@ bool cmExportCommand(std::vector<std::string> const& args,
|
||||
struct Arguments
|
||||
{
|
||||
std::string ExportSetName;
|
||||
cm::optional<std::vector<std::string>> Targets;
|
||||
cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Targets;
|
||||
std::string Namespace;
|
||||
std::string Filename;
|
||||
std::string AndroidMKFile;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmArgumentParser.h"
|
||||
#include "cmArgumentParserTypes.h"
|
||||
#include "cmCMakePath.h"
|
||||
#include "cmCryptoHash.h"
|
||||
#include "cmELF.h"
|
||||
@@ -2505,7 +2506,7 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
|
||||
cm::optional<std::string> NewLineStyle;
|
||||
bool NoSourcePermissions = false;
|
||||
bool UseSourcePermissions = false;
|
||||
std::vector<std::string> FilePermissions;
|
||||
ArgumentParser::NonEmpty<std::vector<std::string>> FilePermissions;
|
||||
};
|
||||
|
||||
static auto const parser =
|
||||
@@ -3052,17 +3053,18 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
|
||||
std::string ConflictingDependenciesPrefix;
|
||||
std::string RPathPrefix;
|
||||
std::string BundleExecutable;
|
||||
std::vector<std::string> Executables;
|
||||
std::vector<std::string> Libraries;
|
||||
std::vector<std::string> Directories;
|
||||
std::vector<std::string> Modules;
|
||||
std::vector<std::string> PreIncludeRegexes;
|
||||
std::vector<std::string> PreExcludeRegexes;
|
||||
std::vector<std::string> PostIncludeRegexes;
|
||||
std::vector<std::string> PostExcludeRegexes;
|
||||
std::vector<std::string> PostIncludeFiles;
|
||||
std::vector<std::string> PostExcludeFiles;
|
||||
std::vector<std::string> PostExcludeFilesStrict;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Executables;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Libraries;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Directories;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Modules;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> PreIncludeRegexes;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> PreExcludeRegexes;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> PostIncludeRegexes;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> PostExcludeRegexes;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> PostIncludeFiles;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> PostExcludeFiles;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>>
|
||||
PostExcludeFilesStrict;
|
||||
};
|
||||
|
||||
static auto const parser =
|
||||
@@ -3098,25 +3100,10 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Arguments that are allowed to be empty lists. Keep entries sorted!
|
||||
static const std::vector<cm::string_view> LIST_ARGS = {
|
||||
"DIRECTORIES"_s,
|
||||
"EXECUTABLES"_s,
|
||||
"LIBRARIES"_s,
|
||||
"MODULES"_s,
|
||||
"POST_EXCLUDE_FILES"_s,
|
||||
"POST_EXCLUDE_FILES_STRICT"_s,
|
||||
"POST_EXCLUDE_REGEXES"_s,
|
||||
"POST_INCLUDE_FILES"_s,
|
||||
"POST_INCLUDE_REGEXES"_s,
|
||||
"PRE_EXCLUDE_REGEXES"_s,
|
||||
"PRE_INCLUDE_REGEXES"_s,
|
||||
};
|
||||
auto kwbegin = keywordsMissingValues.cbegin();
|
||||
auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
|
||||
if (kwend != kwbegin) {
|
||||
status.SetError(cmStrCat("Keywords missing values:\n ",
|
||||
cmJoin(cmMakeRange(kwbegin, kwend), "\n ")));
|
||||
if (!keywordsMissingValues.empty()) {
|
||||
status.SetError(
|
||||
cmStrCat("Keywords missing values:\n ",
|
||||
cmJoin(cmMakeRange(keywordsMissingValues), "\n ")));
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
return false;
|
||||
}
|
||||
@@ -3362,7 +3349,8 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
|
||||
std::string CompressionLevel;
|
||||
std::string MTime;
|
||||
bool Verbose = false;
|
||||
std::vector<std::string> Paths;
|
||||
// "PATHS" requires at least one value, but use a custom check below.
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Paths;
|
||||
};
|
||||
|
||||
static auto const parser =
|
||||
@@ -3393,7 +3381,6 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
|
||||
// value, but it has long been accidentally accepted without
|
||||
// one and treated as if an empty value were given.
|
||||
// Fixing this would require a policy.
|
||||
"PATHS"_s, // "PATHS" is here only so we can issue a custom error below.
|
||||
};
|
||||
auto kwbegin = keywordsMissingValues.cbegin();
|
||||
auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
|
||||
@@ -3496,7 +3483,7 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
|
||||
bool Verbose = false;
|
||||
bool ListOnly = false;
|
||||
std::string Destination;
|
||||
std::vector<std::string> Patterns;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Patterns;
|
||||
bool Touch = false;
|
||||
};
|
||||
|
||||
@@ -3520,13 +3507,10 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Arguments that are allowed to be empty lists. Keep entries sorted!
|
||||
static const std::vector<cm::string_view> LIST_ARGS = { "PATTERNS"_s };
|
||||
auto kwbegin = keywordsMissingValues.cbegin();
|
||||
auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
|
||||
if (kwend != kwbegin) {
|
||||
status.SetError(cmStrCat("Keywords missing values:\n ",
|
||||
cmJoin(cmMakeRange(kwbegin, kwend), "\n ")));
|
||||
if (!keywordsMissingValues.empty()) {
|
||||
status.SetError(
|
||||
cmStrCat("Keywords missing values:\n ",
|
||||
cmJoin(cmMakeRange(keywordsMissingValues), "\n ")));
|
||||
cmSystemTools::SetFatalErrorOccurred();
|
||||
return false;
|
||||
}
|
||||
@@ -3620,9 +3604,9 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
|
||||
|
||||
struct Arguments
|
||||
{
|
||||
std::vector<std::string> Permissions;
|
||||
std::vector<std::string> FilePermissions;
|
||||
std::vector<std::string> DirectoryPermissions;
|
||||
ArgumentParser::NonEmpty<std::vector<std::string>> Permissions;
|
||||
ArgumentParser::NonEmpty<std::vector<std::string>> FilePermissions;
|
||||
ArgumentParser::NonEmpty<std::vector<std::string>> DirectoryPermissions;
|
||||
};
|
||||
|
||||
static auto const parser =
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "cmsys/Glob.hxx"
|
||||
|
||||
#include "cmArgumentParser.h"
|
||||
#include "cmArgumentParserTypes.h"
|
||||
#include "cmExecutionStatus.h"
|
||||
#include "cmExperimental.h"
|
||||
#include "cmExportSet.h"
|
||||
@@ -57,13 +58,13 @@ namespace {
|
||||
|
||||
struct RuntimeDependenciesArgs
|
||||
{
|
||||
std::vector<std::string> Directories;
|
||||
std::vector<std::string> PreIncludeRegexes;
|
||||
std::vector<std::string> PreExcludeRegexes;
|
||||
std::vector<std::string> PostIncludeRegexes;
|
||||
std::vector<std::string> PostExcludeRegexes;
|
||||
std::vector<std::string> PostIncludeFiles;
|
||||
std::vector<std::string> PostExcludeFiles;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Directories;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> PreIncludeRegexes;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> PreExcludeRegexes;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> PostIncludeRegexes;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> PostExcludeRegexes;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> PostIncludeFiles;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> PostExcludeFiles;
|
||||
};
|
||||
|
||||
auto const RuntimeDependenciesArgHelper =
|
||||
@@ -406,18 +407,18 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
|
||||
struct ArgVectors
|
||||
{
|
||||
std::vector<std::string> Archive;
|
||||
std::vector<std::string> Library;
|
||||
std::vector<std::string> Runtime;
|
||||
std::vector<std::string> Object;
|
||||
std::vector<std::string> Framework;
|
||||
std::vector<std::string> Bundle;
|
||||
std::vector<std::string> Includes;
|
||||
std::vector<std::string> PrivateHeader;
|
||||
std::vector<std::string> PublicHeader;
|
||||
std::vector<std::string> Resource;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Archive;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Library;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Runtime;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Object;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Framework;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Bundle;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Includes;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> PrivateHeader;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> PublicHeader;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Resource;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> CxxModulesBmi;
|
||||
std::vector<std::vector<std::string>> FileSets;
|
||||
std::vector<std::string> CxxModulesBmi;
|
||||
};
|
||||
|
||||
static auto const argHelper =
|
||||
@@ -441,9 +442,10 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
// now parse the generic args (i.e. the ones not specialized on LIBRARY/
|
||||
// ARCHIVE, RUNTIME etc. (see above)
|
||||
// These generic args also contain the targets and the export stuff
|
||||
std::vector<std::string> targetList;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> targetList;
|
||||
std::string exports;
|
||||
cm::optional<std::vector<std::string>> runtimeDependenciesArgVector;
|
||||
cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>>
|
||||
runtimeDependenciesArgVector;
|
||||
std::string runtimeDependencySetArg;
|
||||
std::vector<std::string> unknownArgs;
|
||||
cmInstallCommandArguments genericArgs(helper.DefaultComponentName);
|
||||
@@ -1251,10 +1253,10 @@ bool HandleImportedRuntimeArtifactsMode(std::vector<std::string> const& args,
|
||||
|
||||
struct ArgVectors
|
||||
{
|
||||
std::vector<std::string> Library;
|
||||
std::vector<std::string> Runtime;
|
||||
std::vector<std::string> Framework;
|
||||
std::vector<std::string> Bundle;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Library;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Runtime;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Framework;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Bundle;
|
||||
};
|
||||
|
||||
static auto const argHelper = cmArgumentParser<ArgVectors>{}
|
||||
@@ -1268,7 +1270,7 @@ bool HandleImportedRuntimeArtifactsMode(std::vector<std::string> const& args,
|
||||
|
||||
// now parse the generic args (i.e. the ones not specialized on LIBRARY,
|
||||
// RUNTIME etc. (see above)
|
||||
std::vector<std::string> targetList;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> targetList;
|
||||
std::string runtimeDependencySetArg;
|
||||
std::vector<std::string> unknownArgs;
|
||||
cmInstallCommandArguments genericArgs(helper.DefaultComponentName);
|
||||
@@ -1509,7 +1511,7 @@ bool HandleFilesMode(std::vector<std::string> const& args,
|
||||
// This is the FILES mode.
|
||||
bool programs = (args[0] == "PROGRAMS");
|
||||
cmInstallCommandArguments ica(helper.DefaultComponentName);
|
||||
std::vector<std::string> files;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> files;
|
||||
ica.Bind(programs ? "PROGRAMS"_s : "FILES"_s, files);
|
||||
std::vector<std::string> unknownArgs;
|
||||
ica.Parse(args, &unknownArgs);
|
||||
@@ -2140,9 +2142,9 @@ bool HandleRuntimeDependencySetMode(std::vector<std::string> const& args,
|
||||
|
||||
struct ArgVectors
|
||||
{
|
||||
std::vector<std::string> Library;
|
||||
std::vector<std::string> Runtime;
|
||||
std::vector<std::string> Framework;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Library;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Runtime;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Framework;
|
||||
};
|
||||
|
||||
static auto const argHelper = cmArgumentParser<ArgVectors>{}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "cmArgumentParser.h"
|
||||
#include "cmArgumentParserTypes.h"
|
||||
|
||||
class cmInstallCommandArguments : public cmArgumentParser<void>
|
||||
{
|
||||
@@ -44,8 +45,8 @@ private:
|
||||
std::string NamelinkComponent;
|
||||
bool ExcludeFromAll = false;
|
||||
std::string Rename;
|
||||
std::vector<std::string> Permissions;
|
||||
std::vector<std::string> Configurations;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Permissions;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Configurations;
|
||||
bool Optional = false;
|
||||
bool NamelinkOnly = false;
|
||||
bool NamelinkSkip = false;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <cm/string_view>
|
||||
|
||||
#include "cmArgumentParser.h"
|
||||
#include "cmArgumentParserTypes.h"
|
||||
#include "cmExecutionStatus.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
@@ -41,7 +42,8 @@ namespace {
|
||||
|
||||
using options_map = std::map<std::string, bool>;
|
||||
using single_map = std::map<std::string, std::string>;
|
||||
using multi_map = std::map<std::string, std::vector<std::string>>;
|
||||
using multi_map =
|
||||
std::map<std::string, ArgumentParser::NonEmpty<std::vector<std::string>>>;
|
||||
using options_set = std::set<cm::string_view>;
|
||||
|
||||
struct UserArgumentParser : public cmArgumentParser<void>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmArgumentParser.h"
|
||||
#include "cmArgumentParserTypes.h"
|
||||
#include "cmExperimental.h"
|
||||
#include "cmFileSet.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
@@ -28,8 +29,8 @@ struct FileSetArgs
|
||||
{
|
||||
std::string Type;
|
||||
std::string FileSet;
|
||||
std::vector<std::string> BaseDirs;
|
||||
std::vector<std::string> Files;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> BaseDirs;
|
||||
ArgumentParser::MaybeEmpty<std::vector<std::string>> Files;
|
||||
};
|
||||
|
||||
auto const FileSetArgsParser = cmArgumentParser<FileSetArgs>()
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmArgumentParser.h"
|
||||
#include "cmArgumentParserTypes.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -23,11 +24,12 @@ struct Result
|
||||
cm::optional<std::string> String2;
|
||||
cm::optional<std::string> String3;
|
||||
|
||||
std::vector<std::string> List1;
|
||||
std::vector<std::string> List2;
|
||||
cm::optional<std::vector<std::string>> List3;
|
||||
cm::optional<std::vector<std::string>> List4;
|
||||
cm::optional<std::vector<std::string>> List5;
|
||||
ArgumentParser::NonEmpty<std::vector<std::string>> List1;
|
||||
ArgumentParser::NonEmpty<std::vector<std::string>> List2;
|
||||
cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> List3;
|
||||
cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> List4;
|
||||
cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> List5;
|
||||
cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> List6;
|
||||
|
||||
std::vector<std::vector<std::string>> Multi1;
|
||||
std::vector<std::vector<std::string>> Multi2;
|
||||
@@ -48,6 +50,7 @@ std::initializer_list<cm::string_view> const args = {
|
||||
"LIST_3", "foo", // ... with continuation
|
||||
"LIST_4", // list arg missing values, presence captured
|
||||
// "LIST_5", // list arg that is not present
|
||||
"LIST_6", // list arg allowed to be empty
|
||||
"MULTI_2", // multi list with 0 lists
|
||||
"MULTI_3", "foo", "bar", // multi list with first list with two elems
|
||||
"MULTI_3", "bar", "foo", // multi list with second list with two elems
|
||||
@@ -88,6 +91,8 @@ bool verifyResult(Result const& result,
|
||||
ASSERT_TRUE(result.List4);
|
||||
ASSERT_TRUE(result.List4->empty());
|
||||
ASSERT_TRUE(!result.List5);
|
||||
ASSERT_TRUE(result.List6);
|
||||
ASSERT_TRUE(result.List6->empty());
|
||||
|
||||
ASSERT_TRUE(result.Multi1.empty());
|
||||
ASSERT_TRUE(result.Multi2.size() == 1);
|
||||
@@ -122,6 +127,7 @@ bool testArgumentParserDynamic()
|
||||
.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)
|
||||
@@ -145,6 +151,7 @@ bool testArgumentParserStatic()
|
||||
.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)
|
||||
|
||||
Reference in New Issue
Block a user