C++ Utilities
5.4.0
Useful C++ classes and routines such as argument parser, IO and conversion utilities
|
Go to the documentation of this file. 1 #ifndef APPLICATION_UTILITIES_ARGUMENTPARSER_H
2 #define APPLICATION_UTILITIES_ARGUMENTPARSER_H
4 #include "../conversion/stringconversion.h"
5 #include "../misc/traits.h"
8 #include <initializer_list>
11 #ifdef CPP_UTILITIES_DEBUG_BUILD
23 const char *
name =
nullptr;
26 const char *
url =
nullptr;
45 #define SET_DEPENDENCY_INFO ::CppUtilities::applicationInfo.dependencyVersions = DEPENCENCY_VERSIONS
52 #define SET_APPLICATION_INFO \
53 ::CppUtilities::applicationInfo.name = APP_NAME; \
54 ::CppUtilities::applicationInfo.author = APP_AUTHOR; \
55 ::CppUtilities::applicationInfo.version = APP_VERSION; \
56 ::CppUtilities::applicationInfo.url = APP_URL; \
57 ::CppUtilities::applicationInfo.domain = APP_DOMAIN; \
58 ::CppUtilities::applicationInfo.description = APP_DESCRIPTION; \
59 ::CppUtilities::applicationInfo.license = PROJECT_LICENSE; \
60 ::CppUtilities::applicationInfo.credits = APP_CREDITS; \
98 return static_cast<ParseArgumentBehavior>(
static_cast<unsigned char>(lhs) |
static_cast<unsigned char>(rhs));
103 return static_cast<bool>(
static_cast<unsigned char>(lhs) &
static_cast<unsigned char>(rhs));
129 return static_cast<ValueCompletionBehavior>(
static_cast<unsigned char>(lhs) |
static_cast<unsigned char>(rhs));
134 return static_cast<bool>(
static_cast<unsigned char>(lhs) &
static_cast<unsigned char>(rhs));
145 namespace ValueConversion {
146 template <
typename TargetType, Traits::EnableIf<std::is_same<TargetType, std::
string>> * =
nullptr> TargetType
convert(
const char *value)
148 return std::string(value);
151 template <
typename TargetType, Traits::EnableIf<std::is_arithmetic<TargetType>> * =
nullptr> TargetType
convert(
const char *value)
153 return stringToNumber<TargetType>(value);
159 const std::string errorMessage;
160 const char *
const valueToConvert;
161 const char *
const targetTypeName;
163 [[noreturn]]
void throwFailure(
const std::vector<Argument *> &argumentPath)
const;
166 template <std::size_t N,
typename FirstTargetType,
typename... RemainingTargetTypes>
struct ArgumentValueConverter {
167 static std::tuple<FirstTargetType, RemainingTargetTypes...> convertValues(std::vector<const char *>::const_iterator firstValue)
169 return std::tuple_cat(ArgumentValueConverter<1, FirstTargetType>::convertValues(firstValue),
170 ArgumentValueConverter<N - 1, RemainingTargetTypes...>::convertValues(firstValue + 1));
174 template <
typename FirstTargetType,
typename... RemainingTargetTypes>
struct ArgumentValueConverter<1, FirstTargetType, RemainingTargetTypes...> {
175 static std::tuple<FirstTargetType> convertValues(std::vector<const char *>::const_iterator firstValue)
179 return std::make_tuple<FirstTargetType>(ValueConversion::convert<FirstTargetType>(*firstValue));
180 }
catch (
const ConversionException &exception) {
181 throw ArgumentValueConversionError{ exception.what(), *firstValue,
typeid(FirstTargetType).name() };
213 template <
typename... RemainingTargetTypes> std::tuple<RemainingTargetTypes...> convertValues()
const;
216 [[noreturn]]
void throwNumberOfValuesNotSufficient(
unsigned long valuesToConvert)
const;
226 constexpr
auto valuesToConvert =
sizeof...(RemainingTargetTypes);
227 if (
values.size() < valuesToConvert) {
228 throwNumberOfValuesNotSufficient(valuesToConvert);
231 return ValueConversion::Helper::ArgumentValueConverter<valuesToConvert, RemainingTargetTypes...>::convertValues(
values.cbegin());
232 }
catch (
const ValueConversion::Helper::ArgumentValueConversionError &error) {
233 error.throwFailure(
path);
258 path.push_back(parent);
278 Argument(
const char *name,
char abbreviation =
'\0',
const char *description =
nullptr,
const char *example =
nullptr);
289 const char *name()
const;
290 void setName(
const char *name);
291 char abbreviation()
const;
292 void setAbbreviation(
char abbreviation);
293 const char *environmentVariable()
const;
294 void setEnvironmentVariable(
const char *environmentVariable);
295 const char *description()
const;
296 void setDescription(
const char *description);
297 const char *example()
const;
298 void setExample(
const char *example);
299 std::size_t requiredValueCount()
const;
300 void setRequiredValueCount(std::size_t requiredValueCount);
301 const std::vector<const char *> &valueNames()
const;
302 void setValueNames(std::initializer_list<const char *> valueNames);
303 void appendValueName(
const char *valueName);
304 void setConstraints(std::size_t minOccurrences, std::size_t maxOccurrences);
305 const std::vector<Argument *> &path(std::size_t occurrence = 0)
const;
306 bool isRequired()
const;
307 void setRequired(
bool required);
311 bool isCombinable()
const;
312 void setCombinable(
bool combinable);
313 bool isImplicit()
const;
314 void setImplicit(
bool implicit);
315 bool denotesOperation()
const;
316 void setDenotesOperation(
bool denotesOperation);
317 const CallbackFunction &callback()
const;
318 void setCallback(CallbackFunction callback);
322 bool hasSubArguments()
const;
324 void printInfo(std::ostream &os,
unsigned char indentation = 0)
const;
329 const char *preDefinedCompletionValues()
const;
330 void setPreDefinedCompletionValues(
const char *preDefinedCompletionValues);
333 const std::vector<const char *> &values(std::size_t occurrence = 0)
const;
334 template <
typename... TargetType> std::tuple<TargetType...> valuesAs(std::size_t occurrence = 0)
const;
335 template <
typename... TargetType> std::vector<std::tuple<TargetType...>> allValuesAs()
const;
337 const char *firstValue()
const;
338 bool allRequiredValuesPresent(std::size_t occurrence = 0)
const;
339 bool isPresent()
const;
340 std::size_t occurrences()
const;
341 std::size_t index(std::size_t occurrence)
const;
342 std::size_t minOccurrences()
const;
343 std::size_t maxOccurrences()
const;
344 bool isDeprecated()
const;
345 const Argument *deprecatedBy()
const;
346 void markAsDeprecated(
const Argument *deprecatedBy =
nullptr);
347 bool isMainArgument()
const;
348 bool isParentPresent()
const;
349 Argument *conflictsWithArgument()
const;
350 Argument *wouldConflictWithArgument()
const;
351 Argument *specifiedOperation()
const;
352 const std::vector<ArgumentOccurrence> &occurrenceInfo()
const;
353 std::vector<ArgumentOccurrence> &occurrenceInfo();
355 void resetRecursively();
365 bool matchesDenotation(
const char *denotation,
size_t denotationLength)
const;
369 const char *m_environmentVar;
370 const char *m_description;
371 const char *m_example;
372 std::size_t m_minOccurrences;
373 std::size_t m_maxOccurrences;
374 std::size_t m_requiredValueCount;
375 std::vector<const char *> m_valueNames;
377 std::vector<ArgumentOccurrence> m_occurrences;
384 const char *m_preDefinedCompletionValues;
390 return static_cast<Argument::Flags>(
static_cast<unsigned char>(lhs) |
static_cast<unsigned char>(rhs));
395 return static_cast<bool>(
static_cast<unsigned char>(lhs) &
static_cast<unsigned char>(rhs));
404 template <
typename... TargetType> std::tuple<TargetType...>
Argument::valuesAs(std::size_t occurrence)
const
406 return m_occurrences[occurrence].convertValues<TargetType...>();
416 std::vector<std::tuple<TargetType...>> res;
417 res.reserve(m_occurrences.size());
418 for (
const auto &occurrence : m_occurrences) {
419 res.emplace_back(occurrence.convertValues<TargetType...>());
431 OperationArgument(
const char *name,
char abbreviation =
'\0',
const char *description =
nullptr,
const char *example =
nullptr);
436 ConfigValueArgument(
const char *name,
char abbreviation =
'\0',
const char *description =
nullptr,
437 std::initializer_list<const char *> valueNames = std::initializer_list<const char *>());
460 void addMainArgument(
Argument *argument);
463 void printHelp(std::ostream &os)
const;
464 void parseArgs(
int argc,
const char *
const *argv,
467 void readArgs(
int argc,
const char *
const *argv);
469 void checkConstraints();
470 void invokeCallbacks();
473 unsigned int actualArgumentCount()
const;
474 const char *executable()
const;
478 void setDefaultArgument(
Argument *argument);
479 Argument *specifiedOperation()
const;
480 bool isUncombinableMainArgPresent()
const;
481 void setExitFunction(std::function<
void(
int)> exitFunction);
491 int argc,
const char *
const *argv,
unsigned int currentWordIndex,
const ArgumentReader &reader)
const;
492 std::string findSuggestions(
int argc,
const char *
const *argv,
unsigned int cursorPos,
const ArgumentReader &reader)
const;
493 void printBashCompletion(
int argc,
const char *
const *argv,
unsigned int cursorPos,
const ArgumentReader &reader)
const;
496 void invokeExit(
int code);
499 unsigned int m_actualArgc;
500 const char *m_executable;
505 std::function<void(
int)> m_exitFunction;
527 #ifdef CPP_UTILITIES_DEBUG_BUILD
529 assert(*
name !=
'-');
530 for (
const char *c =
name; *c; ++c) {
531 assert(*c !=
' ' && *c !=
'=' && *c !=
'\'' && *c !=
'\"' && *c !=
'\n' && *c !=
'\r');
545 return m_abbreviation;
568 return m_environmentVar;
587 return m_description;
628 return m_occurrences[occurrence].values;
646 return m_requiredValueCount;
705 m_valueNames.emplace_back(valueName);
714 || (m_occurrences[occurrence].values.size() >=
static_cast<std::size_t
>(m_requiredValueCount));
740 return !m_occurrences.empty();
748 return m_occurrences.size();
756 return m_occurrences[occurrence].index;
766 return m_minOccurrences;
776 return m_maxOccurrences;
789 return m_deprecatedBy;
817 inline const std::vector<Argument *> &
Argument::path(std::size_t occurrence)
const
819 return m_occurrences[occurrence].path;
833 return m_minOccurrences;
846 if (!m_minOccurrences) {
847 m_minOccurrences = 1;
850 m_minOccurrences = 0;
875 m_flags = add ? (m_flags |
flags)
876 :
static_cast<Argument::Flags>(
static_cast<std::underlying_type<Argument::Flags>::type
>(m_flags)
877 & ~static_cast<std::underlying_type<Argument::Flags>::type>(
flags));
936 return m_callbackFunction;
969 return !m_subArgs.empty();
1006 return m_valueCompletionBehavior;
1017 m_valueCompletionBehavior = completionValues;
1025 return m_preDefinedCompletionValues;
1043 m_occurrences.clear();
1047 :
Argument(name, abbreviation, description, example)
1056 const char *name,
char abbreviation,
const char *description, std::initializer_list<const char *> valueNames)
1057 :
Argument(name, abbreviation, description)
1070 return m_occurrences;
1081 return m_occurrences;
1098 return m_actualArgc;
1106 return m_executable;
1116 return m_unknownArgBehavior;
1126 m_unknownArgBehavior = behavior;
1135 return m_defaultArg;
1144 m_defaultArg = argument;
1172 m_exitFunction = exitFunction;
1196 return m_noColorArg;
1204 return m_noColorArg;
1209 #endif // APPLICATION_UTILITIES_ARGUMENTPARSER_H
void setConstraints(std::size_t minOccurrences, std::size_t maxOccurrences)
Sets the allowed number of occurrences.
static constexpr std::size_t varValueCount
Denotes a variable number of values.
bool allRequiredValuesPresent(std::size_t occurrence=0) const
Returns an indication whether all required values are present.
const std::vector< ArgumentOccurrence > & occurrenceInfo() const
Returns information about all occurrences of the argument which have been detected when parsing.
void markAsDeprecated(const Argument *deprecatedBy=nullptr)
Marks the argument as deprecated.
std::vector< const char * > dependencyVersions
The Argument class is a wrapper for command line argument information.
const NoColorArgument & noColorArg() const
Returns the --no-color argument.
The ArgumentCompletionInfo struct holds information internally used for shell completion and suggesti...
The ArgumentParserTests class tests the ArgumentParser and Argument classes.
void setDescription(const char *description)
Sets the description of the argument.
void checkConstraints()
Checks whether contraints are violated.
void setRequiredValueCount(std::size_t requiredValueCount)
Sets the number of values which are required to be given for this argument.
const Argument * deprecatedBy() const
Returns the argument which obsoletes this argument.
The NoColorArgument class allows to specify whether use of escape codes or similar technique to provi...
ValueCompletionBehavior
The ValueCompletionBehavior enum specifies the items to be considered when generating completion for ...
void appendValueName(const char *valueName)
Appends a value name.
void setEnvironmentVariable(const char *environmentVariable)
Sets the environment variable queried when firstValue() is called.
const char * name() const
Returns the name of the argument.
void setExample(const char *example)
Sets the a usage example for the argument.
CPP_UTILITIES_EXPORT ApplicationInfo applicationInfo
Stores global application info used by ArgumentParser::printHelp() and AboutDialog.
Stores information about an application.
std::size_t occurrences() const
Returns how often the argument could be detected when parsing.
const CallbackFunction & callback() const
Returns the assigned callback function.
OperationArgument(const char *name, char abbreviation='\0', const char *description=nullptr, const char *example=nullptr)
The OperationArgument class is an Argument where denotesOperation() is true by default.
std::size_t minOccurrences() const
Returns the minimum number of occurrences.
const char * environmentVariable() const
Returns the environment variable queried when firstValue() is called.
const ArgumentVector & mainArguments() const
Returns the main arguments.
bool isDeprecated() const
ArgumentOccurrence(std::size_t index)
Constructs an argument occurrence for the specified index.
const std::vector< const char * > & values(std::size_t occurrence=0) const
Returns the parameter values for the specified occurrence of argument.
std::tuple< TargetType... > valuesAs(std::size_t occurrence=0) const
Converts the present values for the specified occurrence to the specified target types.
std::function< void(const ArgumentOccurrence &)> CallbackFunction
const char * example() const
Returns the usage example of the argument.
ValueCompletionBehavior valueCompletionBehaviour() const
Returns the items to be considered when generating completion for the values.
const ArgumentVector & subArguments() const
Returns the secondary arguments for this argument.
void setCallback(CallbackFunction callback)
Sets a callback function which will be called by the parser if the argument could be found and no par...
Argument * defaultArgument() const
Returns the default argument.
std::size_t requiredValueCount() const
Returns the number of values which are required to be given for this argument.
The ConfigValueArgument class is an Argument where setCombinable() is true by default.
void setImplicit(bool implicit)
Sets whether the argument is an implicit argument.
constexpr T max(T first, T second)
Returns the greatest of the given items.
std::initializer_list< Argument * > ArgumentInitializerList
ConfigValueArgument(const char *name, char abbreviation='\0', const char *description=nullptr, std::initializer_list< const char * > valueNames=std::initializer_list< const char * >())
Constructs a new ConfigValueArgument with the specified parameter.
bool isImplicit() const
Returns an indication whether the argument is an implicit argument.
const char * preDefinedCompletionValues() const
Returns the assigned values used when generating completion for the values.
constexpr bool operator&(FlagEnumClass lhs, FlagEnumClass rhs)
void invokeCallbacks()
Invokes all assigned callbacks.
bool isRequired() const
Returns an indication whether the argument is mandatory.
void setPreDefinedCompletionValues(const char *preDefinedCompletionValues)
Assignes the values to be used when generating completion for the values.
ParseArgumentBehavior
The ParseArgumentBehavior enum specifies the behavior when parsing arguments.
const char * description() const
Returns the description of the argument.
UnknownArgumentBehavior unknownArgumentBehavior() const
Returns how unknown arguments are treated.
constexpr FlagEnumClass operator|(FlagEnumClass lhs, FlagEnumClass rhs)
Contains all utilities provides by the c++utilities library.
bool isPresent() const
Returns an indication whether the argument could be detected when parsing.
void setUnknownArgumentBehavior(UnknownArgumentBehavior behavior)
Sets how unknown arguments are treated.
void setFlags(Argument::Flags flags)
Replaces all Argument::Flags for the argument with the flags.
TargetType convert(const char *value)
const char * executable() const
Returns the name of the current executable.
UnknownArgumentBehavior
The UnknownArgumentBehavior enum specifies the behavior of the argument parser when an unknown argume...
void reset()
Resets occurrences (indices, values and paths).
void setValueNames(std::initializer_list< const char * > valueNames)
Sets the names of the requried values.
std::size_t index(std::size_t occurrence) const
Returns the indices of the argument's occurences which could be detected when parsing.
bool isCombinable() const
Returns an indication whether the argument is combinable.
The ArgumentReader class internally encapsulates the process of reading command line arguments.
const std::vector< Argument * > & path(std::size_t occurrence=0) const
Returns the path of the specified occurrence.
void setName(const char *name)
Sets the name of the argument.
unsigned int actualArgumentCount() const
Returns the actual number of arguments that could be found when parsing.
bool hasSubArguments() const
Returns an indication whether the argument has secondary arguments.
The HelpArgument class prints help information for an argument parser when present (–help,...
Argument::Flags flags() const
Returns Argument::Flags for the argument.
void setDenotesOperation(bool denotesOperation)
Sets whether the argument denotes the operation.
void setDefaultArgument(Argument *argument)
Sets the default argument.
void setRequired(bool required)
Sets whether this argument is mandatory or not.
const ArgumentVector & parents() const
Returns the parents of this argument.
std::vector< const char * > values
The parameter values which have been specified after the occurrence of the argument.
std::tuple< RemainingTargetTypes... > convertValues() const
Converts the present values to the specified target types.
const std::vector< const char * > & valueNames() const
Returns the names of the requried values.
std::size_t maxOccurrences() const
Returns the maximum number of occurrences.
void setCombinable(bool combinable)
Sets whether this argument can be combined.
@ FileSystemIfNoPreDefinedValues
char abbreviation() const
Returns the abbreviation of the argument.
std::function< bool(Argument *)> ArgumentPredicate
std::vector< std::tuple< TargetType... > > allValuesAs() const
Converts the present values for all occurrence to the specified target types.
The ArgumentOccurrence struct holds argument values for an occurrence of an argument.
const HelpArgument & helpArg() const
Returns the --help argument.
std::vector< Argument * > ArgumentVector
#define CPP_UTILITIES_EXPORT
Marks the symbol to be exported by the c++utilities library.
bool isMainArgument() const
Returns an indication whether the argument is used as main argument.
void setExitFunction(std::function< void(int)> exitFunction)
Specifies a function quit the application.
std::size_t index
The index of the occurrence.
std::vector< Argument * > path
The "path" of the occurrence (the parent elements which have been specified before).
void setAbbreviation(char abbreviation)
Sets the abbreviation of the argument.
The ArgumentParser class provides a means for handling command line arguments.
void setValueCompletionBehavior(ValueCompletionBehavior valueCompletionBehaviour)
Sets the items to be considered when generating completion for the values.
#define CPP_UTILITIES_IF_DEBUG_BUILD(x)
Wraps debug-only lines conveniently.
bool denotesOperation() const
Returns whether the argument denotes an operation.