21#include "StringTools.hpp"
28#define CLI11_ERROR_DEF(parent, name) \
30 name(std::string ename, std::string msg, int exit_code) : parent(std::move(ename), std::move(msg), exit_code) {} \
31 name(std::string ename, std::string msg, ExitCodes exit_code) \
32 : parent(std::move(ename), std::move(msg), exit_code) {} \
35 name(std::string msg, ExitCodes exit_code) : parent(#name, std::move(msg), exit_code) {} \
36 name(std::string msg, int exit_code) : parent(#name, std::move(msg), exit_code) {}
39#define CLI11_ERROR_SIMPLE(name) \
40 explicit name(std::string msg) : name(#name, std::move(msg), ExitCodes::name) {}
44enum class ExitCodes :
int {
46 IncorrectConstruction = 100,
73class Error :
public std::runtime_error {
75 std::string error_name{
"Error"};
78 CLI11_NODISCARD
int get_exit_code()
const {
return actual_exit_code; }
80 CLI11_NODISCARD std::string get_name()
const {
return error_name; }
82 Error(std::string name, std::string msg,
int exit_code =
static_cast<int>(ExitCodes::BaseClass))
83 : runtime_error(msg), actual_exit_code(exit_code), error_name(std::move(name)) {}
85 Error(std::string name, std::string msg, ExitCodes exit_code)
86 :
Error(std::move(name), std::move(msg),
static_cast<int>(exit_code)) {}
114 name +
": You can't change expected arguments after you've changed the multi option policy!");
120 return IncorrectConstruction(name +
": multi_option_policy only works for flags and exact value options");
130 return BadNameString(
"Long names strings require 2 dashes " + name);
137 return BadNameString(
"Names '-','--','++' are reserved and not allowed as option names " + name);
139 static BadNameString MultiPositionalNames(std::string name) {
140 return BadNameString(
"Only one positional name allowed, remove: " + name);
150 return {name +
" requires " + other, ExitCodes::OptionAlreadyAdded};
153 return {name +
" excludes " + other, ExitCodes::OptionAlreadyAdded};
169 Success() :
Success(
"Successfully completed, should be caught and quit", ExitCodes::Success) {}
175 CallForHelp() :
CallForHelp(
"This should be caught in your main function, see examples", ExitCodes::Success) {}
182 :
CallForAllHelp(
"This should be caught in your main function, see examples", ExitCodes::Success) {}
189 :
CallForVersion(
"This should be caught in your main function, see examples", ExitCodes::Success) {}
202 static FileError Missing(std::string name) {
return FileError(name +
" was not readable (missing?)"); }
210 :
ConversionError(
"The value " + member +
" is not an allowed value for " + name) {}
212 :
ConversionError(
"Could not convert: " + name +
" = " + detail::join(results)) {}
233 if(min_subcom == 1) {
236 return {
"Requires at least " + std::to_string(min_subcom) +
" subcommands", ExitCodes::RequiredError};
239 Option(std::size_t min_option, std::size_t max_option, std::size_t used,
const std::string &option_list) {
240 if((min_option == 1) && (max_option == 1) && (used == 0))
241 return RequiredError(
"Exactly 1 option from [" + option_list +
"]");
242 if((min_option == 1) && (max_option == 1) && (used > 1)) {
243 return {
"Exactly 1 option from [" + option_list +
"] is required but " + std::to_string(used) +
245 ExitCodes::RequiredError};
247 if((min_option == 1) && (used == 0))
248 return RequiredError(
"At least 1 option from [" + option_list +
"]");
249 if(used < min_option) {
250 return {
"Requires at least " + std::to_string(min_option) +
" options used but only " +
251 std::to_string(used) +
" were given from [" + option_list +
"]",
252 ExitCodes::RequiredError};
255 return {
"Requires at most 1 options be given from [" + option_list +
"]", ExitCodes::RequiredError};
257 return {
"Requires at most " + std::to_string(max_option) +
" options be used but " + std::to_string(used) +
258 " were given from [" + option_list +
"]",
259 ExitCodes::RequiredError};
268 :
ArgumentMismatch(expected > 0 ? (
"Expected exactly " + std::to_string(expected) +
" arguments to " + name +
269 ", got " + std::to_string(received))
270 : (
"Expected at least " + std::to_string(-expected) +
" arguments to " + name +
271 ", got " + std::to_string(received)),
272 ExitCodes::ArgumentMismatch) {}
274 static ArgumentMismatch AtLeast(std::string name,
int num, std::size_t received) {
275 return ArgumentMismatch(name +
": At least " + std::to_string(num) +
" required but received " +
276 std::to_string(received));
278 static ArgumentMismatch AtMost(std::string name,
int num, std::size_t received) {
279 return ArgumentMismatch(name +
": At most " + std::to_string(num) +
" required but received " +
280 std::to_string(received));
282 static ArgumentMismatch TypedAtLeast(std::string name,
int num, std::string type) {
283 return ArgumentMismatch(name +
": " + std::to_string(num) +
" required " + type +
" missing");
288 static ArgumentMismatch PartialType(std::string name,
int num, std::string type) {
289 return ArgumentMismatch(name +
": " + type +
" only partially specified: " + std::to_string(num) +
290 " required for each element");
298 :
RequiresError(curname +
" requires " + subname, ExitCodes::RequiresError) {}
305 :
ExcludesError(curname +
" excludes " + subname, ExitCodes::ExcludesError) {}
311 explicit ExtrasError(std::vector<std::string> args)
312 :
ExtrasError((args.size() > 1 ?
"The following arguments were not expected: "
313 :
"The following argument was not expected: ") +
314 detail::join(args,
" "),
315 ExitCodes::ExtrasError) {}
316 ExtrasError(
const std::string &name, std::vector<std::string> args)
317 :
ExtrasError((name.empty() ? std::string{} : name +
": ") +
318 (args.size() > 1 ?
"The following arguments were not expected: "
319 :
"The following argument was not expected: ") +
320 detail::join(args,
" "),
321 ExitCodes::ExtrasError) {}
329 static ConfigError NotConfigurable(std::string item) {
330 return ConfigError(item +
": This option is not allowed in a configuration file");
338 :
InvalidError(name +
": Too many positional arguments with unlimited expected args", ExitCodes::InvalidError) {
357#undef CLI11_ERROR_DEF
358#undef CLI11_ERROR_SIMPLE
Thrown when the wrong number of arguments has been received.
Definition Error.hpp:264
Thrown on construction of a bad name.
Definition Error.hpp:125
Usually something like –help-all on command line.
Definition Error.hpp:179
-h or –help on command line
Definition Error.hpp:173
-v or –version on command line
Definition Error.hpp:186
Thrown when extra values are found in an INI file.
Definition Error.hpp:325
Construction errors (not in parsing)
Definition Error.hpp:92
Thrown when conversion call back fails, such as when an int fails to coerce to a string.
Definition Error.hpp:206
All errors derive from this one.
Definition Error.hpp:73
Thrown when an excludes option is present.
Definition Error.hpp:302
Thrown when parsing an INI file and it is missing.
Definition Error.hpp:199
Thrown when an option is set to conflicting values (non-vector and multi args, for example)
Definition Error.hpp:97
Thrown when validation fails before parsing.
Definition Error.hpp:335
Thrown when an option already exists.
Definition Error.hpp:145
Definition Option.hpp:259
Thrown when counting a nonexistent option.
Definition Error.hpp:352
Anything that can error in Parse.
Definition Error.hpp:160
Thrown when a required option is missing.
Definition Error.hpp:229
Thrown when a requires option is missing.
Definition Error.hpp:295
Does not output a diagnostic in CLI11_PARSE, but allows main() to return with a specific error code.
Definition Error.hpp:193
This is a successful completion on parsing, supposed to exit.
Definition Error.hpp:167
Thrown when validation of results fails.
Definition Error.hpp:222