6 #include "../conversion/stringbuilder.h" 7 #include "../conversion/stringconversion.h" 8 #include "../io/ansiescapecodes.h" 9 #include "../io/path.h" 44 ArgumentReader::ArgumentReader(
ArgumentParser &parser,
const char *
const *argv,
const char *
const *end,
bool completionMode)
46 , args(parser.m_mainArgs)
51 , argDenotation(nullptr)
52 , completionMode(completionMode)
87 const vector<Argument *> &parentPath = parentArg ? parentArg->
path(parentArg->
occurrences() - 1) : vector<Argument *>();
90 vector<const char *> *values =
nullptr;
100 bool abbreviationFound =
false;
103 abbreviationFound =
false;
113 abbreviationFound =
false;
120 size_t argDenotationLength;
124 argDenotationLength; matchingArg =
nullptr) {
128 if (arg->abbreviation() && arg->abbreviation() == *
argDenotation) {
130 abbreviationFound =
true;
136 if (arg->name() && !strncmp(arg->name(),
argDenotation, argDenotationLength)
137 && *(arg->name() + argDenotationLength) ==
'\0') {
146 matchingArg->m_occurrences.emplace_back(
index, parentPath, parentArg);
149 values = &matchingArg->m_occurrences.back().values;
151 values->push_back(equationPos + 1);
161 argDenotation =
nullptr;
177 for (
auto parentArgument = parentPath.crbegin(), pathEnd = parentPath.crend();; ++parentArgument) {
178 for (
Argument *sibling : (parentArgument != pathEnd ? (*parentArgument)->subArguments() :
parser.m_mainArgs)) {
179 if (sibling->occurrences() < sibling->maxOccurrences()) {
181 || (sibling->name() && !strncmp(sibling->name(),
argDenotation, argDenotationLength))) {
186 if (parentArgument == pathEnd) {
201 if (arg->denotesOperation() && arg->name() && !strcmp(arg->name(), *
argv)) {
202 (matchingArg = arg)->m_occurrences.emplace_back(
index, parentPath, parentArg);
213 if (arg->isImplicit() && !arg->isPresent() && !arg->wouldConflictWithArgument()
214 && (!uncombinableMainArgPresent || !arg->isMainArgument())) {
215 (matchingArg = arg)->m_occurrences.emplace_back(
index, parentPath, parentArg);
223 if (lastArgInLevel == matchingArg) {
228 values = &matchingArg->m_occurrences.back().values;
233 argDenotation =
nullptr;
246 switch (
parser.m_unknownArgBehavior) {
248 cerr <<
"The specified argument \"" << *
argv <<
"\" is unknown and will be ignored." << endl;
282 inline bool notEmpty(
const char *str)
305 Argument::Argument(
const char *name,
char abbreviation,
const char *description,
const char *example)
307 , m_abbreviation(abbreviation)
308 , m_environmentVar(nullptr)
309 , m_description(description)
311 , m_minOccurrences(0)
312 , m_maxOccurrences(1)
313 , m_combinable(false)
314 , m_denotesOperation(false)
315 , m_requiredValueCount(0)
320 , m_preDefinedCompletionValues(nullptr)
340 if (!m_occurrences.empty() && !m_occurrences.front().values.empty()) {
341 return m_occurrences.front().values.front();
342 }
else if (m_environmentVar) {
343 return getenv(m_environmentVar);
356 if (notEmpty(
name())) {
357 os <<
'-' <<
'-' <<
name();
367 unsigned int valueNamesPrint = 0;
369 os <<
' ' <<
'[' << *i <<
']';
376 os <<
" [value " << (valueNamesPrint + 1) <<
']';
382 os <<
'\n' << Indentation(indentation) <<
description();
385 os <<
'\n' << Indentation(indentation) <<
"particularities: mandatory";
387 os <<
" if parent argument is present";
391 os <<
'\n' << Indentation(indentation) <<
"default environment variable: " <<
environmentVariable();
394 os <<
'\n' << Indentation(indentation) <<
"\nusage: " <<
example();
398 arg->printInfo(os, indentation);
410 if (arg != except && arg->
isPresent() && !arg->isCombinable()) {
435 arg->m_parents.erase(
remove(arg->m_parents.begin(), arg->m_parents.end(),
this), arg->m_parents.end());
438 m_subArgs.assign(secondaryArguments);
442 if (find(arg->m_parents.cbegin(), arg->m_parents.cend(),
this) == arg->m_parents.cend()) {
443 arg->m_parents.push_back(
this);
457 if (find(m_subArgs.cbegin(), m_subArgs.cend(), arg) == m_subArgs.cend()) {
458 m_subArgs.push_back(arg);
459 if (find(arg->m_parents.cbegin(), arg->m_parents.cend(),
this) == arg->m_parents.cend()) {
460 arg->m_parents.push_back(
this);
474 for (
const Argument *parent : m_parents) {
475 if (parent->isPresent()) {
506 for (
Argument *parent : m_parents) {
508 if (sibling !=
this && sibling->isPresent() && !sibling->isCombinable()) {
524 arg->resetRecursively();
547 , m_executable(nullptr)
549 , m_defaultArg(nullptr)
564 if (mainArguments.size()) {
565 for (
Argument *arg : mainArguments) {
566 arg->m_isMainArg =
true;
568 m_mainArgs.assign(mainArguments);
570 if (!(*mainArguments.begin())->requiredValueCount()) {
571 bool subArgsRequired =
false;
572 for (
const Argument *subArg : (*mainArguments.begin())->subArguments()) {
573 if (subArg->isRequired()) {
574 subArgsRequired =
true;
578 if (!subArgsRequired) {
579 m_defaultArg = *mainArguments.begin();
596 argument->m_isMainArg =
true;
597 m_mainArgs.push_back(argument);
606 if (applicationName && *applicationName) {
608 if (applicationVersion && *applicationVersion) {
612 if (applicationVersion && *applicationVersion) {
615 if (dependencyVersions.size()) {
616 if ((applicationName && *applicationName) || (applicationVersion && *
applicationVersion)) {
620 auto i = dependencyVersions.begin(), end = dependencyVersions.end();
621 os <<
"Linked against: " << *i;
622 for (++i; i != end; ++i) {
623 os <<
',' <<
' ' << *i;
626 if ((applicationName && *applicationName) || (applicationVersion && *applicationVersion) || dependencyVersions.size()) {
630 if (!m_mainArgs.empty()) {
631 os <<
"Available arguments:";
632 for (
const Argument *arg : m_mainArgs) {
637 if (applicationUrl && *applicationUrl) {
638 os <<
"\nProject website: " << applicationUrl << endl;
671 IF_DEBUG_BUILD(verifyArgs(m_mainArgs, std::vector<char>(), std::vector<const char *>());)
675 m_executable = *argv;
680 bool completionMode = !strcmp(*++argv,
"--bash-completion-for");
681 unsigned int currentWordIndex;
682 if (completionMode) {
685 currentWordIndex = (--argc ? stringToNumber<unsigned int, string>(*(++argv)) : 0);
690 currentWordIndex =
static_cast<unsigned int>(argc - 1);
696 argv + (completionMode ? min(static_cast<unsigned int>(argc), currentWordIndex + 1) : static_cast<unsigned int>(argc)),
701 if (!completionMode) {
706 if (completionMode) {
707 printBashCompletion(argc, argv, currentWordIndex, reader);
713 m_defaultArg->m_occurrences.emplace_back(0);
717 m_executable =
nullptr;
728 arg->resetRecursively();
738 for (
const Argument *arg : m_mainArgs) {
739 if (!arg->isCombinable() && arg->isPresent()) {
763 void ApplicationUtilities::ArgumentParser::verifyArgs(
const ArgumentVector &args, vector<char>, vector<const char *>)
765 vector<const Argument *> verifiedArgs;
766 verifiedArgs.reserve(args.size());
767 vector<char> abbreviations;
768 abbreviations.reserve(abbreviations.size() + args.size());
769 vector<const char *> names;
770 names.reserve(names.size() + args.size());
771 bool hasImplicit =
false;
773 assert(find(verifiedArgs.cbegin(), verifiedArgs.cend(), arg) == verifiedArgs.cend());
774 verifiedArgs.push_back(arg);
775 assert(!arg->isImplicit() || !hasImplicit);
776 hasImplicit |= arg->isImplicit();
777 assert(!arg->abbreviation() || find(abbreviations.cbegin(), abbreviations.cend(), arg->abbreviation()) == abbreviations.cend());
778 abbreviations.push_back(arg->abbreviation());
779 assert(!arg->name() || find_if(names.cbegin(), names.cend(), [arg](
const char *name) {
return !strcmp(arg->name(), name); }) == names.cend());
780 assert(arg->requiredValueCount() == 0 || arg->subArguments().size() == 0);
781 names.emplace_back(arg->name());
784 verifyArgs(arg->subArguments(), vector<char>(), vector<const char *>());
803 return strcmp(arg1->
name(), arg2->
name()) < 0;
813 bool onlyCombinable =
false;
814 for (
const Argument *sibling : siblings) {
815 if (sibling->isPresent() && !sibling->isCombinable()) {
816 onlyCombinable =
true;
820 for (
const Argument *sibling : siblings) {
821 if ((!onlyCombinable || sibling->isCombinable()) && sibling->occurrences() < sibling->maxOccurrences()) {
822 target.push_back(sibling);
832 void ArgumentParser::printBashCompletion(
int argc,
const char *
const *argv,
unsigned int currentWordIndex,
const ArgumentReader &reader)
835 list<const Argument *> relevantArgs, relevantPreDefinedValues;
836 bool completeFiles =
false, completeDirs =
false, noWhitespace =
false;
840 size_t lastDetectedArgIndex;
841 vector<Argument *> lastDetectedArgPath;
842 if (lastDetectedArg) {
844 lastDetectedArgPath = lastDetectedArg->
path(lastDetectedArg->
occurrences() - 1);
848 const char *
const *lastSpecifiedArg;
849 unsigned int lastSpecifiedArgIndex;
851 lastSpecifiedArgIndex =
static_cast<unsigned int>(argc) - 1;
852 lastSpecifiedArg = argv + lastSpecifiedArgIndex;
853 for (; lastSpecifiedArg >= argv && **lastSpecifiedArg ==
'\0'; --lastSpecifiedArg, --lastSpecifiedArgIndex)
858 bool nextArgumentOrValue;
859 if (lastDetectedArg && lastDetectedArg->
isPresent()) {
860 if ((nextArgumentOrValue = (currentWordIndex > lastDetectedArgIndex))) {
862 const auto addValueCompletionsForArg = [&relevantPreDefinedValues, &completeFiles, &completeDirs](
const Argument *arg) {
864 relevantPreDefinedValues.push_back(arg);
867 || !arg->preDefinedCompletionValues()) {
874 auto currentValueCount = lastDetectedArg->
values(lastDetectedArg->
occurrences() - 1).size();
876 if (currentValueCount) {
877 const auto currentWordIndexRelativeToLastDetectedArg = currentWordIndex - lastDetectedArgIndex;
878 if (currentValueCount > currentWordIndexRelativeToLastDetectedArg) {
879 currentValueCount -= currentWordIndexRelativeToLastDetectedArg;
881 currentValueCount = 0;
889 if (child->isImplicit() && child->requiredValueCount()) {
890 addValueCompletionsForArg(child);
898 addValueCompletionsForArg(lastDetectedArg);
905 if (subArg->occurrences() < subArg->maxOccurrences()) {
906 relevantArgs.push_back(subArg);
911 for (
auto parentArgument = lastDetectedArgPath.crbegin(), end = lastDetectedArgPath.crend();; ++parentArgument) {
912 insertSiblings(parentArgument != end ? (*parentArgument)->subArguments() : m_mainArgs, relevantArgs);
913 if (parentArgument == end) {
920 relevantArgs.push_back(lastDetectedArg);
925 nextArgumentOrValue =
true;
930 const char *opening =
nullptr;
931 string compoundOpening;
932 size_t openingLen, compoundOpeningStartLen = 0;
933 unsigned char openingDenotationType =
Value;
934 if (argc && nextArgumentOrValue) {
935 if (currentWordIndex < static_cast<unsigned int>(argc)) {
936 opening = argv[currentWordIndex];
942 size_t minCurrentWordIndex = (lastDetectedArg ? lastDetectedArgIndex : 0);
943 if (currentWordIndex > minCurrentWordIndex && !strcmp(opening,
"=")) {
944 compoundOpening.reserve(compoundOpeningStartLen = strlen(argv[--currentWordIndex]) + 1);
945 compoundOpening = argv[currentWordIndex];
946 compoundOpening +=
'=';
947 }
else if (currentWordIndex > (minCurrentWordIndex + 1) && !strcmp(argv[currentWordIndex - 1],
"=")) {
948 compoundOpening.reserve((compoundOpeningStartLen = strlen(argv[currentWordIndex -= 2]) + 1) + strlen(opening));
949 compoundOpening = argv[currentWordIndex];
950 compoundOpening +=
'=';
951 compoundOpening += opening;
953 if (!compoundOpening.empty()) {
954 opening = compoundOpening.data();
957 opening = *lastSpecifiedArg;
959 *opening ==
'-' && (++opening, ++openingDenotationType) && *opening ==
'-' && (++opening, ++openingDenotationType);
960 openingLen = strlen(opening);
966 cout <<
"COMPREPLY=(";
968 for (
const Argument *arg : relevantPreDefinedValues) {
969 if (arg->preDefinedCompletionValues()) {
971 if (argc && currentWordIndex <= lastSpecifiedArgIndex && opening) {
972 if (openingDenotationType ==
Value) {
973 bool wordStart =
true, ok =
false, equationSignAlreadyPresent =
false;
974 size_t wordIndex = 0;
975 for (
const char *i = arg->preDefinedCompletionValues(), *end = opening + openingLen; *i;) {
977 const char *i1 = i, *i2 = opening;
978 for (; *i1 && i2 != end && *i1 == *i2; ++i1, ++i2)
980 if ((ok = (i2 == end))) {
985 }
else if ((wordStart = (*i ==
' ') || (*i ==
'\n'))) {
986 equationSignAlreadyPresent =
false;
992 }
else if (*i ==
'=') {
993 equationSignAlreadyPresent =
true;
996 if (!compoundOpeningStartLen || wordIndex >= compoundOpeningStartLen) {
1008 if (appendEquationSign && !equationSignAlreadyPresent) {
1010 noWhitespace =
true;
1011 equationSignAlreadyPresent =
false;
1023 }
else if (
const char *i = arg->preDefinedCompletionValues()) {
1024 bool equationSignAlreadyPresent =
false;
1034 equationSignAlreadyPresent =
true;
1039 if (appendEquationSign && !equationSignAlreadyPresent) {
1041 equationSignAlreadyPresent =
false;
1046 cout <<
' ' <<
'\'';
1051 cout <<
'\'' <<
' ';
1056 for (
const Argument *arg : relevantArgs) {
1057 if (argc && currentWordIndex <= lastSpecifiedArgIndex && opening) {
1058 switch (openingDenotationType) {
1060 if (!arg->denotesOperation() || strncmp(arg->name(), opening, openingLen)) {
1067 if (strncmp(arg->name(), opening, openingLen)) {
1073 if (opening && openingDenotationType ==
Abbreviation && !nextArgumentOrValue) {
1074 cout <<
'\'' <<
'-' << opening << arg->abbreviation() <<
'\'' <<
' ';
1076 if (reader.
argv == reader.
end) {
1077 cout <<
'\'' << *(reader.
argv - 1) <<
'\'' <<
' ';
1079 }
else if (arg->denotesOperation()) {
1080 cout <<
'\'' << arg->name() <<
'\'' <<
' ';
1082 cout <<
'\'' <<
'-' <<
'-' << arg->name() <<
'\'' <<
' ';
1087 string actualDir, actualFile;
1088 bool haveFileOrDirCompletions =
false;
1089 if (argc && currentWordIndex == lastSpecifiedArgIndex && opening) {
1091 string unescapedOpening(opening);
1092 findAndReplace<string>(unescapedOpening,
"\\ ",
" ");
1093 findAndReplace<string>(unescapedOpening,
"\\,",
",");
1094 findAndReplace<string>(unescapedOpening,
"\\[",
"[");
1095 findAndReplace<string>(unescapedOpening,
"\\]",
"]");
1096 findAndReplace<string>(unescapedOpening,
"\\!",
"!");
1097 findAndReplace<string>(unescapedOpening,
"\\#",
"#");
1098 findAndReplace<string>(unescapedOpening,
"\\$",
"$");
1099 findAndReplace<string>(unescapedOpening,
"\\'",
"'");
1100 findAndReplace<string>(unescapedOpening,
"\\\"",
"\"");
1101 findAndReplace<string>(unescapedOpening,
"\\\\",
"\\");
1103 string dir =
directory(unescapedOpening);
1107 if (dir[0] ==
'\"' || dir[0] ==
'\'') {
1110 if (dir.size() > 1 && (dir[dir.size() - 2] ==
'\"' || dir[dir.size() - 2] ==
'\'')) {
1111 dir.erase(dir.size() - 2, 1);
1113 actualDir = move(dir);
1116 string file =
fileName(unescapedOpening);
1117 if (file[0] ==
'\"' || file[0] ==
'\'') {
1120 if (file.size() > 1 && (file[dir.size() - 2] ==
'\"' || dir[file.size() - 2] ==
'\'')) {
1121 file.erase(file.size() - 2, 1);
1123 actualFile = move(file);
1128 if (completeFiles) {
1129 entryTypes |= DirectoryEntryType::File;
1132 entryTypes |= DirectoryEntryType::Directory;
1135 const string replace(
"'"), with(
"'\"'\"'");
1136 if (argc && currentWordIndex <= lastSpecifiedArgIndex && opening) {
1139 for (
string &dirEntry : entries) {
1142 if (actualDir !=
".") {
1146 cout << dirEntry <<
'\'' <<
' ';
1147 haveFileOrDirCompletions =
true;
1153 cout <<
'\'' << dirEntry <<
'\'' <<
' ';
1154 haveFileOrDirCompletions =
true;
1161 if (haveFileOrDirCompletions) {
1162 cout <<
"; compopt -o filenames";
1167 cout <<
"; compopt -o nospace";
1180 const auto occurrences = arg->occurrences();
1181 if (arg->isParentPresent() && occurrences > arg->maxOccurrences()) {
1182 throw Failure(
argsToString(
"The argument \"", arg->name(),
"\" mustn't be specified more than ", arg->maxOccurrences(),
1183 (arg->maxOccurrences() == 1 ?
" time." :
" times.")));
1185 if (arg->isParentPresent() && occurrences < arg->minOccurrences()) {
1186 throw Failure(
argsToString(
"The argument \"", arg->name(),
"\" must be specified at least ", arg->minOccurrences(),
1187 (arg->minOccurrences() == 1 ?
" time." :
" times.")));
1189 Argument *conflictingArgument =
nullptr;
1190 if (arg->isMainArgument()) {
1191 if (!arg->isCombinable() && arg->isPresent()) {
1195 conflictingArgument = arg->conflictsWithArgument();
1197 if (conflictingArgument) {
1198 throw Failure(
argsToString(
"The argument \"", conflictingArgument->name(),
"\" can not be combined with \"", arg->name(),
"\"."));
1200 for (
size_t i = 0; i != occurrences; ++i) {
1201 if (!arg->allRequiredValuesPresent(i)) {
1202 stringstream ss(stringstream::in | stringstream::out);
1203 ss <<
"Not all parameter for argument \"" << arg->name() <<
"\" ";
1205 ss <<
" (" << (i + 1) <<
" occurrence) ";
1207 ss <<
"provided. You have to provide the following parameter:";
1208 size_t valueNamesPrint = 0;
1209 for (
const auto &name : arg->m_valueNames) {
1210 ss <<
' ' << name, ++valueNamesPrint;
1212 if (arg->m_requiredValueCount != static_cast<size_t>(-1)) {
1213 while (valueNamesPrint < arg->m_requiredValueCount) {
1214 ss <<
"\nvalue " << (++valueNamesPrint);
1237 if (arg->m_callbackFunction) {
1238 for (
const auto &occurrence : arg->m_occurrences) {
1239 arg->m_callbackFunction(occurrence);
1257 :
Argument(
"help",
'h',
"shows this information")
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()).
bool startsWith(const StringType &str, const StringType &phrase)
Returns whether str starts with phrase.
ValueCompletionBehavior
The ValueCompletionBehavior enum specifies the items to be considered when generating completion for ...
Argument * lastArg
The last Argument instance which could be detected. Set to nullptr in the initial call...
bool denotesOperation() const
Returns whether the argument denotes the operation.
void resetArgs()
Resets all Argument instances assigned as mainArguments() and sub arguments.
std::initializer_list< Argument * > ArgumentInitializerList
#define IF_DEBUG_BUILD(x)
Wraps debug-only lines conveniently.
std::size_t requiredValueCount() const
Returns the number of values which are required to be given for this argument.
Argument * conflictsWithArgument() const
Checks if this arguments conflicts with other arguments.
const char * description() const
Returns the description of the argument.
bool isParentPresent() const
Returns whether at least one parent argument is present.
unsigned char argDenotationType
The type of the currently processed abbreviation denotation. Unspecified if argDenotation is not set...
ArgumentParser()
Constructs a new ArgumentParser.
void readArgs(int argc, const char *const *argv)
Parses the specified command line arguments.
void setStyle(std::ostream &stream, TextAttribute displayAttribute=TextAttribute::Reset)
CPP_UTILITIES_EXPORT std::list< std::string > directoryEntries(const char *path, DirectoryEntryType types=DirectoryEntryType::All)
Returns the names of the directory entries in the specified path with the specified types...
The ConversionException class is thrown by the various conversion functions of this library when a co...
Contains currently only ArgumentParser and related classes.
constexpr StringType argsToString(Args &&... args)
void setMainArguments(const ArgumentInitializerList &mainArguments)
Sets the main arguments for the parser.
Argument(const char *name, char abbreviation='\0', const char *description=nullptr, const char *example=nullptr)
Constructs an Argument with the given name, abbreviation and description.
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 parseArgs(int argc, const char *const *argv)
Parses the specified command line arguments.
const char * firstValue() const
Returns the first parameter value of the first occurrence of the argument.
CPP_UTILITIES_EXPORT const char * applicationVersion
Specifies the version of the application (used by ArgumentParser::printHelp()).
void invokeCallbacks()
Invokes all assigned callbacks.
const char *const * argv
Points to the first argument denotation and will be incremented when a denotation has been processed...
~Argument()
Destroys the Argument.
The Indentation class allows printing indentation conveniently, eg.
#define CMD_UTILS_START_CONSOLE
void addMainArgument(Argument *argument)
Adds the specified argument to the main argument.
#define FALLTHROUGH
Prevents clang from warning about missing break in switch-case.
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.
const char * argDenotation
The currently processed abbreviation denotation (should be substring of one of the args in argv)...
HelpArgument(ArgumentParser &parser)
Constructs a new help argument for the specified parser.
ArgumentParser & parser
The associated ArgumentParser instance.
const ArgumentVector & subArguments() const
Returns the secondary arguments for this argument.
size_t index
An index which is incremented when an argument is encountered (the current index is stored in the occ...
Contains utility classes helping to read and write streams.
void printHelp(std::ostream &os) const
Prints help text for all assigned arguments.
void findAndReplace(StringType &str, const StringType &find, const StringType &replace)
Replaces all occurences of find with relpace in the specified str.
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.
Contains several functions providing conversions between different data types.
CPP_UTILITIES_EXPORT void(* exitFunction)(int)
Specifies a function quit the application.
Argument * wouldConflictWithArgument() const
Checks if this argument would conflict with other arguments if it was present.
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...
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.
ApplicationUtilities::ArgumentReader & reset(const char *const *argv, const char *const *end)
Resets the ArgumentReader to continue reading new argv.
ArgumentVector & args
The Argument instances to store the results. Sub arguments of args are considered as well...
ArgumentDenotationType
The ArgumentDenotationType enum specifies the type of a given argument denotation.
UnknownArgumentBehavior
The UnknownArgumentBehavior enum specifies the behavior of the argument parser when an unknown argume...
void printInfo(std::ostream &os, unsigned char indentation=0) const
Writes the name, the abbreviation and other information about the Argument to the give ostream...
CPP_UTILITIES_EXPORT std::string directory(const std::string &path)
Returns the directory of the specified path string (including trailing slash).
void addSubArgument(Argument *arg)
Adds arg as a secondary argument for this argument.
The ArgumentOccurrence struct holds argument values for an occurrence of an argument.
const char *const * end
Points to the end of the argv array.
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.
The Failure class is thrown by an ArgumentParser when a parsing error occurs.
const ArgumentVector & mainArguments() const
Returns the main arguments.
bool isUncombinableMainArgPresent() const
Checks whether at least one uncombinable main argument is present.
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).
CPP_UTILITIES_EXPORT std::string fileName(const std::string &path)
Returns the file name and extension of the specified path string.
const char *const * lastArgDenotation
Points to the element in argv where lastArg was encountered. Unspecified if lastArg is not set...
CPP_UTILITIES_EXPORT const char * applicationAuthor
Specifies the author of the application (used by ArgumentParser::printHelp()).
DirectoryEntryType
The DirectoryEntryType enum specifies the type of a directory entry (file, directory or symlink)...
const char * environmentVariable() const
Returns the environment variable queried when firstValue() is called.
bool completionMode
Whether completion mode is enabled. In this case reading args will be continued even if an denotation...
void setSubArguments(const ArgumentInitializerList &subArguments)
Sets the secondary arguments for this arguments.
void read()
Reads the commands line arguments specified when constructing the object.
bool compareArgs(const Argument *arg1, const Argument *arg2)
Returns whether arg1 should be listed before arg2 when printing completion.
The ArgumentParser class provides a means for handling command line arguments.
void resetRecursively()
Resets this argument and all sub arguments recursively.
void insertSiblings(const ArgumentVector &siblings, list< const Argument *> &target)
Inserts the specified siblings in the target list.
std::vector< Argument * > ArgumentVector