Make ArgumentParser::verifyArgs() more strict
This commit is contained in:
parent
bbb884da30
commit
9f3ca443e4
|
@ -412,7 +412,7 @@ void ArgumentParser::parseArgs(int argc, const char *const *argv)
|
|||
*/
|
||||
void ArgumentParser::readArgs(int argc, const char * const *argv)
|
||||
{
|
||||
IF_DEBUG_BUILD(verifyArgs(m_mainArgs);)
|
||||
IF_DEBUG_BUILD(verifyArgs(m_mainArgs, std::vector<char>(), std::vector<const char *>());)
|
||||
m_actualArgc = 0;
|
||||
if(argc) {
|
||||
// the first argument is the executable name
|
||||
|
@ -491,14 +491,12 @@ bool ArgumentParser::isUncombinableMainArgPresent() const
|
|||
* - Verifies the sub arguments, too.
|
||||
* - For debugging purposes only; hence only available in debug builds.
|
||||
*/
|
||||
void ApplicationUtilities::ArgumentParser::verifyArgs(const ArgumentVector &args)
|
||||
void ApplicationUtilities::ArgumentParser::verifyArgs(const ArgumentVector &args, vector<char> abbreviations, vector<const char *> names)
|
||||
{
|
||||
vector<const Argument *> verifiedArgs;
|
||||
verifiedArgs.reserve(args.size());
|
||||
vector<char> abbreviations;
|
||||
abbreviations.reserve(args.size());
|
||||
vector<string> names;
|
||||
names.reserve(args.size());
|
||||
abbreviations.reserve(abbreviations.size() + args.size());
|
||||
names.reserve(names.size() + args.size());
|
||||
bool hasImplicit = false;
|
||||
for(const Argument *arg : args) {
|
||||
assert(find(verifiedArgs.cbegin(), verifiedArgs.cend(), arg) == verifiedArgs.cend());
|
||||
|
@ -508,10 +506,12 @@ void ApplicationUtilities::ArgumentParser::verifyArgs(const ArgumentVector &args
|
|||
hasImplicit |= arg->isImplicit();
|
||||
assert(!arg->abbreviation() || find(abbreviations.cbegin(), abbreviations.cend(), arg->abbreviation()) == abbreviations.cend());
|
||||
abbreviations.push_back(arg->abbreviation());
|
||||
assert(!arg->name() || find(names.cbegin(), names.cend(), arg->name()) == names.cend());
|
||||
assert(!arg->name() || find_if(names.cbegin(), names.cend(), [arg] (const char *name) { return !strcmp(arg->name(), name); }) == names.cend());
|
||||
assert(arg->requiredValueCount() == 0 || arg->subArguments().size() == 0);
|
||||
names.emplace_back(arg->name());
|
||||
verifyArgs(arg->subArguments());
|
||||
}
|
||||
for(const Argument *arg : args) {
|
||||
verifyArgs(arg->subArguments(), abbreviations, names);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -231,7 +231,7 @@ public:
|
|||
bool isUncombinableMainArgPresent() const;
|
||||
|
||||
private:
|
||||
IF_DEBUG_BUILD(void verifyArgs(const ArgumentVector &args);)
|
||||
IF_DEBUG_BUILD(void verifyArgs(const ArgumentVector &args, std::vector<char> abbreviations, std::vector<const char *> names);)
|
||||
void readSpecifiedArgs(ArgumentVector &args, std::size_t &index, const char *const *&argv, const char *const *end, Argument *&lastArg, const char *&argDenotation, bool completionMode = false);
|
||||
void printBashCompletion(int argc, const char * const *argv, unsigned int cursorPos, const Argument *lastDetectedArg);
|
||||
void checkConstraints(const ArgumentVector &args);
|
||||
|
|
|
@ -101,17 +101,17 @@ void ArgumentParserTests::testParsing()
|
|||
outputFileArg.setCombinable(true);
|
||||
Argument printFieldNamesArg("print-field-names", '\0', "prints available field names");
|
||||
Argument displayFileInfoArg("display-file-info", 'i', "displays general file information");
|
||||
Argument notAlbumArg("album", 'a', "should not be confused with album value");
|
||||
displayFileInfoArg.setDenotesOperation(true);
|
||||
displayFileInfoArg.setSubArguments({&fileArg, &verboseArg});
|
||||
displayFileInfoArg.setSubArguments({&fileArg, &verboseArg, ¬AlbumArg});
|
||||
Argument fieldsArg("fields", '\0', "specifies the fields");
|
||||
fieldsArg.setRequiredValueCount(-1);
|
||||
fieldsArg.setValueNames({"title", "album", "artist", "trackpos"});
|
||||
fieldsArg.setImplicit(true);
|
||||
Argument notAlbumArg("album", 'a', "should not be confused with album value");
|
||||
Argument displayTagInfoArg("get", 'p', "displays the values of all specified tag fields (displays all fields if none specified)");
|
||||
displayTagInfoArg.setDenotesOperation(true);
|
||||
displayTagInfoArg.setSubArguments({&fieldsArg, &filesArg, &verboseArg, ¬AlbumArg});
|
||||
parser.setMainArguments({&qtConfigArgs.qtWidgetsGuiArg(), &printFieldNamesArg, &displayTagInfoArg, &displayFileInfoArg, &helpArg, ¬AlbumArg});
|
||||
parser.setMainArguments({&qtConfigArgs.qtWidgetsGuiArg(), &printFieldNamesArg, &displayTagInfoArg, &displayFileInfoArg, &helpArg});
|
||||
|
||||
// define some argument values
|
||||
const char *argv[] = {"tageditor", "get", "album", "title", "diskpos", "-f", "somefile"};
|
||||
|
|
Loading…
Reference in New Issue