1 #ifndef APPLICATION_UTILITIES_ARGUMENTPARSER_H 2 #define APPLICATION_UTILITIES_ARGUMENTPARSER_H 4 #include "../conversion/stringconversion.h" 6 #include "../misc/traits.h" 9 #include <initializer_list> 33 #ifndef APP_STATICALLY_LINKED 34 #define SET_DEPENDENCY_INFO ::ApplicationUtilities::dependencyVersions2 = DEPENCENCY_VERSIONS 36 #define SET_DEPENDENCY_INFO ::ApplicationUtilities::dependencyVersions2 = STATIC_DEPENCENCY_VERSIONS 44 #define SET_APPLICATION_INFO \ 45 ::ApplicationUtilities::applicationName = APP_NAME; \ 46 ::ApplicationUtilities::applicationAuthor = APP_AUTHOR; \ 47 ::ApplicationUtilities::applicationVersion = APP_VERSION; \ 48 ::ApplicationUtilities::applicationUrl = APP_URL; \ 88 return static_cast<ParseArgumentBehavior>(static_cast<unsigned char>(lhs) | static_cast<unsigned char>(rhs));
93 return static_cast<bool>(static_cast<unsigned char>(lhs) & static_cast<unsigned char>(rhs));
119 return static_cast<ValueCompletionBehavior>(static_cast<unsigned char>(lhs) | static_cast<unsigned char>(rhs));
124 return static_cast<bool>(static_cast<unsigned char>(lhs) & static_cast<unsigned char>(rhs));
138 namespace ValueConversion {
139 template <
typename TargetType, Traits::EnableIf<std::is_same<TargetType, std::
string>> * =
nullptr> TargetType
convert(
const char *value)
141 return std::string(value);
144 template <
typename TargetType, Traits::EnableIf<std::is_arithmetic<TargetType>> * =
nullptr> TargetType
convert(
const char *value)
146 return ConversionUtilities::stringToNumber<TargetType>(value);
152 const std::string errorMessage;
153 const char *
const valueToConvert;
154 const char *
const targetTypeName;
156 [[noreturn]]
void throwFailure(
const std::vector<Argument *> &argumentPath)
const;
159 template <std::size_t N,
typename FirstTargetType,
typename... RemainingTargetTypes>
struct ArgumentValueConverter {
160 static std::tuple<FirstTargetType, RemainingTargetTypes...> convertValues(std::vector<const char *>::const_iterator firstValue)
162 return std::tuple_cat(ArgumentValueConverter<1, FirstTargetType>::convertValues(firstValue),
163 ArgumentValueConverter<N - 1, RemainingTargetTypes...>::convertValues(firstValue + 1));
167 template <
typename FirstTargetType,
typename... RemainingTargetTypes>
struct ArgumentValueConverter<1, FirstTargetType, RemainingTargetTypes...> {
168 static std::tuple<FirstTargetType> convertValues(std::vector<const char *>::const_iterator firstValue)
172 return std::make_tuple<FirstTargetType>(ValueConversion::convert<FirstTargetType>(*firstValue));
174 throw ArgumentValueConversionError{ exception.what(), *firstValue,
typeid(FirstTargetType).name() };
206 template <
typename... RemainingTargetTypes> std::tuple<RemainingTargetTypes...> convertValues()
const;
209 [[noreturn]]
void throwNumberOfValuesNotSufficient(
unsigned long valuesToConvert)
const;
219 constexpr
auto valuesToConvert =
sizeof...(RemainingTargetTypes);
220 if (
values.size() < valuesToConvert) {
221 throwNumberOfValuesNotSufficient(valuesToConvert);
224 return ValueConversion::Helper::ArgumentValueConverter<valuesToConvert, RemainingTargetTypes...>::convertValues(
values.cbegin());
225 }
catch (
const ValueConversion::Helper::ArgumentValueConversionError &error) {
226 error.throwFailure(
path);
251 path.push_back(parent);
263 Argument(
const char *name,
char abbreviation =
'\0',
const char *description =
nullptr,
const char *example =
nullptr);
274 const char *name()
const;
275 void setName(
const char *name);
276 char abbreviation()
const;
277 void setAbbreviation(
char abbreviation);
278 const char *environmentVariable()
const;
279 void setEnvironmentVariable(
const char *environmentVariable);
280 const char *description()
const;
281 void setDescription(
const char *description);
282 const char *example()
const;
283 void setExample(
const char *example);
284 std::size_t requiredValueCount()
const;
285 void setRequiredValueCount(std::size_t requiredValueCount);
286 const std::vector<const char *> &valueNames()
const;
287 void setValueNames(std::initializer_list<const char *> valueNames);
288 void appendValueName(
const char *valueName);
289 void setConstraints(std::size_t minOccurrences, std::size_t maxOccurrences);
290 const std::vector<Argument *> &path(std::size_t occurrence = 0)
const;
291 bool isRequired()
const;
292 void setRequired(
bool required);
293 bool isCombinable()
const;
294 void setCombinable(
bool value);
295 bool isImplicit()
const;
296 void setImplicit(
bool value);
297 bool denotesOperation()
const;
298 void setDenotesOperation(
bool denotesOperation);
304 bool hasSubArguments()
const;
306 void printInfo(std::ostream &os,
unsigned char indentation = 0)
const;
311 const char *preDefinedCompletionValues()
const;
312 void setPreDefinedCompletionValues(
const char *preDefinedCompletionValues);
315 const std::vector<const char *> &values(std::size_t occurrence = 0)
const;
316 template <
typename... TargetType> std::tuple<TargetType...> valuesAs(std::size_t occurrence = 0)
const;
317 template <
typename... TargetType> std::vector<std::tuple<TargetType...>> allValuesAs()
const;
319 const char *firstValue()
const;
320 bool allRequiredValuesPresent(std::size_t occurrence = 0)
const;
321 bool isPresent()
const;
322 std::size_t occurrences()
const;
323 std::size_t index(std::size_t occurrence)
const;
324 std::size_t minOccurrences()
const;
325 std::size_t maxOccurrences()
const;
326 bool isMainArgument()
const;
327 bool isParentPresent()
const;
328 Argument *conflictsWithArgument()
const;
329 Argument *wouldConflictWithArgument()
const;
330 Argument *specifiedOperation()
const;
331 const std::vector<ArgumentOccurrence> &occurrenceInfo()
const;
332 std::vector<ArgumentOccurrence> &occurrenceInfo();
334 void resetRecursively();
344 bool matchesDenotation(
const char *denotation,
size_t denotationLength)
const;
348 const char *m_environmentVar;
349 const char *m_description;
350 const char *m_example;
351 std::size_t m_minOccurrences;
352 std::size_t m_maxOccurrences;
354 bool m_denotesOperation;
355 std::size_t m_requiredValueCount;
356 std::vector<const char *> m_valueNames;
358 std::vector<ArgumentOccurrence> m_occurrences;
364 const char *m_preDefinedCompletionValues;
372 template <
typename... TargetType> std::tuple<TargetType...>
Argument::valuesAs(std::size_t occurrence)
const 374 return m_occurrences[occurrence].convertValues<TargetType...>();
384 std::vector<std::tuple<TargetType...>> res;
385 res.reserve(m_occurrences.size());
386 for (
const auto &occurrence : m_occurrences) {
387 res.emplace_back(occurrence.convertValues<TargetType...>());
404 void addMainArgument(
Argument *argument);
407 void printHelp(std::ostream &os)
const;
408 void parseArgs(
int argc,
const char *
const *argv);
409 void parseArgsOrExit(
int argc,
const char *
const *argv);
410 void parseArgsExt(
int argc,
const char *
const *argv,
413 void readArgs(
int argc,
const char *
const *argv);
415 void checkConstraints();
416 void invokeCallbacks();
419 unsigned int actualArgumentCount()
const;
420 const char *executable()
const;
424 void setDefaultArgument(
Argument *argument);
425 Argument *specifiedOperation()
const;
426 bool isUncombinableMainArgPresent()
const;
432 int argc,
const char *
const *argv,
unsigned int currentWordIndex,
const ArgumentReader &reader)
const;
433 std::string findSuggestions(
int argc,
const char *
const *argv,
unsigned int cursorPos,
const ArgumentReader &reader)
const;
434 void printBashCompletion(
int argc,
const char *
const *argv,
unsigned int cursorPos,
const ArgumentReader &reader)
const;
439 unsigned int m_actualArgc;
440 const char *m_executable;
466 assert(*
name !=
'-');
467 for (
const char *c =
name; *c; ++c) {
468 assert(*c !=
' ' && *c !=
'=' && *c !=
'\'' && *c !=
'\"' && *c !=
'\n' && *c !=
'\r');
482 return m_abbreviation;
505 return m_environmentVar;
524 return m_description;
565 return m_occurrences[occurrence].values;
583 return m_requiredValueCount;
642 m_valueNames.emplace_back(valueName);
651 || (m_occurrences[occurrence].values.size() >= static_cast<std::size_t>(m_requiredValueCount));
669 m_implicit = implicit;
677 return !m_occurrences.empty();
685 return m_occurrences.size();
693 return m_occurrences[occurrence].index;
703 return m_minOccurrences;
713 return m_maxOccurrences;
730 inline const std::vector<Argument *> &
Argument::path(std::size_t occurrence)
const 732 return m_occurrences[occurrence].path;
746 return m_minOccurrences;
759 if (!m_minOccurrences) {
760 m_minOccurrences = 1;
763 m_minOccurrences = 0;
790 m_combinable = value;
805 return m_denotesOperation;
823 return m_callbackFunction;
856 return !m_subArgs.empty();
895 return m_valueCompletionBehavior;
906 m_valueCompletionBehavior = completionValues;
914 return m_preDefinedCompletionValues;
932 m_occurrences.clear();
941 return m_occurrences;
952 return m_occurrences;
987 return m_unknownArgBehavior;
997 m_unknownArgBehavior = behavior;
1006 return m_defaultArg;
1015 m_defaultArg = argument;
1044 OperationArgument(
const char *name,
char abbreviation =
'\0',
const char *description =
nullptr,
const char *example =
nullptr);
1048 :
Argument(name, abbreviation, description, example)
1055 ConfigValueArgument(
const char *name,
char abbreviation =
'\0',
const char *description =
nullptr,
1056 std::initializer_list<const char *> valueNames = std::initializer_list<const char *>());
1063 const char *name,
char abbreviation,
const char *description, std::initializer_list<const char *> valueNames)
1064 :
Argument(name, abbreviation, description)
1077 static void apply();
1085 #endif // APPLICATION_UTILITIES_ARGUMENTPARSER_H bool isMainArgument() const
Returns an indication whether the argument is used as main argument.
CPP_UTILITIES_EXPORT const char * applicationUrl
Specifies the URL to the application website (used by ArgumentParser::printHelp()).
ValueCompletionBehavior
The ValueCompletionBehavior enum specifies the items to be considered when generating completion for ...
const char * preDefinedCompletionValues() const
Returns the assigned values used when generating completion for the values.
std::tuple< RemainingTargetTypes... > convertValues() const
Converts the present values to the specified target types.
bool denotesOperation() const
Returns whether the argument denotes an operation.
UnknownArgumentBehavior unknownArgumentBehavior() const
Returns how unknown arguments are treated.
The ConfigValueArgument class is an Argument where setCombinable() is true by default.
#define IF_DEBUG_BUILD(x)
Wraps debug-only lines conveniently.
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.
void setImplicit(bool value)
Sets whether the argument is an implicit argument.
const char * description() const
Returns the description of the argument.
std::size_t index
The index of the occurrence.
#define CPP_UTILITIES_EXPORT
void setCombinable(bool value)
Sets whether this argument can be combined.
std::vector< Argument * > ArgumentVector
ValueCompletionBehavior valueCompletionBehaviour() const
Returns the items to be considered when generating completion for the values.
void setUnknownArgumentBehavior(UnknownArgumentBehavior behavior)
Sets how unknown arguments are treated.
const ArgumentVector parents() const
Returns the parents of this argument.
The ConversionException class is thrown by the various conversion functions of this library when a co...
Contains currently only ArgumentParser and related classes.
std::size_t maxOccurrences() const
Returns the maximum number of occurrences.
constexpr DirectoryEntryType operator|(DirectoryEntryType lhs, DirectoryEntryType rhs)
constexpr DirectoryEntryType operator &(DirectoryEntryType lhs, DirectoryEntryType rhs)
bool isRequired() const
Returns an indication whether the argument is mandatory.
Argument CPP_UTILITIES_EXPORT * firstPresentUncombinableArg(const ArgumentVector &args, const Argument *except)
This function return the first present and uncombinable argument of the given list of arguments.
void setRequired(bool required)
Sets whether this argument is mandatory or not.
TargetType convert(const char *value)
const std::vector< ArgumentOccurrence > & occurrenceInfo() const
Returns information about all occurrences of the argument which have been detected when parsing.
std::size_t index(std::size_t occurrence) const
Returns the indices of the argument's occurences which could be detected when parsing.
std::function< void(const ArgumentOccurrence &)> CallbackFunction
void setDefaultArgument(Argument *argument)
Sets the default argument.
CPP_UTILITIES_EXPORT const char * applicationVersion
Specifies the version of the application (used by ArgumentParser::printHelp()).
void invokeCallbacks()
Invokes all assigned callbacks.
The NoColorArgument class allows to specify whether use of escape codes or similar technique to provi...
The ArgumentParserTests class tests the ArgumentParser and Argument classes.
void checkConstraints()
Checks whether contraints are violated.
const char * name() const
Returns the name of the argument.
const std::vector< const char * > & valueNames() const
Returns the names of the requried values.
The OperationArgument class is an Argument where denotesOperation() is true by default.
void setConstraints(std::size_t minOccurrences, std::size_t maxOccurrences)
Sets the allowed number of occurrences.
const ArgumentVector & subArguments() const
Returns the secondary arguments for this argument.
constexpr T max(T first, T second)
Returns the greatest of the given items.
std::initializer_list< Argument * > ArgumentInitializerList
std::size_t minOccurrences() const
Returns the minimum number of occurrences.
void setAbbreviation(char abbreviation)
Sets the abbreviation of the argument.
void setDescription(const char *description)
Sets the description of the argument.
std::function< bool(Argument *)> ArgumentPredicate
void setValueCompletionBehavior(ValueCompletionBehavior valueCompletionBehaviour)
Sets the items to be considered when generating completion for the values.
void appendValueName(const char *valueName)
Appends a value name.
CPP_UTILITIES_EXPORT std::initializer_list< const char * > dependencyVersions
Specifies the dependency versions the application was linked against (used by ArgumentParser::printHe...
const std::vector< const char * > & values(std::size_t occurrence=0) const
Returns the parameter values for the specified occurrence of argument.
CPP_UTILITIES_EXPORT void(* exitFunction)(int)
Specifies a function quit the application.
ParseArgumentBehavior
The ParseArgumentBehavior enum specifies the behavior when parsing arguments.
const char * executable() const
Returns the name of the current executable.
std::size_t occurrences() const
Returns how often the argument could be detected when parsing.
The Argument class is a wrapper for command line argument information.
void setCallback(CallbackFunction callback)
Sets a callback function which will be called by the parser if the argument could be found and no par...
void setExample(const char *example)
Sets the a usage example for the argument.
const std::vector< Argument * > & path(std::size_t occurrence=0) const
Returns the path of the specified occurrence.
static constexpr std::size_t varValueCount
Denotes a variable number of values.
bool isCombinable() const
Returns an indication whether the argument is combinable.
void setPreDefinedCompletionValues(const char *preDefinedCompletionValues)
Assignes the values to be used when generating completion for the values.
The ArgumentCompletionInfo struct holds information internally used for shell completion and suggesti...
std::vector< Argument * > path
The "path" of the occurrence (the parent elements which have been specified before).
UnknownArgumentBehavior
The UnknownArgumentBehavior enum specifies the behavior of the argument parser when an unknown argume...
OperationArgument(const char *name, char abbreviation='\0', const char *description=nullptr, const char *example=nullptr)
void setEnvironmentVariable(const char *environmentVariable)
Sets the environment variable queried when firstValue() is called.
void setValueNames(std::initializer_list< const char * > valueNames)
Sets the names of the requried values.
The ArgumentOccurrence struct holds argument values for an occurrence of an argument.
CPP_UTILITIES_EXPORT const char * applicationName
Specifies the name of the application (used by ArgumentParser::printHelp()).
bool isPresent() const
Returns an indication whether the argument could be detected when parsing.
bool hasSubArguments() const
Returns an indication whether the argument has secondary arguments.
const CallbackFunction & callback() const
Returns the assigned callback function.
The HelpArgument class prints help information for an argument parser when present (–help,...
bool allRequiredValuesPresent(std::size_t occurrence=0) const
Returns an indication whether all required values are present.
CPP_UTILITIES_EXPORT std::vector< const char * > dependencyVersions2
Specifies the dependency versions the application was linked against (used by ArgumentParser::printHe...
const ArgumentVector & mainArguments() const
Returns the main arguments.
void setDenotesOperation(bool denotesOperation)
Sets whether the argument denotes the operation.
char abbreviation() const
Returns the abbreviation of the argument.
const char * example() const
Returns the usage example of the argument.
void reset()
Resets occurrences (indices, values and paths).
ArgumentOccurrence(std::size_t index)
Constructs an argument occurrence for the specified index.
void setRequiredValueCount(std::size_t requiredValueCount)
Sets the number of values which are required to be given for this argument.
CPP_UTILITIES_EXPORT const char * applicationAuthor
Specifies the author of the application (used by ArgumentParser::printHelp()).
The ArgumentReader class internally encapsulates the process of reading command line arguments.
const char * environmentVariable() const
Returns the environment variable queried when firstValue() is called.
std::tuple< TargetType... > valuesAs(std::size_t occurrence=0) const
Converts the present values for the specified occurrence to the specified target types.
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.
unsigned int actualArgumentCount() const
Returns the actual number of arguments that could be found when parsing.
void setName(const char *name)
Sets the name of the argument.
std::vector< std::tuple< TargetType... > > allValuesAs() const
Converts the present values for all occurrence to the specified target types.
bool isImplicit() const
Returns an indication whether the argument is an implicit argument.
The ArgumentParser class provides a means for handling command line arguments.
std::vector< const char * > values
The parameter values which have been specified after the occurrence of the argument.