in log4j-core/src/main/java/org/apache/logging/log4j/core/tools/picocli/CommandLine.java [2010:2082]
private void processArguments(final List<CommandLine> parsedCommands,
final Stack<String> args,
final Collection<Field> required,
final Set<Field> initialized,
final String[] originalArgs) throws Exception {
// arg must be one of:
// 1. the "--" double dash separating options from positional arguments
// 1. a stand-alone flag, like "-v" or "--verbose": no value required, must map to boolean or Boolean field
// 2. a short option followed by an argument, like "-f file" or "-ffile": may map to any type of field
// 3. a long option followed by an argument, like "-file out.txt" or "-file=out.txt"
// 3. one or more remaining arguments without any associated options. Must be the last in the list.
// 4. a combination of stand-alone options, like "-vxr". Equivalent to "-v -x -r", "-v true -x true -r true"
// 5. a combination of stand-alone options and one option with an argument, like "-vxrffile"
while (!args.isEmpty()) {
String arg = args.pop();
if (tracer.isDebug()) {tracer.debug("Processing argument '%s'. Remainder=%s%n", arg, reverse((Stack<String>) args.clone()));}
// Double-dash separates options from positional arguments.
// If found, then interpret the remaining args as positional parameters.
if ("--".equals(arg)) {
tracer.info("Found end-of-options delimiter '--'. Treating remainder as positional parameters.%n");
processRemainderAsPositionalParameters(required, initialized, args);
return; // we are done
}
// if we find another command, we are done with the current command
if (commands.containsKey(arg)) {
if (!isHelpRequested && !required.isEmpty()) { // ensure current command portion is valid
throw MissingParameterException.create(CommandLine.this, required, separator);
}
if (tracer.isDebug()) {tracer.debug("Found subcommand '%s' (%s)%n", arg, commands.get(arg).interpreter.command.getClass().getName());}
commands.get(arg).interpreter.parse(parsedCommands, args, originalArgs);
return; // remainder done by the command
}
// First try to interpret the argument as a single option (as opposed to a compact group of options).
// A single option may be without option parameters, like "-v" or "--verbose" (a boolean value),
// or an option may have one or more option parameters.
// A parameter may be attached to the option.
boolean paramAttachedToOption = false;
final int separatorIndex = arg.indexOf(separator);
if (separatorIndex > 0) {
final String key = arg.substring(0, separatorIndex);
// be greedy. Consume the whole arg as an option if possible.
if (optionName2Field.containsKey(key) && !optionName2Field.containsKey(arg)) {
paramAttachedToOption = true;
final String optionParam = arg.substring(separatorIndex + separator.length());
args.push(optionParam);
arg = key;
if (tracer.isDebug()) {tracer.debug("Separated '%s' option from '%s' option parameter%n", key, optionParam);}
} else if (tracer.isDebug()) {tracer.debug("'%s' contains separator '%s' but '%s' is not a known option%n", arg, separator, key);}
} else if (tracer.isDebug()) {tracer.debug("'%s' cannot be separated into <option>%s<option-parameter>%n", arg, separator);}
if (optionName2Field.containsKey(arg)) {
processStandaloneOption(required, initialized, arg, args, paramAttachedToOption);
}
// Compact (single-letter) options can be grouped with other options or with an argument.
// only single-letter options can be combined with other options or with an argument
else if (arg.length() > 2 && arg.startsWith("-")) {
if (tracer.isDebug()) {tracer.debug("Trying to process '%s' as clustered short options%n", arg, args);}
processClusteredShortOptions(required, initialized, arg, args);
}
// The argument could not be interpreted as an option.
// We take this to mean that the remainder are positional arguments
else {
args.push(arg);
if (tracer.isDebug()) {tracer.debug("Could not find option '%s', deciding whether to treat as unmatched option or positional parameter...%n", arg);}
if (resemblesOption(arg)) { handleUnmatchedArguments(args.pop()); continue; } // #149
if (tracer.isDebug()) {tracer.debug("No option named '%s' found. Processing remainder as positional parameters%n", arg);}
processPositionalParameter(required, initialized, args);
}
}
}