6 #include "../conversion/stringbuilder.h" 7 #include "../conversion/stringconversion.h" 8 #include "../io/ansiescapecodes.h" 9 #include "../io/path.h" 51 ArgumentReader::ArgumentReader(
ArgumentParser &parser,
const char *
const *argv,
const char *
const *end,
bool completionMode)
53 , args(parser.m_mainArgs)
58 , argDenotation(nullptr)
59 , completionMode(completionMode)
94 const vector<Argument *> &parentPath = parentArg ? parentArg->
path(parentArg->
occurrences() - 1) : vector<Argument *>();
97 vector<const char *> *values =
nullptr;
110 bool abbreviationFound =
false;
113 abbreviationFound =
false;
123 abbreviationFound =
false;
130 size_t argDenotationLength;
133 for (argDenotationLength = equationPos ? static_cast<size_t>(equationPos -
argDenotation) : strlen(
argDenotation); argDenotationLength;
134 matchingArg =
nullptr) {
138 if (arg->abbreviation() && arg->abbreviation() == *
argDenotation) {
140 abbreviationFound =
true;
146 if (arg->name() && !strncmp(arg->name(),
argDenotation, argDenotationLength)
147 && *(arg->name() + argDenotationLength) ==
'\0') {
156 matchingArg->m_occurrences.emplace_back(
index, parentPath, parentArg);
159 values = &matchingArg->m_occurrences.back().values;
161 values->push_back(equationPos + 1);
171 argDenotation =
nullptr;
191 for (
auto parentArgument = parentPath.crbegin(), pathEnd = parentPath.crend();; ++parentArgument) {
192 for (
Argument *sibling : (parentArgument != pathEnd ? (*parentArgument)->subArguments() :
parser.m_mainArgs)) {
193 if (sibling->occurrences() < sibling->maxOccurrences()) {
195 || (sibling->name() && !strncmp(sibling->name(),
argDenotation, argDenotationLength))) {
200 if (parentArgument == pathEnd) {
215 if (arg->denotesOperation() && arg->name() && !strcmp(arg->name(), *
argv)) {
216 (matchingArg = arg)->m_occurrences.emplace_back(
index, parentPath, parentArg);
227 if (arg->isImplicit() && !arg->isPresent() && !arg->wouldConflictWithArgument()
228 && (!uncombinableMainArgPresent || !arg->isMainArgument())) {
229 (matchingArg = arg)->m_occurrences.emplace_back(
index, parentPath, parentArg);
237 if (lastArgInLevel == matchingArg) {
242 values = &matchingArg->m_occurrences.back().values;
247 argDenotation =
nullptr;
260 switch (
parser.m_unknownArgBehavior) {
262 cerr << Phrases::Warning <<
"The specified argument \"" << *
argv <<
"\" is unknown and will be ignored." << Phrases::EndFlush;
285 const auto maxColumns = termSize.
columns ? termSize.
columns : numeric_limits<unsigned short>::max();
288 unsigned short currentCol = wrapper.m_indentation.
level;
289 for (
const char *currentChar = wrapper.m_str; *currentChar; ++currentChar) {
290 const bool wrappingRequired = currentCol >= maxColumns;
291 if (wrappingRequired || *currentChar ==
'\n') {
295 if (wrapper.m_indentation.
level < maxColumns) {
296 os << wrapper.m_indentation;
297 currentCol = wrapper.m_indentation.
level;
302 if (*currentChar !=
'\n' && (!wrappingRequired || *currentChar !=
' ')) {
329 inline bool notEmpty(
const char *str)
352 Argument::Argument(
const char *name,
char abbreviation,
const char *description,
const char *example)
354 , m_abbreviation(abbreviation)
355 , m_environmentVar(nullptr)
356 , m_description(description)
358 , m_minOccurrences(0)
359 , m_maxOccurrences(1)
360 , m_combinable(false)
361 , m_denotesOperation(false)
362 , m_requiredValueCount(0)
367 , m_preDefinedCompletionValues(nullptr)
387 if (!m_occurrences.empty() && !m_occurrences.front().values.empty()) {
388 return m_occurrences.front().values.front();
389 }
else if (m_environmentVar) {
390 return getenv(m_environmentVar);
404 if (notEmpty(
name())) {
418 unsigned int valueNamesPrint = 0;
420 os <<
' ' <<
'[' << *i <<
']';
427 os <<
" [value " << (valueNamesPrint + 1) <<
']';
436 os <<
'\n' << ident <<
"particularities: mandatory";
438 os <<
" if parent argument is present";
446 arg->printInfo(os, ident.level);
465 if (arg != except && arg->
isPresent() && !arg->isCombinable()) {
490 arg->m_parents.erase(
remove(arg->m_parents.begin(), arg->m_parents.end(),
this), arg->m_parents.end());
493 m_subArgs.assign(secondaryArguments);
497 if (find(arg->m_parents.cbegin(), arg->m_parents.cend(),
this) == arg->m_parents.cend()) {
498 arg->m_parents.push_back(
this);
512 if (find(m_subArgs.cbegin(), m_subArgs.cend(), arg) == m_subArgs.cend()) {
513 m_subArgs.push_back(arg);
514 if (find(arg->m_parents.cbegin(), arg->m_parents.cend(),
this) == arg->m_parents.cend()) {
515 arg->m_parents.push_back(
this);
529 for (
const Argument *parent : m_parents) {
530 if (parent->isPresent()) {
561 for (
Argument *parent : m_parents) {
563 if (sibling !=
this && sibling->isPresent() && !sibling->isCombinable()) {
579 if (arg->denotesOperation() && arg->isPresent()) {
593 arg->resetRecursively();
616 , m_executable(nullptr)
618 , m_defaultArg(nullptr)
633 if (mainArguments.size()) {
634 for (
Argument *arg : mainArguments) {
635 arg->m_isMainArg =
true;
637 m_mainArgs.assign(mainArguments);
639 if (!(*mainArguments.begin())->requiredValueCount()) {
640 bool subArgsRequired =
false;
641 for (
const Argument *subArg : (*mainArguments.begin())->subArguments()) {
642 if (subArg->isRequired()) {
643 subArgsRequired =
true;
647 if (!subArgsRequired) {
648 m_defaultArg = *mainArguments.begin();
665 argument->m_isMainArg =
true;
666 m_mainArgs.push_back(argument);
675 if (applicationName && *applicationName) {
677 if (applicationVersion && *applicationVersion) {
681 if (applicationVersion && *applicationVersion) {
684 if (dependencyVersions.size()) {
685 if ((applicationName && *applicationName) || (applicationVersion && *
applicationVersion)) {
689 auto i = dependencyVersions.begin(), end = dependencyVersions.end();
690 os <<
"Linked against: " << *i;
691 for (++i; i != end; ++i) {
692 os <<
',' <<
' ' << *i;
695 if ((applicationName && *applicationName) || (applicationVersion && *applicationVersion) || dependencyVersions.size()) {
699 if (!m_mainArgs.empty()) {
700 os <<
"Available arguments:";
701 for (
const Argument *arg : m_mainArgs) {
706 if (applicationUrl && *applicationUrl) {
707 os <<
"\nProject website: " << applicationUrl << endl;
742 }
catch (
const Failure &failure) {
762 IF_DEBUG_BUILD(verifyArgs(m_mainArgs, std::vector<char>(), std::vector<const char *>());)
766 m_executable = *argv;
771 bool completionMode = !strcmp(*++argv,
"--bash-completion-for");
772 unsigned int currentWordIndex;
773 if (completionMode) {
776 currentWordIndex = (--argc ? stringToNumber<unsigned int, string>(*(++argv)) : 0);
781 currentWordIndex =
static_cast<unsigned int>(argc - 1);
787 argv + (completionMode ? min(static_cast<unsigned int>(argc), currentWordIndex + 1) : static_cast<unsigned int>(argc)),
794 if (!completionMode) {
799 if (completionMode) {
800 printBashCompletion(argc, argv, currentWordIndex, reader);
806 m_defaultArg->m_occurrences.emplace_back(0);
810 m_executable =
nullptr;
821 arg->resetRecursively();
834 if (arg->denotesOperation() && arg->isPresent()) {
846 for (
const Argument *arg : m_mainArgs) {
847 if (!arg->isCombinable() && arg->isPresent()) {
871 void ApplicationUtilities::ArgumentParser::verifyArgs(
const ArgumentVector &args, vector<char>, vector<const char *>)
873 vector<const Argument *> verifiedArgs;
874 verifiedArgs.reserve(args.size());
875 vector<char> abbreviations;
876 abbreviations.reserve(abbreviations.size() + args.size());
877 vector<const char *> names;
878 names.reserve(names.size() + args.size());
879 bool hasImplicit =
false;
881 assert(find(verifiedArgs.cbegin(), verifiedArgs.cend(), arg) == verifiedArgs.cend());
882 verifiedArgs.push_back(arg);
883 assert(!arg->isImplicit() || !hasImplicit);
884 hasImplicit |= arg->isImplicit();
885 assert(!arg->abbreviation() || find(abbreviations.cbegin(), abbreviations.cend(), arg->abbreviation()) == abbreviations.cend());
886 abbreviations.push_back(arg->abbreviation());
887 assert(!arg->name() || find_if(names.cbegin(), names.cend(), [arg](
const char *name) {
return !strcmp(arg->name(), name); }) == names.cend());
888 assert(arg->requiredValueCount() == 0 || arg->subArguments().size() == 0);
889 names.emplace_back(arg->name());
892 verifyArgs(arg->subArguments(), vector<char>(), vector<const char *>());
911 return strcmp(arg1->
name(), arg2->
name()) < 0;
921 bool onlyCombinable =
false;
922 for (
const Argument *sibling : siblings) {
923 if (sibling->isPresent() && !sibling->isCombinable()) {
924 onlyCombinable =
true;
928 for (
const Argument *sibling : siblings) {
929 if ((!onlyCombinable || sibling->isCombinable()) && sibling->occurrences() < sibling->maxOccurrences()) {
930 target.push_back(sibling);
940 void ArgumentParser::printBashCompletion(
int argc,
const char *
const *argv,
unsigned int currentWordIndex,
const ArgumentReader &reader)
943 list<const Argument *> relevantArgs, relevantPreDefinedValues;
944 bool completeFiles =
false, completeDirs =
false, noWhitespace =
false;
948 size_t lastDetectedArgIndex;
949 vector<Argument *> lastDetectedArgPath;
950 if (lastDetectedArg) {
952 lastDetectedArgPath = lastDetectedArg->
path(lastDetectedArg->
occurrences() - 1);
956 const char *
const *lastSpecifiedArg;
957 unsigned int lastSpecifiedArgIndex;
959 lastSpecifiedArgIndex =
static_cast<unsigned int>(argc) - 1;
960 lastSpecifiedArg = argv + lastSpecifiedArgIndex;
961 for (; lastSpecifiedArg >= argv && **lastSpecifiedArg ==
'\0'; --lastSpecifiedArg, --lastSpecifiedArgIndex)
966 bool nextArgumentOrValue;
967 if (lastDetectedArg && lastDetectedArg->
isPresent()) {
968 if ((nextArgumentOrValue = (currentWordIndex > lastDetectedArgIndex))) {
970 const auto addValueCompletionsForArg = [&relevantPreDefinedValues, &completeFiles, &completeDirs](
const Argument *arg) {
972 relevantPreDefinedValues.push_back(arg);
975 || !arg->preDefinedCompletionValues()) {
982 auto currentValueCount = lastDetectedArg->
values(lastDetectedArg->
occurrences() - 1).size();
984 if (currentValueCount) {
985 const auto currentWordIndexRelativeToLastDetectedArg = currentWordIndex - lastDetectedArgIndex;
986 if (currentValueCount > currentWordIndexRelativeToLastDetectedArg) {
987 currentValueCount -= currentWordIndexRelativeToLastDetectedArg;
989 currentValueCount = 0;
997 if (child->isImplicit() && child->requiredValueCount()) {
998 addValueCompletionsForArg(child);
1006 addValueCompletionsForArg(lastDetectedArg);
1013 if (subArg->occurrences() < subArg->maxOccurrences()) {
1014 relevantArgs.push_back(subArg);
1019 for (
auto parentArgument = lastDetectedArgPath.crbegin(), end = lastDetectedArgPath.crend();; ++parentArgument) {
1020 insertSiblings(parentArgument != end ? (*parentArgument)->subArguments() : m_mainArgs, relevantArgs);
1021 if (parentArgument == end) {
1028 relevantArgs.push_back(lastDetectedArg);
1033 nextArgumentOrValue =
true;
1038 const char *opening =
nullptr;
1039 string compoundOpening;
1040 size_t openingLen, compoundOpeningStartLen = 0;
1041 unsigned char openingDenotationType =
Value;
1042 if (argc && nextArgumentOrValue) {
1043 if (currentWordIndex < static_cast<unsigned int>(argc)) {
1044 opening = argv[currentWordIndex];
1050 size_t minCurrentWordIndex = (lastDetectedArg ? lastDetectedArgIndex : 0);
1051 if (currentWordIndex > minCurrentWordIndex && !strcmp(opening,
"=")) {
1052 compoundOpening.reserve(compoundOpeningStartLen = strlen(argv[--currentWordIndex]) + 1);
1053 compoundOpening = argv[currentWordIndex];
1054 compoundOpening +=
'=';
1055 }
else if (currentWordIndex > (minCurrentWordIndex + 1) && !strcmp(argv[currentWordIndex - 1],
"=")) {
1056 compoundOpening.reserve((compoundOpeningStartLen = strlen(argv[currentWordIndex -= 2]) + 1) + strlen(opening));
1057 compoundOpening = argv[currentWordIndex];
1058 compoundOpening +=
'=';
1059 compoundOpening += opening;
1061 if (!compoundOpening.empty()) {
1062 opening = compoundOpening.data();
1065 opening = *lastSpecifiedArg;
1067 *opening ==
'-' && (++opening, ++openingDenotationType) && *opening ==
'-' && (++opening, ++openingDenotationType);
1068 openingLen = strlen(opening);
1074 cout <<
"COMPREPLY=(";
1076 for (
const Argument *arg : relevantPreDefinedValues) {
1080 if (arg->preDefinedCompletionValues()) {
1082 if (argc && currentWordIndex <= lastSpecifiedArgIndex && opening) {
1083 if (openingDenotationType ==
Value) {
1084 bool wordStart =
true, ok =
false, equationSignAlreadyPresent =
false;
1085 size_t wordIndex = 0;
1086 for (
const char *i = arg->preDefinedCompletionValues(), *end = opening + openingLen; *i;) {
1088 const char *i1 = i, *i2 = opening;
1089 for (; *i1 && i2 != end && *i1 == *i2; ++i1, ++i2)
1091 if ((ok = (i2 == end))) {
1096 }
else if ((wordStart = (*i ==
' ') || (*i ==
'\n'))) {
1097 equationSignAlreadyPresent =
false;
1099 cout <<
'\'' <<
' ';
1103 }
else if (*i ==
'=') {
1104 equationSignAlreadyPresent =
true;
1107 if (!compoundOpeningStartLen || wordIndex >= compoundOpeningStartLen) {
1119 if (appendEquationSign && !equationSignAlreadyPresent) {
1121 noWhitespace =
true;
1122 equationSignAlreadyPresent =
false;
1134 }
else if (
const char *i = arg->preDefinedCompletionValues()) {
1135 bool equationSignAlreadyPresent =
false;
1145 equationSignAlreadyPresent =
true;
1150 if (appendEquationSign && !equationSignAlreadyPresent) {
1152 equationSignAlreadyPresent =
false;
1157 cout <<
' ' <<
'\'';
1162 cout <<
'\'' <<
' ';
1167 for (
const Argument *arg : relevantArgs) {
1168 if (argc && currentWordIndex <= lastSpecifiedArgIndex && opening) {
1169 switch (openingDenotationType) {
1171 if (!arg->denotesOperation() || strncmp(arg->name(), opening, openingLen)) {
1178 if (strncmp(arg->name(), opening, openingLen)) {
1184 if (opening && openingDenotationType ==
Abbreviation && !nextArgumentOrValue) {
1185 cout <<
'\'' <<
'-' << opening << arg->abbreviation() <<
'\'' <<
' ';
1187 if (reader.
argv == reader.
end) {
1188 cout <<
'\'' << *(reader.
argv - 1) <<
'\'' <<
' ';
1190 }
else if (arg->denotesOperation()) {
1191 cout <<
'\'' << arg->name() <<
'\'' <<
' ';
1193 cout <<
'\'' <<
'-' <<
'-' << arg->name() <<
'\'' <<
' ';
1198 string actualDir, actualFile;
1199 bool haveFileOrDirCompletions =
false;
1200 if (argc && currentWordIndex == lastSpecifiedArgIndex && opening) {
1202 string unescapedOpening(opening);
1203 findAndReplace<string>(unescapedOpening,
"\\ ",
" ");
1204 findAndReplace<string>(unescapedOpening,
"\\,",
",");
1205 findAndReplace<string>(unescapedOpening,
"\\[",
"[");
1206 findAndReplace<string>(unescapedOpening,
"\\]",
"]");
1207 findAndReplace<string>(unescapedOpening,
"\\!",
"!");
1208 findAndReplace<string>(unescapedOpening,
"\\#",
"#");
1209 findAndReplace<string>(unescapedOpening,
"\\$",
"$");
1210 findAndReplace<string>(unescapedOpening,
"\\'",
"'");
1211 findAndReplace<string>(unescapedOpening,
"\\\"",
"\"");
1212 findAndReplace<string>(unescapedOpening,
"\\\\",
"\\");
1214 string dir =
directory(unescapedOpening);
1218 if (dir[0] ==
'\"' || dir[0] ==
'\'') {
1221 if (dir.size() > 1 && (dir[dir.size() - 2] ==
'\"' || dir[dir.size() - 2] ==
'\'')) {
1222 dir.erase(dir.size() - 2, 1);
1224 actualDir = move(dir);
1227 string file =
fileName(unescapedOpening);
1228 if (file[0] ==
'\"' || file[0] ==
'\'') {
1231 if (file.size() > 1 && (file[dir.size() - 2] ==
'\"' || dir[file.size() - 2] ==
'\'')) {
1232 file.erase(file.size() - 2, 1);
1234 actualFile = move(file);
1239 if (completeFiles) {
1240 entryTypes |= DirectoryEntryType::File;
1243 entryTypes |= DirectoryEntryType::Directory;
1246 const string replace(
"'"), with(
"'\"'\"'");
1247 if (argc && currentWordIndex <= lastSpecifiedArgIndex && opening) {
1250 for (
string &dirEntry : entries) {
1253 if (actualDir !=
".") {
1257 cout << dirEntry <<
'\'' <<
' ';
1258 haveFileOrDirCompletions =
true;
1264 cout <<
'\'' << dirEntry <<
'\'' <<
' ';
1265 haveFileOrDirCompletions =
true;
1272 if (haveFileOrDirCompletions) {
1273 cout <<
"; compopt -o filenames";
1278 cout <<
"; compopt -o nospace";
1291 const auto occurrences = arg->occurrences();
1292 if (arg->isParentPresent() && occurrences > arg->maxOccurrences()) {
1293 throw Failure(
argsToString(
"The argument \"", arg->name(),
"\" mustn't be specified more than ", arg->maxOccurrences(),
1294 (arg->maxOccurrences() == 1 ?
" time." :
" times.")));
1296 if (arg->isParentPresent() && occurrences < arg->minOccurrences()) {
1297 throw Failure(
argsToString(
"The argument \"", arg->name(),
"\" must be specified at least ", arg->minOccurrences(),
1298 (arg->minOccurrences() == 1 ?
" time." :
" times.")));
1300 Argument *conflictingArgument =
nullptr;
1301 if (arg->isMainArgument()) {
1302 if (!arg->isCombinable() && arg->isPresent()) {
1306 conflictingArgument = arg->conflictsWithArgument();
1308 if (conflictingArgument) {
1309 throw Failure(
argsToString(
"The argument \"", conflictingArgument->name(),
"\" can not be combined with \"", arg->name(),
"\"."));
1311 for (
size_t i = 0; i != occurrences; ++i) {
1312 if (!arg->allRequiredValuesPresent(i)) {
1313 stringstream ss(stringstream::in | stringstream::out);
1314 ss <<
"Not all parameter for argument \"" << arg->name() <<
"\" ";
1316 ss <<
" (" << (i + 1) <<
" occurrence) ";
1318 ss <<
"provided. You have to provide the following parameter:";
1319 size_t valueNamesPrint = 0;
1320 for (
const auto &name : arg->m_valueNames) {
1321 ss <<
' ' << name, ++valueNamesPrint;
1323 if (arg->m_requiredValueCount != static_cast<size_t>(-1)) {
1324 while (valueNamesPrint < arg->m_requiredValueCount) {
1325 ss <<
"\nvalue " << (++valueNamesPrint);
1348 if (arg->m_callbackFunction) {
1349 for (
const auto &occurrence : arg->m_occurrences) {
1350 arg->m_callbackFunction(occurrence);
1368 :
Argument(
"help",
'h',
"shows this information")
1413 #ifdef CPP_UTILITIES_ESCAPE_CODES_ENABLED_BY_DEFAULT 1414 :
Argument(
"no-color",
'\0',
"disables formatted/colorized output")
1416 :
Argument(
"enable-color",
'\0',
"enables formatted/colorized output")
1434 for (; *envValue; ++envValue) {
1435 switch (*envValue) {
1454 if (s_instance ==
this) {
1455 s_instance =
nullptr;
1464 if (NoColorArgument::s_instance && NoColorArgument::s_instance->
isPresent()) {
1465 #ifdef CPP_UTILITIES_ESCAPE_CODES_ENABLED_BY_DEFAULT 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.
Encapsulates functions for formatted terminal output using ANSI escape codes.
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.
static void apply()
Sets EscapeCodes::enabled according to the presense of the first instantiation of NoColorArgument...
unsigned char argDenotationType
The type of the currently processed abbreviation denotation. Unspecified if argDenotation is not set...
void setCombinable(bool value)
Sets whether this argument can be combined.
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...
NoColorArgument()
Constructs a new NoColorArgument argument.
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
The NoColorArgument class allows to specify whether use of escape codes or similar technique to provi...
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.
CPP_UTILITIES_EXPORT bool enabled
Controls whether the functions inside the EscapeCodes namespace actually make use of escape codes...
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 CPP_UTILITIES_EXPORT 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.
void setEnvironmentVariable(const char *environmentVariable)
Sets the environment variable queried when firstValue() is called.
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.
~NoColorArgument()
Destroys the object.
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