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)
88 bool Argument::matchesDenotation(
const char *denotation,
size_t denotationLength)
const 90 return m_name && !strncmp(m_name, denotation, denotationLength) && *(m_name + denotationLength) ==
'\0';
102 const vector<Argument *> &parentPath = parentArg ? parentArg->
path(parentArg->
occurrences() - 1) : vector<Argument *>();
105 vector<const char *> *values =
nullptr;
118 bool abbreviationFound =
false;
121 abbreviationFound =
false;
131 abbreviationFound =
false;
145 for (; argDenotationLength; matchingArg =
nullptr) {
149 if (arg->abbreviation() && arg->abbreviation() == *
argDenotation) {
151 abbreviationFound =
true;
157 if (arg->matchesDenotation(
argDenotation, argDenotationLength)) {
168 matchingArg->m_occurrences.emplace_back(
index, parentPath, parentArg);
171 values = &matchingArg->m_occurrences.back().values;
175 values->push_back(equationPos + 1);
189 const char *
const *currentArgValue =
argv;
207 for (
auto parentArgument = parentPath.crbegin(), pathEnd = parentPath.crend();; ++parentArgument) {
208 for (
Argument *sibling : (parentArgument != pathEnd ? (*parentArgument)->subArguments() :
parser.m_mainArgs)) {
209 if (sibling->occurrences() < sibling->maxOccurrences()) {
215 if (sibling->matchesDenotation(
argDenotation, argDenotationLength)) {
220 if (parentArgument == pathEnd) {
235 if (arg->denotesOperation() && arg->name() && !strcmp(arg->name(), *
argv)) {
236 (matchingArg = arg)->m_occurrences.emplace_back(
index, parentPath, parentArg);
247 if (arg->isImplicit() && !arg->isPresent() && !arg->wouldConflictWithArgument()
248 && (!uncombinableMainArgPresent || !arg->isMainArgument())) {
249 (matchingArg = arg)->m_occurrences.emplace_back(
index, parentPath, parentArg);
257 if (lastArgInLevel == matchingArg) {
262 values = &matchingArg->m_occurrences.back().values;
280 switch (
parser.m_unknownArgBehavior) {
282 cerr << Phrases::Warning <<
"The specified argument \"" << *
argv <<
"\" is unknown and will be ignored." << Phrases::EndFlush;
305 const auto maxColumns = termSize.
columns ? termSize.
columns : numeric_limits<unsigned short>::max();
308 unsigned short currentCol = wrapper.m_indentation.
level;
309 for (
const char *currentChar = wrapper.m_str; *currentChar; ++currentChar) {
310 const bool wrappingRequired = currentCol >= maxColumns;
311 if (wrappingRequired || *currentChar ==
'\n') {
315 if (wrapper.m_indentation.
level < maxColumns) {
316 os << wrapper.m_indentation;
317 currentCol = wrapper.m_indentation.
level;
322 if (*currentChar !=
'\n' && (!wrappingRequired || *currentChar !=
' ')) {
349 inline bool notEmpty(
const char *str)
372 Argument::Argument(
const char *name,
char abbreviation,
const char *description,
const char *example)
374 , m_abbreviation(abbreviation)
375 , m_environmentVar(nullptr)
376 , m_description(description)
378 , m_minOccurrences(0)
379 , m_maxOccurrences(1)
380 , m_combinable(false)
381 , m_denotesOperation(false)
382 , m_requiredValueCount(0)
387 , m_preDefinedCompletionValues(nullptr)
407 if (!m_occurrences.empty() && !m_occurrences.front().values.empty()) {
408 return m_occurrences.front().values.front();
409 }
else if (m_environmentVar) {
410 return getenv(m_environmentVar);
424 if (notEmpty(
name())) {
438 unsigned int valueNamesPrint = 0;
440 os <<
' ' <<
'[' << *i <<
']';
447 os <<
" [value " << (valueNamesPrint + 1) <<
']';
456 os <<
'\n' << ident <<
"particularities: mandatory";
458 os <<
" if parent argument is present";
466 arg->printInfo(os, ident.level);
485 if (arg != except && arg->
isPresent() && !arg->isCombinable()) {
510 arg->m_parents.erase(
remove(arg->m_parents.begin(), arg->m_parents.end(),
this), arg->m_parents.end());
513 m_subArgs.assign(secondaryArguments);
517 if (find(arg->m_parents.cbegin(), arg->m_parents.cend(),
this) == arg->m_parents.cend()) {
518 arg->m_parents.push_back(
this);
532 if (find(m_subArgs.cbegin(), m_subArgs.cend(), arg) == m_subArgs.cend()) {
533 m_subArgs.push_back(arg);
534 if (find(arg->m_parents.cbegin(), arg->m_parents.cend(),
this) == arg->m_parents.cend()) {
535 arg->m_parents.push_back(
this);
549 for (
const Argument *parent : m_parents) {
550 if (parent->isPresent()) {
581 for (
Argument *parent : m_parents) {
583 if (sibling !=
this && sibling->isPresent() && !sibling->isCombinable()) {
599 if (arg->denotesOperation() && arg->isPresent()) {
613 arg->resetRecursively();
636 , m_executable(nullptr)
638 , m_defaultArg(nullptr)
655 arg->m_isMainArg =
true;
660 bool subArgsRequired =
false;
662 if (subArg->isRequired()) {
663 subArgsRequired =
true;
667 if (!subArgsRequired) {
685 argument->m_isMainArg =
true;
686 m_mainArgs.push_back(argument);
710 os <<
"Linked against: " << *i;
711 for (++i; i != end; ++i) {
712 os <<
',' <<
' ' << *i;
719 if (!m_mainArgs.empty()) {
720 bool hasOperations =
false;
721 for (
const Argument *arg : m_mainArgs) {
722 if (arg->denotesOperation()) {
723 hasOperations =
true;
731 os <<
"Available operations:";
732 for (
const Argument *arg : m_mainArgs) {
733 if (arg->denotesOperation() && strcmp(arg->name(),
"help")) {
738 os <<
"\nAvailable top-level options:";
739 for (
const Argument *arg : m_mainArgs) {
740 if (!arg->denotesOperation() && strcmp(arg->name(),
"help")) {
747 os <<
"Available arguments:";
748 for (
const Argument *arg : m_mainArgs) {
749 if (strcmp(arg->name(),
"help")) {
821 }
catch (
const Failure &failure) {
846 IF_DEBUG_BUILD(verifyArgs(m_mainArgs, std::vector<char>(), std::vector<const char *>());)
851 m_executable =
nullptr;
854 m_executable = *argv;
860 m_defaultArg->m_occurrences.emplace_back(0);
866 bool completionMode = !strcmp(*++argv,
"--bash-completion-for");
867 unsigned int currentWordIndex;
868 if (completionMode) {
871 currentWordIndex = (--argc ? stringToNumber<unsigned int, string>(*(++argv)) : 0);
876 currentWordIndex =
static_cast<unsigned int>(argc - 1);
882 argv + (completionMode ? min(static_cast<unsigned int>(argc), currentWordIndex + 1) : static_cast<unsigned int>(argc)), completionMode);
888 if (!completionMode) {
893 if (completionMode) {
894 printBashCompletion(argc, argv, currentWordIndex, reader);
906 arg->resetRecursively();
919 if (arg->denotesOperation() && arg->isPresent()) {
931 for (
const Argument *arg : m_mainArgs) {
932 if (!arg->isCombinable() && arg->isPresent()) {
956 void ApplicationUtilities::ArgumentParser::verifyArgs(
const ArgumentVector &args, vector<char>, vector<const char *>)
958 vector<const Argument *> verifiedArgs;
959 verifiedArgs.reserve(args.size());
960 vector<char> abbreviations;
961 abbreviations.reserve(abbreviations.size() + args.size());
962 vector<const char *> names;
963 names.reserve(names.size() + args.size());
964 bool hasImplicit =
false;
966 assert(find(verifiedArgs.cbegin(), verifiedArgs.cend(), arg) == verifiedArgs.cend());
967 verifiedArgs.push_back(arg);
968 assert(!arg->isImplicit() || !hasImplicit);
969 hasImplicit |= arg->isImplicit();
970 assert(!arg->abbreviation() || find(abbreviations.cbegin(), abbreviations.cend(), arg->abbreviation()) == abbreviations.cend());
971 abbreviations.push_back(arg->abbreviation());
972 assert(!arg->name() || find_if(names.cbegin(), names.cend(), [arg](
const char *name) {
return !strcmp(arg->name(), name); }) == names.cend());
973 assert(arg->requiredValueCount() == 0 || arg->subArguments().size() == 0);
974 names.emplace_back(arg->name());
976 for (
const Argument *arg : args) {
977 verifyArgs(arg->subArguments(), vector<char>(), vector<const char *>());
996 return strcmp(arg1->
name(), arg2->
name()) < 0;
1006 bool onlyCombinable =
false;
1007 for (
const Argument *sibling : siblings) {
1008 if (sibling->isPresent() && !sibling->isCombinable()) {
1009 onlyCombinable =
true;
1013 for (
const Argument *sibling : siblings) {
1014 if ((!onlyCombinable || sibling->isCombinable()) && sibling->occurrences() < sibling->maxOccurrences()) {
1015 target.push_back(sibling);
1025 void ArgumentParser::printBashCompletion(
int argc,
const char *
const *argv,
unsigned int currentWordIndex,
const ArgumentReader &reader)
1028 list<const Argument *> relevantArgs, relevantPreDefinedValues;
1029 bool completeFiles =
false, completeDirs =
false, noWhitespace =
false;
1032 const Argument *
const lastDetectedArg = reader.lastArg;
1033 size_t lastDetectedArgIndex;
1034 vector<Argument *> lastDetectedArgPath;
1035 if (lastDetectedArg) {
1036 lastDetectedArgIndex = reader.lastArgDenotation - argv;
1037 lastDetectedArgPath = lastDetectedArg->path(lastDetectedArg->occurrences() - 1);
1041 const char *
const *lastSpecifiedArg;
1042 unsigned int lastSpecifiedArgIndex;
1044 lastSpecifiedArgIndex =
static_cast<unsigned int>(argc) - 1;
1045 lastSpecifiedArg = argv + lastSpecifiedArgIndex;
1046 for (; lastSpecifiedArg >= argv && **lastSpecifiedArg ==
'\0'; --lastSpecifiedArg, --lastSpecifiedArgIndex)
1051 bool nextArgumentOrValue;
1052 if (lastDetectedArg && lastDetectedArg->isPresent()) {
1053 if ((nextArgumentOrValue = (currentWordIndex > lastDetectedArgIndex))) {
1055 const auto addValueCompletionsForArg = [&relevantPreDefinedValues, &completeFiles, &completeDirs](
const Argument *arg) {
1057 relevantPreDefinedValues.push_back(arg);
1060 || !arg->preDefinedCompletionValues()) {
1067 auto currentValueCount = lastDetectedArg->values(lastDetectedArg->occurrences() - 1).size();
1069 if (currentValueCount) {
1070 const auto currentWordIndexRelativeToLastDetectedArg = currentWordIndex - lastDetectedArgIndex;
1071 if (currentValueCount > currentWordIndexRelativeToLastDetectedArg) {
1072 currentValueCount -= currentWordIndexRelativeToLastDetectedArg;
1074 currentValueCount = 0;
1080 if (!currentValueCount && !lastDetectedArg->requiredValueCount()) {
1081 for (
const Argument *child : lastDetectedArg->subArguments()) {
1082 if (child->isImplicit() && child->requiredValueCount()) {
1083 addValueCompletionsForArg(child);
1090 if (lastDetectedArg->requiredValueCount() ==
Argument::varValueCount || (currentValueCount < lastDetectedArg->requiredValueCount())) {
1091 addValueCompletionsForArg(lastDetectedArg);
1095 || lastDetectedArg->values(lastDetectedArg->occurrences() - 1).size() >= lastDetectedArg->requiredValueCount()) {
1097 for (
const Argument *subArg : lastDetectedArg->subArguments()) {
1098 if (subArg->occurrences() < subArg->maxOccurrences()) {
1099 relevantArgs.push_back(subArg);
1104 for (
auto parentArgument = lastDetectedArgPath.crbegin(), end = lastDetectedArgPath.crend();; ++parentArgument) {
1105 insertSiblings(parentArgument != end ? (*parentArgument)->subArguments() : m_mainArgs, relevantArgs);
1106 if (parentArgument == end) {
1113 relevantArgs.push_back(lastDetectedArg);
1118 nextArgumentOrValue =
true;
1123 const char *opening =
nullptr;
1124 string compoundOpening;
1125 size_t openingLen, compoundOpeningStartLen = 0;
1126 unsigned char openingDenotationType =
Value;
1127 if (argc && nextArgumentOrValue) {
1128 if (currentWordIndex < static_cast<unsigned int>(argc)) {
1129 opening = argv[currentWordIndex];
1135 size_t minCurrentWordIndex = (lastDetectedArg ? lastDetectedArgIndex : 0);
1136 if (currentWordIndex > minCurrentWordIndex && !strcmp(opening,
"=")) {
1137 compoundOpening.reserve(compoundOpeningStartLen = strlen(argv[--currentWordIndex]) + 1);
1138 compoundOpening = argv[currentWordIndex];
1139 compoundOpening +=
'=';
1140 }
else if (currentWordIndex > (minCurrentWordIndex + 1) && !strcmp(argv[currentWordIndex - 1],
"=")) {
1141 compoundOpening.reserve((compoundOpeningStartLen = strlen(argv[currentWordIndex -= 2]) + 1) + strlen(opening));
1142 compoundOpening = argv[currentWordIndex];
1143 compoundOpening +=
'=';
1144 compoundOpening += opening;
1146 if (!compoundOpening.empty()) {
1147 opening = compoundOpening.data();
1150 opening = *lastSpecifiedArg;
1152 *opening ==
'-' && (++opening, ++openingDenotationType) && *opening ==
'-' && (++opening, ++openingDenotationType);
1153 openingLen = strlen(opening);
1159 cout <<
"COMPREPLY=(";
1161 for (
const Argument *arg : relevantPreDefinedValues) {
1163 arg->m_callbackFunction(arg->isPresent() ? arg->m_occurrences.front() : ArgumentOccurrence(
Argument::varValueCount));
1165 if (arg->preDefinedCompletionValues()) {
1167 if (argc && currentWordIndex <= lastSpecifiedArgIndex && opening) {
1168 if (openingDenotationType ==
Value) {
1169 bool wordStart =
true, ok =
false, equationSignAlreadyPresent =
false;
1170 size_t wordIndex = 0;
1171 for (
const char *i = arg->preDefinedCompletionValues(), *end = opening + openingLen; *i;) {
1173 const char *i1 = i, *i2 = opening;
1174 for (; *i1 && i2 != end && *i1 == *i2; ++i1, ++i2)
1176 if ((ok = (i2 == end))) {
1181 }
else if ((wordStart = (*i ==
' ') || (*i ==
'\n'))) {
1182 equationSignAlreadyPresent =
false;
1184 cout <<
'\'' <<
' ';
1188 }
else if (*i ==
'=') {
1189 equationSignAlreadyPresent =
true;
1192 if (!compoundOpeningStartLen || wordIndex >= compoundOpeningStartLen) {
1204 if (appendEquationSign && !equationSignAlreadyPresent) {
1206 noWhitespace =
true;
1207 equationSignAlreadyPresent =
false;
1219 }
else if (
const char *i = arg->preDefinedCompletionValues()) {
1220 bool equationSignAlreadyPresent =
false;
1230 equationSignAlreadyPresent =
true;
1235 if (appendEquationSign && !equationSignAlreadyPresent) {
1237 equationSignAlreadyPresent =
false;
1242 cout <<
' ' <<
'\'';
1247 cout <<
'\'' <<
' ';
1252 for (
const Argument *arg : relevantArgs) {
1253 if (argc && currentWordIndex <= lastSpecifiedArgIndex && opening) {
1254 switch (openingDenotationType) {
1256 if (!arg->denotesOperation() || strncmp(arg->name(), opening, openingLen)) {
1263 if (strncmp(arg->name(), opening, openingLen)) {
1269 if (opening && openingDenotationType ==
Abbreviation && !nextArgumentOrValue) {
1271 cout <<
'\'' <<
'-' << opening << arg->abbreviation() <<
'\'' <<
' ';
1272 }
else if (lastDetectedArg && reader.argDenotationType ==
Abbreviation && !nextArgumentOrValue) {
1273 if (reader.argv == reader.end) {
1274 cout <<
'\'' << *(reader.argv - 1) <<
'\'' <<
' ';
1276 }
else if (arg->denotesOperation()) {
1277 cout <<
'\'' << arg->name() <<
'\'' <<
' ';
1279 cout <<
'\'' <<
'-' <<
'-' << arg->name() <<
'\'' <<
' ';
1284 string actualDir, actualFile;
1285 bool haveFileOrDirCompletions =
false;
1286 if (argc && currentWordIndex == lastSpecifiedArgIndex && opening) {
1288 string unescapedOpening(opening);
1289 findAndReplace<string>(unescapedOpening,
"\\ ",
" ");
1290 findAndReplace<string>(unescapedOpening,
"\\,",
",");
1291 findAndReplace<string>(unescapedOpening,
"\\[",
"[");
1292 findAndReplace<string>(unescapedOpening,
"\\]",
"]");
1293 findAndReplace<string>(unescapedOpening,
"\\!",
"!");
1294 findAndReplace<string>(unescapedOpening,
"\\#",
"#");
1295 findAndReplace<string>(unescapedOpening,
"\\$",
"$");
1296 findAndReplace<string>(unescapedOpening,
"\\'",
"'");
1297 findAndReplace<string>(unescapedOpening,
"\\\"",
"\"");
1298 findAndReplace<string>(unescapedOpening,
"\\\\",
"\\");
1300 string dir =
directory(unescapedOpening);
1304 if (dir[0] ==
'\"' || dir[0] ==
'\'') {
1307 if (dir.size() > 1 && (dir[dir.size() - 2] ==
'\"' || dir[dir.size() - 2] ==
'\'')) {
1308 dir.erase(dir.size() - 2, 1);
1310 actualDir = move(dir);
1313 string file =
fileName(unescapedOpening);
1314 if (file[0] ==
'\"' || file[0] ==
'\'') {
1317 if (file.size() > 1 && (file[dir.size() - 2] ==
'\"' || dir[file.size() - 2] ==
'\'')) {
1318 file.erase(file.size() - 2, 1);
1320 actualFile = move(file);
1325 if (completeFiles) {
1326 entryTypes |= DirectoryEntryType::File;
1329 entryTypes |= DirectoryEntryType::Directory;
1332 const string replace(
"'"), with(
"'\"'\"'");
1333 if (argc && currentWordIndex <= lastSpecifiedArgIndex && opening) {
1336 for (
string &dirEntry : entries) {
1339 if (actualDir !=
".") {
1343 cout << dirEntry <<
'\'' <<
' ';
1344 haveFileOrDirCompletions =
true;
1350 cout <<
'\'' << dirEntry <<
'\'' <<
' ';
1351 haveFileOrDirCompletions =
true;
1358 if (haveFileOrDirCompletions) {
1359 cout <<
"; compopt -o filenames";
1364 cout <<
"; compopt -o nospace";
1376 for (
const Argument *arg : args) {
1377 const auto occurrences = arg->occurrences();
1378 if (arg->isParentPresent() && occurrences > arg->maxOccurrences()) {
1379 throw Failure(
argsToString(
"The argument \"", arg->name(),
"\" mustn't be specified more than ", arg->maxOccurrences(),
1380 (arg->maxOccurrences() == 1 ?
" time." :
" times.")));
1382 if (arg->isParentPresent() && occurrences < arg->minOccurrences()) {
1383 throw Failure(
argsToString(
"The argument \"", arg->name(),
"\" must be specified at least ", arg->minOccurrences(),
1384 (arg->minOccurrences() == 1 ?
" time." :
" times.")));
1386 Argument *conflictingArgument =
nullptr;
1387 if (arg->isMainArgument()) {
1388 if (!arg->isCombinable() && arg->isPresent()) {
1392 conflictingArgument = arg->conflictsWithArgument();
1394 if (conflictingArgument) {
1395 throw Failure(
argsToString(
"The argument \"", conflictingArgument->name(),
"\" can not be combined with \"", arg->name(),
"\"."));
1397 for (
size_t i = 0; i != occurrences; ++i) {
1398 if (!arg->allRequiredValuesPresent(i)) {
1399 stringstream ss(stringstream::in | stringstream::out);
1400 ss <<
"Not all parameter for argument \"" << arg->name() <<
"\" ";
1402 ss <<
" (" << (i + 1) <<
" occurrence) ";
1404 ss <<
"provided. You have to provide the following parameter:";
1405 size_t valueNamesPrint = 0;
1406 for (
const auto &name : arg->m_valueNames) {
1407 ss <<
' ' << name, ++valueNamesPrint;
1410 while (valueNamesPrint < arg->m_requiredValueCount) {
1411 ss <<
"\nvalue " << (++valueNamesPrint);
1414 throw Failure(ss.str());
1432 for (
const Argument *arg : args) {
1434 if (arg->m_callbackFunction) {
1435 for (
const auto &occurrence : arg->m_occurrences) {
1436 arg->m_callbackFunction(occurrence);
1454 :
Argument(
"help",
'h',
"shows this information")
1499 #ifdef CPP_UTILITIES_ESCAPE_CODES_ENABLED_BY_DEFAULT 1500 :
Argument(
"no-color",
'\0',
"disables formatted/colorized output")
1502 :
Argument(
"enable-color",
'\0',
"enables formatted/colorized output")
1505 setCombinable(
true);
1513 setEnvironmentVariable(
"ENABLE_ESCAPE_CODES");
1516 const char *envValue = getenv(environmentVariable());
1520 for (; *envValue; ++envValue) {
1521 switch (*envValue) {
1540 if (s_instance ==
this) {
1541 s_instance =
nullptr;
1550 if (NoColorArgument::s_instance && NoColorArgument::s_instance->
isPresent()) {
1551 #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...
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.
void parseArgsExt(int argc, const char *const *argv, ParseArgumentBehavior behavior=ParseArgumentBehavior::CheckConstraints|ParseArgumentBehavior::InvokeCallbacks|ParseArgumentBehavior::ExitOnFailure)
Parses the specified command line arguments.
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...
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.
ParseArgumentBehavior
The ParseArgumentBehavior enum specifies the behavior when parsing arguments.
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.
~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