6 #include "../conversion/stringbuilder.h" 7 #include "../conversion/stringconversion.h" 8 #include "../io/ansiescapecodes.h" 9 #include "../io/path.h" 50 ArgumentReader::ArgumentReader(
ArgumentParser &parser,
const char *
const *argv,
const char *
const *end,
bool completionMode)
52 , args(parser.m_mainArgs)
57 , argDenotation(nullptr)
58 , completionMode(completionMode)
93 const vector<Argument *> &parentPath = parentArg ? parentArg->
path(parentArg->
occurrences() - 1) : vector<Argument *>();
96 vector<const char *> *values =
nullptr;
106 bool abbreviationFound =
false;
109 abbreviationFound =
false;
119 abbreviationFound =
false;
126 size_t argDenotationLength;
130 argDenotationLength; matchingArg =
nullptr) {
134 if (arg->abbreviation() && arg->abbreviation() == *
argDenotation) {
136 abbreviationFound =
true;
142 if (arg->name() && !strncmp(arg->name(),
argDenotation, argDenotationLength)
143 && *(arg->name() + argDenotationLength) ==
'\0') {
152 matchingArg->m_occurrences.emplace_back(
index, parentPath, parentArg);
155 values = &matchingArg->m_occurrences.back().values;
157 values->push_back(equationPos + 1);
167 argDenotation =
nullptr;
183 for (
auto parentArgument = parentPath.crbegin(), pathEnd = parentPath.crend();; ++parentArgument) {
184 for (
Argument *sibling : (parentArgument != pathEnd ? (*parentArgument)->subArguments() :
parser.m_mainArgs)) {
185 if (sibling->occurrences() < sibling->maxOccurrences()) {
187 || (sibling->name() && !strncmp(sibling->name(),
argDenotation, argDenotationLength))) {
192 if (parentArgument == pathEnd) {
207 if (arg->denotesOperation() && arg->name() && !strcmp(arg->name(), *
argv)) {
208 (matchingArg = arg)->m_occurrences.emplace_back(
index, parentPath, parentArg);
219 if (arg->isImplicit() && !arg->isPresent() && !arg->wouldConflictWithArgument()
220 && (!uncombinableMainArgPresent || !arg->isMainArgument())) {
221 (matchingArg = arg)->m_occurrences.emplace_back(
index, parentPath, parentArg);
229 if (lastArgInLevel == matchingArg) {
234 values = &matchingArg->m_occurrences.back().values;
239 argDenotation =
nullptr;
252 switch (
parser.m_unknownArgBehavior) {
254 cerr <<
"The specified argument \"" << *
argv <<
"\" is unknown and will be ignored." << endl;
279 const auto maxColumns = termSize.
columns ? termSize.
columns : numeric_limits<unsigned short>::max();
282 unsigned short currentCol = wrapper.m_indentation.
level;
283 for (
const char *currentChar = wrapper.m_str; *currentChar; ++currentChar) {
284 const bool wrappingRequired = currentCol >= maxColumns;
285 if (wrappingRequired || *currentChar ==
'\n') {
289 if (wrapper.m_indentation.
level < maxColumns) {
290 os << wrapper.m_indentation;
291 currentCol = wrapper.m_indentation.
level;
296 if (*currentChar !=
'\n' && (!wrappingRequired || *currentChar !=
' ')) {
323 inline bool notEmpty(
const char *str)
346 Argument::Argument(
const char *name,
char abbreviation,
const char *description,
const char *example)
348 , m_abbreviation(abbreviation)
349 , m_environmentVar(nullptr)
350 , m_description(description)
352 , m_minOccurrences(0)
353 , m_maxOccurrences(1)
354 , m_combinable(false)
355 , m_denotesOperation(false)
356 , m_requiredValueCount(0)
361 , m_preDefinedCompletionValues(nullptr)
381 if (!m_occurrences.empty() && !m_occurrences.front().values.empty()) {
382 return m_occurrences.front().values.front();
383 }
else if (m_environmentVar) {
384 return getenv(m_environmentVar);
398 if (notEmpty(
name())) {
412 unsigned int valueNamesPrint = 0;
414 os <<
' ' <<
'[' << *i <<
']';
421 os <<
" [value " << (valueNamesPrint + 1) <<
']';
430 os <<
'\n' << ident <<
"particularities: mandatory";
432 os <<
" if parent argument is present";
440 arg->printInfo(os, ident.level);
459 if (arg != except && arg->
isPresent() && !arg->isCombinable()) {
484 arg->m_parents.erase(
remove(arg->m_parents.begin(), arg->m_parents.end(),
this), arg->m_parents.end());
487 m_subArgs.assign(secondaryArguments);
491 if (find(arg->m_parents.cbegin(), arg->m_parents.cend(),
this) == arg->m_parents.cend()) {
492 arg->m_parents.push_back(
this);
506 if (find(m_subArgs.cbegin(), m_subArgs.cend(), arg) == m_subArgs.cend()) {
507 m_subArgs.push_back(arg);
508 if (find(arg->m_parents.cbegin(), arg->m_parents.cend(),
this) == arg->m_parents.cend()) {
509 arg->m_parents.push_back(
this);
523 for (
const Argument *parent : m_parents) {
524 if (parent->isPresent()) {
555 for (
Argument *parent : m_parents) {
557 if (sibling !=
this && sibling->isPresent() && !sibling->isCombinable()) {
573 if (arg->denotesOperation() && arg->isPresent()) {
587 arg->resetRecursively();
610 , m_executable(nullptr)
612 , m_defaultArg(nullptr)
627 if (mainArguments.size()) {
628 for (
Argument *arg : mainArguments) {
629 arg->m_isMainArg =
true;
631 m_mainArgs.assign(mainArguments);
633 if (!(*mainArguments.begin())->requiredValueCount()) {
634 bool subArgsRequired =
false;
635 for (
const Argument *subArg : (*mainArguments.begin())->subArguments()) {
636 if (subArg->isRequired()) {
637 subArgsRequired =
true;
641 if (!subArgsRequired) {
642 m_defaultArg = *mainArguments.begin();
659 argument->m_isMainArg =
true;
660 m_mainArgs.push_back(argument);
669 if (applicationName && *applicationName) {
671 if (applicationVersion && *applicationVersion) {
675 if (applicationVersion && *applicationVersion) {
678 if (dependencyVersions.size()) {
679 if ((applicationName && *applicationName) || (applicationVersion && *
applicationVersion)) {
683 auto i = dependencyVersions.begin(), end = dependencyVersions.end();
684 os <<
"Linked against: " << *i;
685 for (++i; i != end; ++i) {
686 os <<
',' <<
' ' << *i;
689 if ((applicationName && *applicationName) || (applicationVersion && *applicationVersion) || dependencyVersions.size()) {
693 if (!m_mainArgs.empty()) {
694 os <<
"Available arguments:";
695 for (
const Argument *arg : m_mainArgs) {
700 if (applicationUrl && *applicationUrl) {
701 os <<
"\nProject website: " << applicationUrl << endl;
736 }
catch (
const Failure &failure) {
756 IF_DEBUG_BUILD(verifyArgs(m_mainArgs, std::vector<char>(), std::vector<const char *>());)
760 m_executable = *argv;
765 bool completionMode = !strcmp(*++argv,
"--bash-completion-for");
766 unsigned int currentWordIndex;
767 if (completionMode) {
770 currentWordIndex = (--argc ? stringToNumber<unsigned int, string>(*(++argv)) : 0);
775 currentWordIndex =
static_cast<unsigned int>(argc - 1);
781 argv + (completionMode ? min(static_cast<unsigned int>(argc), currentWordIndex + 1) : static_cast<unsigned int>(argc)),
786 if (!completionMode) {
791 if (completionMode) {
792 printBashCompletion(argc, argv, currentWordIndex, reader);
798 m_defaultArg->m_occurrences.emplace_back(0);
802 m_executable =
nullptr;
813 arg->resetRecursively();
826 if (arg->denotesOperation() && arg->isPresent()) {
838 for (
const Argument *arg : m_mainArgs) {
839 if (!arg->isCombinable() && arg->isPresent()) {
863 void ApplicationUtilities::ArgumentParser::verifyArgs(
const ArgumentVector &args, vector<char>, vector<const char *>)
865 vector<const Argument *> verifiedArgs;
866 verifiedArgs.reserve(args.size());
867 vector<char> abbreviations;
868 abbreviations.reserve(abbreviations.size() + args.size());
869 vector<const char *> names;
870 names.reserve(names.size() + args.size());
871 bool hasImplicit =
false;
873 assert(find(verifiedArgs.cbegin(), verifiedArgs.cend(), arg) == verifiedArgs.cend());
874 verifiedArgs.push_back(arg);
875 assert(!arg->isImplicit() || !hasImplicit);
876 hasImplicit |= arg->isImplicit();
877 assert(!arg->abbreviation() || find(abbreviations.cbegin(), abbreviations.cend(), arg->abbreviation()) == abbreviations.cend());
878 abbreviations.push_back(arg->abbreviation());
879 assert(!arg->name() || find_if(names.cbegin(), names.cend(), [arg](
const char *name) {
return !strcmp(arg->name(), name); }) == names.cend());
880 assert(arg->requiredValueCount() == 0 || arg->subArguments().size() == 0);
881 names.emplace_back(arg->name());
884 verifyArgs(arg->subArguments(), vector<char>(), vector<const char *>());
903 return strcmp(arg1->
name(), arg2->
name()) < 0;
913 bool onlyCombinable =
false;
914 for (
const Argument *sibling : siblings) {
915 if (sibling->isPresent() && !sibling->isCombinable()) {
916 onlyCombinable =
true;
920 for (
const Argument *sibling : siblings) {
921 if ((!onlyCombinable || sibling->isCombinable()) && sibling->occurrences() < sibling->maxOccurrences()) {
922 target.push_back(sibling);
932 void ArgumentParser::printBashCompletion(
int argc,
const char *
const *argv,
unsigned int currentWordIndex,
const ArgumentReader &reader)
935 list<const Argument *> relevantArgs, relevantPreDefinedValues;
936 bool completeFiles =
false, completeDirs =
false, noWhitespace =
false;
940 size_t lastDetectedArgIndex;
941 vector<Argument *> lastDetectedArgPath;
942 if (lastDetectedArg) {
944 lastDetectedArgPath = lastDetectedArg->
path(lastDetectedArg->
occurrences() - 1);
948 const char *
const *lastSpecifiedArg;
949 unsigned int lastSpecifiedArgIndex;
951 lastSpecifiedArgIndex =
static_cast<unsigned int>(argc) - 1;
952 lastSpecifiedArg = argv + lastSpecifiedArgIndex;
953 for (; lastSpecifiedArg >= argv && **lastSpecifiedArg ==
'\0'; --lastSpecifiedArg, --lastSpecifiedArgIndex)
958 bool nextArgumentOrValue;
959 if (lastDetectedArg && lastDetectedArg->
isPresent()) {
960 if ((nextArgumentOrValue = (currentWordIndex > lastDetectedArgIndex))) {
962 const auto addValueCompletionsForArg = [&relevantPreDefinedValues, &completeFiles, &completeDirs](
const Argument *arg) {
964 relevantPreDefinedValues.push_back(arg);
967 || !arg->preDefinedCompletionValues()) {
974 auto currentValueCount = lastDetectedArg->
values(lastDetectedArg->
occurrences() - 1).size();
976 if (currentValueCount) {
977 const auto currentWordIndexRelativeToLastDetectedArg = currentWordIndex - lastDetectedArgIndex;
978 if (currentValueCount > currentWordIndexRelativeToLastDetectedArg) {
979 currentValueCount -= currentWordIndexRelativeToLastDetectedArg;
981 currentValueCount = 0;
989 if (child->isImplicit() && child->requiredValueCount()) {
990 addValueCompletionsForArg(child);
998 addValueCompletionsForArg(lastDetectedArg);
1005 if (subArg->occurrences() < subArg->maxOccurrences()) {
1006 relevantArgs.push_back(subArg);
1011 for (
auto parentArgument = lastDetectedArgPath.crbegin(), end = lastDetectedArgPath.crend();; ++parentArgument) {
1012 insertSiblings(parentArgument != end ? (*parentArgument)->subArguments() : m_mainArgs, relevantArgs);
1013 if (parentArgument == end) {
1020 relevantArgs.push_back(lastDetectedArg);
1025 nextArgumentOrValue =
true;
1030 const char *opening =
nullptr;
1031 string compoundOpening;
1032 size_t openingLen, compoundOpeningStartLen = 0;
1033 unsigned char openingDenotationType =
Value;
1034 if (argc && nextArgumentOrValue) {
1035 if (currentWordIndex < static_cast<unsigned int>(argc)) {
1036 opening = argv[currentWordIndex];
1042 size_t minCurrentWordIndex = (lastDetectedArg ? lastDetectedArgIndex : 0);
1043 if (currentWordIndex > minCurrentWordIndex && !strcmp(opening,
"=")) {
1044 compoundOpening.reserve(compoundOpeningStartLen = strlen(argv[--currentWordIndex]) + 1);
1045 compoundOpening = argv[currentWordIndex];
1046 compoundOpening +=
'=';
1047 }
else if (currentWordIndex > (minCurrentWordIndex + 1) && !strcmp(argv[currentWordIndex - 1],
"=")) {
1048 compoundOpening.reserve((compoundOpeningStartLen = strlen(argv[currentWordIndex -= 2]) + 1) + strlen(opening));
1049 compoundOpening = argv[currentWordIndex];
1050 compoundOpening +=
'=';
1051 compoundOpening += opening;
1053 if (!compoundOpening.empty()) {
1054 opening = compoundOpening.data();
1057 opening = *lastSpecifiedArg;
1059 *opening ==
'-' && (++opening, ++openingDenotationType) && *opening ==
'-' && (++opening, ++openingDenotationType);
1060 openingLen = strlen(opening);
1066 cout <<
"COMPREPLY=(";
1068 for (
const Argument *arg : relevantPreDefinedValues) {
1072 if (arg->preDefinedCompletionValues()) {
1074 if (argc && currentWordIndex <= lastSpecifiedArgIndex && opening) {
1075 if (openingDenotationType ==
Value) {
1076 bool wordStart =
true, ok =
false, equationSignAlreadyPresent =
false;
1077 size_t wordIndex = 0;
1078 for (
const char *i = arg->preDefinedCompletionValues(), *end = opening + openingLen; *i;) {
1080 const char *i1 = i, *i2 = opening;
1081 for (; *i1 && i2 != end && *i1 == *i2; ++i1, ++i2)
1083 if ((ok = (i2 == end))) {
1088 }
else if ((wordStart = (*i ==
' ') || (*i ==
'\n'))) {
1089 equationSignAlreadyPresent =
false;
1091 cout <<
'\'' <<
' ';
1095 }
else if (*i ==
'=') {
1096 equationSignAlreadyPresent =
true;
1099 if (!compoundOpeningStartLen || wordIndex >= compoundOpeningStartLen) {
1111 if (appendEquationSign && !equationSignAlreadyPresent) {
1113 noWhitespace =
true;
1114 equationSignAlreadyPresent =
false;
1126 }
else if (
const char *i = arg->preDefinedCompletionValues()) {
1127 bool equationSignAlreadyPresent =
false;
1137 equationSignAlreadyPresent =
true;
1142 if (appendEquationSign && !equationSignAlreadyPresent) {
1144 equationSignAlreadyPresent =
false;
1149 cout <<
' ' <<
'\'';
1154 cout <<
'\'' <<
' ';
1159 for (
const Argument *arg : relevantArgs) {
1160 if (argc && currentWordIndex <= lastSpecifiedArgIndex && opening) {
1161 switch (openingDenotationType) {
1163 if (!arg->denotesOperation() || strncmp(arg->name(), opening, openingLen)) {
1170 if (strncmp(arg->name(), opening, openingLen)) {
1176 if (opening && openingDenotationType ==
Abbreviation && !nextArgumentOrValue) {
1177 cout <<
'\'' <<
'-' << opening << arg->abbreviation() <<
'\'' <<
' ';
1179 if (reader.
argv == reader.
end) {
1180 cout <<
'\'' << *(reader.
argv - 1) <<
'\'' <<
' ';
1182 }
else if (arg->denotesOperation()) {
1183 cout <<
'\'' << arg->name() <<
'\'' <<
' ';
1185 cout <<
'\'' <<
'-' <<
'-' << arg->name() <<
'\'' <<
' ';
1190 string actualDir, actualFile;
1191 bool haveFileOrDirCompletions =
false;
1192 if (argc && currentWordIndex == lastSpecifiedArgIndex && opening) {
1194 string unescapedOpening(opening);
1195 findAndReplace<string>(unescapedOpening,
"\\ ",
" ");
1196 findAndReplace<string>(unescapedOpening,
"\\,",
",");
1197 findAndReplace<string>(unescapedOpening,
"\\[",
"[");
1198 findAndReplace<string>(unescapedOpening,
"\\]",
"]");
1199 findAndReplace<string>(unescapedOpening,
"\\!",
"!");
1200 findAndReplace<string>(unescapedOpening,
"\\#",
"#");
1201 findAndReplace<string>(unescapedOpening,
"\\$",
"$");
1202 findAndReplace<string>(unescapedOpening,
"\\'",
"'");
1203 findAndReplace<string>(unescapedOpening,
"\\\"",
"\"");
1204 findAndReplace<string>(unescapedOpening,
"\\\\",
"\\");
1206 string dir =
directory(unescapedOpening);
1210 if (dir[0] ==
'\"' || dir[0] ==
'\'') {
1213 if (dir.size() > 1 && (dir[dir.size() - 2] ==
'\"' || dir[dir.size() - 2] ==
'\'')) {
1214 dir.erase(dir.size() - 2, 1);
1216 actualDir = move(dir);
1219 string file =
fileName(unescapedOpening);
1220 if (file[0] ==
'\"' || file[0] ==
'\'') {
1223 if (file.size() > 1 && (file[dir.size() - 2] ==
'\"' || dir[file.size() - 2] ==
'\'')) {
1224 file.erase(file.size() - 2, 1);
1226 actualFile = move(file);
1231 if (completeFiles) {
1232 entryTypes |= DirectoryEntryType::File;
1235 entryTypes |= DirectoryEntryType::Directory;
1238 const string replace(
"'"), with(
"'\"'\"'");
1239 if (argc && currentWordIndex <= lastSpecifiedArgIndex && opening) {
1242 for (
string &dirEntry : entries) {
1245 if (actualDir !=
".") {
1249 cout << dirEntry <<
'\'' <<
' ';
1250 haveFileOrDirCompletions =
true;
1256 cout <<
'\'' << dirEntry <<
'\'' <<
' ';
1257 haveFileOrDirCompletions =
true;
1264 if (haveFileOrDirCompletions) {
1265 cout <<
"; compopt -o filenames";
1270 cout <<
"; compopt -o nospace";
1283 const auto occurrences = arg->occurrences();
1284 if (arg->isParentPresent() && occurrences > arg->maxOccurrences()) {
1285 throw Failure(
argsToString(
"The argument \"", arg->name(),
"\" mustn't be specified more than ", arg->maxOccurrences(),
1286 (arg->maxOccurrences() == 1 ?
" time." :
" times.")));
1288 if (arg->isParentPresent() && occurrences < arg->minOccurrences()) {
1289 throw Failure(
argsToString(
"The argument \"", arg->name(),
"\" must be specified at least ", arg->minOccurrences(),
1290 (arg->minOccurrences() == 1 ?
" time." :
" times.")));
1292 Argument *conflictingArgument =
nullptr;
1293 if (arg->isMainArgument()) {
1294 if (!arg->isCombinable() && arg->isPresent()) {
1298 conflictingArgument = arg->conflictsWithArgument();
1300 if (conflictingArgument) {
1301 throw Failure(
argsToString(
"The argument \"", conflictingArgument->name(),
"\" can not be combined with \"", arg->name(),
"\"."));
1303 for (
size_t i = 0; i != occurrences; ++i) {
1304 if (!arg->allRequiredValuesPresent(i)) {
1305 stringstream ss(stringstream::in | stringstream::out);
1306 ss <<
"Not all parameter for argument \"" << arg->name() <<
"\" ";
1308 ss <<
" (" << (i + 1) <<
" occurrence) ";
1310 ss <<
"provided. You have to provide the following parameter:";
1311 size_t valueNamesPrint = 0;
1312 for (
const auto &name : arg->m_valueNames) {
1313 ss <<
' ' << name, ++valueNamesPrint;
1315 if (arg->m_requiredValueCount != static_cast<size_t>(-1)) {
1316 while (valueNamesPrint < arg->m_requiredValueCount) {
1317 ss <<
"\nvalue " << (++valueNamesPrint);
1340 if (arg->m_callbackFunction) {
1341 for (
const auto &occurrence : arg->m_occurrences) {
1342 arg->m_callbackFunction(occurrence);
1360 :
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.
std::ostream & operator<<(std::ostream &os, const Wrapper &wrapper)
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...
The Wrapper class is internally used print text which might needs to be wrapped preserving the indent...
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.
void parseArgsOrExit(int argc, const char *const *argv)
Parses the specified command line arguments.
#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.
The TerminalSize struct describes a terminal size.
CPP_UTILITIES_EXPORT void(* exitFunction)(int)
Specifies a function quit the application.
TerminalSize determineTerminalSize()
Returns the current size of the terminal.
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()).
unsigned short columns
number of columns
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).
Argument * specifiedOperation() const
Returns the first operation argument specified by the user or nullptr if no operation has been specif...
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)...
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.
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.
Argument * specifiedOperation() const
Returns the first operation argument specified by the user or nullptr if no operation has been specif...
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