/** * Called when parsing varargs parameters for a multi-value option. * When an option is encountered, the remainder should not be interpreted as vararg elements. * @param arg the string to determine whether it is an option or not * @return true if it is an option, false otherwise */ private boolean isOption(String arg) { if (arg == null) { return false; } if ("--".equals(arg)) { return true; } // not just arg prefix: we may be in the middle of parsing -xrvfFILE if (commandSpec.optionsMap().containsKey(arg)) { // -v or -f or --file (not attached to param or other option) return true; } int separatorIndex = arg.indexOf(config().separator()); if (separatorIndex > 0) { // -f=FILE or --file==FILE (attached to param via separator) if (commandSpec.optionsMap().containsKey(arg.substring(0, separatorIndex))) { return true; } } return (arg.length() > 2 && arg.startsWith("-") && commandSpec.posixOptionsMap().containsKey(arg.charAt(1))); } private Object tryConvert(ArgSpec argSpec, int index, ITypeConverter<?> converter, String value, Class<?> type)
private void handleUnmatchedArgument(Stack<String> args) throws Exception { if (!args.isEmpty()) { handleUnmatchedArgument(args.pop()); } if (config().stopAtUnmatched()) { // addAll would give args in reverse order while (!args.isEmpty()) { handleUnmatchedArgument(args.pop()); } } } private void handleUnmatchedArgument(String arg) {
private void addOrExpand(String arg, List<String> arguments, Set<String> visited) { if (config().expandAtFiles() && !arg.equals("@") && arg.startsWith("@")) { arg = arg.substring(1); if (arg.startsWith("@")) { if (tracer.isInfo()) { tracer.info("Not expanding @-escaped argument %s (trimmed leading '@' char)%n", arg); } } else { if (tracer.isInfo()) { tracer.info("Expanding argument file @%s%n", arg); } expandArgumentFile(arg, arguments, visited); return; } } arguments.add(arg); } private void expandArgumentFile(String fileName, List<String> arguments, Set<String> visited) {
String separator = config().separator(); while (!args.isEmpty()) { if (endOfOptions) { else if (config().posixClusteredShortOptionsAllowed() && 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);
paramAttachedToOption = cluster.length() > 0; LookBehind lookBehind = paramAttachedToOption ? LookBehind.ATTACHED : LookBehind.SEPARATE; if (cluster.startsWith(config().separator())) {// attached with separator, like -f=FILE or -v=true lookBehind = LookBehind.ATTACHED_WITH_SEPARATOR; cluster = cluster.substring(config().separator().length()); arity = arity.min(Math.max(1, arity.min)); // if key=value, minimum arity is at least 1
for (ArgSpec missing : required) { if (missing.isOption()) { maybeThrow(MissingParameterException.create(CommandLine.this, required, config().separator())); } else { assertNoMissingParameters(missing, missing.arity(), argumentStack);
private void processPositionalParameter(Collection<ArgSpec> required, Set<ArgSpec> initialized, Stack<String> args) throws Exception { if (tracer.isDebug()) {tracer.debug("Processing next arg as a positional parameter at index=%d. Remainder=%s%n", position, reverse(copy(args)));} if (config().stopAtPositional()) { if (!endOfOptions && tracer.isDebug()) {tracer.debug("Parser was configured with stopAtPositional=true, treating remaining arguments as positional parameters.%n");} endOfOptions = true;
/** * Called when parsing varargs parameters for a multi-value option. * When an option is encountered, the remainder should not be interpreted as vararg elements. * @param arg the string to determine whether it is an option or not * @return true if it is an option, false otherwise */ private boolean isOption(String arg) { if (arg == null) { return false; } if ("--".equals(arg)) { return true; } // not just arg prefix: we may be in the middle of parsing -xrvfFILE if (commandSpec.optionsMap().containsKey(arg)) { // -v or -f or --file (not attached to param or other option) return true; } int separatorIndex = arg.indexOf(config().separator()); if (separatorIndex > 0) { // -f=FILE or --file==FILE (attached to param via separator) if (commandSpec.optionsMap().containsKey(arg.substring(0, separatorIndex))) { return true; } } return (arg.length() > 2 && arg.startsWith("-") && commandSpec.posixOptionsMap().containsKey(arg.charAt(1))); } private Object tryConvert(ArgSpec argSpec, int index, ITypeConverter<?> converter, String value, Class<?> type)
/** * Entry point into parsing command line arguments. * @param args the command line arguments * @return a list with all commands and subcommands initialized by this method * @throws ParameterException if the specified command line arguments are invalid */ List<CommandLine> parse(String... args) { Assert.notNull(args, "argument array"); if (tracer.isInfo()) {tracer.info("Picocli version: %s%n", versionString());} if (tracer.isInfo()) {tracer.info("Parsing %d command line args %s%n", args.length, Arrays.toString(args));} if (tracer.isDebug()){tracer.debug("Parser configuration: %s%n", config());} if (tracer.isDebug()){tracer.debug("(ANSI is %s by default: isatty=%s, XTERM=%s, OSTYPE=%s, isWindows=%s, JansiConsoleInstalled=%s, ANSICON=%s, ConEmuANSI=%s, NO_COLOR=%s, CLICOLOR=%s, CLICOLOR_FORCE=%s)%n", Help.Ansi.ansiPossible() ? "enabled" : "disabled", Help.Ansi.isTTY(), System.getenv("XTERM"), System.getenv("OSTYPE"), Help.Ansi.isWindows(), Help.Ansi.isJansiConsoleInstalled(), System.getenv("ANSICON"), System.getenv("ConEmuANSI"), System.getenv("NO_COLOR"), System.getenv("CLICOLOR"), System.getenv("CLICOLOR_FORCE"));} List<String> expanded = new ArrayList<String>(); for (String arg : args) { addOrExpand(arg, expanded, new LinkedHashSet<String>()); } Stack<String> arguments = new Stack<String>(); arguments.addAll(reverseList(expanded)); List<CommandLine> result = new ArrayList<CommandLine>(); parse(result, arguments, args, new ArrayList<Object>()); return result; }
private void addOrExpand(String arg, List<String> arguments, Set<String> visited) { if (config().expandAtFiles() && !arg.equals("@") && arg.startsWith("@")) { arg = arg.substring(1); if (arg.startsWith("@")) { if (tracer.isInfo()) { tracer.info("Not expanding @-escaped argument %s (trimmed leading '@' char)%n", arg); } } else { if (tracer.isInfo()) { tracer.info("Expanding argument file @%s%n", arg); } expandArgumentFile(arg, arguments, visited); return; } } arguments.add(arg); } private void expandArgumentFile(String fileName, List<String> arguments, Set<String> visited) {
private void handleUnmatchedArgument(Stack<String> args) throws Exception { if (!args.isEmpty()) { handleUnmatchedArgument(args.pop()); } if (config().stopAtUnmatched()) { // addAll would give args in reverse order while (!args.isEmpty()) { handleUnmatchedArgument(args.pop()); } } } private void handleUnmatchedArgument(String arg) {
String separator = config().separator(); while (!args.isEmpty()) { if (endOfOptions) { else if (config().posixClusteredShortOptionsAllowed() && 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);
paramAttachedToOption = cluster.length() > 0; LookBehind lookBehind = paramAttachedToOption ? LookBehind.ATTACHED : LookBehind.SEPARATE; if (cluster.startsWith(config().separator())) {// attached with separator, like -f=FILE or -v=true lookBehind = LookBehind.ATTACHED_WITH_SEPARATOR; cluster = cluster.substring(config().separator().length()); arity = arity.min(Math.max(1, arity.min)); // if key=value, minimum arity is at least 1
for (ArgSpec missing : required) { if (missing.isOption()) { maybeThrow(MissingParameterException.create(CommandLine.this, required, config().separator())); } else { assertNoMissingParameters(missing, missing.arity(), argumentStack);
private void processPositionalParameter(Collection<ArgSpec> required, Set<ArgSpec> initialized, Stack<String> args) throws Exception { if (tracer.isDebug()) {tracer.debug("Processing next arg as a positional parameter at index=%d. Remainder=%s%n", position, reverse(copy(args)));} if (config().stopAtPositional()) { if (!endOfOptions && tracer.isDebug()) {tracer.debug("Parser was configured with stopAtPositional=true, treating remaining arguments as positional parameters.%n");} endOfOptions = true;
/** * Entry point into parsing command line arguments. * @param args the command line arguments * @return a list with all commands and subcommands initialized by this method * @throws ParameterException if the specified command line arguments are invalid */ List<CommandLine> parse(String... args) { Assert.notNull(args, "argument array"); if (tracer.isInfo()) {tracer.info("Picocli version: %s%n", versionString());} if (tracer.isInfo()) {tracer.info("Parsing %d command line args %s%n", args.length, Arrays.toString(args));} if (tracer.isDebug()){tracer.debug("Parser configuration: %s%n", config());} if (tracer.isDebug()){tracer.debug("(ANSI is %s by default: isatty=%s, XTERM=%s, OSTYPE=%s, isWindows=%s, JansiConsoleInstalled=%s, ANSICON=%s, ConEmuANSI=%s, NO_COLOR=%s, CLICOLOR=%s, CLICOLOR_FORCE=%s)%n", Help.Ansi.ansiPossible() ? "enabled" : "disabled", Help.Ansi.isTTY(), System.getenv("XTERM"), System.getenv("OSTYPE"), Help.Ansi.isWindows(), Help.Ansi.isJansiConsoleInstalled(), System.getenv("ANSICON"), System.getenv("ConEmuANSI"), System.getenv("NO_COLOR"), System.getenv("CLICOLOR"), System.getenv("CLICOLOR_FORCE"));} List<String> expanded = new ArrayList<String>(); for (String arg : args) { addOrExpand(arg, expanded, new LinkedHashSet<String>()); } Stack<String> arguments = new Stack<String>(); arguments.addAll(reverseList(expanded)); List<CommandLine> result = new ArrayList<CommandLine>(); parse(result, arguments, args, new ArrayList<Object>()); return result; }
private String[] splitKeyValue(ArgSpec argSpec, String value) { String[] keyValue = ArgSpec.splitRespectingQuotedStrings(value, 2, config(), argSpec, "="); if (keyValue.length < 2) { String splitRegex = argSpec.splitRegex(); if (splitRegex.length() == 0) { throw new ParameterException(CommandLine.this, "Value for option " + optionDescription("", argSpec, 0) + " should be in KEY=VALUE format but was " + value, argSpec, value); } else { throw new ParameterException(CommandLine.this, "Value for option " + optionDescription("", argSpec, 0) + " should be in KEY=VALUE[" + splitRegex + "KEY=VALUE]... format but was " + value, argSpec, value); } } return keyValue; }