in src/apps/applib/lib/args.c [99:175]
int _parseArgsList(int argc, char* argv[], int numArgs, Arg* args[],
const Arg* helpArg, const char** errorMessage,
const char** errorDetail) {
// Whether help was found and required arguments do not need to be checked
bool foundHelp = false;
for (int i = 1; i < argc; i++) {
bool foundMatch = false;
for (int j = 0; j < numArgs; j++) {
// Test this argument, which may have multiple names, for whether it
// matches. argName will be set to the name used for this argument
// if it matches.
const char* argName = NULL;
for (int k = 0; k < NUM_ARG_NAMES; k++) {
if (args[j]->names[k] == NULL) continue;
if (strcmp(argv[i], args[j]->names[k]) == 0) {
argName = args[j]->names[k];
break;
}
}
// argName unchanged from NULL indicates this didn't match, try the
// next argument.
if (argName == NULL) continue;
if (args[j]->found) {
*errorMessage = "Argument specified multiple times";
*errorDetail = argName;
return PARSE_ARGS_REPEATED_ARGUMENT;
}
if (args[j]->scanFormat != NULL) {
// Argument has a value, need to advance one and read the value.
i++;
if (i >= argc) {
*errorMessage = "Argument value not present";
*errorDetail = argName;
return PARSE_ARGS_MISSING_VALUE;
}
if (!sscanf(argv[i], args[j]->scanFormat, args[j]->value)) {
*errorMessage = "Failed to parse argument";
*errorDetail = argName;
return PARSE_ARGS_FAILED_PARSE;
}
}
if (args[j] == helpArg) {
foundHelp = true;
}
args[j]->found = true;
foundMatch = true;
break;
}
if (!foundMatch) {
*errorMessage = "Unknown argument";
// Don't set errorDetail, since the input could be unprintable.
return PARSE_ARGS_UNKNOWN_ARGUMENT;
}
}
// Check for missing required arguments.
if (!foundHelp) {
for (int i = 0; i < numArgs; i++) {
if (args[i]->required && !args[i]->found) {
*errorMessage = "Required argument missing";
*errorDetail = args[i]->names[0];
return PARSE_ARGS_MISSING_REQUIRED;
}
}
}
return PARSE_ARGS_SUCCESS;
}