pax_global_header00006660000000000000000000000064124001020560014500gustar00rootroot0000000000000052 comment=e809834e97bbbf785e7ecfde55bdc975c5e3d24a argparse4j-argparse4j-0.4.4/000077500000000000000000000000001240010205600156075ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/.classpath000066400000000000000000000005541240010205600175760ustar00rootroot00000000000000 argparse4j-argparse4j-0.4.4/.gitignore000066400000000000000000000000161240010205600175740ustar00rootroot00000000000000bin target *~ argparse4j-argparse4j-0.4.4/.project000066400000000000000000000005611240010205600172600ustar00rootroot00000000000000 argparse4j org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature argparse4j-argparse4j-0.4.4/LICENSE.txt000066400000000000000000000021601240010205600174310ustar00rootroot00000000000000/* * Copyright (C) 2011, 2014 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ argparse4j-argparse4j-0.4.4/NEWS000066400000000000000000000136531240010205600163160ustar00rootroot00000000000000argparse4j 0.4.4 ================ Release Note ------------ This release fixes several reported bugs. It adds some new features. ArgumentParsers.setSingleMetavar() was added to show metavar string only once instead of printing them for each flag. Namespace.getString() now calls toString() of object found instead of just casting to String. Now Argument.type() can take primitive classes and they are converted to their wrapped type counterpart to ease some work for developers. Changes ------- * Argument.type: Convert primitive type to its wrapped type counterpart We only support 7 out of 9 primitive types, that is char.class and void.class are not supported. char.class is not supported because it lacks valueOf method. Fixes gh#36 * Namespace.getString() now calls toString() of object found Fixes gh#35 * Fixed trailing spaces. Also fixed the condition to add commas at the help message of a series of flags. Patch from lekkas * Optional argument help messages now display the metavar name once. The metavar is now printed only once, at the end of the series of flags: -c, --create Create vault instead of: -c , --create Create vault Patch from lekkas This is disabled by default. Use ArgumentParsers.setSingleMetavar(true) to enable it. * Handle enums with abstract methods Arg parser currently throws IllegalArgumentException if you set choices to .values() of an enum with abstract methods & pass anything other than the first value. Use getDeclaringClass to check enum types instead of getClass. Patch from Jenny Williamson * Fix for NPE if there is no PATH env var Patch from Wolfgang Hoschek * Use language neutral locale object instead of (Locale) null * Defer exception for missing required argument so that -h for subparser works Previously, if -c is required option in main parser and "install" is a subcommand: $ prog install -h produces exception saying -c is not provided. This change will defer the throw of the exception for missing required arguments so that -h option works for subcommands. argparse4j 0.4.3 ================ Release Note ------------ This release fixes a bug that causes unexpected string formatting due to the localization using the default locale. Now we use null Locale object to avoid the localization. Changes ------- * Use null Locale for format method argparse4j 0.4.2 ================ Release Note ------------ This release fixes several bugs related to help and usage output. Now HelpArgumentAction throws exception instead of quit a program. The generic get method was added to Namespace object. Changes ------- * ArgumentParserImpl: Only flush output in methods without PrintWriter parameter * Added generic get method to Namespace Contributed by jon-ruckwood * Changed HelpArgumentAction to throw exception rather than exit Contributed by Adam Parkin * Fixed bug where System.out got closed in printHelp Contributed by Adam Parkin argparse4j 0.4.1 ================ Release Note ------------ This release changes error message when matching empty string for subcommand. It adds the method to verify that a file argument can be created. Changes ------- * Throw "invalid choice" error when matching empty string for subcommand * Added method to verify that a file argument can be created. Contributed by Juan Manuel Caicedo Carvajal argparse4j 0.4.0 ================ Release Note ------------ This release fixes the bug that argument is processed twice with concatenated short options. The following new features were added: argument/sub-command abbreviations, usage text override, ${prog} substitution in version text, sub-command aliases and count() action. If neither title nor description are specified to MutuallyExclusiveGroup, the help message for the group is merged into other optinal arguments. The Argument.type(Class) now supports valueOf(String) static method for conversion. It also now supports enums directly. The behavior of nargs("*") for optional arguments are slightly changed for some corner-cases. See the changes for details. Changes ------- * Show command aliases in help message * Avoid ``\n`` and use %n or TextHelper.LINESEP instead * Add CountArgumentAction CountArgumentAction counts the number of occurrence of an option. Arguments.count() returns the instance of this object for shortcut. * Support ${prog} substitution in version string * Add ArgumentParser.usage() By default, the program usage is generated from the arguments the ArgumentParser object contains. This method overrides it. * Add ArgumentParser.addMutuallyExclusiveGroup() without title arg If both title and description are empty, the help message for the group is merged into other optional arguments. * Don't show available enum constants when conversion failed If they are shown, user may be confused with choices because choices may be more limited. * Add ReflectArgumentType ReflectArgumentType is an enhanced version of ConstructorArgumentType. It first tries to convert given String to desired type using valueOf static method of the type. If it failed, use the constructor of given type just like a ConstructorArgumentType. Since enums have valueOf static method, ReflectArgumentType works with enums as well. The ReflectArgumentType effectively deprecates ConstructorArgumentType and EnumArgumentType. * Throw exception if no nameOrFlags is given * Support argument/sub-command abbreviations * Adjust narg("*") handling for optinal arguments The optional argument with nargs("*") and without default set is not given in command-line, the result is now null instead of empty list. The optional argument with nargs("*") is given in command-line with emtpy list, the result is now empty list. It will overwrite existing value or appened to the existing list in case of append() action. * Fix bug that argument is processed twice with concatenated short options argparse4j-argparse4j-0.4.4/README.rst000066400000000000000000000033261240010205600173020ustar00rootroot00000000000000Argparse4j - The Java command-line argument parser library ========================================================== Argparse4j is a command line argument parser library for Java based on Python's `argparse `_ module. Argparse4j is available in Maven central repository: .. code-block:: xml net.sourceforge.argparse4j argparse4j 0.4.4 There are still missing features which exist in argparse but not in argparse4j, but there are also new features which only exist in argparse4j. Here is summary of features: * Supported positional arguments and optional arguments. * Variable number of arguments. * Generates well formatted line-wrapped help message. * Suggests optional arguments/sub-command if unrecognized arguments/sub-command were given, e.g.: .. code-block:: console unrecognized argument '--tpye' Did you mean: --type * Takes into account East Asian Width ambiguous characters when line-wrap. * Sub-commands like, ``git add``. * Sub-command alias names, e.g., ``co`` for ``checkout``. * Customizable option prefix characters, e.g. ``+f`` and ``/h``. * Print default values in help message. * Choice from given collection of values. * Type conversion from option strings. * Can directly assign values into user defined classes using annotation. * Group arguments so that it will be printed in help message in more readable way. * Mutually exclusive argument group. * Read additional arguments from file. * Argument/sub-command abbreviations. The primary documentation is done using `Sphinx `_. You need Sphinx to run ``mvn site``. argparse4j-argparse4j-0.4.4/pom.xml000066400000000000000000000121341240010205600171250ustar00rootroot00000000000000 4.0.0 net.sourceforge.argparse4j argparse4j 0.4.4-SNAPSHOT jar argparse4j http://argparse4j.sourceforge.net The command-line parser library based on Python's argparse 2012 UTF-8 org.sonatype.oss oss-parent 7 MIT https://raw.github.com/tatsuhiro-t/argparse4j/master/LICENSE.txt tatsuhiro_t Tatsuhiro Tsujikawa +9 github.com https://github.com/tatsuhiro-t/argparse4j/issues scm:git:git://github.com/tatsuhiro-t/argparse4j.git scm:git:git@github.com:tatsuhiro-t/argparse4j.git https://github.com/tatsuhiro-t/argparse4j ossrh https://oss.sonatype.org/content/repositories/snapshots junit junit 4.8.1 test maven-project-info-reports-plugin 2.4 summary dependencies project-team issue-tracking license scm org.apache.maven.plugins maven-javadoc-plugin 2.9.1 en default javadoc src/test/resources org.apache.maven.plugins maven-site-plugin 3.0 org.codehaus.mojo exec-maven-plugin 1.2.1 sphinx-doc site exec sphinx-make-html ${project.version} maven-assembly-plugin 2.2.1 bin src maven-javadoc-plugin 2.9.1 en maven attach-javadocs jar org.apache.maven.plugins maven-source-plugin 2.1.2 attach-sources jar org.apache.maven.plugins maven-release-plugin 2.2.1 org.apache.maven.plugins maven-compiler-plugin 3.0 org.sonatype.plugins nexus-staging-maven-plugin 1.6.2 true ossrh https://oss.sonatype.org/ true argparse4j-argparse4j-0.4.4/sphinx-make-html000077500000000000000000000002341240010205600207220ustar00rootroot00000000000000#!/bin/sh -e echo "Building sphinx documentation for version $1" cd src/site/sphinx make html PACKAGE_VERSION=$1 cp -vr _build/html/* ../../../target/site/ argparse4j-argparse4j-0.4.4/src/000077500000000000000000000000001240010205600163765ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/000077500000000000000000000000001240010205600173225ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/000077500000000000000000000000001240010205600202435ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/000077500000000000000000000000001240010205600210315ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/000077500000000000000000000000001240010205600233545ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/000077500000000000000000000000001240010205600254165ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/ArgumentParsers.java000066400000000000000000000203471240010205600314110ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j; import java.util.Arrays; import java.util.List; import java.util.Locale; import net.sourceforge.argparse4j.helper.ASCIITextWidthCounter; import net.sourceforge.argparse4j.helper.CJKTextWidthCounter; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.internal.ArgumentParserImpl; import net.sourceforge.argparse4j.internal.TerminalWidth; /** * Factory class to create new ArgumentParser. * */ public final class ArgumentParsers { /** * Intentionally made private to avoid to get instantiated in application * code. */ private ArgumentParsers() { } /** * Default prefix characters. */ public static final String DEFAULT_PREFIX_CHARS = "-"; /** *

* Creates {@link ArgumentParser} with given program name. *

* *

* This is equivalent with {@code newArgumentParser(prog, true, "-", null)}. *

* * @param prog * The program name * @return ArgumentParser object */ public static ArgumentParser newArgumentParser(String prog) { return newArgumentParser(prog, true, DEFAULT_PREFIX_CHARS, null); } /** *

* Creates {@link ArgumentParser} with given program name and addHelp. *

* *

* This is equivalent with {@code ArgumentParser(prog, addHelp, "-", null)}. *

* * @param prog * The program name * @param addHelp * If true, {@code -h/--help} are available. If false, they are * not. * @return ArgumentParser object */ public static ArgumentParser newArgumentParser(String prog, boolean addHelp) { return newArgumentParser(prog, addHelp, DEFAULT_PREFIX_CHARS, null); } /** *

* Creates {@link ArgumentParser} with given program name, addHelp and * prefixChars. *

* *

* This is equivalent with * {@code ArgumentParser(prog, addHelp, prefixChars, null)}. *

* * @param prog * The program name * @param addHelp * If true, {@code -h/--help} are available. If false, they are * not. * @param prefixChars * The set of characters that prefix optional arguments. * @return ArgumentParser object. */ public static ArgumentParser newArgumentParser(String prog, boolean addHelp, String prefixChars) { return newArgumentParser(prog, addHelp, prefixChars, null); } /** *

* Creates {@link ArgumentParser} with given program name, addHelp and * prefixChars. *

* * @param prog * The program name * @param addHelp * If true, {@code -h/--help} are available. If false, they are * not. * @param prefixChars * The set of characters that prefix optional arguments. * @param fromFilePrefix * The set of characters that prefix file path from which * additional arguments should be read. Specify {@code null} to * disable reading arguments from file. * @return ArgumentParser object. */ public static ArgumentParser newArgumentParser(String prog, boolean addHelp, String prefixChars, String fromFilePrefix) { return new ArgumentParserImpl(prog, addHelp, prefixChars, fromFilePrefix, cjkWidthHack_ && cjkWidthLangs_.contains(Locale.getDefault() .getLanguage()) ? new CJKTextWidthCounter() : new ASCIITextWidthCounter()); } private static final String cjkWidthLangsSrc_[] = { "ja", "zh", "ko" }; private static List cjkWidthLangs_ = Arrays .asList(cjkWidthLangsSrc_); private static boolean cjkWidthHack_ = true; /** *

* Set {@code true} to enable CJK width hack. *

* *

* The CJK width hack is treat Unicode characters having East Asian Width * property Wide/Full/Ambiguous to have twice a width of ascii characters * when formatting help message if locale is "ja", "zh" or "ko". This * feature is enabled by default. *

* * @param flag * {@code true} or {@code false} */ public static void setCJKWidthHack(boolean flag) { cjkWidthHack_ = flag; } /** * Returns true iff CJK width hack is enabled. * * @return {@code true} or {@code false} */ public static boolean getCjkWidthHack() { return cjkWidthHack_; } private static boolean terminalWidthDetection_ = true; /** *

* Set {@code true} to enable terminal width detection. *

* *

* If this feature is enabled, argparse4j will automatically detect the * terminal width and use it to format help messages. *

* * @param flag * {@code true} or {@code false} */ public static void setTerminalWidthDetection(boolean flag) { terminalWidthDetection_ = flag; } /** * Returns true iff terminal width detection is enabled. * * @return {@code true} or {@code false} */ public static boolean getTerminalWidthDetection() { return terminalWidthDetection_; } /** * Default format width of text output. */ public static final int DEFAULT_FORMAT_WIDTH = 75; /** * Returns the width of formatted text. If the terminal width detection is * enabled, this method will detect the terminal width automatically and * calculate the width based on it. If it is not enabled or auto-detection * was failed, the {@link ArgumentParsers#DEFAULT_FORMAT_WIDTH} is returned. * * @return the width of formatted text */ public static int getFormatWidth() { if (terminalWidthDetection_) { int w = new TerminalWidth().getTerminalWidth() - 5; return w <= 0 ? DEFAULT_FORMAT_WIDTH : w; } else { return DEFAULT_FORMAT_WIDTH; } } private static boolean singleMetavar_ = false; /** *

* If singleMetavar is {@code true}, a metavar string in help message is * only shown after the last flag instead of each flag. *

*

* By default and {@code false} is given to this method, a metavar is shown * after each flag: *

* *
     * -f FOO, --foo FOO
     * 
*

* If {@code true} is given to this method, a metavar string is shown only * once: *

* *
     * -f, --foo FOO
     * 
* * @param singleMetavar * Switch to display a metavar only after the last flag. */ public static void setSingleMetavar(boolean singleMetavar) { singleMetavar_ = singleMetavar; } /** * Returns true iff a metavar is shown only after the last flag. * * @return {@code true} or {@code false} */ public static boolean isSingleMetavar() { return singleMetavar_; } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/annotation/000077500000000000000000000000001240010205600275705ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/annotation/Arg.java000066400000000000000000000043311240010205600311450ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** *

* Annotation specifies location where attribute should be stored. *

*

* You can annotate fields and methods. For methods, it must have only 1 format * argument. Use {@link #dest()} to specify which attribute to be assigned. If * it is empty, the name of the attribute or method will be used instead. If the * attribute value cannot be assigned to designated location, error will be * issued. If you want to ignore this error, use {@link #ignoreError()}. *

*/ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.FIELD, ElementType.METHOD }) public @interface Arg { /** * The name of attribute to be assigned. * * @return The name of attribute */ String dest() default ""; /** * Set {@code true} if you want to ignore the error in assignment. * * @return {@code true} or {@code false} */ boolean ignoreError() default false; } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/helper/000077500000000000000000000000001240010205600266755ustar00rootroot00000000000000ASCIITextWidthCounter.java000066400000000000000000000030471240010205600335220ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/helper/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.helper; /** *

* This implementation assumes text contains only narrow characters, *

* *

* The width is just simply the length of given text. The application * code should not use this class directly. *

* */ public class ASCIITextWidthCounter implements TextWidthCounter { @Override public int width(String text) { return text.length(); } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/helper/CJKTextWidthCounter.java000066400000000000000000000370001240010205600333540ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.helper; import java.util.Arrays; import java.util.Comparator; /** *

* CJK aware TextWidthCounter implementation. *

* *

* This class uses East Asian Width information of Unicode and counts 2 for * Wide, Full and Ambiguous characters. *

* *

* The application code should not use this class directly. *

* */ public class CJKTextWidthCounter implements TextWidthCounter { @Override public int width(String text) { int len = text.length(); CpRange key = new CpRange(); int cnt = 0; for (int i = 0, cp; i < len; i += Character.charCount(cp)) { cp = text.codePointAt(i); key.first = cp; key.last = cp + 1; if (Arrays.binarySearch(ranges_, key, cpRangeCmp_) >= 0) { cnt += 2; } else { ++cnt; } } return cnt; } private static enum EastAsianWidth { W, // Wide F, // Full A // Ambiguous } /** * Range is [first, last) * */ private static class CpRange { int first, last; EastAsianWidth w; public CpRange(int first, int last, EastAsianWidth w) { this.first = first; this.last = last; this.w = w; } public CpRange() { } } private static class CpRangeCmp implements Comparator { @Override public int compare(CpRange lhs, CpRange rhs) { // Assumes rhs is [x, x+1) if (lhs.last <= rhs.first) { return -1; } else if (rhs.last <= lhs.first) { return 1; } else { return 0; } } } private static final CpRangeCmp cpRangeCmp_ = new CpRangeCmp(); /** * Compiled using wfarange.py. * * # EastAsianWidth-6.0.0.txt * # Date: 2010-08-17, 12:17:00 PDT [KW] */ private static final CpRange[] ranges_ = { new CpRange(0x00A1, 0x00A2, EastAsianWidth.A), new CpRange(0x00A4, 0x00A5, EastAsianWidth.A), new CpRange(0x00A7, 0x00A9, EastAsianWidth.A), new CpRange(0x00AA, 0x00AB, EastAsianWidth.A), new CpRange(0x00AD, 0x00AF, EastAsianWidth.A), new CpRange(0x00B0, 0x00B5, EastAsianWidth.A), new CpRange(0x00B6, 0x00BB, EastAsianWidth.A), new CpRange(0x00BC, 0x00C0, EastAsianWidth.A), new CpRange(0x00C6, 0x00C7, EastAsianWidth.A), new CpRange(0x00D0, 0x00D1, EastAsianWidth.A), new CpRange(0x00D7, 0x00D9, EastAsianWidth.A), new CpRange(0x00DE, 0x00E2, EastAsianWidth.A), new CpRange(0x00E6, 0x00E7, EastAsianWidth.A), new CpRange(0x00E8, 0x00EB, EastAsianWidth.A), new CpRange(0x00EC, 0x00EE, EastAsianWidth.A), new CpRange(0x00F0, 0x00F1, EastAsianWidth.A), new CpRange(0x00F2, 0x00F4, EastAsianWidth.A), new CpRange(0x00F7, 0x00FB, EastAsianWidth.A), new CpRange(0x00FC, 0x00FD, EastAsianWidth.A), new CpRange(0x00FE, 0x00FF, EastAsianWidth.A), new CpRange(0x0101, 0x0102, EastAsianWidth.A), new CpRange(0x0111, 0x0112, EastAsianWidth.A), new CpRange(0x0113, 0x0114, EastAsianWidth.A), new CpRange(0x011B, 0x011C, EastAsianWidth.A), new CpRange(0x0126, 0x0128, EastAsianWidth.A), new CpRange(0x012B, 0x012C, EastAsianWidth.A), new CpRange(0x0131, 0x0134, EastAsianWidth.A), new CpRange(0x0138, 0x0139, EastAsianWidth.A), new CpRange(0x013F, 0x0143, EastAsianWidth.A), new CpRange(0x0144, 0x0145, EastAsianWidth.A), new CpRange(0x0148, 0x014C, EastAsianWidth.A), new CpRange(0x014D, 0x014E, EastAsianWidth.A), new CpRange(0x0152, 0x0154, EastAsianWidth.A), new CpRange(0x0166, 0x0168, EastAsianWidth.A), new CpRange(0x016B, 0x016C, EastAsianWidth.A), new CpRange(0x01CE, 0x01CF, EastAsianWidth.A), new CpRange(0x01D0, 0x01D1, EastAsianWidth.A), new CpRange(0x01D2, 0x01D3, EastAsianWidth.A), new CpRange(0x01D4, 0x01D5, EastAsianWidth.A), new CpRange(0x01D6, 0x01D7, EastAsianWidth.A), new CpRange(0x01D8, 0x01D9, EastAsianWidth.A), new CpRange(0x01DA, 0x01DB, EastAsianWidth.A), new CpRange(0x01DC, 0x01DD, EastAsianWidth.A), new CpRange(0x0251, 0x0252, EastAsianWidth.A), new CpRange(0x0261, 0x0262, EastAsianWidth.A), new CpRange(0x02C4, 0x02C5, EastAsianWidth.A), new CpRange(0x02C7, 0x02C8, EastAsianWidth.A), new CpRange(0x02C9, 0x02CC, EastAsianWidth.A), new CpRange(0x02CD, 0x02CE, EastAsianWidth.A), new CpRange(0x02D0, 0x02D1, EastAsianWidth.A), new CpRange(0x02D8, 0x02DC, EastAsianWidth.A), new CpRange(0x02DD, 0x02DE, EastAsianWidth.A), new CpRange(0x02DF, 0x02E0, EastAsianWidth.A), new CpRange(0x0300, 0x0370, EastAsianWidth.A), new CpRange(0x0391, 0x03A2, EastAsianWidth.A), new CpRange(0x03A3, 0x03AA, EastAsianWidth.A), new CpRange(0x03B1, 0x03C2, EastAsianWidth.A), new CpRange(0x03C3, 0x03CA, EastAsianWidth.A), new CpRange(0x0401, 0x0402, EastAsianWidth.A), new CpRange(0x0410, 0x0450, EastAsianWidth.A), new CpRange(0x0451, 0x0452, EastAsianWidth.A), new CpRange(0x1100, 0x1160, EastAsianWidth.W), new CpRange(0x11A3, 0x11A8, EastAsianWidth.W), new CpRange(0x11FA, 0x1200, EastAsianWidth.W), new CpRange(0x2010, 0x2011, EastAsianWidth.A), new CpRange(0x2013, 0x2017, EastAsianWidth.A), new CpRange(0x2018, 0x201A, EastAsianWidth.A), new CpRange(0x201C, 0x201E, EastAsianWidth.A), new CpRange(0x2020, 0x2023, EastAsianWidth.A), new CpRange(0x2024, 0x2028, EastAsianWidth.A), new CpRange(0x2030, 0x2031, EastAsianWidth.A), new CpRange(0x2032, 0x2034, EastAsianWidth.A), new CpRange(0x2035, 0x2036, EastAsianWidth.A), new CpRange(0x203B, 0x203C, EastAsianWidth.A), new CpRange(0x203E, 0x203F, EastAsianWidth.A), new CpRange(0x2074, 0x2075, EastAsianWidth.A), new CpRange(0x207F, 0x2080, EastAsianWidth.A), new CpRange(0x2081, 0x2085, EastAsianWidth.A), new CpRange(0x20AC, 0x20AD, EastAsianWidth.A), new CpRange(0x2103, 0x2104, EastAsianWidth.A), new CpRange(0x2105, 0x2106, EastAsianWidth.A), new CpRange(0x2109, 0x210A, EastAsianWidth.A), new CpRange(0x2113, 0x2114, EastAsianWidth.A), new CpRange(0x2116, 0x2117, EastAsianWidth.A), new CpRange(0x2121, 0x2123, EastAsianWidth.A), new CpRange(0x2126, 0x2127, EastAsianWidth.A), new CpRange(0x212B, 0x212C, EastAsianWidth.A), new CpRange(0x2153, 0x2155, EastAsianWidth.A), new CpRange(0x215B, 0x215F, EastAsianWidth.A), new CpRange(0x2160, 0x216C, EastAsianWidth.A), new CpRange(0x2170, 0x217A, EastAsianWidth.A), new CpRange(0x2189, 0x218A, EastAsianWidth.A), new CpRange(0x2190, 0x219A, EastAsianWidth.A), new CpRange(0x21B8, 0x21BA, EastAsianWidth.A), new CpRange(0x21D2, 0x21D3, EastAsianWidth.A), new CpRange(0x21D4, 0x21D5, EastAsianWidth.A), new CpRange(0x21E7, 0x21E8, EastAsianWidth.A), new CpRange(0x2200, 0x2201, EastAsianWidth.A), new CpRange(0x2202, 0x2204, EastAsianWidth.A), new CpRange(0x2207, 0x2209, EastAsianWidth.A), new CpRange(0x220B, 0x220C, EastAsianWidth.A), new CpRange(0x220F, 0x2210, EastAsianWidth.A), new CpRange(0x2211, 0x2212, EastAsianWidth.A), new CpRange(0x2215, 0x2216, EastAsianWidth.A), new CpRange(0x221A, 0x221B, EastAsianWidth.A), new CpRange(0x221D, 0x2221, EastAsianWidth.A), new CpRange(0x2223, 0x2224, EastAsianWidth.A), new CpRange(0x2225, 0x2226, EastAsianWidth.A), new CpRange(0x2227, 0x222D, EastAsianWidth.A), new CpRange(0x222E, 0x222F, EastAsianWidth.A), new CpRange(0x2234, 0x2238, EastAsianWidth.A), new CpRange(0x223C, 0x223E, EastAsianWidth.A), new CpRange(0x2248, 0x2249, EastAsianWidth.A), new CpRange(0x224C, 0x224D, EastAsianWidth.A), new CpRange(0x2252, 0x2253, EastAsianWidth.A), new CpRange(0x2260, 0x2262, EastAsianWidth.A), new CpRange(0x2264, 0x2268, EastAsianWidth.A), new CpRange(0x226A, 0x226C, EastAsianWidth.A), new CpRange(0x226E, 0x2270, EastAsianWidth.A), new CpRange(0x2282, 0x2284, EastAsianWidth.A), new CpRange(0x2286, 0x2288, EastAsianWidth.A), new CpRange(0x2295, 0x2296, EastAsianWidth.A), new CpRange(0x2299, 0x229A, EastAsianWidth.A), new CpRange(0x22A5, 0x22A6, EastAsianWidth.A), new CpRange(0x22BF, 0x22C0, EastAsianWidth.A), new CpRange(0x2312, 0x2313, EastAsianWidth.A), new CpRange(0x2329, 0x232B, EastAsianWidth.W), new CpRange(0x2460, 0x24EA, EastAsianWidth.A), new CpRange(0x24EB, 0x254C, EastAsianWidth.A), new CpRange(0x2550, 0x2574, EastAsianWidth.A), new CpRange(0x2580, 0x2590, EastAsianWidth.A), new CpRange(0x2592, 0x2596, EastAsianWidth.A), new CpRange(0x25A0, 0x25A2, EastAsianWidth.A), new CpRange(0x25A3, 0x25AA, EastAsianWidth.A), new CpRange(0x25B2, 0x25B4, EastAsianWidth.A), new CpRange(0x25B6, 0x25B8, EastAsianWidth.A), new CpRange(0x25BC, 0x25BE, EastAsianWidth.A), new CpRange(0x25C0, 0x25C2, EastAsianWidth.A), new CpRange(0x25C6, 0x25C9, EastAsianWidth.A), new CpRange(0x25CB, 0x25CC, EastAsianWidth.A), new CpRange(0x25CE, 0x25D2, EastAsianWidth.A), new CpRange(0x25E2, 0x25E6, EastAsianWidth.A), new CpRange(0x25EF, 0x25F0, EastAsianWidth.A), new CpRange(0x2605, 0x2607, EastAsianWidth.A), new CpRange(0x2609, 0x260A, EastAsianWidth.A), new CpRange(0x260E, 0x2610, EastAsianWidth.A), new CpRange(0x2614, 0x2616, EastAsianWidth.A), new CpRange(0x261C, 0x261D, EastAsianWidth.A), new CpRange(0x261E, 0x261F, EastAsianWidth.A), new CpRange(0x2640, 0x2641, EastAsianWidth.A), new CpRange(0x2642, 0x2643, EastAsianWidth.A), new CpRange(0x2660, 0x2662, EastAsianWidth.A), new CpRange(0x2663, 0x2666, EastAsianWidth.A), new CpRange(0x2667, 0x266B, EastAsianWidth.A), new CpRange(0x266C, 0x266E, EastAsianWidth.A), new CpRange(0x266F, 0x2670, EastAsianWidth.A), new CpRange(0x269E, 0x26A0, EastAsianWidth.A), new CpRange(0x26BE, 0x26C0, EastAsianWidth.A), new CpRange(0x26C4, 0x26CE, EastAsianWidth.A), new CpRange(0x26CF, 0x26E2, EastAsianWidth.A), new CpRange(0x26E3, 0x26E4, EastAsianWidth.A), new CpRange(0x26E8, 0x2700, EastAsianWidth.A), new CpRange(0x273D, 0x273E, EastAsianWidth.A), new CpRange(0x2757, 0x2758, EastAsianWidth.A), new CpRange(0x2776, 0x2780, EastAsianWidth.A), new CpRange(0x2B55, 0x2B5A, EastAsianWidth.A), new CpRange(0x2E80, 0x2E9A, EastAsianWidth.W), new CpRange(0x2E9B, 0x2EF4, EastAsianWidth.W), new CpRange(0x2F00, 0x2FD6, EastAsianWidth.W), new CpRange(0x2FF0, 0x2FFC, EastAsianWidth.W), new CpRange(0x3000, 0x3001, EastAsianWidth.F), new CpRange(0x3001, 0x303F, EastAsianWidth.W), new CpRange(0x3041, 0x3097, EastAsianWidth.W), new CpRange(0x3099, 0x3100, EastAsianWidth.W), new CpRange(0x3105, 0x312E, EastAsianWidth.W), new CpRange(0x3131, 0x318F, EastAsianWidth.W), new CpRange(0x3190, 0x31BB, EastAsianWidth.W), new CpRange(0x31C0, 0x31E4, EastAsianWidth.W), new CpRange(0x31F0, 0x321F, EastAsianWidth.W), new CpRange(0x3220, 0x3248, EastAsianWidth.W), new CpRange(0x3248, 0x3250, EastAsianWidth.A), new CpRange(0x3250, 0x32FF, EastAsianWidth.W), new CpRange(0x3300, 0x4DC0, EastAsianWidth.W), new CpRange(0x4E00, 0xA48D, EastAsianWidth.W), new CpRange(0xA490, 0xA4C7, EastAsianWidth.W), new CpRange(0xA960, 0xA97D, EastAsianWidth.W), new CpRange(0xAC00, 0xD7A4, EastAsianWidth.W), new CpRange(0xD7B0, 0xD7C7, EastAsianWidth.W), new CpRange(0xD7CB, 0xD7FC, EastAsianWidth.W), new CpRange(0xE000, 0xF900, EastAsianWidth.A), new CpRange(0xF900, 0xFB00, EastAsianWidth.W), new CpRange(0xFE00, 0xFE10, EastAsianWidth.A), new CpRange(0xFE10, 0xFE1A, EastAsianWidth.W), new CpRange(0xFE30, 0xFE53, EastAsianWidth.W), new CpRange(0xFE54, 0xFE67, EastAsianWidth.W), new CpRange(0xFE68, 0xFE6C, EastAsianWidth.W), new CpRange(0xFF01, 0xFF61, EastAsianWidth.F), new CpRange(0xFFE0, 0xFFE7, EastAsianWidth.F), new CpRange(0xFFFD, 0xFFFE, EastAsianWidth.A), new CpRange(0x1B000, 0x1B002, EastAsianWidth.W), new CpRange(0x1F100, 0x1F10B, EastAsianWidth.A), new CpRange(0x1F110, 0x1F12E, EastAsianWidth.A), new CpRange(0x1F130, 0x1F16A, EastAsianWidth.A), new CpRange(0x1F170, 0x1F19B, EastAsianWidth.A), new CpRange(0x1F200, 0x1F203, EastAsianWidth.W), new CpRange(0x1F210, 0x1F23B, EastAsianWidth.W), new CpRange(0x1F240, 0x1F249, EastAsianWidth.W), new CpRange(0x1F250, 0x1F252, EastAsianWidth.W), new CpRange(0x20000, 0x2F740, EastAsianWidth.W), new CpRange(0x2B740, 0x2FFFE, EastAsianWidth.W), new CpRange(0x30000, 0x3FFFE, EastAsianWidth.W), new CpRange(0xE0100, 0xE01F0, EastAsianWidth.A), new CpRange(0xF0000, 0xFFFFE, EastAsianWidth.A), new CpRange(0x100000, 0x10FFFE, EastAsianWidth.A) }; } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/helper/PrefixPattern.java000066400000000000000000000072571240010205600323460ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.helper; import java.util.regex.Matcher; import java.util.regex.Pattern; /** *

* This object performs operations related to prefixChars of option flags. *

*

* The application code should not use this class directly. *

*/ public class PrefixPattern { private String prefixChars_; private Pattern prefixPattern_; /** * Creates this object using given {@code prefixChars}. * * @param prefixChars * The prefixChars */ public PrefixPattern(String prefixChars) { prefixChars_ = prefixChars; prefixPattern_ = compilePrefixPattern(prefixChars); } /** * Returns {@code true} if flag string {@code str} matches prefixChars. * * @param str * The flag string to match * @return {@code true} or {@code false} */ public boolean match(String str) { Matcher m = prefixPattern_.matcher(str); return m.find() && !m.group(0).equals(str); } /** * Returns {@code true} if flag string {@code str} matches prefixChars and * it is long flag. * * @param str * The flag string to match * @return {@code true} or {@code false} */ public boolean matchLongFlag(String str) { Matcher m = prefixPattern_.matcher(str); return m.find() && !m.group(0).equals(str) && m.group(0).length() >= 2; } /** *

* Removes prefixChars from given flag string. *

*

* If given flag string does not contains prefixChars, it is returned as is. *

* * @param str * The flag string * @return The string after prefixChars are removed from {@code str} */ public String removePrefix(String str) { Matcher m = prefixPattern_.matcher(str); if (m.find() && !m.group(0).equals(str)) { return m.replaceFirst(""); } else { return str; } } /** * Returns prefixChars with this object constructed. * * @return prefixChars */ public String getPrefixChars() { return prefixChars_; } /** * Returns compiled regular expression pattern of prefixChars. * * @return The compiled regular expression pattern of prefixChars. */ public Pattern getPrefixPattern() { return prefixPattern_; } private static Pattern compilePrefixPattern(String prefixChars) { String qs = Pattern.quote(prefixChars); return Pattern.compile("^[" + qs + "]+"); } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/helper/ReflectHelper.java000066400000000000000000000056261240010205600322750ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.helper; import java.lang.reflect.Array; import java.util.List; /** *

* This class provides helper functions related to reflection. *

*

* The application code should not use this class directly. *

* */ public final class ReflectHelper { private ReflectHelper() { } /** *

* Convert {@code src} to object of type {@code targetType} recursively *

* *

* Convert {@code src} to object of type {@code targetType} recursively, but * it only converts {@link List} to array. If {@code targetType} is array * type and {@code src} is {@link List}, new array is created with the size * of {@code src} and for each element of {@code src}, * {@link #list2Array(Class, Object)} will be called recursively with the * component type of {@code targetType} and the element of {@code src}. The * returned object is assigned to newly created array. If either * {@code targetType} is not array or {@code src} is not {@link List}, * simply returns {@code src}. *

* * @param targetType * The target type * @param src * The src object * @return The converted object */ public static Object list2Array(Class targetType, Object src) { if (targetType.isArray() && src instanceof List) { List list = (List) src; int len = list.size(); Object dest = Array.newInstance(targetType.getComponentType(), len); for (int i = 0; i < len; ++i) { Array.set(dest, i, list2Array(targetType.getComponentType(), list.get(i))); } return dest; } else { return src; } } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/helper/TextHelper.java000066400000000000000000000206561240010205600316350ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.helper; import java.io.PrintWriter; import java.text.BreakIterator; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Locale; /** *

* This class provides various helper function related to text processing. *

*

* The application code should not use this class directly. *

* */ public final class TextHelper { private TextHelper() { } /** * Language neutral locale. Defined here for Java5. */ public static final Locale LOCALE_ROOT = new Locale("", "", ""); public static final String LINESEP = System.getProperty("line.separator"); public static String concat(T a[], int offset, String sep, String start, String end) { StringBuilder sb = new StringBuilder(); sb.append(start); if (a.length - offset > 0) { sb.append(a[offset]); for (int i = offset + 1, len = a.length; i < len; ++i) { sb.append(sep).append(a[i]); } } sb.append(end); return sb.toString(); } public static String concat(T a[], int offset, String sep) { return concat(a, offset, sep, "", ""); } public static String concat(Collection a, int offset, String sep, String start, String end) { StringBuilder sb = new StringBuilder(); sb.append(start); Iterator it; for (it = a.iterator(); offset > 0 && it.hasNext(); --offset, it.next()) ; if (offset == 0 && it.hasNext()) { sb.append(it.next()); while (it.hasNext()) { sb.append(sep).append(it.next()); } } sb.append(end); return sb.toString(); } public static String concat(Collection a, int offset, String sep) { return concat(a, offset, sep, "", ""); } public static String wrap(TextWidthCounter textWidthCounter, String s, int width, int initialOffset, String initialIndent, String subsequentIndent) { BreakIterator iter = BreakIterator.getLineInstance(); iter.setText(s); StringBuilder res = new StringBuilder(initialIndent); StringBuilder sb = new StringBuilder(); int currentWidth = initialOffset + initialIndent.length(); for (int start = iter.first(), end = iter.next(); end != BreakIterator.DONE; start = end, end = iter .next()) { String sub = s.substring(start, end); int subwidth = textWidthCounter.width(sub); currentWidth += subwidth; if (currentWidth > width) { res.append(adjustSpace(sb, width, currentWidth - subwidth)) .append(TextHelper.LINESEP).append(subsequentIndent); sb.delete(0, sb.length()); currentWidth = subsequentIndent.length() + subwidth; } sb.append(sub); // What if the application specifies text with line separator \n, // while TextHelper.LINESEP is not \n (e.g., \r\n)? Historically, we // just checked only \n here. For backward compatibility, We also // check that line ends with \n too. if (sub.endsWith(TextHelper.LINESEP) || sub.endsWith("\n")) { res.append(sb).append(subsequentIndent); sb.delete(0, sb.length()); currentWidth = subsequentIndent.length(); } } res.append(sb); return res.toString(); } /** * Given the maximum line width and current line width in sb, insert white * spaces in sb to make it look more "natural". The insertion points are the * contagious block of white spaces. Before the processing, leading and * trailing white spaces are removed from sb. * * @param sb * String to adjust * @param width * maximum line width * @param curwidth * current line width * @return adjusted sb */ public static StringBuilder adjustSpace(StringBuilder sb, int width, int curwidth) { int i, len = sb.length(); int origLen = len; for (i = 0; i < len && sb.charAt(i) == ' '; ++i) ; sb.delete(0, i); len = sb.length(); for (i = len - 1; i >= 0 && sb.charAt(i) == ' '; --i) ; sb.delete(i + 1, len); len = sb.length(); curwidth -= origLen - len; int numWsBlock = 0; boolean cont = false; for (i = 0; i < len; ++i) { if (sb.charAt(i) == ' ') { if (!cont) { cont = true; ++numWsBlock; } } else { cont = false; } } if (numWsBlock == 0) { return sb; } // Distribute needWs white spaces to numWsBlock blocks. // Put one more space to the middle of the blocks to look nicer if // needWs is not divisible by numWsBlock. int needWs = width - curwidth; int eachWs = needWs / numWsBlock; int rem = needWs % numWsBlock; int remStart = (numWsBlock - rem + 1) / 2; int remEnd = remStart + rem; cont = false; int b = 0; for (i = 0; i < len; ++i) { if (sb.charAt(i) == ' ') { if (!cont) { cont = true; int add = eachWs + (remStart <= b && b < remEnd ? 1 : 0); for (int j = 0; j < add; ++j) { sb.insert(i, ' '); } len = sb.length(); ++b; } } else { cont = false; } } return sb; } public static void printHelp(PrintWriter writer, String title, String help, TextWidthCounter textWidthCounter, int width) { int INDENT_WIDTH = 25; writer.print(" "); writer.print(title); if (!help.isEmpty()) { int titleWidth = textWidthCounter.width(title); int indentWidth = INDENT_WIDTH; if (titleWidth <= 21) { indentWidth -= titleWidth + 2; } else { writer.println(); } for (int i = 0; i < indentWidth; ++i) { writer.print(" "); } writer.println(wrap(textWidthCounter, help, width, INDENT_WIDTH, "", " ")); } else { writer.println(); } } public static String nonNull(String str) { if (str == null) { return ""; } else { return str; } } /** * From src, find string whose prefix is prefix and store them in List and * return it. * * @param src * collection contains strings to inspect * @param prefix * prefix * @return List of strings matched */ public static List findPrefix(Collection src, String prefix) { List res = new ArrayList(); for (String s : src) { if (s.startsWith(prefix)) { res.add(s); } } return res; } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/helper/TextWidthCounter.java000066400000000000000000000036661240010205600330370ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.helper; /** *

* This interface abstracts the way of counting text width. *

* *

* Since argparse4j is command line argument parser package and it is intended * to be used in terminal emulator and the terminal emulator in general uses * fixed width fonts, the meaning of "width" here is given text consumes how * many fixed character width. For string consisting only with ascii latin * characters, it will be the same as the number of characters in given text. * But for CJK characters are concerned this is not the case. *

*/ public interface TextWidthCounter { /** * Counts given text consumes how many fixed character width. * * @param text * The text to inspect. * @return The computed value. */ int width(String text); } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/000077500000000000000000000000001240010205600263575ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/Arguments.java000066400000000000000000000203671240010205600311770ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl; import java.util.List; import net.sourceforge.argparse4j.impl.action.AppendArgumentAction; import net.sourceforge.argparse4j.impl.action.AppendConstArgumentAction; import net.sourceforge.argparse4j.impl.action.CountArgumentAction; import net.sourceforge.argparse4j.impl.action.HelpArgumentAction; import net.sourceforge.argparse4j.impl.action.StoreArgumentAction; import net.sourceforge.argparse4j.impl.action.StoreConstArgumentAction; import net.sourceforge.argparse4j.impl.action.StoreFalseArgumentAction; import net.sourceforge.argparse4j.impl.action.StoreTrueArgumentAction; import net.sourceforge.argparse4j.impl.action.VersionArgumentAction; import net.sourceforge.argparse4j.impl.choice.RangeArgumentChoice; import net.sourceforge.argparse4j.impl.type.EnumArgumentType; import net.sourceforge.argparse4j.impl.type.FileArgumentType; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.FeatureControl; /** *

* This class provides useful shortcuts and constants. *

* *

* They are mainly used to specify parameter to {@link Argument} object. *

* */ public final class Arguments { /** * Intentionally made private to avoid instantiation in application code. */ private Arguments() { } /** *

* Creates new range constrained choice. *

*

* The value specified in command line will be checked to see whether it * fits in given range [min, max], inclusive. *

* * @param min * The lowerbound of the range, inclusive. * @param max * The upperbound of the range, inclusive. * @return {@link RangeArgumentChoice} object. */ public static > RangeArgumentChoice range(T min, T max) { return new RangeArgumentChoice(min, max); } private static final StoreArgumentAction store_ = new StoreArgumentAction(); private static final StoreTrueArgumentAction storeTrue_ = new StoreTrueArgumentAction(); private static final StoreFalseArgumentAction storeFalse_ = new StoreFalseArgumentAction(); private static final StoreConstArgumentAction storeConst_ = new StoreConstArgumentAction(); private static final AppendArgumentAction append_ = new AppendArgumentAction(); private static final AppendConstArgumentAction appendConst_ = new AppendConstArgumentAction(); private static final HelpArgumentAction help_ = new HelpArgumentAction(); private static final VersionArgumentAction version_ = new VersionArgumentAction(); private static final CountArgumentAction count_ = new CountArgumentAction(); /** *

* The value of {@link FeatureControl#SUPPRESS}. *

* *

* If value is used with {@link Argument#setDefault(FeatureControl)}, no * attribute is added if the command line argument was not present. * Otherwise, the default value, which defaults to null, will be added to * the object, regardless of the presence of command line argument, returned * by {@link ArgumentParser#parseArgs(String[])}. *

*/ public static final FeatureControl SUPPRESS = FeatureControl.SUPPRESS; /** * Returns store action. * * @return {@link StoreArgumentAction} object. */ public static StoreArgumentAction store() { return store_; } /** *

* Returns storeTrue action. *

* *

* If this action is used, the value specified using * {@link Argument#nargs(int)} will be ignored. *

* * @return {@link StoreTrueArgumentAction} object. */ public static StoreTrueArgumentAction storeTrue() { return storeTrue_; } /** *

* Returns storeFalse action. *

* *

* If this action is used, the value specified using * {@link Argument#nargs(int)} will be ignored. *

* * @return {@link StoreFalseArgumentAction} object. */ public static StoreFalseArgumentAction storeFalse() { return storeFalse_; } /** *

* Returns storeConst action. *

* *

* If this action is used, the value specified using * {@link Argument#nargs(int)} will be ignored. *

* * @return {@link StoreConstArgumentAction} object. */ public static StoreConstArgumentAction storeConst() { return storeConst_; } /** *

* Returns append action. *

*

* If this action is used, the attribute will be of type {@link List}. If * used with {@link Argument#nargs(int)}, the element of List will be List. * This is because {@link Argument#nargs(int)} produces List. *

* * @return {@link AppendArgumentAction} object. */ public static AppendArgumentAction append() { return append_; } /** *

* Returns appendConst action. *

*

* If this action is used, the value specified using * {@link Argument#nargs(int)} will be ignored. *

* * @return {@link AppendConstArgumentAction} object. */ public static AppendConstArgumentAction appendConst() { return appendConst_; } /** *

* Returns help action. *

*

* This is used for an option printing help message. Please note that this * action terminates program after printing help message. *

* * @return {@link HelpArgumentAction} object. */ public static HelpArgumentAction help() { return help_; } /** *

* Returns version action. *

*

* This is used for an option printing version message. Please note that * this action terminates program after printing version message. *

* * @return {@link VersionArgumentAction} object. */ public static VersionArgumentAction version() { return version_; } /** *

* Returns count action. *

*

* This action counts the number of occurrence of the option. This action * does not consume argument. *

* * @return {@link CountArgumentAction} object. */ public static CountArgumentAction count() { return count_; } /** *

* Returns {@link EnumArgumentType} with given enum {@code type}. *

*

* Since enum does not have a constructor with string argument, you cannot * use {@link Argument#type(Class)}. Instead use this convenient function. *

* * @param type * The enum type * @return {@link EnumArgumentType} object */ public static > EnumArgumentType enumType(Class type) { return new EnumArgumentType(type); } /** *

* Returns new {@link FileArgumentType} object. *

* * @return {@link FileArgumentType} object */ public static FileArgumentType fileType() { return new FileArgumentType(); } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/action/000077500000000000000000000000001240010205600276345ustar00rootroot00000000000000AppendArgumentAction.java000066400000000000000000000051621240010205600344740ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/action/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl.action; import java.util.ArrayList; import java.util.List; import java.util.Map; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentAction; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; /** *

* Argument action to store a list. *

* *

* This action appends each argument value to the list. The list is of type * {@link java.util.List}. This is useful to allow an option to be specified * multiple times. If {@code attrs} contains non-List object for key * {@link Argument#getDest()}, it will be overwritten by the List containing * {@code value}. {@link #consumeArgument()} always returns {@code true}. *

*/ public class AppendArgumentAction implements ArgumentAction { @Override public void run(ArgumentParser parser, Argument arg, Map attrs, String flag, Object value) throws ArgumentParserException { if (attrs.containsKey(arg.getDest())) { Object obj = attrs.get(arg.getDest()); if (obj instanceof List) { ((List) obj).add(value); return; } } List list = new ArrayList(); list.add(value); attrs.put(arg.getDest(), list); } @Override public boolean consumeArgument() { return true; } @Override public void onAttach(Argument arg) { } } AppendConstArgumentAction.java000066400000000000000000000054141240010205600355030ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/action/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl.action; import java.util.ArrayList; import java.util.List; import java.util.Map; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentAction; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; /** *

* Argument action to store a list. *

*

* This action appends the value specified by {@link Argument#setConst(Object)} * to the list. (Note that the const value defaults to {@code null}.) The list * is of type {@link java.util.List}. This action is typically useful when * multiple arguments need to store constants to the same list. If {@code attrs} * contains non-List object for key {@link Argument#getDest()}, it will be * overwritten by the List containing {@code value}. {@link #consumeArgument()} * always returns {@code false}. *

* */ public class AppendConstArgumentAction implements ArgumentAction { @Override public void run(ArgumentParser parser, Argument arg, Map attrs, String flag, Object value) throws ArgumentParserException { if (attrs.containsKey(arg.getDest())) { Object obj = attrs.get(arg.getDest()); if (obj instanceof List) { ((List) obj).add(arg.getConst()); return; } } List list = new ArrayList(); list.add(arg.getConst()); attrs.put(arg.getDest(), list); } @Override public boolean consumeArgument() { return false; } @Override public void onAttach(Argument arg) { } } CountArgumentAction.java000066400000000000000000000042731240010205600343570ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/action/* * Copyright (C) 2013 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl.action; import java.util.Map; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentAction; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; /** *

* Argument action to count the occurrence of the option. *

*

* In addition, it creates default value of {@code 0}. Thus the type of this * argument is of type {@link Integer}. {@link #consumeArgument()} always * returns {@code false}. *

* */ public class CountArgumentAction implements ArgumentAction { @Override public void run(ArgumentParser parser, Argument arg, Map attrs, String flag, Object value) throws ArgumentParserException { String dest = arg.getDest(); int n = (Integer) attrs.get(dest); attrs.put(dest, n + 1); } @Override public void onAttach(Argument arg) { arg.setDefault(0); } @Override public boolean consumeArgument() { return false; } } HelpArgumentAction.java000066400000000000000000000043701240010205600341550ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/action/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl.action; import java.util.Map; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentAction; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.internal.HelpScreenException; /** *

* Argument action to print help message and exit program. *

*

* Please note that this * {@link #run(ArgumentParser, Argument, Map, String, Object)} always throws a * {@code HelpScreenException} exception after printing the help message. * {@link #consumeArgument()} always returns {@code false}. *

* */ public class HelpArgumentAction implements ArgumentAction { @Override public void run(ArgumentParser parser, Argument arg, Map attrs, String flag, Object value) throws ArgumentParserException { parser.printHelp(); throw new HelpScreenException(parser); } @Override public boolean consumeArgument() { return false; } @Override public void onAttach(Argument arg) { } } StoreArgumentAction.java000066400000000000000000000035521240010205600343620ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/action/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl.action; import java.util.Map; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentAction; import net.sourceforge.argparse4j.inf.ArgumentParser; /** *

* Argument action to store argument value. *

*

* {@link #consumeArgument()} always returns {@code true}. *

* */ public class StoreArgumentAction implements ArgumentAction { @Override public void run(ArgumentParser parser, Argument arg, Map attrs, String flag, Object value) { attrs.put(arg.getDest(), value); } @Override public boolean consumeArgument() { return true; } @Override public void onAttach(Argument arg) { } } StoreConstArgumentAction.java000066400000000000000000000042431240010205600353670ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/action/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl.action; import java.util.Map; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentAction; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; /** *

* Argument action to store the value specified by the * {@link Argument#setConst(Object)}. *

*

* Note that by default const value is {@code null}. This action is most * commonly used with optional arguments that specify sort of flags. * {@link #consumeArgument()} always returns {@code false}. *

* */ public class StoreConstArgumentAction implements ArgumentAction { @Override public void run(ArgumentParser parser, Argument arg, Map attrs, String flag, Object value) throws ArgumentParserException { attrs.put(arg.getDest(), arg.getConst()); } @Override public boolean consumeArgument() { return false; } @Override public void onAttach(Argument arg) { } } StoreFalseArgumentAction.java000066400000000000000000000042241240010205600353320ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/action/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl.action; import java.util.Map; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentAction; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; /** *

* Argument action to store value {@code false}. *

*

* In addition, it creates default value of {@code true}. * {@link #onAttach(Argument)} calls {@link Argument#setDefault(Object)} with * {@code true}. {@link #consumeArgument()} always returns {@code false}. *

* */ public class StoreFalseArgumentAction implements ArgumentAction { @Override public void run(ArgumentParser parser, Argument arg, Map attrs, String flag, Object value) throws ArgumentParserException { attrs.put(arg.getDest(), false); } @Override public boolean consumeArgument() { return false; } @Override public void onAttach(Argument arg) { arg.setDefault(true); } } StoreTrueArgumentAction.java000066400000000000000000000042241240010205600352170ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/action/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl.action; import java.util.Map; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentAction; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; /** *

* Argument action to store value {@code true}. *

*

* In addition, it creates default value of {@code false}. * {@link #onAttach(Argument)} calls {@link Argument#setDefault(Object)} with * {@code false}. {@link #consumeArgument()} always returns {@code false}. *

* */ public class StoreTrueArgumentAction implements ArgumentAction { @Override public void run(ArgumentParser parser, Argument arg, Map attrs, String flag, Object value) throws ArgumentParserException { attrs.put(arg.getDest(), true); } @Override public boolean consumeArgument() { return false; } @Override public void onAttach(Argument arg) { arg.setDefault(false); } } VersionArgumentAction.java000066400000000000000000000042121240010205600347050ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/action/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl.action; import java.util.Map; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentAction; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; /** *

* Argument action to print version message and exit program. *

*

* Please note that this * {@link #run(ArgumentParser, Argument, Map, String, Object)} terminates * program after printing the version message. {@link #consumeArgument()} always * returns {@code false}. *

* */ public class VersionArgumentAction implements ArgumentAction { @Override public void run(ArgumentParser parser, Argument arg, Map attrs, String flag, Object value) throws ArgumentParserException { parser.printVersion(); System.exit(0); } @Override public boolean consumeArgument() { return false; } @Override public void onAttach(Argument arg) { } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/choice/000077500000000000000000000000001240010205600276115ustar00rootroot00000000000000CollectionArgumentChoice.java000066400000000000000000000062011240010205600353050ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/choice/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl.choice; import java.util.Arrays; import java.util.Collection; import net.sourceforge.argparse4j.helper.TextHelper; import net.sourceforge.argparse4j.inf.ArgumentChoice; /** *

* Choice from given collection of values. *

*

* {@link #contains(Object)} checks given {@code val} is contained in values * given in constructor argument. *

*/ public class CollectionArgumentChoice implements ArgumentChoice { private Collection values_; /** * Initializes this object from given values. * * @param values * Valid values */ public CollectionArgumentChoice(E... values) { values_ = Arrays.asList(values); } /** * Initializes this object from given values. * * @param values * Valid values */ public CollectionArgumentChoice(Collection values) { values_ = values; } @Override public boolean contains(Object val) { if (values_.isEmpty()) { // If values is empty, we don't have type information, so // just return false. return false; } Object first = values_.iterator().next(); if (first.getClass().equals(val.getClass()) || first instanceof Enum && val instanceof Enum && ((Enum) first).getDeclaringClass().equals(((Enum) val).getDeclaringClass())) { return values_.contains(val); } else { throw new IllegalArgumentException(String.format( TextHelper.LOCALE_ROOT, "type mismatch (Make sure that you specified correct Argument.type()):" + " expected: %s actual: %s", first.getClass().getName(), val.getClass().getName() )); } } @Override public String textualFormat() { return TextHelper.concat(values_, 0, ",", "{", "}"); } @Override public String toString() { return textualFormat(); } } RangeArgumentChoice.java000066400000000000000000000054311240010205600342520ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/choice/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl.choice; import net.sourceforge.argparse4j.helper.TextHelper; import net.sourceforge.argparse4j.inf.ArgumentChoice; /** *

* Choices from given range. *

* *

* The given value will be checked if it is in range [min, max], inclusive. The * {@code min} and {@code max} are specified in constructor arguments. *

* * @param * The type to compare. */ public class RangeArgumentChoice> implements ArgumentChoice { private T min_; private T max_; /** * Creates object using range [{@code min}, {@code max}], inclusive. * * @param min * The lowerbound of the range, inclusive. * @param max * The upperbound of the range, inclusive. */ public RangeArgumentChoice(T min, T max) { min_ = min; max_ = max; } @Override public boolean contains(Object val) { if (min_.getClass().equals(val.getClass())) { T v = (T) val; return min_.compareTo(v) <= 0 && 0 <= max_.compareTo(v); } else { throw new IllegalArgumentException(String.format( TextHelper.LOCALE_ROOT, "type mismatch (Make sure that you specified corrent Argument.type()):" + " expected: %s actual: %s", min_.getClass() .getName(), val.getClass().getName())); } } @Override public String textualFormat() { return String.format(TextHelper.LOCALE_ROOT, "{%s..%s}", min_, max_); } @Override public String toString() { return textualFormat(); } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/type/000077500000000000000000000000001240010205600273405ustar00rootroot00000000000000ConstructorArgumentType.java000066400000000000000000000065401240010205600350230ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/type/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl.type; import java.lang.reflect.InvocationTargetException; import net.sourceforge.argparse4j.helper.TextHelper; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.ArgumentType; /** *

* This implementation converts String value into given type using given type's * constructor. *

*

* The constructor must have 1 String argument. If error occurred inside the * constructor, {@link ArgumentParserException} will be thrown. If error * occurred in other locations, subclass of {@link RuntimeException} will be * thrown. *

* * @deprecated Use {@link ReflectArgumentType} instead. */ public class ConstructorArgumentType implements ArgumentType { private Class type_; /** *

* Creates {@link ConstructorArgumentType} object with given {@code type}. *

*

* The constructor of {@code type} must have 1 String argument. *

* * @param type * The type String value should be converted to. */ public ConstructorArgumentType(Class type) { type_ = type; } @Override public T convert(ArgumentParser parser, Argument arg, String value) throws ArgumentParserException { T obj = null; try { obj = type_.getConstructor(String.class).newInstance(value); } catch (InstantiationException e) { handleInstatiationError(e); } catch (IllegalAccessException e) { handleInstatiationError(e); } catch (InvocationTargetException e) { throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "could not convert '%s' to %s (%s)", value, type_.getSimpleName(), e.getCause().getMessage()), e.getCause(), parser, arg); } catch (NoSuchMethodException e) { handleInstatiationError(e); } return obj; } private void handleInstatiationError(Exception e) { throw new IllegalArgumentException("Failed to instantiate object", e); } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/type/EnumArgumentType.java000066400000000000000000000034141240010205600334560ustar00rootroot00000000000000package net.sourceforge.argparse4j.impl.type; import net.sourceforge.argparse4j.helper.TextHelper; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.ArgumentType; /** *

* ArgumentType subclass for enum type. *

*

* Since enum does not have a constructor with string argument, it cannot be * used with {@link Argument#type(Class)}. Instead use this class to specify * enum type. The enums in its nature have limited number of members. In * {@link #convert(ArgumentParser, Argument, String)}, String value will be * converted to one of them. If it cannot be converted, * {@link #convert(ArgumentParser, Argument, String)} will throw * {@link ArgumentParserException}. This means it already act like a * {@link Argument#choices(Object...)}. *

* * @deprecated Use {@link ReflectArgumentType} instead. * @param * Type of enum */ public class EnumArgumentType> implements ArgumentType { private Class type_; public EnumArgumentType(Class type) { type_ = type; } @Override public T convert(ArgumentParser parser, Argument arg, String value) throws ArgumentParserException { try { return Enum.valueOf(type_, value); } catch (IllegalArgumentException e) { String choices = TextHelper.concat(type_.getEnumConstants(), 0, ",", "{", "}"); throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "could not convert '%s' (choose from %s)", value, choices), e, parser, arg); } } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/type/FileArgumentType.java000066400000000000000000000243311240010205600334320ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package net.sourceforge.argparse4j.impl.type; import java.io.File; import java.io.IOException; import net.sourceforge.argparse4j.helper.TextHelper; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.ArgumentType; /** * ArgumentType subclass for File type, using fluent style API. * * This object can convert path string to {@link java.io.File} object. The * command-line programs traditionally accept the file path "-" as standard * input. This object supports this when * {@link FileArgumentType#acceptSystemIn()} is used. Also there are several * convenient verification features such as checking readability or existence. */ public class FileArgumentType implements ArgumentType { private boolean acceptSystemIn = false; private boolean verifyExists = false; private boolean verifyNotExists = false; private boolean verifyIsFile = false; private boolean verifyIsDirectory = false; private boolean verifyCanRead = false; private boolean verifyCanWrite = false; private boolean verifyCanWriteParent = false; private boolean verifyCanCreate = false; private boolean verifyCanExecute = false; private boolean verifyIsAbsolute = false; public FileArgumentType() { } /** * If the argument is "-", accept it as standard input. If this method is * used, all verification methods will be ignored. * * @return this */ public FileArgumentType acceptSystemIn() { acceptSystemIn = true; return this; } /** * Verifies that the specified path exists. If the verification fails, error * will be reported. * * @return this */ public FileArgumentType verifyExists() { verifyExists = true; return this; } /** * Verifies that the specified path does not exist. If the verification * fails, error will be reported. * * @return this */ public FileArgumentType verifyNotExists() { verifyNotExists = true; return this; } /** * Verifies that the specified path is a regular file. If the verification * fails, error will be reported. * * @return this */ public FileArgumentType verifyIsFile() { verifyIsFile = true; return this; } /** * Verifies that the specified path is a directory. If the verification * fails, error will be reported. * * @return this */ public FileArgumentType verifyIsDirectory() { verifyIsDirectory = true; return this; } /** * Verifies that the specified path is readable. If the verification fails, * error will be reported. * * @return this */ public FileArgumentType verifyCanRead() { verifyCanRead = true; return this; } /** * Verifies that the specified path is writable. If the verification fails, * error will be reported. * * @return this */ public FileArgumentType verifyCanWrite() { verifyCanWrite = true; return this; } /** * Verifies that the parent directory of the specified path is writable. If * the verification fails, error will be reported. * * @return this */ public FileArgumentType verifyCanWriteParent() { verifyCanWriteParent = true; return this; } /** * Verifies that the specified path is writable. If the verification fails, * error will be reported. * * @return this */ public FileArgumentType verifyCanCreate() { verifyCanCreate = true; return this; } /** * Verifies that the specified path is executable. If the verification * fails, error will be reported. * * @return this */ public FileArgumentType verifyCanExecute() { verifyCanExecute = true; return this; } /** * Verifies that the specified path is an absolute path. If the verification * fails, error will be reported. * * @return this */ public FileArgumentType verifyIsAbsolute() { verifyIsAbsolute = true; return this; } @Override public File convert(ArgumentParser parser, Argument arg, String value) throws ArgumentParserException { File file = new File(value); if (verifyIsAbsolute && !isSystemIn(file)) { verifyIsAbsolute(parser, arg, file); } if (verifyExists && !isSystemIn(file)) { verifyExists(parser, arg, file); } if (verifyNotExists && !isSystemIn(file)) { verifyNotExists(parser, arg, file); } if (verifyIsFile && !isSystemIn(file)) { verifyIsFile(parser, arg, file); } if (verifyIsDirectory && !isSystemIn(file)) { verifyIsDirectory(parser, arg, file); } if (verifyCanRead && !isSystemIn(file)) { verifyCanRead(parser, arg, file); } if (verifyCanWrite && !isSystemIn(file)) { verifyCanWrite(parser, arg, file); } if (verifyCanWriteParent && !isSystemIn(file)) { verifyCanWriteParent(parser, arg, file); } if (verifyCanCreate && !isSystemIn(file)) { verifyCanCreate(parser, arg, file); } if (verifyCanExecute && !isSystemIn(file)) { verifyCanExecute(parser, arg, file); } return file; } private void verifyExists(ArgumentParser parser, Argument arg, File file) throws ArgumentParserException { if (!file.exists()) { throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "File not found: '%s'", file), parser, arg); } } private void verifyNotExists(ArgumentParser parser, Argument arg, File file) throws ArgumentParserException { if (file.exists()) { throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "File found: '%s'", file), parser, arg); } } private void verifyIsFile(ArgumentParser parser, Argument arg, File file) throws ArgumentParserException { if (!file.isFile()) { throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "Not a file: '%s'", file), parser, arg); } } private void verifyIsDirectory(ArgumentParser parser, Argument arg, File file) throws ArgumentParserException { if (!file.isDirectory()) { throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "Not a directory: '%s'", file), parser, arg); } } private void verifyCanRead(ArgumentParser parser, Argument arg, File file) throws ArgumentParserException { if (!file.canRead()) { throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "Insufficient permissions to read file: '%s'", file), parser, arg); } } private void verifyCanWrite(ArgumentParser parser, Argument arg, File file) throws ArgumentParserException { if (!file.canWrite()) { throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "Insufficient permissions to write file: '%s'", file), parser, arg); } } private void verifyCanWriteParent(ArgumentParser parser, Argument arg, File file) throws ArgumentParserException { File parent = file.getParentFile(); if (parent == null || !parent.canWrite()) { throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "Cannot write parent of file: '%s'", file), parser, arg); } } private void verifyCanCreate(ArgumentParser parser, Argument arg, File file) throws ArgumentParserException { try { File parent = file.getCanonicalFile().getParentFile(); if (parent != null && parent.canWrite()) { return; } } catch (IOException e) { } // An exception was thrown or the parent directory can't be written throw new ArgumentParserException(String.format(TextHelper.LOCALE_ROOT, "Cannot create file: '%s'", file), parser, arg); } private void verifyCanExecute(ArgumentParser parser, Argument arg, File file) throws ArgumentParserException { if (!file.canExecute()) { throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "Insufficient permissions to execute file: '%s'", file), parser, arg); } } private void verifyIsAbsolute(ArgumentParser parser, Argument arg, File file) throws ArgumentParserException { if (!file.isAbsolute()) { throw new ArgumentParserException( String.format(TextHelper.LOCALE_ROOT, "Not an absolute file: '%s'", file), parser, arg); } } private boolean isSystemIn(File file) { return acceptSystemIn && file.getPath().equals("-"); } } ReflectArgumentType.java000066400000000000000000000140671240010205600340650ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/type/* * Copyright (C) 2013 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl.type; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import net.sourceforge.argparse4j.helper.TextHelper; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.ArgumentType; /** *

* This implementation converts String value into given type using type's * {@code valueOf(java.lang.String)} static method or its constructor. *

*/ public class ReflectArgumentType implements ArgumentType { private Class type_; /** *

* Creates {@link ReflectArgumentType} object with given {@code type}. *

*

* This object first tries to convert given String using * {@code valueOf(java.lang.String)} static method of given {@code type}. If * that failed, then use constructor of given {@code type} for conversion. * {@code valueOf()} method and/or constructor must be declared as public. * Otherwise, they cannot be invoked. The constructor of {@code type} must * accept 1 String argument. *

*

* If error occurred inside the {@code valueOf} static method or * constructor, {@link ArgumentParserException} will be thrown. If error * occurred in other locations, subclass of {@link RuntimeException} will be * thrown. *

*

* This object works with enums as well. The enums in its nature have * limited number of members. In * {@link #convert(ArgumentParser, Argument, String)}, string value will be * converted to one of them. If it cannot be converted, * {@link #convert(ArgumentParser, Argument, String)} will throw * {@link ArgumentParserException}. This means it already act like a * {@link Argument#choices(Object...)}. *

* * @param type * The type String value should be converted to. */ public ReflectArgumentType(Class type) { type_ = type; } @Override public T convert(ArgumentParser parser, Argument arg, String value) throws ArgumentParserException { // Handle enums separately. Enum.valueOf() is very convenient here. // It somehow can access private enum values, where normally T.valueOf() // cannot without setAccessible(true). if (type_.isEnum()) { try { return (T) Enum.valueOf((Class) type_, value); } catch (IllegalArgumentException e) { throwArgumentParserException(parser, arg, value, e); } } Method m = null; try { m = type_.getMethod("valueOf", String.class); } catch (NoSuchMethodException e) { // If no valueOf static method found, try constructor. return convertUsingConstructor(parser, arg, value); } catch (SecurityException e) { handleInstatiationError(e); } // Only interested in static valueOf method. if (!Modifier.isStatic(m.getModifiers()) || !type_.isAssignableFrom(m.getReturnType())) { return convertUsingConstructor(parser, arg, value); } Object obj = null; try { obj = m.invoke(null, value); } catch (IllegalAccessException e) { return convertUsingConstructor(parser, arg, value); } catch (IllegalArgumentException e) { handleInstatiationError(e); } catch (InvocationTargetException e) { throwArgumentParserException(parser, arg, value, e.getCause() == null ? e : e.getCause()); } return (T) obj; } private T convertUsingConstructor(ArgumentParser parser, Argument arg, String value) throws ArgumentParserException { T obj = null; try { obj = type_.getConstructor(String.class).newInstance(value); } catch (InstantiationException e) { handleInstatiationError(e); } catch (IllegalAccessException e) { handleInstatiationError(e); } catch (InvocationTargetException e) { throwArgumentParserException(parser, arg, value, e.getCause() == null ? e : e.getCause()); } catch (NoSuchMethodException e) { handleInstatiationError(e); } return obj; } private void throwArgumentParserException(ArgumentParser parser, Argument arg, String value, Throwable t) throws ArgumentParserException { throw new ArgumentParserException(String.format(TextHelper.LOCALE_ROOT, "could not convert '%s' to %s (%s)", value, type_.getSimpleName(), t.getMessage()), t, parser, arg); } private void handleInstatiationError(Exception e) { throw new IllegalArgumentException("reflect type conversion error", e); } } StringArgumentType.java000066400000000000000000000032461240010205600337440ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/impl/type/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.impl.type; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.ArgumentType; /** * Specialized to String type, just echos back given string. * */ public class StringArgumentType implements ArgumentType { @Override public String convert(ArgumentParser parser, Argument arg, String value) throws ArgumentParserException { return value; } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/inf/000077500000000000000000000000001240010205600261725ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/inf/Argument.java000066400000000000000000000251211240010205600306200ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.inf; import java.util.Collection; import java.util.List; /** * This interface provides a way to specify parameters to argument to be * processed in {@link ArgumentParser} object. * */ public interface Argument { /** *

* Sets the number of command line arguments that should be consumed. *

*

* Don't give this method {@code '*'}, {@code '+'} or {@code '?'}. They are * converted to {@code int} value and it is not what you expect. For these * strings, use {@link #nargs(String)}. *

* * @param n * A positive integer * @return this */ Argument nargs(int n); /** *

* Sets the number of command line arguments that should be consumed. *

*

* This method takes one of following string: {@code "*"}, {@code "+"} and * {@code "?"}. If {@code "*"} is given, All command line arguments present * are gathered into a {@link java.util.List}. If {@code "+"} is given, just * like {@code "*"}, all command line arguments present are gathered into a * {@link java.util.List}. Additionally, an error message will be generated * if there wasn't at least one command line argument present. If * {@code "?"} is given, one argument will be consumed from the command line * if possible, and produced as a single item. If no command line argument * is present, the value from {@link #setDefault(Object)} will be produced. * Note that for optional arguments, there is an additional case - the * option string is present but not followed by a command line argument. In * this case the value from {@link #setConst(Object)} will be produced. *

* * @param n * {@code "*"}, {@code "+"} or {@code "?"} * @return this */ Argument nargs(String n); /** *

* Sets constant values that are not read from the command line but are * required for the various actions. *

* *

* The const value defauls to {@code null}. *

* * @param value * The const value * @return this */ Argument setConst(Object value); /** *

* Sets list of constant values that are not read from the command line but * are required for the various actions. *

*

* The given {@code values} will be converted to {@link List}. The const * value defauls to {@code null}. If you want to set non-List item, use * {@link #setConst(Object)}. *

* * @param values * The const values * @return this */ Argument setConst(E... values); /** *

* Sets value which should be used if the command line argument is not * present. *

*

* The default value defaults to {@code null}. *

* * @param value * The default value * @return this */ Argument setDefault(Object value); /** *

* Sets list of values which should be used if the command line argument is * not present. *

*

* The default value defaults to {@code null}. The given {@code values} will * be converted to {@link List}. If you want to set non-List item, use * {@link Argument#setDefault(Object)}. *

* * @param values * The default values * @return this */ Argument setDefault(E... values); /** *

* Sets special value to control default value handling. *

*

* Currently, only {@link FeatureControl#SUPPRESS} is available. If it is * given, default value is not add as a attribute. *

* * @param ctrl * The special value to control default value handling. * @return this */ Argument setDefault(FeatureControl ctrl); /** *

* Sets the type which the command line argument should be converted to. *

*

* By default, type is String, which means no conversion is made. The type * must have a constructor which takes one String argument. *

*

* As a convenience, if one of following primitive types (boolean.class, * byte.class, short.class, int.class, long.class, float.class and * double.class) is specified, it is converted to its wrapped type * counterpart. For example, if int.class is given, it is silently converted * to Integer.class. *

* * @param type * The type which the command line argument should be converted * to. * @return this */ Argument type(Class type); /** *

* Sets {@link ArgumentType} object which converts command line argument to * appropriate type. *

*

* This would be useful if you need to convert the command line argument * into a type which does not have a constructor with one String argument. *

* * @param type * The {@link ArgumentType} object * @return this */ Argument type(ArgumentType type); /** *

* If {@code true} is given, this optional argument must be specified in * command line otherwise error will be issued. *

*

* The default value is {@code false}. This object is a positional argument, * this property is ignored. *

* * @param required * {@code true} or {@code false} * @return this */ Argument required(boolean required); /** * Sets the action to be taken when this argument is encountered at the * command line. * * @param action * {@link ArgumentAction} object * @return this */ Argument action(ArgumentAction action); /** *

* Sets {@link ArgumentChoice} object which inspects value so that it * fulfills its criteria. *

*

* This method is useful if more complex inspection is necessary than basic * {@link #choices(Object...)}. *

* * @param choice * {@link ArgumentChoice} object. * @return this */ Argument choices(ArgumentChoice choice); /** * Sets a collection of the allowable values for the argument. * * @param values * A collection of the allowable values * @return this */ Argument choices(Collection values); /** * Sets a collection of the allowable values for the argument. * * @param values * A collection of the allowable values * @return this */ Argument choices(E... values); /** *

* The name of the attribute to be added. *

*

* The default value is For positional arguments, The default value is * normally supplied as the first argument to * {@link ArgumentParser#parseArgs(String[])}. For optional arguments, * {@link ArgumentParser} generates the default value of {@code dest} by * taking the first long option string and stripping away the initial * {@code --} string. If no long option strings were supplied, {@code dest} * will be derived from the first short option string by stripping the * initial {@code -} character. Any internal {@code -} characters will be * converted to {@code _}. *

* * @param dest * The name of the attribute to be added * @return this */ Argument dest(String dest); /** * Set the name for the argument in usage messages. * * @param metavar * The name for the argument in usage messages * @return this */ Argument metavar(String... metavar); /** * Sets the brief description of what the argument does. * * @param help * The brief description of what the argument does * @return this */ Argument help(String help); /** *

* Sets special value to control help message handling. *

*

* Currently, only {@link FeatureControl#SUPPRESS} is available. If it is * given, the help entry for this option is not displayed in the help * message. *

* * @param ctrl * The special value to control help message handling. * @return this */ Argument help(FeatureControl ctrl); /** *

* Returns textual representation of the argument name. *

* *

* For optional arguments, this method returns the first argument given in * {@link ArgumentParser#addArgument(String...)}. For positional arguments, * this method returns the flags joined with "/", e.g. {@code -f/--foo}. *

* * @return The textual representation of the argument name. */ String textualName(); // Getter methods /** * Returns dest value. * * @return The dest value */ String getDest(); /** * Returns const value. * * @return The const value */ Object getConst(); /** * Returns default value. * * @return The default value */ Object getDefault(); /** * Returns default control. * * @return The default control */ FeatureControl getDefaultControl(); /** * Returns help control. * * @return The help control */ FeatureControl getHelpControl(); } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/inf/ArgumentAction.java000066400000000000000000000056371240010205600317700ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.inf; import java.util.Map; /** * This interface defines behavior of action when an argument is encountered at * the command line. * */ public interface ArgumentAction { /** *

* Executes this action. *

*

* If the objects derived from {@link RuntimeException} are thrown in this * method because of invalid input from command line, subclass must catch * these exceptions and wrap them in {@link ArgumentParserException} and * give simple error message to explain what happened briefly. *

* * @param parser * The parser. * @param arg * The argument this action attached to. * @param attrs * Map to store attributes. * @param flag * The actual option flag in command line if {@code arg} is an * optional arguments. {@code null} if {@code arg} is a * positional argument. * @param value * The attribute value. This may be null if this action does not * consume any arguments. * @throws ArgumentParserException * If error occurred. */ void run(ArgumentParser parser, Argument arg, Map attrs, String flag, Object value) throws ArgumentParserException; /** * Called when ArgumentAction is added to {@link Argument} using * {@link Argument#action(ArgumentAction)}. * * @param arg * {@link Argument} object to which this object is added. */ void onAttach(Argument arg); /** * Returns {@code true} if this action consumes argument. Otherwise returns * {@code false}. * * @return {@code true} or {@code false}. */ boolean consumeArgument(); } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/inf/ArgumentChoice.java000066400000000000000000000040041240010205600317300ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.inf; /** * This interface defines simple data validation method. * */ public interface ArgumentChoice { /** *

* Returns {@code true} iff {@code val} is valid choice according to this * object's constraint. *

*

* If the objects derived from {@link RuntimeException} are thrown because * of invalid input from command line, subclass must catch these exceptions * and return {@code false}. *

* * @param val * The attribute value. * @return {@code true} or {@code false}. */ boolean contains(Object val); /** *

* Return textual representation of this choice. *

*

* This string will be used in help and error messages. *

* * @return The textual representation of this choice. */ String textualFormat(); } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/inf/ArgumentGroup.java000066400000000000000000000036661240010205600316470ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.inf; /** * This interface defines a method to conceptually group up {@link Argument} * objects. * */ public interface ArgumentGroup { /** * Sets description to customize help message of this group. * * @param description * The description of this group. * @return this */ ArgumentGroup description(String description); /** *

* Creates new {@link Argument} and adds it to the underlining parser and * returns it. *

*

* See {@link ArgumentParser#addArgument(String...)} for details. *

* * @param nameOrFlags * A name or a list of option strings of new {@link Argument}. * @return {@link Argument} object. */ Argument addArgument(String... nameOrFlags); } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/inf/ArgumentParser.java000066400000000000000000000317141240010205600320020ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.inf; import java.io.PrintWriter; import java.util.List; import java.util.Map; import net.sourceforge.argparse4j.ArgumentParsers; import net.sourceforge.argparse4j.annotation.Arg; /** *

* This interface defines behavior of ArgumentParser. *

*

* The typical usage is set description using {@link #description(String)} and * add arguments using {@link #addArgument(String...)}. To add sub-command, * first call {@link #addSubparsers()} to obtain {@link Subparsers} object. * {@link Subparsers} object provides necessary methods to add sub-commands. To * make a conceptual group of arguments, first call * {@link #addArgumentGroup(String)} to create {@link ArgumentGroup} object. And * add argument to that group using {@link ArgumentGroup#addArgument(String...)} * . Similarly, to add the mutually exclusive group of arguments, use * {@link #addMutuallyExclusiveGroup(String)} to create * {@link MutuallyExclusiveGroup} object. To parse command-line arguments, call * {@link #parseArgs(String[])} or several overloaded methods. *

*/ public interface ArgumentParser { /** *

* Creates new {@link Argument} object and adds to this parser and returns * the object. *

*

* The {@code nameOrFlags} is either a single name of positional argument or * a list of option strings for optional argument, e.g. {@code foo} or * {@code -f, --foo}. *

* * @param nameOrFlags * A name or a list of option strings of new {@link Argument}. * @return {@link Argument} object. */ Argument addArgument(String... nameOrFlags); /** *

* Creates new {@link ArgumentGroup} object and adds to this parser and * returns the object. *

*

* The {@code title} is printed in help message as a title of this group. * {@link ArgumentGroup} provides a way to conceptually group up command * line arguments. *

* * @param title * The title printed in help message. * @return {@link ArgumentGroup} object. */ ArgumentGroup addArgumentGroup(String title); /** *

* Creates new mutually exclusive group, {@link MutuallyExclusiveGroup} * object, without title and adds to this parser and returns the object. *

* * @return {@link MutuallyExclusiveGroup} object. */ MutuallyExclusiveGroup addMutuallyExclusiveGroup(); /** *

* Creates new mutually exclusive group, {@link MutuallyExclusiveGroup} * object, and adds to this parser and returns the object. *

*

* The arguments added to this group are mutually exclusive; if more than * one argument belong to the group are specified, an error will be * reported. The {@code title} is printed in help message as a title of this * group. *

* * @param title * The title printed in help message. * @return The {@link MutuallyExclusiveGroup} object. */ MutuallyExclusiveGroup addMutuallyExclusiveGroup(String title); /** *

* Returns {@link Subparsers}. *

*

* The method name is rather controversial because repeated call of this * method does not add new {@link Subparsers} object. Instead, this method * always returns same {@link Subparsers} object. {@link Subparsers} object * provides a way to add sub-commands. *

* * @return {@link Subparsers} object. */ Subparsers addSubparsers(); /** *

* Sets the text to display as usage line. By default, the usage line is * calculated from the arguments this object contains. *

*

* If the given usage contains ${prog} string, it will be replaced * with the program name given in * {@link ArgumentParsers#newArgumentParser(String)}. *

* * @param usage * usage text * @return this */ ArgumentParser usage(String usage); /** * Sets the text to display before the argument help. * * @param description * The text to display before the argument help. * @return this */ ArgumentParser description(String description); /** * Sets the text to display after the argument help. * * @param epilog * The text to display after the argument help. * @return this */ ArgumentParser epilog(String epilog); /** *

* Sets version string. It will be displayed {@link #printVersion()}. *

*

* If the given usage contains ${prog} string, it will be replaced * with the program name given in * {@link ArgumentParsers#newArgumentParser(String)}. This processed text * will be printed without text-wrapping. *

* * @param version * The version string. * @return this */ ArgumentParser version(String version); /** *

* If defaultHelp is {@code true}, the default values of arguments are * printed in help message. *

*

* By default, the default values are not printed in help message. *

* * @param defaultHelp * Switch to display the default value in help message. * @return this */ ArgumentParser defaultHelp(boolean defaultHelp); /** * Prints help message in stdout. */ void printHelp(); /** * Prints help message in writer. * * @param writer * Writer to print message. */ void printHelp(PrintWriter writer); /** * Returns help message. * * @return The help message. */ String formatHelp(); /** * Print a brief description of how the program should be invoked on the * command line in stdout. */ void printUsage(); /** * Print a brief description of how the program should be invoked on the * command line in writer. * * @param writer * Writer to print message. */ void printUsage(PrintWriter writer); /** * Returns a brief description of how the program should be invoked on the * command line. * * @return Usage text. */ String formatUsage(); /** * Prints version string in stdout. */ void printVersion(); /** * Prints version string in writer. * * @param writer * Writer to print version string. */ void printVersion(PrintWriter writer); /** * Returns version string. * * @return The version string. */ String formatVersion(); /** *

* Sets parser-level default value of attribute {@code dest}. *

*

* The parser-level defaults always override argument-level defaults. *

* * @param dest * The attribute name. * @param value * The default value. * @return this */ ArgumentParser setDefault(String dest, Object value); /** *

* Sets parser-level default values from {@code attrs}. *

*

* All key-value pair in {@code attrs} are registered to parser-level * defaults. The parser-level defaults always override argument-level * defaults. *

* * @param attrs * The parser-level default values to add. * @return this */ ArgumentParser setDefaults(Map attrs); /** *

* Returns default value of given {@code dest}. *

*

* Returns default value set by {@link Argument#setDefault(Object)}, * {@link ArgumentParser#setDefault(String, Object)} or * {@link #setDefaults(Map)}. Please note that while parser-level defaults * always override argument-level defaults while parsing, this method * examines argument-level defaults first. If no default value is found, * then check parser-level defaults. If no default value is found, returns * {@code null}. *

* * @param dest * The attribute name of default value to get. * @return The default value of given dest. */ Object getDefault(String dest); /** *

* Parses command line arguments, handling any errors. *

*

* This is a shortcut method that combines {@link #parseArgs} and * {@link #handleError }. If the arguments can be successfully parsed, the * resulted attributes are returned as a {@link Namespace} object. * Otherwise, the program exits with a 1 return code. * *

* * @param args * Command line arguments. * @return {@link Namespace} object. */ Namespace parseArgsOrFail(String args[]); /** *

* Parses command line arguments. *

*

* The resulted attributes are returned as {@link Namespace} object. This * method must not alter the status of this parser and can be called * multiple times. *

* * @param args * Command line arguments. * @return {@link Namespace} object. * @throws ArgumentParserException * If an error occurred. */ Namespace parseArgs(String args[]) throws ArgumentParserException; /** *

* Parses command line arguments. *

*

* Unlike {@link #parseArgs(String[])}, which returns {@link Namespace} * object, this method stores attributes in given {@code attrs}. *

* * @param args * Command line arguments. * @param attrs * Map object to store attributes. * @throws ArgumentParserException * If an error occurred. */ void parseArgs(String[] args, Map attrs) throws ArgumentParserException; /** *

* Parses command line arguments. *

*

* Unlike {@link #parseArgs(String[])}, which returns {@link Namespace} * object, this method stores attributes in given {@code userData}. The * location to store value is designated using {@link Arg} annotations. User * don't have to specify {@link Arg} for all attributes: the missing * attributes are just skipped. This method performs simple {@link List} to * generic array conversion. For example, user can assign * {@code List} attribute to generic array {@code int[]}. *

* * @param args * Command line arguments. * @param userData * Object to store attributes. * @throws ArgumentParserException * If an error occurred. */ void parseArgs(String[] args, Object userData) throws ArgumentParserException; /** *

* Parses command line arguments. *

*

* This is a combination of {@link #parseArgs(String[], Map)} and * {@link #parseArgs(String[], Object)}. The all attributes will be stored * in {@code attrs}. The attributes specified in {@link Arg} annotations * will be also stored in {@code userData}. *

* * @param args * Command line arguments. * @param attrs * Map to store attributes. * @param userData * Object to store attributes. * @throws ArgumentParserException * If an error occurred. */ void parseArgs(String[] args, Map attrs, Object userData) throws ArgumentParserException; /** *

* Prints usage and error message. *

*

* Please note that this method does not terminate the program. *

* * @param e * Error thrown by {@link #parseArgs(String[])}. */ void handleError(ArgumentParserException e); } ArgumentParserException.java000066400000000000000000000054361240010205600336040ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/inf/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.inf; import net.sourceforge.argparse4j.helper.TextHelper; /** * The exception thrown from {@link ArgumentParser#parseArgs(String[])} if error * occurred while processing command line argument. The argument {@code parser} * in constructor is the ArgumentParser object where an error occurred. * */ public class ArgumentParserException extends Exception { /** * */ private static final long serialVersionUID = 1L; private transient ArgumentParser parser_; public ArgumentParserException(ArgumentParser parser) { super(); parser_ = parser; } public ArgumentParserException(String message, ArgumentParser parser) { super(message); parser_ = parser; } public ArgumentParserException(String message, Throwable cause, ArgumentParser parser) { super(message, cause); parser_ = parser; } public ArgumentParserException(Throwable cause, ArgumentParser parser) { super(cause); parser_ = parser; } public ArgumentParserException(String message, ArgumentParser parser, Argument arg) { super(formatMessage(message, arg)); parser_ = parser; } public ArgumentParserException(String message, Throwable cause, ArgumentParser parser, Argument arg) { super(formatMessage(message, arg), cause); parser_ = parser; } private static String formatMessage(String message, Argument arg) { return String.format(TextHelper.LOCALE_ROOT, "argument %s: %s", arg.textualName(), message); } public ArgumentParser getParser() { return parser_; } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/inf/ArgumentType.java000066400000000000000000000041501240010205600314610ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.inf; /** * This interface defines type conversion method. * * @param * Type this object convert to. */ public interface ArgumentType { /** *

* Converts {@code value} to appropriate type. *

*

* If the objects derived from {@link RuntimeException} are thrown in * conversion because of invalid input from command line, subclass must * catch these exceptions and wrap them in {@link ArgumentParserException} * and give simple error message to explain what happened briefly. *

* * @param parser * The aprser. * @param arg * The argument this type attached to. * @param value * The attribute value. * @return Converted object. * @throws ArgumentParserException * If conversion fails. */ T convert(ArgumentParser parser, Argument arg, String value) throws ArgumentParserException; } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/inf/FeatureControl.java000066400000000000000000000024311240010205600317710ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.inf; /** * This enum defines constants to be used throughout the argparse4j package. * */ public enum FeatureControl { SUPPRESS } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/inf/MutuallyExclusiveGroup.java000066400000000000000000000043441240010205600335630ustar00rootroot00000000000000/* * Copyright (C) 2012 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.inf; public interface MutuallyExclusiveGroup { /** * Sets description to customize help message of this group. * * @param description * The description of this group. * @return this */ MutuallyExclusiveGroup description(String description); /** *

* Creates new {@link Argument} and adds it to the underlining parser and * returns it. *

*

* See {@link ArgumentParser#addArgument(String...)} for details. *

* * @param nameOrFlags * A name or a list of option strings of new {@link Argument}. * @return {@link Argument} object. */ Argument addArgument(String... nameOrFlags); /** *

* If {@code true} is given, one of the arguments in this group must be * specified otherwise error will be issued. *

*

* The default value is {@code false}. *

* * @param required * {@code true} or {@code false} * @return this */ MutuallyExclusiveGroup required(boolean required); } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/inf/Namespace.java000066400000000000000000000145151240010205600307370ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.inf; import java.util.List; import java.util.Map; /** *

* This class holds attributes added by * {@link ArgumentParser#parseArgs(String[])}. *

*

* It is just a wrapper of {@link Map} object which stores actual attributes. * {@link Map} object can be retrieved using {@link #getAttrs()}. This class * provides several shortcut methods to get attribute values. * {@link #toString()} provides nice textual representation of stored * attributes. *

* */ public class Namespace { private Map attrs_; /** * Construct this object using given {@code attrs}. * * @param attrs * The attributes */ public Namespace(Map attrs) { attrs_ = attrs; } /** * Returns attribute with given attribute name {@code dest}. * * @param dest * The attribute name * @return The attribute value, or {@code null} if it is not found. */ @SuppressWarnings("unchecked") public T get(String dest) { return (T) attrs_.get(dest); } /** * Returns attribute as {@link String} with given attribute name * {@code dest}. This method calls {@link Object#toString()} method of a * found object to get string representation unless object is {@code null}. * * @param dest * The attribute name * @return The attribute value casted to {@link String}, or {@code null} if * is not found. */ public String getString(String dest) { Object o = get(dest); if(o == null) { return null; } return o.toString(); } /** * Returns attribute as {@link Byte} with given attribute name {@code dest}. * * @param dest * The attribute name * @return The attribute value casted to {@link Byte}, or {@code null} if it * is not found. */ public Byte getByte(String dest) { return get(dest); } /** * Returns attribute as {@link Short} with given attribute name {@code dest} * . * * @param dest * The attribute name * @return The attribute value casted to {@link Short}, or {@code null} if * it is not found. */ public Short getShort(String dest) { return get(dest); } /** * Returns attribute as {@link Integer} with given attribute name * {@code dest}. * * @param dest * The attribute name * @return The attribute value casted to {@link Integer}, or {@code null} if * it is not found. */ public Integer getInt(String dest) { return get(dest); } /** * Returns attribute as {@link Long} with given attribute name {@code dest}. * * @param dest * The attribute name * @return The attribute value casted to {@link Long}, or {@code null} if it * is not found. */ public Long getLong(String dest) { return get(dest); } /** * Returns attribute as {@link Float} with given attribute name {@code dest} * . * * @param dest * The attribute name * @return The attribute value casted to {@link Float}, or {@code null} if * it is not found. */ public Float getFloat(String dest) { return get(dest); } /** * Returns attribute as {@link Double} with given attribute name * {@code dest}. * * @param dest * The attribute name * @return The attribute value casted to {@link Double}, or {@code null} if * it is not found. */ public Double getDouble(String dest) { return get(dest); } /** * Returns attribute as {@link Boolean} with given attribute name * {@code dest}. * * @param dest * The attribute name * @return The attribute value casted to {@link Boolean}, or {@code null} if * it is not found. */ public Boolean getBoolean(String dest) { return get(dest); } /** * Returns attribute as {@link List} with given attribute name {@code dest}. * * @param dest * The attribute name * @return The attribute value casted to {@link List}, or {@code null} if it * is not found. */ public List getList(String dest) { return get(dest); } /** *

* Returns {@link Map} object holding attribute values. *

*

* The application code can freely use returned object. *

* * @return {@link Map} object holding attribute values. */ public Map getAttrs() { return attrs_; } @Override public String toString() { StringBuilder sb = new StringBuilder(getClass().getSimpleName()) .append("("); for (Map.Entry entry : attrs_.entrySet()) { sb.append(entry.getKey()).append("=").append(entry.getValue()) .append(", "); } if (!attrs_.isEmpty()) { sb.delete(sb.length() - 2, sb.length()); } return sb.append(")").toString(); } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/inf/Subparser.java000066400000000000000000000042711240010205600310070ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.inf; import java.util.Map; /** *

* This interface defines Subparser used to add sub-command to * {@link ArgumentParser}. *

*/ public interface Subparser extends ArgumentParser { @Override Subparser description(String description); @Override Subparser epilog(String epilog); @Override Subparser version(String version); @Override Subparser defaultHelp(boolean defaultHelp); @Override Subparser setDefault(String dest, Object value); @Override Subparser setDefaults(Map attrs); /** * Sets the text to display in help message. * * @param help * The text to display in help message. * @return this */ Subparser help(String help); /** * Sets alias names for this Subparser. The alias names must be unique for * each {@link Subparsers} instance which this object belongs to. * * @param alias * Alias name for this Subparser. * @return this */ Subparser aliases(String... alias); } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/inf/Subparsers.java000066400000000000000000000122031240010205600311640ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.inf; import net.sourceforge.argparse4j.ArgumentParsers; /** *

* This interface defines Subparsers which used to add {@link Subparser}. *

*

* {@link Subparser} is used to add sub-command to {@link ArgumentParser}. *

* */ public interface Subparsers { /** *

* Adds and returns {@link Subparser} object with given sub-command name. * The given command must be unique for each Subparsers instance. *

*

* The prefixChars is inherited from main ArgumentParser. *

* * @param command * Sub-command name * @return {@link Subparser} object. */ Subparser addParser(String command); /** *

* Adds and returns {@link Subparser} object with given sub-command name and * addHelp. The given command must be unique for each Subparsers instance. *

*

* For {@code addHelp}, see * {@link ArgumentParsers#newArgumentParser(String, boolean, String)}. The * prefixChars is inherited from main ArgumentParser. *

* * @param command * Sub-command name * @param addHelp * If true, {@code -h/--help} are available. If false, they are * not. * @return {@link Subparser} object */ Subparser addParser(String command, boolean addHelp); /** *

* Adds and returns {@link Subparser} object with given sub-command name, * addHelp and prefixChars. The given command must be unique for each * Subparsers instance. *

*

* For {@code addHelp}, see * {@link ArgumentParsers#newArgumentParser(String, boolean, String)}. *

* * @param command * Sub-command name * @param addHelp * If true, {@code -h/--help} are available. If false, they are * not. * @param prefixChars * The set of characters that prefix optional arguments. * @return {@link Subparser} object */ Subparser addParser(String command, boolean addHelp, String prefixChars); /** * Sets the name of attribute which the selected command name is stored. * * @param dest * The name of attribute the selected command name is stored. * @return this. */ Subparsers dest(String dest); /** * Sets the text to display in the help message for sub-commands. * * @param help * The text to display in the help message. * @return this */ Subparsers help(String help); /** *

* Sets the text to display as a title of sub-commands in the help message. *

*

* If either title or description({@link #description(String)}) is * specified, sub-command help will be displayed in its own group. *

* * @param title * The text to display as a title of sub-commands * @return this */ Subparsers title(String title); /** *

* Sets the text to display to briefly describe sub-commands in the help * message. *

*

* If either description or title({@link #title(String)}) is specified, * sub-command help will be displayed in its own group. *

* * @param description * The text to display to briefly describe sub-commands * @return this */ Subparsers description(String description); /** *

* Sets the text used to represent sub-commands in help messages. *

*

* By default, text to represent sub-commands are concatenation of all * sub-commands. This method can override this default behavior and sets * arbitrary string to use. This is useful if there are many sub-commands * and you don't want to show them all. *

* * @param metavar * The text used to represent sub-commands in help messages * @return this */ Subparsers metavar(String metavar); } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/internal/000077500000000000000000000000001240010205600272325ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/internal/ArgumentGroupImpl.java000066400000000000000000000102241240010205600335150ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.internal; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import net.sourceforge.argparse4j.helper.TextHelper; import net.sourceforge.argparse4j.inf.ArgumentGroup; import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup; /** * The application code must not use this class directly. * * This class implements both mutually exclusive group and just a conceptual * group. */ public final class ArgumentGroupImpl implements ArgumentGroup, MutuallyExclusiveGroup { /** * Index in {@link ArgumentParserImpl}. */ private int index_; private String title_ = ""; private String description_ = ""; private ArgumentParserImpl argumentParser_; private List args_ = new ArrayList(); /** * true if this is a mutually exclusive group. */ private boolean mutex_ = false; /** * true if one of the arguments in this group must be specified. */ private boolean required_ = false; public ArgumentGroupImpl(ArgumentParserImpl argumentParser, String title) { argumentParser_ = argumentParser; title_ = TextHelper.nonNull(title); } @Override public ArgumentGroupImpl description(String description) { description_ = TextHelper.nonNull(description); return this; } @Override public ArgumentImpl addArgument(String... nameOrFlags) { ArgumentImpl arg = argumentParser_.addArgument(this, nameOrFlags); args_.add(arg); return arg; } @Override public ArgumentGroupImpl required(boolean required) { required_ = required; return this; } public void printHelp(PrintWriter writer, int format_width) { if (!title_.isEmpty()) { writer.print(title_); writer.println(":"); } if (!description_.isEmpty()) { writer.print(" "); writer.println(TextHelper.wrap( argumentParser_.getTextWidthCounter(), description_, format_width, 2, "", " ")); writer.println(); } for (ArgumentImpl arg : args_) { arg.printHelp(writer, argumentParser_.isDefaultHelp(), argumentParser_.getTextWidthCounter(), format_width); } } public int getIndex() { return index_; } public void setIndex(int index) { index_ = index; } public boolean isMutex() { return mutex_; } public void setMutex(boolean mutex) { mutex_ = mutex; } public boolean isRequired() { return required_; } public List getArgs() { return args_; } /** * Returns true if the help message for this group should be in separate * group. * * @return true if the help message for this group should be in separate * group. */ public boolean isSeparateHelp() { return !mutex_ || !title_.isEmpty() || !description_.isEmpty(); } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/internal/ArgumentImpl.java000066400000000000000000000412021240010205600325000ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.internal; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Map; import net.sourceforge.argparse4j.ArgumentParsers; import net.sourceforge.argparse4j.helper.PrefixPattern; import net.sourceforge.argparse4j.helper.TextHelper; import net.sourceforge.argparse4j.helper.TextWidthCounter; import net.sourceforge.argparse4j.impl.Arguments; import net.sourceforge.argparse4j.impl.choice.CollectionArgumentChoice; import net.sourceforge.argparse4j.impl.type.ReflectArgumentType; import net.sourceforge.argparse4j.impl.type.StringArgumentType; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentAction; import net.sourceforge.argparse4j.inf.ArgumentChoice; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.ArgumentType; import net.sourceforge.argparse4j.inf.FeatureControl; /** * The application code must not use this class directly. * */ public final class ArgumentImpl implements Argument { private String name_; private String flags_[]; private String dest_; private ArgumentType type_ = new StringArgumentType(); private ArgumentAction action_ = Arguments.store(); private ArgumentChoice choice_; private Object const_; private Object default_; private FeatureControl defaultControl_; private FeatureControl helpControl_; private boolean required_; private String metavar_[]; private int minNumArg_ = -1; private int maxNumArg_ = -1; private String help_ = ""; private ArgumentGroupImpl argumentGroup_; public ArgumentImpl(PrefixPattern prefixPattern, String... nameOrFlags) { this(prefixPattern, null, nameOrFlags); } public ArgumentImpl(PrefixPattern prefixPattern, ArgumentGroupImpl argumentGroup, String... nameOrFlags) { if (nameOrFlags.length == 0) { throw new IllegalArgumentException("no nameOrFlags was specified"); } argumentGroup_ = argumentGroup; if (nameOrFlags.length == 1 && !prefixPattern.match(nameOrFlags[0])) { if (argumentGroup_ != null && argumentGroup_.isMutex()) { throw new IllegalArgumentException( "mutually exclusive arguments must be optional"); } name_ = nameOrFlags[0]; dest_ = name_; } else { flags_ = nameOrFlags; for (String flag : flags_) { if (!prefixPattern.match(flag)) { throw new IllegalArgumentException( String.format( TextHelper.LOCALE_ROOT, "invalid option string '%s': must start with a character '%s'", flag, prefixPattern.getPrefixChars())); } } for (String flag : flags_) { boolean longflag = prefixPattern.matchLongFlag(flag); if (dest_ == null) { dest_ = flag; if (longflag) { break; } } else if (longflag) { dest_ = flag; break; } } dest_ = prefixPattern.removePrefix(dest_).replace('-', '_'); } } @Override public String textualName() { if (name_ == null) { return TextHelper.concat(flags_, 0, "/"); } else { return name_; } } /** * Short syntax is used in usage message, e.g. --foo BAR * * @return short syntax */ public String formatShortSyntax() { if (name_ == null) { StringBuilder sb = new StringBuilder(); if (!required_) { sb.append("["); } sb.append(flags_[0]); String mv = formatMetavar(); if (!mv.isEmpty()) { sb.append(" ").append(mv); } if (!required_) { sb.append("]"); } return sb.toString(); } else { return formatMetavar(); } } /** * Short syntax is used in usage message, e.g. --foo BAR, but without * bracket when this is not required option. * * @return short syntax */ public String formatShortSyntaxNoBracket() { if (name_ == null) { StringBuilder sb = new StringBuilder(); sb.append(flags_[0]); String mv = formatMetavar(); if (!mv.isEmpty()) { sb.append(" ").append(mv); } return sb.toString(); } else { return formatMetavar(); } } public String[] resolveMetavar() { if (metavar_ == null) { String[] metavar = new String[1]; if (choice_ == null) { metavar[0] = isOptionalArgument() ? dest_.toUpperCase() : dest_; } else { metavar[0] = choice_.textualFormat(); } return metavar; } else { return metavar_; } } public String formatMetavar() { StringBuilder sb = new StringBuilder(); if (action_.consumeArgument()) { String[] metavar = resolveMetavar(); if (minNumArg_ == 0 && maxNumArg_ == 1) { sb.append("[").append(metavar[0]).append("]"); } else if (minNumArg_ == 0 && maxNumArg_ == Integer.MAX_VALUE) { sb.append("[").append(metavar[0]).append(" [") .append(metavar.length == 1 ? metavar[0] : metavar[1]) .append(" ...]]"); } else if (minNumArg_ == 1 && maxNumArg_ == Integer.MAX_VALUE) { sb.append(metavar[0]).append(" [") .append(metavar.length == 1 ? metavar[0] : metavar[1]) .append(" ...]"); } else if (minNumArg_ == -1) { sb.append(metavar[0]); } else if (minNumArg_ > 0 && minNumArg_ == maxNumArg_) { int i, max; for (i = 0, max = Math.min(minNumArg_, metavar.length); i < max; ++i) { sb.append(metavar[i]).append(" "); } for (; i < minNumArg_; ++i) { sb.append(metavar[metavar.length - 1]).append(" "); } sb.delete(sb.length() - 1, sb.length()); } } return sb.toString(); } private String formatHelpTitle() { if (isOptionalArgument()) { String mv = formatMetavar(); StringBuilder sb = new StringBuilder(); if(ArgumentParsers.isSingleMetavar()) { for (String flag : flags_) { if(sb.length() > 0) { sb.append(", "); } sb.append(flag); } if (!mv.isEmpty()) { sb.append(" ").append(mv); } } else { for (String flag : flags_) { sb.append(flag); if (!mv.isEmpty()) { sb.append(" ").append(mv); } sb.append(", "); } if (sb.length() > 2) { sb.delete(sb.length() - 2, sb.length()); } } return sb.toString(); } else { return resolveMetavar()[0]; } } public void printHelp(PrintWriter writer, boolean defaultHelp, TextWidthCounter textWidthCounter, int width) { if (helpControl_ == Arguments.SUPPRESS) { return; } String help; if (defaultHelp && default_ != null) { StringBuilder sb = new StringBuilder(help_); if (!help_.isEmpty()) { sb.append(" "); } sb.append("(default: ").append(default_.toString()).append(")"); help = sb.toString(); } else { help = help_; } TextHelper.printHelp(writer, formatHelpTitle(), help, textWidthCounter, width); } public Object convert(ArgumentParserImpl parser, String value) throws ArgumentParserException { Object obj = type_.convert(parser, this, value); if (choice_ != null && !choice_.contains(obj)) { throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "invalid choice: '%s' (choose from %s)", value, choice_.textualFormat()), parser, this); } return obj; } @Override public ArgumentImpl nargs(int n) { if (n <= 0) { throw new IllegalArgumentException("nargs must be positive integer"); } minNumArg_ = maxNumArg_ = n; return this; } @Override public ArgumentImpl nargs(String n) { if (n.equals("*")) { minNumArg_ = 0; maxNumArg_ = Integer.MAX_VALUE; } else if (n.equals("+")) { minNumArg_ = 1; maxNumArg_ = Integer.MAX_VALUE; } else if (n.equals("?")) { minNumArg_ = 0; maxNumArg_ = 1; } else { throw new IllegalArgumentException( "narg expects positive integer or one of '*', '+' or '?'"); } return this; } @Override public ArgumentImpl setConst(Object value) { // Allow null const_ = value; return this; } @Override public ArgumentImpl setConst(E... values) { // Allow null const_ = Arrays.asList(values); return this; } @Override public ArgumentImpl setDefault(Object value) { // Allow null default_ = value; return this; } @Override public ArgumentImpl setDefault(E... values) { // Allow null default_ = Arrays.asList(values); return this; } @Override public ArgumentImpl setDefault(FeatureControl ctrl) { defaultControl_ = ctrl; return this; } private ReflectArgumentType createReflectArgumentType(Class type) { return new ReflectArgumentType(type); } @Override public ArgumentImpl type(Class type) { if (type == null) { throw new IllegalArgumentException("type cannot be null"); } if (type.isPrimitive()) { // Convert primitive type class to its object counterpart if (type == boolean.class) { type_ = createReflectArgumentType(Boolean.class); } else if (type == byte.class) { type_ = createReflectArgumentType(Byte.class); } else if (type == short.class) { type_ = createReflectArgumentType(Short.class); } else if (type == int.class) { type_ = createReflectArgumentType(Integer.class); } else if (type == long.class) { type_ = createReflectArgumentType(Long.class); } else if (type == float.class) { type_ = createReflectArgumentType(Float.class); } else if (type == double.class) { type_ = createReflectArgumentType(Double.class); } else { // void and char are not supported. // char.class does not have valueOf(String) method throw new IllegalArgumentException("unexpected primitive type"); } } else { type_ = createReflectArgumentType(type); } return this; } @Override public ArgumentImpl type(ArgumentType type) { if (type == null) { throw new IllegalArgumentException("type cannot be null"); } type_ = type; return this; } @Override public ArgumentImpl required(boolean required) { required_ = required; return this; } @Override public ArgumentImpl action(ArgumentAction action) { if (action == null) { throw new IllegalArgumentException("action cannot be null"); } action_ = action; action_.onAttach(this); return this; } @Override public ArgumentImpl choices(ArgumentChoice choice) { if (choice == null) { throw new IllegalArgumentException("choice cannot be null"); } choice_ = choice; return this; } @Override public ArgumentImpl choices(Collection values) { if (values == null) { throw new IllegalArgumentException("choice cannot be null"); } choice_ = new CollectionArgumentChoice(values); return this; } @Override public ArgumentImpl choices(E... values) { if (values == null) { throw new IllegalArgumentException("choice cannot be null"); } choice_ = new CollectionArgumentChoice(values); return this; } @Override public ArgumentImpl dest(String dest) { if (dest == null) { throw new IllegalArgumentException("dest cannot be null"); } dest_ = dest; return this; } @Override public ArgumentImpl metavar(String... metavar) { if (metavar.length == 0) { throw new IllegalArgumentException("No metavar specified"); } for (String m : metavar) { if (m == null) { throw new IllegalArgumentException("metavar cannot be null"); } } metavar_ = metavar; return this; } @Override public ArgumentImpl help(String help) { help_ = TextHelper.nonNull(help); return this; } @Override public ArgumentImpl help(FeatureControl ctrl) { helpControl_ = ctrl; return this; } public boolean isOptionalArgument() { return name_ == null; } public void run(ArgumentParserImpl parser, Map res, String flag, Object value) throws ArgumentParserException { action_.run(parser, this, res, flag, value); } // Getter methods @Override public String getDest() { return dest_; } @Override public Object getConst() { return const_; } @Override public Object getDefault() { // For positional arguments, we perform special treatment if // they are configured with nargs("*") and default is null. // In this case, return empty list. if (!isOptionalArgument() && default_ == null && maxNumArg_ > 1) { return new ArrayList(); } else { return default_; } } @Override public FeatureControl getDefaultControl() { return defaultControl_; } @Override public FeatureControl getHelpControl() { return helpControl_; } public String getName() { return name_; } public boolean isRequired() { return required_; } public int getMinNumArg() { return minNumArg_; } public int getMaxNumArg() { return maxNumArg_; } public String[] getMetavar() { return metavar_; } public ArgumentGroupImpl getArgumentGroup() { return argumentGroup_; } public ArgumentAction getAction() { return action_; } public String getHelp() { return help_; } public String[] getFlags() { return flags_; } } ArgumentParserImpl.java000066400000000000000000001503231240010205600336030ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/internal/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.internal; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; import net.sourceforge.argparse4j.ArgumentParsers; import net.sourceforge.argparse4j.annotation.Arg; import net.sourceforge.argparse4j.helper.ASCIITextWidthCounter; import net.sourceforge.argparse4j.helper.PrefixPattern; import net.sourceforge.argparse4j.helper.ReflectHelper; import net.sourceforge.argparse4j.helper.TextHelper; import net.sourceforge.argparse4j.helper.TextWidthCounter; import net.sourceforge.argparse4j.impl.Arguments; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentGroup; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup; import net.sourceforge.argparse4j.inf.Namespace; /** * The application code must not use this class directly. * */ public final class ArgumentParserImpl implements ArgumentParser { private Map optargIndex_ = new HashMap(); private List optargs_ = new ArrayList(); private List posargs_ = new ArrayList(); private List arggroups_ = new ArrayList(); private Map defaults_ = new HashMap(); private SubparsersImpl subparsers_ = new SubparsersImpl(this); private ArgumentParserImpl mainParser_; private String command_; private String prog_; private String usage_ = ""; private String description_ = ""; private String epilog_ = ""; private String version_ = ""; private PrefixPattern prefixPattern_; private PrefixPattern fromFilePrefixPattern_; private boolean defaultHelp_ = false; private boolean negNumFlag_ = false; private TextWidthCounter textWidthCounter_; private static final Pattern NEG_NUM_PATTERN = Pattern.compile("-\\d+"); private static final Pattern SHORT_OPTS_PATTERN = Pattern .compile("-[^-].*"); public ArgumentParserImpl(String prog) { this(prog, true, ArgumentParsers.DEFAULT_PREFIX_CHARS, null, new ASCIITextWidthCounter(), null, null); } public ArgumentParserImpl(String prog, boolean addHelp) { this(prog, addHelp, ArgumentParsers.DEFAULT_PREFIX_CHARS, null, new ASCIITextWidthCounter(), null, null); } public ArgumentParserImpl(String prog, boolean addHelp, String prefixChars) { this(prog, addHelp, prefixChars, null, new ASCIITextWidthCounter(), null, null); } public ArgumentParserImpl(String prog, boolean addHelp, String prefixChars, String fromFilePrefix) { this(prog, addHelp, prefixChars, fromFilePrefix, new ASCIITextWidthCounter(), null, null); } public ArgumentParserImpl(String prog, boolean addHelp, String prefixChars, String fromFilePrefix, TextWidthCounter textWidthCounter) { this(prog, addHelp, prefixChars, fromFilePrefix, textWidthCounter, null, null); } public ArgumentParserImpl(String prog, boolean addHelp, String prefixChars, String fromFilePrefix, TextWidthCounter textWidthCounter, String command, ArgumentParserImpl mainParser) { this.prog_ = TextHelper.nonNull(prog); this.command_ = command; this.mainParser_ = mainParser; this.textWidthCounter_ = textWidthCounter; if (prefixChars == null || prefixChars.isEmpty()) { throw new IllegalArgumentException( "prefixChars cannot be a null or empty"); } this.prefixPattern_ = new PrefixPattern(prefixChars); if (fromFilePrefix != null) { this.fromFilePrefixPattern_ = new PrefixPattern(fromFilePrefix); } if (addHelp) { String prefix = prefixChars.substring(0, 1); addArgument(prefix + "h", prefix + prefix + "help") .action(Arguments.help()) .help("show this help message and exit") .setDefault(Arguments.SUPPRESS); } } @Override public ArgumentImpl addArgument(String... nameOrFlags) { return addArgument(null, nameOrFlags); } public ArgumentImpl addArgument(ArgumentGroupImpl group, String... nameOrFlags) { ArgumentImpl arg = new ArgumentImpl(prefixPattern_, group, nameOrFlags); if (arg.isOptionalArgument()) { for (String flag : arg.getFlags()) { ArgumentImpl another = optargIndex_.get(flag); if (another != null) { // TODO No conflict handler ATM throw new IllegalArgumentException(String.format( TextHelper.LOCALE_ROOT, "argument %s: conflicting option string(s): %s", flag, another.textualName())); } } for (String flag : arg.getFlags()) { if (NEG_NUM_PATTERN.matcher(flag).matches()) { negNumFlag_ = true; } optargIndex_.put(flag, arg); } optargs_.add(arg); } else { for (ArgumentImpl another : posargs_) { if (arg.getName().equals(another.getName())) { // TODO No conflict handler ATM throw new IllegalArgumentException(String.format( TextHelper.LOCALE_ROOT, "argument %s: conflicting option string(s): %s", arg.getName(), another.textualName())); } } posargs_.add(arg); } return arg; } @Override public SubparsersImpl addSubparsers() { return subparsers_; } @Override public ArgumentGroup addArgumentGroup(String title) { ArgumentGroupImpl group = new ArgumentGroupImpl(this, title); group.setIndex(arggroups_.size()); arggroups_.add(group); return group; } @Override public MutuallyExclusiveGroup addMutuallyExclusiveGroup() { return addMutuallyExclusiveGroup(""); } @Override public MutuallyExclusiveGroup addMutuallyExclusiveGroup(String title) { ArgumentGroupImpl group = new ArgumentGroupImpl(this, title); group.setIndex(arggroups_.size()); group.setMutex(true); arggroups_.add(group); return group; } @Override public ArgumentParserImpl usage(String usage) { usage_ = TextHelper.nonNull(usage); return this; } /** * Set text to display before the argument help. * * @param description * text to display before the argument help * @return this */ @Override public ArgumentParserImpl description(String description) { description_ = TextHelper.nonNull(description); return this; } @Override public ArgumentParserImpl epilog(String epilog) { epilog_ = TextHelper.nonNull(epilog); return this; } @Override public ArgumentParserImpl version(String version) { version_ = TextHelper.nonNull(version); return this; } @Override public ArgumentParserImpl defaultHelp(boolean defaultHelp) { defaultHelp_ = defaultHelp; return this; } public boolean isDefaultHelp() { return defaultHelp_; } private void printArgumentHelp(PrintWriter writer, List args, int format_width) { for (ArgumentImpl arg : args) { if (arg.getArgumentGroup() == null || !arg.getArgumentGroup().isSeparateHelp()) { arg.printHelp(writer, defaultHelp_, textWidthCounter_, format_width); } } } @Override public void printHelp() { PrintWriter writer = new PrintWriter(System.out); printHelp(writer); writer.flush(); } @Override public void printHelp(PrintWriter writer) { int formatWidth = ArgumentParsers.getFormatWidth(); printUsage(writer, formatWidth); if (!description_.isEmpty()) { writer.println(); writer.println(TextHelper.wrap(textWidthCounter_, description_, formatWidth, 0, "", "")); } boolean subparsersUntitled = subparsers_.getTitle().isEmpty() && subparsers_.getDescription().isEmpty(); if (checkDefaultGroup(posargs_) || (subparsers_.hasSubCommand() && subparsersUntitled)) { writer.println(); writer.println("positional arguments:"); printArgumentHelp(writer, posargs_, formatWidth); if (subparsers_.hasSubCommand() && subparsersUntitled) { subparsers_.printSubparserHelp(writer, formatWidth); } } if (checkDefaultGroup(optargs_)) { writer.println(); writer.println("optional arguments:"); printArgumentHelp(writer, optargs_, formatWidth); } if (subparsers_.hasSubCommand() && !subparsersUntitled) { writer.println(); writer.print(subparsers_.getTitle().isEmpty() ? "subcommands" : subparsers_.getTitle()); writer.println(":"); if (!subparsers_.getDescription().isEmpty()) { writer.print(" "); writer.println(TextHelper.wrap(textWidthCounter_, subparsers_.getDescription(), formatWidth, 2, "", " ")); writer.println(); } subparsers_.printSubparserHelp(writer, formatWidth); } for (ArgumentGroupImpl group : arggroups_) { if (group.isSeparateHelp()) { writer.println(); group.printHelp(writer, formatWidth); } } if (!epilog_.isEmpty()) { writer.println(); writer.println(TextHelper.wrap(textWidthCounter_, epilog_, formatWidth, 0, "", "")); } } private boolean checkDefaultGroup(List args) { if (args.isEmpty()) { return false; } for (ArgumentImpl arg : args) { if (arg.getArgumentGroup() == null || !arg.getArgumentGroup().isSeparateHelp()) { return true; } } return false; } @Override public String formatHelp() { StringWriter writer = new StringWriter(); printHelp(new PrintWriter(writer)); return writer.toString(); } private void printArgumentUsage(PrintWriter writer, List opts, int offset, String firstIndent, String subsequentIndent, int format_width) { int currentWidth = offset + firstIndent.length(); writer.print(firstIndent); boolean first = true; for (String syntax : opts) { if (!first && currentWidth + syntax.length() + 1 > format_width) { writer.println(); writer.print(subsequentIndent); writer.print(" "); writer.print(syntax); currentWidth = subsequentIndent.length() + 1 + syntax.length(); } else { writer.print(" "); writer.print(syntax); currentWidth += 1 + syntax.length(); first = false; } } writer.println(); } @Override public void printUsage() { PrintWriter writer = new PrintWriter(System.out); printUsage(writer); writer.flush(); } @Override public void printUsage(PrintWriter writer) { printUsage(writer, ArgumentParsers.getFormatWidth()); } private void printUsage(PrintWriter writer, int format_width) { if (!usage_.isEmpty()) { writer.print("usage: "); writer.println(substitutePlaceholder(usage_)); return; } String usageprog = "usage: " + prog_; writer.print(usageprog); int offset; String firstIndent; String subsequentIndent; String indent = " "; int usageprogWidth = textWidthCounter_.width(usageprog); if (usageprogWidth > indent.length()) { writer.println(); offset = 6; firstIndent = subsequentIndent = indent.substring(0, offset); } else { offset = usageprogWidth; firstIndent = ""; subsequentIndent = indent.substring(0, offset); } List opts = new ArrayList(); addUpperParserUsage(opts, mainParser_); if (command_ != null) { opts.add(command_); } for (ArgumentImpl arg : optargs_) { if (arg.getHelpControl() != Arguments.SUPPRESS && (arg.getArgumentGroup() == null || !arg .getArgumentGroup().isMutex())) { opts.add(arg.formatShortSyntax()); } } for (ArgumentGroupImpl group : arggroups_) { List args = filterSuppressedArgs(group.getArgs()); int numArgs = args.size(); if (group.isMutex()) { if (numArgs > 1) { opts.add((group.isRequired() ? "(" : "[") + args.get(0).formatShortSyntaxNoBracket()); for (int i = 1; i < numArgs - 1; ++i) { ArgumentImpl arg = args.get(i); opts.add("|"); opts.add(arg.formatShortSyntaxNoBracket()); } opts.add("|"); opts.add(args.get(numArgs - 1).formatShortSyntaxNoBracket() + (group.isRequired() ? ")" : "]")); } else if (numArgs == 1) { if (group.isRequired()) { opts.add(args.get(0).formatShortSyntaxNoBracket()); } else { opts.add(args.get(0).formatShortSyntax()); } } } } for (ArgumentImpl arg : posargs_) { if (arg.getHelpControl() != Arguments.SUPPRESS) { opts.add(arg.formatShortSyntax()); } } if (subparsers_.hasSubCommand()) { opts.add(subparsers_.formatShortSyntax()); opts.add("..."); } printArgumentUsage(writer, opts, offset, firstIndent, subsequentIndent, format_width); } /** * Returns arguments in {@code args} whose {@link Argument#getHelpControl()} * do not return {@link Arguments#SUPPRESS}. * * @param args * @return filtered list of arguments */ private static List filterSuppressedArgs( Collection args) { ArrayList res = new ArrayList(); for (ArgumentImpl arg : args) { if (arg.getHelpControl() != Arguments.SUPPRESS) { res.add(arg); } } return res; } /** * Appends command, required optional arguments and positional arguments in * {@code parser} to {@code opts} recursively. Most upper parser stores * first, just like post order traversal. * * @param opts * Command, required optional arguments and positional arguments. * @param parser * The parser */ private void addUpperParserUsage(List opts, ArgumentParserImpl parser) { if (parser == null) { return; } addUpperParserUsage(opts, parser.mainParser_); if (parser.command_ != null) { opts.add(parser.command_); } for (ArgumentImpl arg : parser.optargs_) { if (arg.getHelpControl() != Arguments.SUPPRESS && arg.isRequired() && (arg.getArgumentGroup() == null || !arg .getArgumentGroup().isMutex())) { opts.add(arg.formatShortSyntax()); } } for (ArgumentGroupImpl group : parser.arggroups_) { List args = filterSuppressedArgs(group.getArgs()); int numArgs = args.size(); if (group.isMutex()) { if (numArgs > 1) { if (group.isRequired()) { opts.add("(" + args.get(0).formatShortSyntaxNoBracket()); for (int i = 1; i < numArgs - 1; ++i) { ArgumentImpl arg = args.get(i); opts.add("|"); opts.add(arg.formatShortSyntaxNoBracket()); } opts.add("|"); opts.add(args.get(numArgs - 1) .formatShortSyntaxNoBracket() + ")"); } } else if (numArgs == 1) { if (group.isRequired()) { opts.add(args.get(0).formatShortSyntaxNoBracket()); } else if (args.get(0).isRequired()) { opts.add(args.get(0).formatShortSyntax()); } } } } for (ArgumentImpl arg : parser.posargs_) { if (arg.getHelpControl() != Arguments.SUPPRESS) { opts.add(arg.formatShortSyntax()); } } } @Override public String formatUsage() { StringWriter writer = new StringWriter(); printUsage(new PrintWriter(writer)); return writer.toString(); } @Override public ArgumentParserImpl setDefault(String dest, Object value) { defaults_.put(dest, value); return this; } @Override public ArgumentParserImpl setDefaults(Map attrs) { defaults_.putAll(attrs); return this; } /** * Returns default value set by {@link ArgumentImpl#setDefault(Object)} or * {@link ArgumentParserImpl#setDefault(String, Object)}. Please note that * while parser-level defaults always override argument-level defaults while * parsing, this method examines argument-level defaults first. If no * default value is found, then check parser-level defaults. * * @param dest * attribute name of default value to get. * @return default value of given dest. */ @Override public Object getDefault(String dest) { for (ArgumentImpl arg : optargs_) { if (dest.equals(arg.getDest()) && arg.getDefault() != null) { return arg.getDefault(); } } for (ArgumentImpl arg : posargs_) { if (dest.equals(arg.getDest()) && arg.getDefault() != null) { return arg.getDefault(); } } return defaults_.get(dest); } @Override public Namespace parseArgsOrFail(String args[]) { try { Namespace ns = parseArgs(args); return ns; } catch (ArgumentParserException e) { handleError(e); System.exit(1); } return null; } @Override public Namespace parseArgs(String args[]) throws ArgumentParserException { Map attrs = new HashMap(); parseArgs(args, attrs); return new Namespace(attrs); } @Override public void parseArgs(String[] args, Map attrs) throws ArgumentParserException { parseArgs(args, 0, attrs); } @Override public void parseArgs(String[] args, Object userData) throws ArgumentParserException { Map opts = new HashMap(); parseArgs(args, opts, userData); } @Override public void parseArgs(String[] args, Map attrs, Object userData) throws ArgumentParserException { parseArgs(args, 0, attrs); Class userClass = userData.getClass(); while (userClass != null) { for (final Field field : userClass.getDeclaredFields()) { Arg ann = field.getAnnotation(Arg.class); if (ann != null) { String argDest = ann.dest(); if (argDest.isEmpty()) { argDest = field.getName(); } if (!attrs.containsKey(argDest)) { continue; } Object val = attrs.get(argDest); try { AccessController .doPrivileged(new PrivilegedAction() { @Override public Void run() { field.setAccessible(true); return null; } }); field.set(userData, ReflectHelper.list2Array(field.getType(), val)); } catch (RuntimeException e) { if (!ann.ignoreError()) { throw e; } } catch (Exception e) { if (!ann.ignoreError()) { throw new IllegalArgumentException(String.format( TextHelper.LOCALE_ROOT, "Could not set %s to field %s", val, field.getName()), e); } } } } for (final Method method : userClass.getDeclaredMethods()) { Arg ann = method.getAnnotation(Arg.class); if (ann != null) { String argDest = ann.dest(); if (argDest.isEmpty()) { argDest = method.getName(); } if (!attrs.containsKey(argDest)) { continue; } Object val = attrs.get(argDest); Class[] fargs = method.getParameterTypes(); if (fargs.length != 1) { throw new IllegalArgumentException(String.format( TextHelper.LOCALE_ROOT, "Method %s must have one formal parameter", method.getName())); } try { AccessController .doPrivileged(new PrivilegedAction() { @Override public Void run() { method.setAccessible(true); return null; } }); method.invoke(userData, ReflectHelper.list2Array(fargs[0], val)); } catch (RuntimeException e) { if (!ann.ignoreError()) { throw e; } } catch (Exception e) { if (!ann.ignoreError()) { throw new IllegalArgumentException(String.format( TextHelper.LOCALE_ROOT, "Could not call method %s with %s", method.getName(), val), e); } } } } userClass = userClass.getSuperclass(); } } public void parseArgs(String args[], int offset, Map attrs) throws ArgumentParserException { ParseState state = new ParseState(args, offset, negNumFlag_); parseArgs(state, attrs); if (state.deferredException != null) { throw state.deferredException; } } /** * Check that term forms a valid concatenated short options. Note that this * option does not actually process arguments. Therefore, true from this * function does not mean all arguments in term are acceptable. * * @param term * string to inspect * @return true if term forms a valid concatenated short options. */ private boolean checkConcatenatedShortOpts(String term) { if (SHORT_OPTS_PATTERN.matcher(term).matches()) { for (int i = 1, termlen = term.length(); i < termlen; ++i) { String shortFlag = "-" + term.charAt(i); ArgumentImpl arg = optargIndex_.get(shortFlag); if (arg == null) { return false; } if (arg.getAction().consumeArgument()) { return true; } } return true; } else { return false; } } /** * Returns optional argument ArgumentImpl which matches given flag. This * function handles abbreviation as well. If flag is ambiguous, * {@link ArgumentParserException} will be thrown. If flag does not match * nay ArgumentImpl, this function returns null. * * @param flag * flag to match * @return ArgumentImpl which matches flag if it succeeds, or null * @throws ArgumentParserException * if flag is ambiguous */ private ArgumentImpl resolveNextFlag(String flag) throws ArgumentParserException { ArgumentImpl arg = optargIndex_.get(flag); if (arg != null) { return arg; } List cand = TextHelper.findPrefix(optargIndex_.keySet(), flag); if (cand.isEmpty()) { return null; } else if (checkConcatenatedShortOpts(flag)) { // Get first short option cand.add(flag.substring(0, 2)); } else if (cand.size() == 1) { return optargIndex_.get(cand.get(0)); } // At this point, more than 1 flags were found from optargIndex_ // and/or flag forms concatenated short options. // Sort in order to make unit test easier. Collections.sort(cand); throw new ArgumentParserException(String.format(TextHelper.LOCALE_ROOT, "ambiguous option: %s could match %s", flag, TextHelper.concat(cand, 0, ", ")), this); } public void parseArgs(ParseState state, Map attrs) throws ArgumentParserException { populateDefaults(attrs); Set used = new HashSet(); ArgumentImpl[] groupUsed = new ArgumentImpl[arggroups_.size()]; int posargIndex = 0; int posargsLen = posargs_.size(); while (state.isArgAvail()) { // We first evaluate flagFound(state) before comparing arg to "--" // in order to expand arguments from file. if (flagFound(state) && !"--".equals(state.getArg())) { String term = state.getArg(); int p = term.indexOf("="); String flag; String embeddedValue; if (p == -1) { flag = term; embeddedValue = null; } else { flag = term.substring(0, p); embeddedValue = term.substring(p + 1); } ArgumentImpl arg = resolveNextFlag(flag); if (arg == null) { // Assign null for clarity embeddedValue = null; boolean shortOptsFound = false; if (SHORT_OPTS_PATTERN.matcher(term).matches()) { shortOptsFound = true; // Possible concatenated short options for (int i = 1, termlen = term.length(); i < termlen; ++i) { String shortFlag = "-" + term.charAt(i); arg = optargIndex_.get(shortFlag); if (arg == null) { shortOptsFound = false; break; } if (arg.getAction().consumeArgument()) { flag = shortFlag; shortOptsFound = true; if (term.length() > i + 1) { embeddedValue = term.substring(i + 1); } break; } checkMutex(arg, groupUsed); arg.run(this, attrs, shortFlag, null); used.add(arg); // Set null to avoid using it twice. arg = null; } } if (!shortOptsFound) { throw new UnrecognizedArgumentException( formatUnrecognizedArgumentErrorMessage(state, term), this, term); } } ++state.index; if (arg != null) { checkMutex(arg, groupUsed); processArg(attrs, state, arg, flag, embeddedValue); used.add(arg); } } else if ("--".equals(state.getArg()) && !state.consumedSeparator) { state.consumedSeparator = true; state.negNumFlag = false; ++state.index; } else if (posargIndex < posargsLen) { ArgumentImpl arg = posargs_.get(posargIndex++); processArg(attrs, state, arg, null, null); } else if (!state.consumedSeparator && subparsers_.hasSubCommand()) { checkRequiredArgument(state, used, posargIndex); checkRequiredMutex(state, groupUsed); subparsers_.parseArg(state, attrs); return; } else { throw new ArgumentParserException( formatUnrecognizedArgumentErrorMessage(state, TextHelper.concat(state.args, state.index, " ")), this); } } if (subparsers_.hasSubCommand()) { throw new ArgumentParserException("too few arguments", this); } while (posargIndex < posargsLen) { ArgumentImpl arg = posargs_.get(posargIndex++); processArg(attrs, state, arg, null, null); } checkRequiredArgument(state, used, posargIndex); checkRequiredMutex(state, groupUsed); } /** * Format message for "Unrecognized arguments" error. * * @param state * Current parser state * @param args * Textual representation of unrecognized arguments to be * included in the message as is. * @return formatted error message */ private String formatUnrecognizedArgumentErrorMessage(ParseState state, String args) { return String .format(TextHelper.LOCALE_ROOT, "unrecognized arguments: '%s'%s", args, state.index > state.lastFromFileArgIndex ? "" : String.format( TextHelper.LOCALE_ROOT, "%nChecking trailing white spaces or new lines in %sfile may help.", fromFilePrefixPattern_.getPrefixChars() .length() == 1 ? fromFilePrefixPattern_ .getPrefixChars() : "[" + fromFilePrefixPattern_ .getPrefixChars() + "]")); } /** * Check that another option in mutually exclusive group has already been * specified. If so, throw an exception. * * @param arg * The argument currently processed * @param groupUsed * The cache of used argument in each groups. * @throws ArgumentParserException * If another option in mutually exclusive group has already * been used. */ private void checkMutex(ArgumentImpl arg, ArgumentImpl[] groupUsed) throws ArgumentParserException { if (arg.getArgumentGroup() != null) { if (arg.getArgumentGroup().isMutex()) { ArgumentImpl usedMutexArg = groupUsed[arg.getArgumentGroup() .getIndex()]; if (usedMutexArg == null) { groupUsed[arg.getArgumentGroup().getIndex()] = arg; } else if (usedMutexArg != arg) { throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "not allowed with argument %s", usedMutexArg.textualName()), this, arg); } } } } /** * @param res * @param state * state.offset points to the argument next to flag * @param arg * @param flag * @param embeddedValue * If optional argument is given as "foo=bar" or "-fbar" (short * option), embedded value is "bar". Otherwise {@code null} * @throws ArgumentParserException */ private void processArg(Map res, ParseState state, ArgumentImpl arg, String flag, String embeddedValue) throws ArgumentParserException { if (!arg.getAction().consumeArgument()) { if (embeddedValue == null) { arg.run(this, res, flag, null); return; } else { throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "ignore implicit argument '%s'", embeddedValue), this, arg); } } if (arg.getMinNumArg() == -1 || (arg.getMinNumArg() == 0 && arg.getMaxNumArg() == 1)) { // In case of: option takes exactly one argument, or nargs("?") String argval = null; if (embeddedValue == null) { if (state.isArgAvail() && !flagFound(state)) { argval = state.getArg(); ++state.index; } } else { argval = embeddedValue; } if (argval == null) { if (arg.getMinNumArg() == -1) { if (arg.isOptionalArgument()) { throw new ArgumentParserException( "expected one argument", this, arg); } else { throw new ArgumentParserException("too few arguments", this); } } else if (arg.isOptionalArgument()) { // This is a special treatment for nargs("?"). If flag is // given but no argument follows, produce const value. arg.run(this, res, flag, arg.getConst()); } } else { arg.run(this, res, flag, arg.convert(this, argval)); } } else { List list = new ArrayList(); if (embeddedValue == null) { for (int i = 0; i < arg.getMaxNumArg() && state.isArgAvail(); ++i, ++state.index) { if (flagFound(state)) { break; } list.add(arg.convert(this, state.getArg())); } } else { list.add(arg.convert(this, embeddedValue)); } if (list.size() < arg.getMinNumArg()) { if (arg.isOptionalArgument()) { throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "expected %d argument(s)", arg.getMinNumArg()), this, arg); } else { throw new ArgumentParserException("too few arguments", this); } } // For optional arguments, always process the list even if it is // empty. // For positional arguments, empty list means no positional argument // is given. In this case, we want to keep default value, so // don't process the list. if (arg.isOptionalArgument() || !list.isEmpty()) { arg.run(this, res, flag, list); } } } /** * Returns true if state.getArg() is flag. Note that if "--" is met and not * consumed, this function returns true, because "--" is treated as special * optional argument. If prefixFileChar is found in prefix of argument, read * arguments from that file and expand arguments in state necessary. * * @param state * @return * @throws ArgumentParserException */ private boolean flagFound(ParseState state) throws ArgumentParserException { while (fromFileFound(state)) { extendArgs(state, fromFilePrefixPattern_.removePrefix(state.getArg())); } String term = state.getArg(); if (state.consumedSeparator) { return false; } else if ("--".equals(term)) { return true; } return prefixPattern_.match(term) && (state.negNumFlag || !NEG_NUM_PATTERN.matcher(term) .matches()); } private boolean fromFileFound(ParseState state) { return fromFilePrefixPattern_ != null && fromFilePrefixPattern_.match(state.getArg()); } /** * Extends arguments by reading additional arguments from file. * * @param state * Current parser state. * @param file * File from which additional arguments are read. * @throws ArgumentParserException */ private void extendArgs(ParseState state, String file) throws ArgumentParserException { List list = new ArrayList(); BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader( new FileInputStream(file), "utf-8")); String line; while ((line = reader.readLine()) != null) { list.add(line); } } catch (IOException e) { throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "Could not read arguments from file '%s'", file), e, this); } finally { try { if (reader != null) { reader.close(); } } catch (IOException e) { } } int offset = state.index + 1; String[] newargs = new String[list.size() + state.args.length - offset]; list.toArray(newargs); System.arraycopy(state.args, offset, newargs, list.size(), state.args.length - offset); if (state.lastFromFileArgIndex < offset) { state.lastFromFileArgIndex = list.size() - 1; } else { state.lastFromFileArgIndex += -offset + list.size(); } state.resetArgs(newargs); } private void checkRequiredArgument(ParseState state, Set used, int posargIndex) throws ArgumentParserException { if (state.deferredException != null) { return; } for (ArgumentImpl arg : optargs_) { if (arg.isRequired() && !used.contains(arg)) { state.deferredException = new ArgumentParserException( String.format(TextHelper.LOCALE_ROOT, "argument %s is required", arg.textualName()), this); } } if (posargs_.size() > posargIndex) { state.deferredException = new ArgumentParserException( "too few arguments", this); } } private void checkRequiredMutex(ParseState state, ArgumentImpl[] used) throws ArgumentParserException { if (state.deferredException != null) { return; } for (int i = 0; i < arggroups_.size(); ++i) { ArgumentGroupImpl group = arggroups_.get(i); if (group.isMutex() && group.isRequired() && used[i] == null) { StringBuilder sb = new StringBuilder(); for (ArgumentImpl arg : group.getArgs()) { if (arg.getHelpControl() != Arguments.SUPPRESS) { sb.append(arg.textualName()).append(" "); } } state.deferredException = new ArgumentParserException( String.format(TextHelper.LOCALE_ROOT, "one of the arguments %sis required", sb.toString()), this); } } } private void populateDefaults(Map opts) { for (ArgumentImpl arg : posargs_) { if (arg.getDefaultControl() != Arguments.SUPPRESS) { opts.put(arg.getDest(), arg.getDefault()); } } for (ArgumentImpl arg : optargs_) { if (arg.getDefaultControl() != Arguments.SUPPRESS) { opts.put(arg.getDest(), arg.getDefault()); } } for (Map.Entry entry : defaults_.entrySet()) { opts.put(entry.getKey(), entry.getValue()); } } public String getProg() { return prog_; } @Override public void printVersion() { PrintWriter writer = new PrintWriter(System.out); printVersion(writer); writer.flush(); } @Override public void printVersion(PrintWriter writer) { writer.println(formatVersion()); } @Override public String formatVersion() { return substitutePlaceholder(version_); } @Override public void handleError(ArgumentParserException e) { if (e.getParser() != this) { e.getParser().handleError(e); return; } // if --help triggered, just return (help info displayed by other // method) if (e instanceof HelpScreenException) { return; } PrintWriter writer = new PrintWriter(System.err); printUsage(writer); writer.write(TextHelper.wrap(textWidthCounter_, String.format( TextHelper.LOCALE_ROOT, "%s: error: %s%n", prog_, e.getMessage()), ArgumentParsers.getFormatWidth(), 0, "", "")); if (e instanceof UnrecognizedArgumentException) { UnrecognizedArgumentException ex = (UnrecognizedArgumentException) e; String argument = ex.getArgument(); if (prefixPattern_.match(argument)) { String flagBody = prefixPattern_.removePrefix(argument); if (flagBody.length() >= 2) { printFlagCandidates(flagBody, writer); } } } else if (e instanceof UnrecognizedCommandException) { UnrecognizedCommandException ex = (UnrecognizedCommandException) e; String command = ex.getCommand(); printCommandCandidates(command, writer); } writer.flush(); } /** * Calculates Damerau–Levenshtein distance between string {@code a} and * {@code b} with given costs. * * @param a * String * @param b * String * @param swap * Cost to swap 2 adjacent characters. * @param sub * Cost to substitute character. * @param add * Cost to add character. * @param del * Cost to delete character. * @return Damerau–Levenshtein distance between {@code a} and {@code b} */ private int levenshtein(String a, String b, int swap, int sub, int add, int del) { int alen = a.length(); int blen = b.length(); int[][] dp = new int[3][blen + 1]; for (int i = 0; i <= blen; ++i) { dp[1][i] = i; } for (int i = 1; i <= alen; ++i) { dp[0][0] = i; for (int j = 1; j <= blen; ++j) { dp[0][j] = dp[1][j - 1] + (a.charAt(i - 1) == b.charAt(j - 1) ? 0 : sub); if (i >= 2 && j >= 2 && a.charAt(i - 1) != b.charAt(j - 1) && a.charAt(i - 2) == b.charAt(j - 1) && a.charAt(i - 1) == b.charAt(j - 2)) { dp[0][j] = Math.min(dp[0][j], dp[2][j - 2] + swap); } dp[0][j] = Math.min(dp[0][j], Math.min(dp[1][j] + del, dp[0][j - 1] + add)); } int[] temp = dp[2]; dp[2] = dp[1]; dp[1] = dp[0]; dp[0] = temp; } return dp[1][blen]; } private static class SubjectBody { public String subject; public String body; public SubjectBody(String subject, String body) { this.subject = subject; this.body = body; } } // Made public for unit test public static class Candidate implements Comparable { public int similarity; public String subject; public Candidate(int similarity, String subject) { this.similarity = similarity; this.subject = subject; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!this.getClass().equals(obj.getClass())) { return false; } Candidate other = (Candidate) obj; if (subject == null) { if (other.subject != null) { return false; } } else if (other.subject == null) { return false; } else if (!subject.equals(other.subject)) { return false; } if (similarity != other.similarity) { return false; } return true; } @Override public int hashCode() { int prime = 31; int hash = 1; hash = hash * prime + (subject == null ? 0 : subject.hashCode()); hash = hash * prime + similarity; return hash; } @Override public int compareTo(Candidate rhs) { if (similarity < rhs.similarity) { return -1; } else if (similarity == rhs.similarity) { return subject.compareTo(rhs.subject); } else { return 1; } } } private void printFlagCandidates(String flagBody, PrintWriter writer) { List subjects = new ArrayList(); for (ArgumentImpl arg : optargs_) { String[] flags = arg.getFlags(); for (int i = 0, len = flags.length; i < len; ++i) { String body = prefixPattern_.removePrefix(flags[i]); if (body.length() <= 1) { continue; } subjects.add(new SubjectBody(flags[i], body)); } } printCandidates(flagBody, subjects, writer); } private void printCommandCandidates(String command, PrintWriter writer) { List subjects = new ArrayList(); for (String com : subparsers_.getCommands()) { subjects.add(new SubjectBody(com, com)); } printCandidates(command, subjects, writer); } /** * Prints most similar subjects in subjects to body. Similarity is * calculated between body and each {@link SubjectBody#body} in subjects. * * @param body * String to compare. * @param subjects * Target to be compared. * @param writer * Output */ private void printCandidates(String body, List subjects, PrintWriter writer) { List candidates = new ArrayList(); for (SubjectBody sub : subjects) { if (sub.body.startsWith(body)) { candidates.add(new Candidate(0, sub.subject)); continue; } else { // Cost values were borrowed from git, help.c candidates.add(new Candidate(levenshtein(body, sub.body, 0, 2, 1, 4), sub.subject)); } } if (candidates.isEmpty()) { return; } Collections.sort(candidates); int threshold = candidates.get(0).similarity; // Magic number 7 was borrowed from git, help.c if (threshold >= 7) { return; } writer.println(); writer.println("Did you mean:"); for (Candidate cand : candidates) { if (cand.similarity > threshold) { break; } writer.print("\t"); writer.println(cand.subject); } } /** * Replace placeholder in src with actual value. The only known placeholder * is ${prog}, which is replaced with {@link #prog_}. * * @param src * string to be processed * @return the substituted string */ private String substitutePlaceholder(String src) { return src.replaceAll(Pattern.quote("${prog}"), prog_); } public String getCommand() { return command_; } public TextWidthCounter getTextWidthCounter() { return textWidthCounter_; } public String getPrefixChars() { return prefixPattern_.getPrefixChars(); } public String getFromFilePrefixChars() { return fromFilePrefixPattern_ == null ? null : fromFilePrefixPattern_ .getPrefixChars(); } /** * Returns main (parent) parser. * * @return The main (parent) parser. null if this object is a root parser. */ public ArgumentParserImpl getMainParser() { return mainParser_; } } HelpScreenException.java000066400000000000000000000006311240010205600337250ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/internalpackage net.sourceforge.argparse4j.internal; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; public class HelpScreenException extends ArgumentParserException { private static final long serialVersionUID = -7303433847334132539L; public HelpScreenException(ArgumentParser parser) { super("Help Screen", parser); } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/internal/ParseState.java000066400000000000000000000031111240010205600321440ustar00rootroot00000000000000package net.sourceforge.argparse4j.internal; import net.sourceforge.argparse4j.inf.ArgumentParserException; public class ParseState { /** * Array of arguments. */ public String[] args; /** * Index in args array, which points next argument to process. */ public int index; /** * Index in {@link #args} array, which points to the last argument read from * file. -1 means that no argument is read from file. If arguments are read * from file recursively (e.g., argument file is found in argument file), * this value is properly extended to point to the actual last argument by * position. */ public int lastFromFileArgIndex; /** * True if special argument "--" is found and consumed. */ public boolean consumedSeparator; /** * True if negative number like flag is registered in the parser. */ public boolean negNumFlag; /** * Deferred exception encountered while parsing. This will be thrown after * parsing completed and no other exception was thrown. */ public ArgumentParserException deferredException; public ParseState(String args[], int index, boolean negNumFlag) { this.args = args; this.index = index; this.lastFromFileArgIndex = -1; this.negNumFlag = negNumFlag; this.deferredException = null; } void resetArgs(String args[]) { this.args = args; this.index = 0; } String getArg() { return args[index]; } boolean isArgAvail() { return index < args.length; } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/internal/SubparserImpl.java000066400000000000000000000154321240010205600326720ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.internal; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Map; import net.sourceforge.argparse4j.helper.TextHelper; import net.sourceforge.argparse4j.helper.TextWidthCounter; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentGroup; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup; import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparsers; /** * The application code must not use this class directly. * */ public final class SubparserImpl implements Subparser { private String command_; private List aliases_ = new ArrayList(); private ArgumentParserImpl parser_; private String help_ = ""; public SubparserImpl(String prog, boolean addHelp, String prefixChars, String fromFilePrefix, TextWidthCounter textWidthCounter, String command, ArgumentParserImpl mainParser) { command_ = command; parser_ = new ArgumentParserImpl(prog, addHelp, prefixChars, fromFilePrefix, textWidthCounter, command, mainParser); } @Override public Argument addArgument(String... nameOrFlags) { return parser_.addArgument(nameOrFlags); } @Override public ArgumentGroup addArgumentGroup(String title) { return parser_.addArgumentGroup(title); } @Override public MutuallyExclusiveGroup addMutuallyExclusiveGroup() { return parser_.addMutuallyExclusiveGroup(); } @Override public MutuallyExclusiveGroup addMutuallyExclusiveGroup(String title) { return parser_.addMutuallyExclusiveGroup(title); } @Override public Subparsers addSubparsers() { return parser_.addSubparsers(); } @Override public SubparserImpl usage(String usage) { parser_.usage(usage); return this; } @Override public SubparserImpl description(String description) { parser_.description(description); return this; } @Override public SubparserImpl epilog(String epilog) { parser_.epilog(epilog); return this; } @Override public SubparserImpl version(String version) { parser_.version(version); return this; } @Override public SubparserImpl defaultHelp(boolean defaultHelp) { parser_.defaultHelp(defaultHelp); return this; } @Override public void printHelp() { parser_.printHelp(); } @Override public void printHelp(PrintWriter writer) { parser_.printHelp(writer); } @Override public String formatHelp() { return parser_.formatHelp(); } @Override public void printUsage() { parser_.printUsage(); } @Override public void printUsage(PrintWriter writer) { parser_.printUsage(writer); } @Override public String formatUsage() { return parser_.formatUsage(); } @Override public void printVersion() { parser_.printVersion(); } @Override public void printVersion(PrintWriter writer) { parser_.printVersion(writer); } @Override public String formatVersion() { return parser_.formatVersion(); } @Override public SubparserImpl setDefault(String dest, Object value) { parser_.setDefault(dest, value); return this; } @Override public SubparserImpl setDefaults(Map attrs) { parser_.setDefaults(attrs); return this; } @Override public Object getDefault(String dest) { return parser_.getDefault(dest); } @Override public SubparserImpl help(String help) { help_ = TextHelper.nonNull(help); return this; } @Override public Namespace parseArgsOrFail(String args[]) { return parser_.parseArgsOrFail(args); } @Override public Namespace parseArgs(String[] args) throws ArgumentParserException { return parser_.parseArgs(args); } @Override public void parseArgs(String[] args, Map attrs) throws ArgumentParserException { parser_.parseArgs(args, attrs); } @Override public void parseArgs(String[] args, Object userData) throws ArgumentParserException { parser_.parseArgs(args, userData); } @Override public void parseArgs(String[] args, Map attrs, Object userData) throws ArgumentParserException { parser_.parseArgs(args, attrs, userData); } @Override public void handleError(ArgumentParserException e) { parser_.handleError(e); } @Override public SubparserImpl aliases(String... alias) { parser_.getMainParser().addSubparsers().addAlias(this, alias); for (String s : alias) { aliases_.add(s); } return this; } public void parseArgs(ParseState state, Map opts) throws ArgumentParserException { parser_.parseArgs(state, opts); } public void printSubparserHelp(PrintWriter writer, int format_width) { if (!help_.isEmpty()) { String title = " " + command_; if (!aliases_.isEmpty()) { title += " (" + TextHelper.concat(aliases_, 0, ",") + ")"; } TextHelper.printHelp(writer, title, help_, parser_.getTextWidthCounter(), format_width); } } public String getCommand() { return parser_.getCommand(); } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/internal/SubparsersImpl.java000066400000000000000000000217711240010205600330600ustar00rootroot00000000000000/* * Copyright (C) 2011 Tatsuhiro Tsujikawa * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sourceforge.argparse4j.internal; import java.io.PrintWriter; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import net.sourceforge.argparse4j.helper.TextHelper; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparsers; /** * The application code must not use this class directly. * */ public final class SubparsersImpl implements Subparsers { private ArgumentParserImpl mainParser_; /** * The key is subparser command or alias name and value is subparser object. * The real command and alias names share the same subparser object. To * identify the aliases, check key equals to * {@link SubparserImpl#getCommand()}. If they are equal, it is not alias. */ private Map parsers_ = new LinkedHashMap(); private String help_ = ""; private String title_ = ""; private String description_ = ""; private String dest_ = ""; private String metavar_ = ""; public SubparsersImpl(ArgumentParserImpl mainParser) { mainParser_ = mainParser; } @Override public SubparserImpl addParser(String command) { return addParser(command, true, mainParser_.getPrefixChars()); } @Override public SubparserImpl addParser(String command, boolean addHelp) { return addParser(command, addHelp, mainParser_.getPrefixChars()); } @Override public SubparserImpl addParser(String command, boolean addHelp, String prefixChars) { if (command == null || command.isEmpty()) { throw new IllegalArgumentException( "command cannot be null or empty"); } else if (parsers_.containsKey(command)) { throw new IllegalArgumentException(String.format( TextHelper.LOCALE_ROOT, "command '%s' has been already used", command)); } SubparserImpl parser = new SubparserImpl(mainParser_.getProg(), addHelp, prefixChars, mainParser_.getFromFilePrefixChars(), mainParser_.getTextWidthCounter(), command, mainParser_); parsers_.put(command, parser); return parser; } @Override public SubparsersImpl dest(String dest) { dest_ = TextHelper.nonNull(dest); return this; } @Override public SubparsersImpl help(String help) { help_ = TextHelper.nonNull(help); return this; } @Override public SubparsersImpl title(String title) { title_ = TextHelper.nonNull(title); return this; } public String getTitle() { return title_; } @Override public SubparsersImpl description(String description) { description_ = TextHelper.nonNull(description); return this; } public String getDescription() { return description_; } @Override public SubparsersImpl metavar(String metavar) { metavar_ = TextHelper.nonNull(metavar); return this; } public boolean hasSubCommand() { return !parsers_.isEmpty(); } /** * Get next SubparserImpl from given command and state. This function * resolves abbreviated command input as well. If the given command is * ambiguous, {@link ArgumentParserException} will be thrown. If no matching * SubparserImpl is found, this function returns null. * * @param state * @param command * @return next SubparserImpl or null * @throws ArgumentParserException */ private SubparserImpl resolveNextSubparser(ParseState state, String command) throws ArgumentParserException { if (command.isEmpty()) { return null; } SubparserImpl ap = parsers_.get(command); if (ap == null) { List cand = TextHelper.findPrefix(parsers_.keySet(), command); int size = cand.size(); if (size == 1) { ap = parsers_.get(cand.get(0)); } else if (size > 1) { // Sort it to make unit test easier Collections.sort(cand); throw new ArgumentParserException(String.format( TextHelper.LOCALE_ROOT, "ambiguous command: %s could match %s", command, TextHelper.concat(cand, 0, ", ")), mainParser_); } } return ap; } public void parseArg(ParseState state, Map opts) throws ArgumentParserException { if (parsers_.isEmpty()) { throw new IllegalArgumentException("too many arguments"); } SubparserImpl ap = resolveNextSubparser(state, state.getArg()); if (ap == null) { StringBuilder sb = new StringBuilder(); for (Map.Entry entry : parsers_.entrySet()) { sb.append("'").append(entry.getKey()).append("', "); } sb.delete(sb.length() - 2, sb.length()); throw new UnrecognizedCommandException(String.format( TextHelper.LOCALE_ROOT, "invalid choice: '%s' (choose from %s)", state.getArg(), sb.toString()), mainParser_, state.getArg()); } else { ++state.index; ap.parseArgs(state, opts); // Call after parseArgs to overwrite dest_ attribute set by // sub-parsers. if (!dest_.isEmpty()) { opts.put(dest_, ap.getCommand()); } } } public String formatShortSyntax() { if (metavar_.isEmpty()) { StringBuilder sb = new StringBuilder(); sb.append("{"); for (Map.Entry entry : parsers_.entrySet()) { sb.append(entry.getKey()).append(","); } if (sb.length() > 1) { sb.delete(sb.length() - 1, sb.length()); } sb.append("}"); return sb.toString(); } else { return metavar_; } } /** * Writes the help message for this and descendants. * * @param writer * The writer to output * @param format_width * column width */ public void printSubparserHelp(PrintWriter writer, int format_width) { TextHelper.printHelp(writer, formatShortSyntax(), help_, mainParser_.getTextWidthCounter(), format_width); for (Map.Entry entry : parsers_.entrySet()) { // Don't generate help for aliases. if (entry.getKey().equals(entry.getValue().getCommand())) { entry.getValue().printSubparserHelp(writer, format_width); } } } /** * Returns collection of the sub-command name under this object. * * @return collection of the sub-comman name */ public Collection getCommands() { return parsers_.keySet(); } /** * Adds Subparser alias names for given Subparser. For each SubparsersImpl * instance, alias names and commands must be unique. If duplication is * found, {@link IllegalArgumentException} is thrown. * * @param subparser * Subparser to add alias names * @param alias * alias name */ public void addAlias(SubparserImpl subparser, String... alias) { for (String command : alias) { if (parsers_.containsKey(command)) { throw new IllegalArgumentException(String.format( TextHelper.LOCALE_ROOT, "command '%s' has been already used", command)); } else { parsers_.put(command, subparser); } } } } argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/internal/TerminalWidth.java000066400000000000000000000110031240010205600326430ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.sourceforge.argparse4j.internal; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Returns the column width of the command line terminal from which this program * was started. Typically the column width is around 80 characters or so. * * Currently works on Linux and OSX. * * Returns -1 if the column width cannot be determined for some reason. */ public class TerminalWidth { private static final int UNKNOWN_WIDTH = -1; public static void main(String[] args) { System.out.println("terminalWidth: " + new TerminalWidth().getTerminalWidth()); } public int getTerminalWidth() { String width = System.getenv("COLUMNS"); if (width != null) { try { return Integer.parseInt(width); } catch (NumberFormatException e) { return UNKNOWN_WIDTH; } } try { return getTerminalWidth2(); } catch (IOException e) { return UNKNOWN_WIDTH; } } // see // http://grokbase.com/t/gg/clojure/127qwgscvc/how-do-you-determine-terminal-console-width-in-%60lein-repl%60 private int getTerminalWidth2() throws IOException { String osName = System.getProperty("os.name"); boolean isOSX = osName.startsWith("Mac OS X"); boolean isLinux = osName.startsWith("Linux") || osName.startsWith("LINUX"); if (!isLinux && !isOSX) { return UNKNOWN_WIDTH; // actually, this might also work on Solaris // but this hasn't been tested } ProcessBuilder builder = new ProcessBuilder(which("sh").toString(), "-c", "stty -a < /dev/tty"); builder.redirectErrorStream(true); Process process = builder.start(); InputStream in = process.getInputStream(); ByteArrayOutputStream resultBytes = new ByteArrayOutputStream(); try { byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) >= 0) { resultBytes.write(buf, 0, len); } } finally { in.close(); } String result = new String(resultBytes.toByteArray()); // System.out.println("result=" + result); try { if (process.waitFor() != 0) { return UNKNOWN_WIDTH; } } catch (InterruptedException e) { return UNKNOWN_WIDTH; } String pattern; if (isOSX) { // Extract columns from a line such as this: // speed 9600 baud; 39 rows; 80 columns; pattern = "(\\d+) columns"; } else { // Extract columns from a line such as this: // speed 9600 baud; rows 50; columns 83; line = 0; pattern = "columns (\\d+)"; } Matcher m = Pattern.compile(pattern).matcher(result); if (!m.find()) { return UNKNOWN_WIDTH; } result = m.group(1); try { return Integer.parseInt(result); } catch (NumberFormatException e) { return UNKNOWN_WIDTH; } } private File which(String cmd) throws IOException { String path = System.getenv("PATH"); if (path != null) { for (String dir : path.split(Pattern.quote(File.pathSeparator))) { File command = new File(dir.trim(), cmd); if (command.canExecute()) { return command.getAbsoluteFile(); } } } throw new IOException("No command '" + cmd + "' on path " + path); } } UnrecognizedArgumentException.java000066400000000000000000000012631240010205600360360ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/internalpackage net.sourceforge.argparse4j.internal; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; /** * Exception thrown when unrecognized argument is encountered. * */ public class UnrecognizedArgumentException extends ArgumentParserException { /** * */ private static final long serialVersionUID = -256412358164687976L; private String argument_; public UnrecognizedArgumentException(String message, ArgumentParser parser, String argument) { super(message, parser); argument_ = argument; } public String getArgument() { return argument_; } } UnrecognizedCommandException.java000066400000000000000000000012531240010205600356310ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/main/java/net/sourceforge/argparse4j/internalpackage net.sourceforge.argparse4j.internal; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; /** * Exception thrown when unrecognized command is encountered. * */ public class UnrecognizedCommandException extends ArgumentParserException { /** * */ private static final long serialVersionUID = 2733149394568914256L; private String command_; public UnrecognizedCommandException(String message, ArgumentParser parser, String command) { super(message, parser); command_ = command; } public String getCommand() { return command_; } } argparse4j-argparse4j-0.4.4/src/site/000077500000000000000000000000001240010205600173425ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/site/site.xml000066400000000000000000000021631240010205600210320ustar00rootroot00000000000000 org.apache.maven.skins maven-fluido-skin 1.3.0 Argparse4j - The command line argument parser library false argparse4j-argparse4j-0.4.4/src/site/sphinx/000077500000000000000000000000001240010205600206535ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/site/sphinx/.gitignore000066400000000000000000000000071240010205600226400ustar00rootroot00000000000000_build argparse4j-argparse4j-0.4.4/src/site/sphinx/Makefile000066400000000000000000000110611240010205600223120ustar00rootroot00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = -D version=$(PACKAGE_VERSION) -D release=$(PACKAGE_VERSION) SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Spdylay.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Spdylay.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/Spdylay" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Spdylay" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." argparse4j-argparse4j-0.4.4/src/site/sphinx/_static/000077500000000000000000000000001240010205600223015ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/site/sphinx/_static/default2.css000066400000000000000000000004611240010205600245220ustar00rootroot00000000000000@import url(http://fonts.googleapis.com/css?family=Roboto:400,400italic,500,500italic); pre, tt { font-family: monospace, sans-serif; } tt { font-size: 100%; } div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 { border: 0; margin: 0; padding: 0.3em 0; } argparse4j-argparse4j-0.4.4/src/site/sphinx/_templates/000077500000000000000000000000001240010205600230105ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/site/sphinx/_templates/menu.html000066400000000000000000000010571240010205600246450ustar00rootroot00000000000000

Menu

argparse4j-argparse4j-0.4.4/src/site/sphinx/conf.py000066400000000000000000000233761240010205600221650ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'argparse4j' copyright = u'2011, 2014, Tatsuhiro Tsujikawa' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = 'SNAPSHOT' # The full version, including alpha/beta/rc tags. release = 'SNAPSHOT' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['README.rst'] # The reST default role (used for this markup: `text`) to use for all documents. default_role = 'py:func' primary_domain = 'py' # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The default language to highlight source code in. The default is 'python'. highlight_language = 'java' # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. html_theme_options = {'bodyfont':'roboto, sans-serif', 'headfont':'roboto, "Trebuchet MS", sans-serif', 'relbarbgcolor':'#fff', 'relbartextcolor':'#444', 'relbarlinkcolor':'#444', 'sidebarbgcolor':'none', 'sidebartextcolor':'#444', 'sidebarlinkcolor':'#444', 'headbgcolor':'none', 'footerbgcolor':'none', 'footertextcolor':'#444'} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static/default2.css'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. html_use_smartypants = False # Custom sidebar templates, maps document names to template names. html_sidebars = { '**': ['menu.html', 'localtoc.html', 'relations.html', 'sourcelink.html', 'searchbox.html'] } # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'Argparse4jdoc' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'Argparse4j.tex', u'Argparse4j Documentation', u'Tatsuhiro Tsujikawa', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'argparse4j', u'Argparse4j Documentation', [u'Tatsuhiro Tsujikawa'], 1) ] # Ugly javadoc link generator roles import re from docutils import nodes def _ap4j_javadoc_genuri(text): base = 'apidocs/net/sourceforge/argparse4j/' return ''.join([base, re.sub(r'\.', '/', text), ".html"]) def _ap4j_genliteral(rawtext, text): ''' Create literal node which just look like cross reference. ''' return nodes.literal(rawtext, text, classes=['xref']) def _ap4j_javadoc_role(name, rawtext, text, lineno, inliner, options={}, content=[]): ''' Link to Java class javadoc. The text must be qualified class name relative to net.sourceforge.argparse4j ''' app = inliner.document.settings.env.app node = nodes.reference(rawtext, text.split('.')[-1], refuri=_ap4j_javadoc_genuri(text), **options) lit = _ap4j_genliteral(rawtext, "") lit += node return [lit], [] def _ap4j_javadocfunc_role(name, rawtext, text, lineno, inliner, options={}, content=[]): ''' Link to Java method javadoc. The text must be qualified method signature relative to net.sourceforge.argparse4j ''' app = inliner.document.settings.env.app m = re.match(r'([^\(]+)\.([^\(]+\(.*\))', text) type_text, funcsig = m.groups() node = nodes.reference(rawtext, ''.join([type_text.split('.')[-1], '.', funcsig.split('(', 1)[0], '()']), refuri='#'.join([_ap4j_javadoc_genuri(type_text), funcsig]), **options) lit = _ap4j_genliteral(rawtext, "") lit += node return [lit], [] def _ap4j_literal_role(name, rawtext, text, lineno, inliner, options={}, content=[]): ''' Literal node, making it just look like cross reference. ''' return [_ap4j_genliteral(rawtext, text)], [] def setup(app): app.add_stylesheet('default2.css') app.add_role('javadoc', _ap4j_javadoc_role) app.add_role('javadocfunc', _ap4j_javadocfunc_role) app.add_role('javatype', _ap4j_literal_role) app.add_role('javafunc', _ap4j_literal_role) app.add_role('javafield', _ap4j_literal_role) argparse4j-argparse4j-0.4.4/src/site/sphinx/examples.rst000066400000000000000000000156501240010205600232320ustar00rootroot00000000000000Examples ======== CJK line-wrap example --------------------- Sub-set of options of :manpage:`ls(1)`. The help messages are from Debian Linux:: import static net.sourceforge.argparse4j.impl.Arguments.storeTrue; import net.sourceforge.argparse4j.ArgumentParsers; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.Namespace; public class LsHelpDemo { public static void main(String[] args) { ArgumentParser parser = ArgumentParsers .newArgumentParser("ls") .defaultHelp(true) .description( "FILE に関する情報を一覧表示します (デフォルトは現在のディレクトリ)。\n" + "-cftuvSUX または --sort が指定されない限り、要素はアルファベット順で並べ替えられます。") .epilog("SIZE は次のうちの一つです (整数の後に付加されるかもしれません):\n" + "KB 1000, K 1024, MB 1000*1000, M 1024*1024, その他 G, T, P, E, Z, Y など。"); parser.addArgument("-a", "--all").help(". で始まる要素を無視しない") .action(storeTrue()); parser.addArgument("-A", "--almost-all").help(". および .. を一覧表示しない") .action(storeTrue()); parser.addArgument("--author").help("-l と合わせて使用した時、各ファイルの作成者を表示する") .action(storeTrue()); parser.addArgument("-b", "--escape") .help("表示不可能な文字の場合に C 形式のエスケープ文字を表示する").action(storeTrue()); parser.addArgument("--block-size") .type(Integer.class) .metavar("SIZE") .help("SIZE の倍数として表示する。例: `--block-size=M' は" + "表示する時に 1,048,576 バイトの倍数としてサイズを" + "表示する。SIZE の形式は以下を参照)"); parser.addArgument("-B", "--ignore-backups").help("~ で終了する要素を一覧表示しない") .action(storeTrue()); parser.addArgument("-c") .help("-lt と使用した場合: ctime (ファイル状態情報を変更した時間)で並べ替えて表示する\n" + "-l と使用した場合: 名前で並べ替えて ctime を表示する\n" + "それ以外: ctime で新しい順に並べ替える)").action(storeTrue()); parser.addArgument("-C").help("要素を列ごとに並べる").action(storeTrue()); parser.addArgument("--color") .nargs("?") .choices("always", "never", "auto") .metavar("WHEN") .setDefault("always") .help("カラー出力をする。 WHEN のデフォルト値は `always'、" + "`never' または `auto'。詳細は下部を参照)"); parser.addArgument("file").nargs("*"); Namespace res; try { res = parser.parseArgs(args); System.out.println(res); } catch (ArgumentParserException e) { parser.handleError(e); System.exit(1); } } } .. code-block:: console $ java LsHelpDemo -h usage: ls [-h] [-a] [-A] [--author] [-b] [--block-size SIZE] [-B] [-c] [-C] [--color [WHEN]] [file [file ...]] FILE に関する情報を一覧表示します (デフォルトは現在のディレクトリ)。 -cftuvSUX または --sort が指定されない限り、要素はアルファベット順で並べ替 えられます。 positional arguments: file optional arguments: -h, --help show this help message and exit -a, --all . で始まる要素を無視しない (default: false) -A, --almost-all . および .. を一覧表示しない (default: false) --author -l と合わせて使用した時、各ファイルの作成者を表示 する (default: false) -b, --escape 表示不可能な文字の場合に C 形式のエスケープ文字を 表示する (default: false) --block-size SIZE SIZE の倍数として表示する。例: `--block-size=M' は 表示する時に 1,048,576 バイトの倍数としてサイズを 表示する。SIZE の形式は以下を参照) -B, --ignore-backups ~ で終了する要素を一覧表示しない (default: false) -c -lt と使用した場合: ctime (ファイル状態情報を変更 した時間)で並べ替えて表示する -l と使用した場合: 名前で並べ替えて ctime を表示す る それ以外: ctime で新しい順に並べ替える) (default: false) -C 要素を列ごとに並べる (default: false) --color [WHEN] カラー出力をする。 WHEN のデフォルト値は `always'、`never' または `auto'。詳細は下部を参 照) (default: always) SIZE は次のうちの一つです (整数の後に付加されるかもしれません): KB 1000, K 1024, MB 1000*1000, M 1024*1024, その他 G, T, P, E, Z, Y など。 Clojure example --------------- .. code-block:: clojure (ns argparse4j-demo (:import (net.sourceforge.argparse4j ArgumentParsers) (net.sourceforge.argparse4j.impl Arguments) (net.sourceforge.argparse4j.inf ArgumentParserException))) ;; Helper function to convert closure list to array (defn va [& name-and-flags] (into-array name-and-flags)) (def ap (. ArgumentParsers newArgumentParser "java -cp clojure.jar clojure.main")) (let [group (. ap addArgumentGroup "init options")] (doto (. group addArgument (va "-i" "--init")) (.metavar (va "path")) (.help "Load a file or resource")) (doto (. group addArgument (va "-e" "--eval")) (.metavar (va "string")) (.help "Evaluate expressions in string; print non-nil values"))) (let [group (. ap addArgumentGroup "main options")] (doto (. group addArgument (va "-m" "--main")) (.metavar (va "ns-name")) (.help "Call the -main function from a namespace with args")) (doto (. group addArgument (va "-r" "--repl")) (.action (. Arguments storeTrue)) (.help "Run a repl")) (doto (. group addArgument (va "path")) (.help (str "Run a script from from a file or resource;" " use '-' to read from standard input")))) (try (println (. ap parseArgs (into-array String *command-line-args*))) (catch RuntimeException e (if (instance? ArgumentParserException (. e getCause)) (. ap handleError (. e getCause)) (. e printStackTrace)) (. System exit 1))) With Closure, use :javatype:`Long` type instead of :javatype:`Integer` if you use |Argument.choices| with integer constants: .. code-block:: clojure (def ap (. ArgumentParsers newArgumentParser "hello")) (doto (. ap addArgument (va "-i")) (.type Long) (.choices [1 2 3]) (.action (. Arguments append))) .. |Argument.choices| replace:: :javadocfunc:`inf.Argument.choices(E...)` argparse4j-argparse4j-0.4.4/src/site/sphinx/index.rst000066400000000000000000000067431240010205600225260ustar00rootroot00000000000000.. include:: ../../../README.rst To see how to use argparse4j, see :doc:`usage`. See also :doc:`examples`. Contents -------- .. toctree:: :maxdepth: 2 usage examples Demo ---- Here is the working demo program to calculate checksum. Argparse4j is used to parse command line arguments (Java 7 required to compile this source code):: import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.ByteChannel; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import net.sourceforge.argparse4j.ArgumentParsers; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.Namespace; public class Checksum { public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("Checksum") .defaultHelp(true) .description("Calculate checksum of given files."); parser.addArgument("-t", "--type") .choices("SHA-256", "SHA-512", "SHA1").setDefault("SHA-256") .help("Specify hash function to use"); parser.addArgument("file").nargs("*") .help("File to calculate checksum"); Namespace ns = null; try { ns = parser.parseArgs(args); } catch (ArgumentParserException e) { parser.handleError(e); System.exit(1); } MessageDigest digest = null; try { digest = MessageDigest.getInstance(ns.getString("type")); } catch (NoSuchAlgorithmException e) { System.err.printf("Could not get instance of algorithm %s: %s", ns.getString("type"), e.getMessage()); System.exit(1); } for (String name : ns. getList("file")) { Path path = Paths.get(name); try (ByteChannel channel = Files.newByteChannel(path, StandardOpenOption.READ);) { ByteBuffer buffer = ByteBuffer.allocate(4096); while (channel.read(buffer) > 0) { buffer.flip(); digest.update(buffer); buffer.clear(); } } catch (IOException e) { System.err .printf("%s: failed to read data: %s", e.getMessage()); continue; } byte md[] = digest.digest(); StringBuffer sb = new StringBuffer(); for (int i = 0, len = md.length; i < len; ++i) { String x = Integer.toHexString(0xff & md[i]); if (x.length() == 1) { sb.append("0"); } sb.append(x); } System.out.printf("%s %s\n", sb.toString(), name); } } } When executed: .. code-block:: console $ java Checksum -h usage: Checksum [-h] [-t {SHA-256,SHA-512,SHA1}] [file [file ...]] Calculate checksum of given files. positional arguments: file File to calculate checksum optional arguments: -h, --help show this help message and exit -t {SHA-256,SHA-512,SHA1}, --type {SHA-256,SHA-512,SHA1} Specify hash function to use (default: SHA-256) $ java Checksum file1.cc file1.h 6bd85bf4b936bc8870c70bea04cd12d4fe3745934f511e6e188d718d32154a79 file1.cc 839ef370cbd54f62985bac7b974cc575eaaa24a8edd6ae7787cfc71829ceda40 file1.h $ java Checksum --tpye file1.cc usage: Checksum [-h] [-t {SHA-256,SHA-512,SHA1}] [file [file ...]] Checksum: error: unrecognized arguments: --tpye Did you mean: --type $ java Checksum -t SHA1 file1.cc 20bada64dde97b98faaba09ebbfdb70af71476f1 file1.cc argparse4j-argparse4j-0.4.4/src/site/sphinx/usage.rst000066400000000000000000002433051240010205600225200ustar00rootroot00000000000000The Argparse4j User Manual ========================== Argparse4j is a command line argument parser library for Java based on Python's `argparse `_ module. Because of the difference of language features, we cannot use same syntax and usage of original, but we have tried to bring the same touch and feel as much as possible. We also use same terminology as much as possible. This manual was written based on argparse's manual and most of the the sentences are almost identical, just replaced code examples. We use this approach because argparse manual is well written and since both are do the same thing, using existing manual makes us create a manual with good quality in a short time. Thanks to Python community for the great module and documentation. We omitted package names from Java classes in this documentation for readability because they tend to be quite long. Most Java programmers use IDE (e.g., eclipse) and it has powerful auto-completion features. And each class in argparse4j has unique name so it is not a big problem after all. The ``import`` statements are also omitted from the code snippet by the same reason. Examples -------- The following code is a Java program that takes a list of integers and produces either the sum or the max:: public class Prog { private static interface Accumulate { int accumulate(Collection ints); } private static class Sum implements Accumulate { @Override public int accumulate(Collection ints) { int sum = 0; for (Integer i : ints) { sum += i; } return sum; } @Override public String toString() { return getClass().getSimpleName(); } } private static class Max implements Accumulate { @Override public int accumulate(Collection ints) { return Collections.max(ints); } @Override public String toString() { return getClass().getSimpleName(); } } public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog") .description("Process some integers."); parser.addArgument("integers") .metavar("N") .type(Integer.class) .nargs("+") .help("an integer for the accumulator"); parser.addArgument("--sum") .dest("accumulate") .action(Arguments.storeConst()) .setConst(new Sum()) .setDefault(new Max()) .help("sum the integers (default: find the max)"); try { Namespace res = parser.parseArgs(args); System.out.println(((Accumulate) res.get("accumulate")) .accumulate((List) res.get("integers"))); } catch (ArgumentParserException e) { parser.handleError(e); } } } It can be run at the command line and provides useful help messages: .. code-block:: console $ java Prog -h usage: prog [-h] [--sum] N [N ...] Process some integers. positional arguments: N an integer for the accumulator optional arguments: -h, --help show this help message and exit --sum sum the integers (default: find the max) When run with the appropriate arguments, it prints either the sum or the max of the command-line integers: .. code-block:: console $ java Prog 1 2 3 4 4 $ java Prog 1 2 3 4 --sum 10 If invalid arguments are passed in, it will throw an exception. The user program can catch the exception and show error message: .. code-block:: console $ java Prog a b c usage: prog [-h] [--sum] N [N ...] prog: error: argument integers: could not construct class java.lang.Integer from a (For input string: "a") The following sections walk you through this example. Creating a parser ^^^^^^^^^^^^^^^^^ The first step using the argparse4j is creating :javadoc:`inf.ArgumentParser` object. To do this, use |ArgumentParsers.newArgumentParser| static method of :javadoc:`ArgumentParsers` class:: ArgumentParser parser = ArgumentParsers.newArgumentParser("prog") .description("Process some integers."); The :javadoc:`inf.ArgumentParser` object will hold all the information necessary to parse the command line into Java data types. .. _Adding-arguments: Adding arguments ^^^^^^^^^^^^^^^^ Filling an ArgumentParser with information about program arguments is done by making calls to the |ArgumentParser.addArgument| method. Generally, this calls tell the ArgumentParser how to take the strings on the command line and turn them into objects. This information is stored and used when |ArgumentParser.parseArgs| is called. For example:: parser.addArgument("integers") .metavar("N") .type(Integer.class) .nargs("+") .help("an integer for the accumulator"); parser.addArgument("--sum") .dest("accumulate") .action(Arguments.storeConst()) .setConst(new Sum()) .setDefault(new Max()) .help("sum the integers (default: find the max)"); Later, calling |ArgumentParser.parseArgs| will return an :javadoc:`inf.Namespace` object with two attributes, ``integers`` and ``accumulate``. The ``integers`` attribute will be a :javatype:`List` which has one or more ints, and the ``accumulate`` attribute will be either the :javatype:`Sum` object, if ``--sum`` was specified at the command line, or the :javatype:`Max` object if it was not. Passing arguments ^^^^^^^^^^^^^^^^^ ArgumentParser parses arguments through the |ArgumentParser.parseArgs| method. This will inspect the command line, convert each argument to the appropriate type and then invoke the appropriate action. In most cases, this means a simple :javadoc:`inf.Namespace` object will have attributes parsed out of the command line. The following code:: Namespace res = parser.parseArgs(new String[] { "--sum", "7", "-1", "42" }); System.out.println(res); will display: .. code-block:: console Namespace(integers=[7, -1, 42], accumulate=Sum) In Java, the command line arguments are typically given as ``String[] argv``. To parse the command line, pass this object to |ArgumentParser.parseArgs| method. ArgumentParser objects ---------------------- To create :javadoc:`inf.ArgumentParser` object, one can use one of |ArgumentParsers.newArgumentParser| static methods of :javadoc:`ArgumentParsers` class. The following parameters can be specified: * :ref:`ArgumentParsers-newArgumentParser-prog` - The name of the program. This is necessary because ``main()`` method in Java does not provide program name. * :ref:`ArgumentParsers-newArgumentParser-addHelp` - Add a -h/--help option to the parser. (default: ``true``). * :ref:`ArgumentParsers-newArgumentParser-prefixChars` - The set of characters that prefix optional arguments. (default: '-') * :ref:`ArgumentParsers-newArgumentParser-fromFilePrefixChars` - The set of characters that prefix file path from which additional arguments are read. (default: ``null``) After creation of the instance, several additional parameters can be specified using following methods: * :ref:`ArgumentParser-description` - Text to display before the argument help. * :ref:`ArgumentParser-epilog` - Text to display after the argument help. * :ref:`ArgumentParser-defaultHelp` - Display default value to help message. (default: ``false``) * :ref:`ArgumentParser-usage` - The string describing the program usage (default: generated) * :ref:`ArgumentParser-version` - The string describing the program version. The following sections describes how each of these are used. .. _ArgumentParsers-newArgumentParser-prog: prog ^^^^ In Java, the name of the program is not included in the argument in `main()` method. Because of this, the name of the program must be supplied to |ArgumentParsers.newArgumentParser|. .. _ArgumentParsers-newArgumentParser-addHelp: addHelp ^^^^^^^ By default, :javadoc:`inf.ArgumentParser` objects add an option which simply displays the parser's help message. For example, consider following code:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").help("foo help"); Namespace res = parser.parseArgs(args); } If ``-h`` or ``--help`` is supplied at the command line, the ArgumentParser will display help message: .. code-block:: console $ java Demo --help usage: prog [-h] [--foo FOO] optional arguments: -h, --help show this help message and exit --foo FOO foo help Occasionally, it may be useful to disable the addition of this help option. This can be achieved by passing ``false`` as the addHelp_ argument to |ArgumentParsers.newArgumentParser|:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers .newArgumentParser("prog", /*addHelp*/ false); parser.addArgument("--foo").help("foo help"); parser.printHelp(); } .. code-block:: console $ java Demo usage: prog [--foo FOO] optional arguments: --foo FOO foo help The help option is typically ``-h/--help``. The exception to this is if the :ref:`ArgumentParsers-newArgumentParser-prefixChars` is specified and does not include ``-``, in which case ``-h`` and ``--help`` are not valid options. In this case, the first character in :ref:`ArgumentParsers-newArgumentParser-prefixChars` is used to prefix the help options:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers .newArgumentParser("prog", /*addHelp*/ true, /*prefixChars*/ "+/"); parser.printHelp(); } .. code-block:: console $ java Demo usage: prog [+h] optional arguments: +h, ++help show this help message and exit .. _ArgumentParsers-newArgumentParser-prefixChars: prefixChars ^^^^^^^^^^^ Most command line options will use ``-`` as the prefix, e.g. ``-f/--foo``. Parsers that need to support different or additional prefix characters, e.g. for options like ``+f`` or ``/foo``, may specify them using the *prefixChars* to |ArgumentParsers.newArgumentParser|:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog", true, /*prefixChars*/ "-+"); parser.addArgument("+f"); parser.addArgument("++bar"); Namespace res = parser.parseArgs(args); System.out.println(res); } .. code-block:: console $ java Demo +f X ++bar Y Namespace(f=X, bar=Y) The *prefixChars* argument defaults to ``-`` (you can use :javafield:`ArgumentParsers.DEFAULT_PREFIX_CHARS` for this). Supplying a set of characters that does not include ``-`` will cause ``-f/--foo`` options to be disallowed. .. _ArgumentParsers-newArgumentParser-fromFilePrefixChars: fromFilePrefixChars ^^^^^^^^^^^^^^^^^^^ It is sometimes useful to read arguments from file other than typing them in command line, for example, when lots of arguments are needed. If *fromFilePrefixChars* is given as non ``null`` string, arguments starts with one of these characters are treated as file path and ArgumentParser reads additional arguments from the file. For example: .. code-block:: console $ cat args.txt -f bar :: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog", true, "-", /*fromFilePrefixChars*/ "@"); parser.addArgument("-f"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); System.exit(1); } } .. code-block:: console $ java Demo -f foo @args.txt Namespace(f=bar) The each line of the file is treated as one argument. Please be aware that trailing empty lines or line with only white spaces are also considered as arguments, although it is not readily noticeable to the user. The empty line is treated as empty string. By default, *fromFilePrefixChars* is ``null``, which means no argument is treated as file path. .. _ArgumentParser-description: ArgumentParser.description() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The |ArgumentParser.description| gives a brief description of what the program does and how it works. In help message, the description is displayed between command line usage string and the help messages for the various arguments:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog") .description("A foo that bars"); parser.printHelp(); } .. code-block:: console $ java Demo usage: prog [-h] A foo that bars optional arguments: -h, --help show this help message and exit By default, the description will be line-wrapped so that it fits within the given space. .. _ArgumentParser-epilog: ArgumentParser.epilog() ^^^^^^^^^^^^^^^^^^^^^^^ Some programs like to display additional description of the program after the description of the arguments. Such text can be specified using |ArgumentParser.epilog| method:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog") .description("A foo that bars") .epilog("And that's how you'd foo a bar"); parser.printHelp(); } .. code-block:: console $ java Demo usage: prog [-h] A foo that bars optional arguments: -h, --help show this help message and exit And that's how you'd foo a bar As with the :ref:`ArgumentParser-description` method, text specified in |ArgumentParser.epilog| is by default line-wrapped. .. _ArgumentParser-defaultHelp: ArgumentParser.defaultHelp() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The default value of each argument is not by default displayed in help message. Specifying ``true`` to |ArgumentParser.defaultHelp| method will display the default value of each argument in help message:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog") .defaultHelp(true); parser.addArgument("--foo") .type(Integer.class) .setDefault(42) .help("FOO!"); parser.addArgument("bar") .nargs("*") .setDefault(1, 2, 3) .help("BAR!"); parser.printHelp(); } .. code-block:: console $ java Demo usage: prog [-h] [-f FOO] [bar [bar ...]] positional arguments: bar BAR! (default: [1, 2, 3]) optional arguments: -h, --help show this help message and exit -f FOO, --foo FOO FOO! (default: 42) .. _ArgumentParser-usage: ArgumentParser.usage() ^^^^^^^^^^^^^^^^^^^^^^ By default, :javadoc:`inf.ArgumentParser` calculates the usage message from the arguments it contains:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").nargs("?").help("foo help"); parser.addArgument("bar").nargs("+").help("bar help"); Namespace res = parser.parseArgsOrFail(args); } .. code-block:: console $ java Demo -h usage: prog [-h] [--foo [FOO]] bar [bar ...] positional arguments: bar bar help optional arguments: -h, --help show this help message and exit --foo [FOO] foo help The default message can be overridden with the |ArgumentParser.usage| method:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog") .usage("${prog} [OPTIONS]"); parser.addArgument("--foo").nargs("?").help("foo help"); parser.addArgument("bar").nargs("+").help("bar help"); Namespace res = parser.parseArgsOrFail(args); } .. code-block:: console $ java Demo -h usage: prog [OPTIONS] positional arguments: bar bar help optional arguments: -h, --help show this help message and exit --foo [FOO] foo help The ``${prog}`` literal string in the given usage message will be replaced with the program name :ref:`ArgumentParsers-newArgumentParser-prog`. .. _ArgumentParser-version: ArgumentParser.version() ^^^^^^^^^^^^^^^^^^^^^^^^ The |ArgumentParser.version| method sets the string describing program version. It will be displayed when :ref:`Arguments-version` action is used. The ``${prog}`` literal string in the given string will be replaced with the program name :ref:`ArgumentParsers-newArgumentParser-prog`. .. _ArgumentParser-addArgument: The ArgumentParser.addArgument() method --------------------------------------- |ArgumentParser.addArgument| method creates new :javadoc:`inf.Argument` object and adds it to ArgumentParser's internal memory and returns the object to the user code. :javadoc:`inf.Argument` object defines how a single command line argument should be parsed. |ArgumentParser.addArgument| method receives :ref:`ArgumentParser-addArgument-nameOrFlags` argument, which is either a name or a list of option strings, e.g. ``"foo"`` or ``"-f", "--foo"``. After obtained :javadoc:`inf.Argument` object, several parameters can be specified using following methods: * :ref:`Argument-action` - The basic type of action to be taken when this argument is encountered at the command line. * :ref:`Argument-nargs` - The number of command line arguments that should be consumed. * :ref:`Argument-setConst` - A constant value required by some :ref:`Argument-action` and :ref:`Argument-nargs` selections. * :ref:`Argument-setDefault` - The value produced if the argument is absent from the command line. * :ref:`Argument-type` - The type to which the command line argument should be converted. * :ref:`Argument-choices` - A collection of the allowable values for the argument. * :ref:`Argument-required` - Whether or not the command line option may be omitted(optional arguments only). * :ref:`Argument-help` - A brief description of what the argument does. * :ref:`Argument-metavar` - A name for the argument in usage messages. * :ref:`Argument-dest` - The name of the attribute to be added as a result of |ArgumentParser.parseArgs| method. The following sections describe how each of these are used. .. _Argumentparser-addArgument-nameOrFlags: nameOrFlags ^^^^^^^^^^^ The |ArgumentParser.addArgument| method must know whether an optional argument, like ``-f`` or ``--foo``, or a positional argument, like a list of filenames, is expected. The arguments passed to |ArgumentParser.addArgument| must therefore be either a series of flags, or a simple argument name. For example, an optional argument could be created like:: parser.addArgument("-f", "--foo"); while a positional argument could be created like:: parser.addArgument("bar"); When |ArgumentParser.parseArgs| is called, optional arguments will be identified by the ``-`` prefix (or one of :ref:`ArgumentParsers-newArgumentParser-prefixChars` if it is specified in |ArgumentParsers.newArgumentParser|, and the remaining arguments will be assumed to be positional:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("-f", "--foo"); parser.addArgument("bar"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo BAR Namespace(foo=null, bar=BAR) $ java Demo BAR --foo FOO Namespace(foo=FOO, bar=BAR) $ java Demo --foo FOO usage: prog [-h] [-f FOO] bar prog: error: too few arguments .. _Argument-action: Argument.action() ^^^^^^^^^^^^^^^^^ :javadoc:`inf.Argument` objects associate command line arguments with actions. These actions can do just about anything with command line arguments associated with them, though most of the actions simply add an attribute to the object returned by |ArgumentParser.parseArgs|. The |Argument.action| method specifies how the command line arguments should be handled. The supported actions follow. .. _Arguments-store: Arguments.store() ~~~~~~~~~~~~~~~~~ |Arguments.store| just stores the argument's value. This is the default action. For example:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("-f", "--foo"); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo --foo 1 Namespace(foo=1) .. _Arguments-storeConst: Arguments.storeConst() ~~~~~~~~~~~~~~~~~~~~~~ |Arguments.storeConst| stores the value specified by the :ref:`Argument-setConst`. (Note that by default const value is the rather unhelpful ``null``.) The |Arguments.storeConst| action is most commonly used with optional arguments that specify sort of flags. For example:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").action(Arguments.storeConst()).setConst(42); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo --foo Namespace(foo=42) .. _Arguments-storeBool: Arguments.storeTrue() and Arguments.storeFalse() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |Arguments.storeTrue| and |Arguments.storeFalse| are special cases of :ref:`Arguments-storeConst` using for storing values ``true`` and ``false`` respectively. In addition, they create default values of ``false`` and ``true`` respectively. For example:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").action(Arguments.storeTrue()); parser.addArgument("--bar").action(Arguments.storeFalse()); parser.addArgument("--baz").action(Arguments.storeFalse()); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo --foo --bar Namespace(baz=true, foo=true, bar=false) .. _Arguments-appendAction: Arguments.append() ~~~~~~~~~~~~~~~~~~ |Arguments.append| stores a list, and appends each argument value to the list. The list is of type :javatype:`List`. This is useful to allow an option to be specified multiple times. For example:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").action(Arguments.append()); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo --foo 1 --foo 2 Namespace(foo=[1, 2]) .. _Arguments-appendConst: Arguments.appendConst() ~~~~~~~~~~~~~~~~~~~~~~~ |Arguments.appendConst| stores a list, and appends the value specified by :ref:`Argument-setConst` to the list. (Note that the const value defaults to ``null``.) The list is of type :javatype:`List`. The |Arguments.appendConst| action is typically useful when multiple arguments need to store constants to the same list. For example:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--str") .dest("types") .action(Arguments.appendConst()) .setConst(String.class); parser.addArgument("--int") .dest("types") .action(Arguments.appendConst()) .setConst(Integer.class); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo --str --int Namespace(types=[class java.lang.String, class java.lang.Integer]) .. _Arguments-count: Arguments.count() ~~~~~~~~~~~~~~~~~ |Arguments.count| counts the number of times an option occurs. For example, this is useful for increasing verbosity levels:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--verbose", "-v").action(Arguments.count()); Namespace res = parser.parseArgsOrFail(args); System.out.println(res); } .. code-block:: console $ java Demo -vvv Namespace(verbose=3) .. _Arguments-version: Arguments.version() ~~~~~~~~~~~~~~~~~~~ |Arguments.version| prints version string specified by :ref:`ArgumentParser-version` and exists when invoked:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("PROG") .version("${prog} 2.0"); parser.addArgument("--version").action(Arguments.version()); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo --version PROG 2.0 .. _Arguments-help: Arguments.help() ~~~~~~~~~~~~~~~~ |Arguments.help| prints help message and exits when invoked:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog", /*defaultHelp*/ false); parser.addArgument("--help").action(Arguments.help()); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo --help usage: prog [--help] optional arguments: --help Custom actions ~~~~~~~~~~~~~~ You can also specify your custom action by implementing :javadoc:`inf.ArgumentAction` interface. For example:: private static class FooAction implements ArgumentAction { @Override public void run(ArgumentParser parser, Argument arg, Map attrs, String flag, Object value) throws ArgumentParserException { System.out.printf("%s '%s' %s\n", attrs, value, flag); attrs.put(arg.getDest(), value); } @Override public void onAttach(Argument arg) { } @Override public boolean consumeArgument() { return true; } } public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); FooAction fooAction = new FooAction(); parser.addArgument("--foo").action(fooAction); parser.addArgument("bar").action(fooAction); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo 1 --foo 2 {foo=null, bar=null} '1' null {foo=null, bar=1} '2' --foo Namespace(foo=2, bar=1) .. _Argument-nargs: Argument.nargs() ^^^^^^^^^^^^^^^^ :javadoc:`inf.ArgumentParser` objects usually associate a single command line argument with a single action to be taken. The |Argument.nargs| associate different number of command line arguments with a single action. The supported values are: * ``N`` (an integer). ``N`` arguments from the command line will be gathered into a :javatype:`List`. For example:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").nargs(2); parser.addArgument("bar").nargs(1); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo c --foo a b Namespace(foo=[a, b], bar=[c]) Note that ``nargs(1)`` produces a list of one item. This is different from the default, in which the item is produced by itself. * ``"?"``. One argument will be consumed from the command line if possible, and produced as a single item. If no command line argument is present, the value from :ref:`Argument-setDefault` will be produced. Note that for optional arguments, there is an additional case - the option string is present but not followed by a command line argument. In this case the value from :ref:`Argument-setConst` will be produced. Some examples to illustrate this:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").nargs("?").setConst("c").setDefault("d"); parser.addArgument("bar").nargs("?").setDefault("d"); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo XX --foo YY Namespace(foo=YY, bar=XX) $ java Demo XX --foo Namespace(foo=c, bar=XX) $ java Demo Namespace(foo=d, bar=d) One of the more common usage of ``nargs("?")`` is to allow optional input and output files:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("infile").nargs("?").type(FileInputStream.class) .setDefault(System.in); parser.addArgument("outfile").nargs("?").type(PrintStream.class) .setDefault(System.out); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo input.txt output.txt Namespace(infile=java.io.FileInputStream@4ce86da0, outfile=java.io.PrintStream@2f754ad2) $ java Demo Namespace(infile=java.io.BufferedInputStream@e05d173, outfile=java.io.PrintStream@1ff9dc36) It is not obvious that outfile points to output.txt from the abolve output, but it is actually PrintStream to outfile.txt. * ``"*"``. All command line arguments present are gathered into a :javatype:`List`. Note that it generally does not make sense to have more than one positional argument with ``nargs("*")``, but multiple optional arguments with ``nargs("*")`` is possible. For example:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").nargs("*"); parser.addArgument("--bar").nargs("*"); parser.addArgument("baz").nargs("*"); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo Namespace(baz=[], foo=null, bar=null) $ java Demo a b --foo x y --bar 1 2 Namespace(baz=[a, b], foo=[x, y], bar=[1, 2]) * ``"+"``. Just like ``"*"``, all command line arguments present are gathered into a :javatype:`List`. Additionally, an error message will be generated if there wasn't at least one command line argument present. For example:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("foo").nargs("+"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo a b Namespace(foo=[a, b]) $ java Demo usage: prog [-h] foo [foo ...] prog: error: too few arguments If |Argument.nargs| is not used, the number of arguments consumed is determined by the :ref:`Argument-action`. Generally this means a single command line argument will be consumed and a single item(not a :javatype:`List`) will be produced. Please note that |Argument.nargs| are ignored if one of :ref:`Arguments-storeConst`, :ref:`Arguments-appendConst`, :ref:`Arguments-storeBool` is provided. More specifically, subclass of :javadoc:`inf.ArgumentAction` whose :javafunc:`consumeArgument()` returns ``false`` ignores |Argument.nargs|. .. _Argument-setConst: Argument.setConst() ^^^^^^^^^^^^^^^^^^^ The |Argument.setConst| is used to hold constant values that are not read from the command line but are required for the various actions. The two most common uses of it are: * When :ref:`Arguments-storeConst` or :ref:`Arguments-appendConst` are specified. These actions add the value spcified by |Argument.setConst| to one of the attributes of the object returned by |ArgumentParser.parseArgs|. See the :ref:`Argument-action` for examples. * When |ArgumentParser.addArgument| is called with option strings (like ``-f`` or ``--foo``) and ``nargs("?")`` is used. This creates an optional argument that can be followed by zero or one command line argument. When parsing the command line, if the option string is encountered with no command line argument following it, the value specified by |Argument.setConst| will be assumed instead. See the :ref:`Argument-nargs` description for examples. The const value defauls to ``null``. .. _Argument-setDefault: Argument.setDefault() ^^^^^^^^^^^^^^^^^^^^^ All optional arguments and some positional arguments may be omitted at the command line. The |Argument.setDefault| specifies what value should be used if the command line argument is not present. The default value defaults to ``null``. For optional arguments, the default value is used when the option string was not present at the command line:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").setDefault(42); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo --foo 2 Namespace(foo=2) $ java Demo Namespace(foo=42) For positional arguments with ``nargs("?")`` or ``nargs("*")``, the default value is used when no command line argument was present:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("foo").nargs("?").setDefault(42); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo a Namespace(foo=a) $ java Demo Namespace(foo=42) Providing :javafield:`Arguments.SUPPRESS` causes no attribute to be added if the command ine argument was not present:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").setDefault(Arguments.SUPPRESS); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo Namespace() $ java Demo --foo 1 Namespace(foo=1) .. _Argument-type: Argument.type() ^^^^^^^^^^^^^^^ By default, :javadoc:`inf.ArgumentParser` objects read command line arguments in as simple strings. However, quite often the command line string should instead be interpreted as another type, like a :javatype:`Float` or :javatype:`Integer`. The |Argument.type| allows any necessary type-checking and type conversions to be performed. The Classes which have :javafunc:`valueOf()` static method with 1 String argument or a constructor with 1 String argument can be passed directly:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("foo").type(Integer.class); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo 100 Namespace(foo=100) As a convenience, if one of following primitive types (``boolean.class``, ``byte.class``, ``short.class``, ``int.class``, ``long.class``, ``float.class`` and ``double.class``) is specified, it is converted to its wrapped type counterpart. For example, if ``int.class`` is given, it is automatically converted to ``Integer.class``. The |Argument.type| can accept enums. Since enums have limited number of members, type conversion effectively acts like a choice from members. For example:: enum Enums { FOO, BAR, BAZ } public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("-x").type(Enums.class); try { Namespace res = parser.parseArgs(args); System.out.println(res); Enums x = (Enums) res.get("x"); System.out.printf("x=%s\n", x.name()); } catch (ArgumentParserException e) { parser.handleError(e); System.exit(1); } } .. code-block:: console $ java Demo -x BAR Namespace(x=BAR) x=BAR $ java Demo -h usage: prog [-h] [-x X] optional arguments: -h, --help show this help message and exit -x X To show available enum values in help message, use |Argument.choices|:: parser.addArgument("-x").type(Enums.class).choices(Enums.values()); .. code-block:: console $ java Demo -h usage: prog [-h] [-x {FOO,BAR,BAZ}] optional arguments: -h, --help show this help message and exit -x {FOO,BAR,BAZ} To limit enum values to choose from, specify them in |Argument.choices|:: parser.addArgument("-x").type(Enums.class).choices(Enums.FOO, Enums.BAZ); .. code-block:: console $ java Demo -h usage: prog [-h] [-x {FOO,BAZ}] optional arguments: -h, --help show this help message and exit -x {FOO,BAZ} The |Argument.type| has a version which accepts an object which implements :javadoc:`inf.ArgumentType` interface:: private static class PerfectSquare implements ArgumentType { @Override public Integer convert(ArgumentParser parser, Argument arg, String value) throws ArgumentParserException { try { int n = Integer.parseInt(value); double sqrt = Math.sqrt(n); if (sqrt != (int) sqrt) { throw new ArgumentParserException(String.format( "%d is not a perfect square", n), parser); } return n; } catch (NumberFormatException e) { throw new ArgumentParserException(e, parser); } } } public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("foo").type(new PerfectSquare()); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo 9 Namespace(foo=9) $ java Demo 7 usage: prog [-h] foo prog: error: 7 is not a perfect square The :ref:`Argument-choices` may be more convenient for type checkers that simply check against a range of values:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("foo").type(Integer.class) .choices(Arguments.range(5, 10)); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo 7 Namespace(foo=7) $ java Demo 11 usage: prog [-h] foo prog: error: foo expects value in range [5, 10], inclusive See :ref:`Argument-choices` for more details. .. _Argument-choices: Argument.choices() ^^^^^^^^^^^^^^^^^^ Some command line arguments should be selected from a restricted set of values. These can be handled by passing a list of objects to |Argument.choices|. When the command line is parsed, argument values will be checked, and an error message will be displayed if the argument was not one of the accepted values:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("foo").choices("a", "b", "c"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo c Namespace(foo=c) $ java Demo X usage: prog [-h] {a,b,c} prog: error: argument foo: invalid choice: 'X' (choose from {a,b,c}) Note that inclusion in the choices list is checked after any type conversions have been performed. If a list of value is not enough, you can create your own by subclassing :javadoc:`inf.ArgumentChoice`. For example, argparse4j provides |Arguments.range| to check whether an integer is in specified range:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("foo").type(Integer.class) .choices(Arguments.range(1, 10)); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo 1 Namespace(foo=1) $ java Demo 11 usage: prog [-h] foo prog: error: foo expects value in range [1, 10], inclusive Please pay attention to the type specified in :ref:`Argument-type` and type in |Argument.choices|. If they are not compatible, subclass of :javatype:`RuntimeException` will be thrown. .. _Argument-required: Argument.required() ^^^^^^^^^^^^^^^^^^^ In general, the :javadoc:`inf.ArgumentParser` assumes that flags like ``-f`` and ``--bar`` indicate optional arguments, which can always be omitted at the command line. To make an option required, ``true`` can be specified for |Argument.required|:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").required(true); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo --foo BAR Namespace(foo=BAR) $ java Demo usage: prog [-h] --foo FOO prog: error: argument --foo is required As the example shows, if an option is marked as required, |ArgumentParser.parseArgs| will report an error if that option is not present at the command line. |Argument.required| will be ignored for positional arguments. .. Note:: Required options are generally considered bad form because users expect options to be optional, and thus they should be avoided when possible. .. _Argument-help: Argument.help() ^^^^^^^^^^^^^^^ |Argument.help| method can take string containing a brief description of the argument. When a user requests help (usually by using ``-h`` or ``--help`` at the command line), these help descriptions will be displayed with each argument:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").action(Arguments.storeTrue()) .help("foo the bars before frobbling"); parser.addArgument("bar").nargs("+").help("one of the bars to be frobbled"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo -h usage: prog [-h] [--foo] bar [bar ...] positional arguments: bar one of the bars to be frobbled optional arguments: -h, --help show this help message and exit --foo foo the bars before frobbling The help strings are used as is: no special string replacement will not be done. The argparse4j supports silencing the help entry for certain options, by passing :javafield:`Arguments.SUPPRESS` to |Argument.help| method:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").help(Arguments.SUPPRESS); try { Namespace ns = parser.parseArgs(args); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo -h usage: prog [-h] optional arguments: -h, --help show this help message and exit .. _Argument-metavar: Argument.metavar() ^^^^^^^^^^^^^^^^^^ When :javadoc:`inf.ArgumentParser` generates help messages, it need some way to referer to each expected argument. By default, :javadoc:`inf.ArgumentParser` objects use the "dest" value (see :ref:`Argument-dest` about "dest" value) as the "name" of each object. By default, for positional arguments, the dest value is used directly, and for optional arguments, the dest value is uppercased. So, a single positional argument with ``dest("bar")`` will be referred to as ``bar``. A single optional argument ``--foo`` that should be followed by a single command line argument will be referred to as ``FOO``. For example:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo"); parser.addArgument("bar"); parser.printHelp(); } .. code-block:: console $ java Demo usage: prog [-h] [--foo FOO] bar positional arguments: bar optional arguments: -h, --help show this help message and exit --foo FOO An alternative name can be specified with |Argument.metavar| method:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").metavar("YY"); parser.addArgument("bar").metavar("XX"); parser.printHelp(); } .. code-block:: console $ java Demo usage: prog [-h] [--foo YY] XX positional arguments: XX optional arguments: -h, --help show this help message and exit --foo YY Note that |Argument.metavar| method only changes the displayed name - the name of the attribute in the object returned by |ArgumentParser.parseArgs| method is still determined by the dest value. Different values of :ref:`Argument-nargs` may cause the metavar to be used multiple times. Providing multiple values to |Argument.metavar| method specifies a different display for each of the arguments:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("-x").nargs(2); parser.addArgument("--foo").nargs(2).metavar("bar", "baz"); parser.printHelp(); } .. code-block:: console $ java Demo usage: prog [-h] [-x X X] [--foo bar baz] optional arguments: -h, --help show this help message and exit -x X X --foo bar baz If the number of values specified in |Argument.metavar| is not sufficient for the number of arguments given in :ref:`Argument-nargs`, the last value of metavar is repeated. .. _Argument-dest: Argument.dest() ^^^^^^^^^^^^^^^ Most :javadoc:`inf.ArgumentParser` actions add some values as an attribute of the object returned by |ArgumentParser.parseArgs| method. The name of this attribute is determined by "dest". For positional arguments, dest is normally supplied as the first argument to |ArgumentParser.addArgument| method:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("bar"); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo XX Namespace(bar=XX) For optional arguments, the value of dest is normally inferred from the option strings. :javadoc:`inf.ArgumentParser` generates the value of dest by taking the first long option string and stripping away the initial ``--`` string. If no long option strings were supplied, dest will be derived from the first short option string by stripping the initial ``-`` character. Any internal ``-`` characters will be converted to ``_``. The example below illustrate this behavior:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("-f", "--foo-bar", "--foo"); parser.addArgument("-x", "-y"); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo -f 1 -x 2 Namespace(x=2, foo_bar=1) $ java Demo --foo 1 -y 2 Namespace(x=2, foo_bar=1) |Argument.dest| method allows a custom attribute name to be provided:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").dest("bar"); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo --foo XX Namespace(bar=XX) .. _ArgumentParser-parseArgs: The ArgumentParser.parseArgs() method ------------------------------------- |ArgumentParser.parseArgs| method converts argument strings to objects and populates :javadoc:`inf.Namespace` object with these values. The populated :javadoc:`inf.Namespace` object is returned. Previous calls to |ArgumentParser.addArgument| method determine exactly what objects are created and how they are assigned. See the documentation for :ref:`Adding-arguments` for details. :javadoc:`inf.ArgumentParser` also provides a way to populate attributes other than using :javadoc:`inf.Namespace` object. See :ref:`Namespace` for details. Option value syntax ^^^^^^^^^^^^^^^^^^^ |ArgumentParser.parseArgs| method supports several ways of specifying the value of an option (if it takes one). In the simplest case, the option and its value are passed as two separate arguments:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("-x"); parser.addArgument("--foo"); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo -x X Namespace(foo=null, x=X) $ java Demo --foo FOO Namespace(foo=FOO, x=null) For long options (options with names longer than single character), the option and value can also be passed as a single command line argument, using ``=`` to separate them: .. code-block:: console $ java Demo --foo=FOO Namespace(foo=FOO, x=null) For short options (options only one character long), the option and its value can be concatenated: .. code-block:: console $ java Demo -xX Namespace(foo=null, x=X) Several short options can be joined together, using only a single ``-`` prefix, as long as only the last option (or none of them) requires a value:: public static void main(String[] args) throws ArgumentParserException { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("-x").action(Arguments.storeTrue()); parser.addArgument("-y").action(Arguments.storeTrue()); parser.addArgument("-z"); System.out.println(parser.parseArgs(args)); } .. code-block:: console $ java Demo -xyzZ Namespace(z=Z, y=true, x=true) Invalid arguments ^^^^^^^^^^^^^^^^^ While parsing the command line, |ArgumentParser.parseArgs| method checks for a variety of errors, including invalid types, invalid options, wrong number of positional arguments, etc. When it encounters such an error, it throws :javadoc:`inf.ArgumentParserException`. The typical error handling is catch the exception and use |ArgumentParser.handleError| method to print error message and exit the program:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").type(Integer.class); parser.addArgument("bar").nargs("?"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); System.exit(1); } } .. code-block:: console $ java Demo --foo spam usage: prog [-h] [--foo FOO] [bar] prog: error: argument --foo: could not convert 'spam' to Integer (For input string: "spam") $ java Demo --bar usage: prog [-h] [--foo FOO] [bar] prog: error: unrecognized arguments: --bar $ java Demo spam badger usage: prog [-h] [--foo FOO] [bar] prog: error: unrecognized arguments: badger Arguments containing "-" ^^^^^^^^^^^^^^^^^^^^^^^^ |ArgumentParser.parseArgs| method attempts to give errors whenever the user has cearly made a mistake, but some situations are inherently ambiguous. For example, the command line argument ``-1`` could either be an attempt to specify an option or an attempt to provide a positional argument. The |ArgumentParser.parseArgs| method is cautious here: positional arguments may only begin with ``-`` if they look like negative numbers and there are no options in the parser that look like negative numbers:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("-x"); parser.addArgument("foo").nargs("?"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); System.exit(1); } } .. code-block:: console $ # no negative number options, so -1 is a positional argument $ java Demo -x -1 Namespace(foo=null, x=-1) $ # no negative number options, so -1 and -5 are positional arguments $ java Demo -x -1 -5 Namespace(foo=-5, x=-1) :: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("-1").dest("one"); parser.addArgument("foo").nargs("?"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); System.exit(1); } } .. code-block:: console $ # negative number options present, so -1 is an option $ java Demo -1 X Namespace(one=X, foo=null) $ # negative number options present, so -2 is an option $ java Demo -2 usage: prog [-h] [-1 ONE] [foo] prog: error: unrecognized arguments: -2 $ # negative number options present, so both -1s are options $ java Demo -1 -1 usage: prog [-h] [-1 ONE] [foo] prog: error: argument -1: expected one argument If you have positional arguments that must begin with ``-`` and don't look like negative numbers, you can insert the pseudo-argument ``--`` which tells |ArgumentParser.parseArgs| method that everything after that is a positional argument: .. code-block:: console $ java Demo -- -f Namespace(one=null, foo=-f) Please note that whatever :ref:`ArgumentParsers-newArgumentParser-prefixChars` is specified in |ArgumentParsers.newArgumentParser| method, pseudo-argument is ``--``. After ``--``, sub-command cannot be recognized. Argument abbreviations ^^^^^^^^^^^^^^^^^^^^^^ The |ArgumentParser.parseArgs| method allows long options to be abbreviated if the abbreviation is unambiguous:: public static void main(String[] args) { ArgumentParser ap = ArgumentParsers.newArgumentParser("prog"); ap.addArgument("-bacon"); ap.addArgument("-badger"); Namespace res = ap.parseArgsOrFail(args); System.out.println(res); } .. code-block:: console $ java Demo -bac MMM Namespace(bacon=MMM, badger=null) $ java Demo -bad WOOD Namespace(bacon=null, badger=WOOD) $ java Demo -ba BA usage: prog [-h] [-bacon BACON] [-badger BADGER] prog: error: ambiguous option: -ba could match -bacon, -badger An error is produced for arguments that could produce more than one options. .. _Namespace: The Namespace object -------------------- :javadoc:`inf.Namespace` object is used to store attributes as a result of |ArgumentParser.parseArgs| method. It is just a wrapper to :javatype:`Map` and several shortcut getter methods are provided. The actual attributes are stored in :javatype:`Map` object and can be retrieved using |Namespace.getAttrs| method. You don't have to use :javadoc:`inf.Namespace` object. You can directly populate attributes to your :javatype:`Map` object using |ArgumentParser.parseArgs| method. You can also assign values to user defined object. In this case, you can use :javadoc:`annotation.Arg` annotation to designate where the attribute to be stored. To specify the name of attribute to assign, use :javatype:`Arg.dest`; if it is not specified the name of the attribute or the method will be used instead. For example:: private static class Option { @Arg(dest = "filename") public String filename; @Arg(dest = "rows") public int matrix[][]; @Arg public String url; } public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--rows").type(Integer.class).nargs("+") .action(Arguments.append()).metavar("N"); parser.addArgument("--filename"); parser.addArgument("--url"); Option opt = new Option(); try { parser.parseArgs(args, opt); System.out.println("outusername=" + opt.filename); System.out.println("outurl=" + opt.url); int rows = opt.matrix.length; for (int i = 0; i < rows; ++i) { int cols = opt.matrix[i].length; for (int j = 0; j < cols; ++j) { System.out.printf("%d\t", opt.matrix[i][j]); } System.out.println(); } } catch (ArgumentParserException e) { parser.handleError(e); System.exit(1); } } .. code-block:: console $ java Demo --rows 1 2 3 --rows 4 5 6 --filename out --url http://example.com outusername=out http://example.com 1 2 3 4 5 6 As shown above, argparse4j supports simple :javatype:`List` to array conversion. This is useful if you want primitive int array instead of :javatype:`List` of Integers. Other utilities --------------- .. _Sub-commands: Sub-commands ^^^^^^^^^^^^ Many programs split up their functionality into a number of sub-commands, for example, the git program can invoke sub-commands like ``git stash``, ``git checkout`` and ``git commit``. Splitting up functionality this way can be a particularly good idea when a program performs several different functions which requires different kinds of command-line arguments. :javadoc:`inf.ArgumentParser` supports the creation of such sub-commands with the |ArgumentParser.addSubparsers| method. |ArgumentParser.addSubparsers| method is normally called with no arguments and returns :javadoc:`inf.Subparsers` object. This object has |Subparsers.addParser| method, which takes a command name and returns :javadoc:`inf.Subparser` object. |Subparsers.addParser| method can take *prefixChars* argument just like :ref:`ArgumentParsers-newArgumentParser-prefixChars` of |ArgumentParsers.newArgumentParser| method. If a version of |Subparsers.addParser| method without *prefixChars* is used, *prefixChars* is inherited from main parser. Some example usage:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").action(Arguments.storeTrue()).help("foo help"); Subparsers subparsers = parser.addSubparsers().help("sub-command help"); Subparser parserA = subparsers.addParser("a").help("a help"); parserA.addArgument("bar").type(Integer.class).help("bar help"); Subparser parserB = subparsers.addParser("b").help("b help"); parserB.addArgument("--baz").choices("X", "Y", "Z").help("baz help"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); System.exit(1); } } .. code-block:: console $ java Demo a 12 Namespace(foo=false, bar=12) $ java Demo --foo b --baz Z Namespace(baz=Z, foo=true) Note that the object returned by |ArgumentParser.parseArgs| method will only contain attributes for the main parser and the subparser that was selected by the command line (and not any other subparsers). So in the example above, when the ``a`` command is specified, only the ``foo`` and ``bar`` attributes are present, and when the ``b`` command is specified, only ``foo`` and ``baz`` attributes are present. Similarly, when a help message is requested from a subparser, only the help for that particular parser will be printed. The help message will not include parent parser or sibling parser messages (A help message for each subparser command, however, can be given using |Subparser.help| method.): .. code-block:: console $ java Demo --help usage: prog [-h] [--foo] {a,b} ... positional arguments: {a,b} sub-command help a a help b b help optional arguments: -h, --help show this help message and exit --foo foo help $ java Demo a --help usage: prog a [-h] bar positional arguments: bar bar help optional arguments: -h, --help show this help message and exit $ java Demo b --help usage: prog b [-h] [--baz BAZ] optional arguments: -h, --help show this help message and exit --baz BAZ baz help :javadoc:`inf.Subparsers` also has |Subparsers.title| method and |Subparsers.description| method. When either is present, the subparser's commands will appear in their own group in the help output. For example:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); Subparsers subparsers = parser.addSubparsers() .title("subcommands") .description("valid subcommands") .help("additional help"); subparsers.addParser("foo"); subparsers.addParser("bar"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); System.exit(1); } } .. code-block:: console $ java Demo -h usage: prog [-h] {foo,bar} ... optional arguments: -h, --help show this help message and exit subcommands: valid subcommands {foo,bar} additional help As you can see above, all sub-commands are printed in help message. It would be good for only 2 or 3 sub-commands, but if there are many sub-commands, the display will become quite ugly. In that case, |Subparsers.metavar| method sets text to use instead of all sub-command names. For example:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); Subparsers subparsers = parser.addSubparsers().title("subcommands") .description("valid subcommands").help("additional help") .metavar("COMMAND"); subparsers.addParser("foo").help("foo help"); subparsers.addParser("bar").help("bar help"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); System.exit(1); } } .. code-block:: console $ java Demo -h usage: prog [-h] COMMAND ... optional arguments: -h, --help show this help message and exit subcommands: valid subcommands COMMAND additional help foo foo help bar bar help Furthermore, :javadoc:`inf.Subparser` supports alias names, which allows multiple strings to refer to the same subparser. This example, like ``svn``, aliases ``co`` as a shorthand for ``checkout``:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); Subparsers subparsers = parser.addSubparsers(); Subparser checkout = subparsers.addParser("checkout").aliases("co"); checkout.addArgument("foo"); Namespace ns = parser.parseArgsOrFail(args); System.out.println(ns); } .. code-block:: console $ java Demo co bar Namespace(foo=bar) One particularly effective way of handling sub-commands is to combine the use of |Subparser.setDefault| method so that each subparser knows which function it should execute. For example:: private static interface Accumulate { int accumulate(Collection ints); } private static class Sum implements Accumulate { @Override public int accumulate(Collection ints) { int sum = 0; for (Integer i : ints) { sum += i; } return sum; } @Override public String toString() { return getClass().getSimpleName(); } } private static class Max implements Accumulate { @Override public int accumulate(Collection ints) { return Collections.max(ints); } @Override public String toString() { return getClass().getSimpleName(); } } public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); Subparsers subparsers = parser.addSubparsers(); Subparser parserSum = subparsers.addParser("sum") .setDefault("func", new Sum()); parserSum.addArgument("ints").type(Integer.class).nargs("*"); Subparser parserMax = subparsers.addParser("max") .setDefault("func", new Max()); parserMax.addArgument("ints").type(Integer.class).nargs("+"); try { Namespace res = parser.parseArgs(args); System.out.println(((Accumulate) res.get("func")) .accumulate((Collection) res.get("ints"))); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo sum 1 3 2 6 $ java Demo max 1 3 2 3 The alternative way is use |Subparsers.dest| method. With this dest value, the selected command name is stored as an attribute:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); Subparsers subparsers = parser.addSubparsers().dest("subparser_name"); Subparser subparser1 = subparsers.addParser("1"); subparser1.addArgument("-x"); Subparser subparser2 = subparsers.addParser("2"); subparser2.addArgument("y"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo 2 frobble Namespace(subparser_name=2, y=frobble) Subparsers allows sub-command names to be abbreviated as long as the abbreviation is unambiguous, just like long options:: enum Command { CLONE, CLEAN }; public static void main(String[] args) { ArgumentParser ap = ArgumentParsers.newArgumentParser("prog"); Subparsers subparsers = ap.addSubparsers(); subparsers.addParser("clone").setDefault("command", Command.CLONE); subparsers.addParser("clean").setDefault("command", Command.CLEAN); Namespace res = ap.parseArgsOrFail(args); System.out.println(res); } .. code-block:: console $ java Demo clo Namespace(command=CLONE) $ java Demo cle Namespace(command=CLEAN) $ java Demo cl usage: prog [-h] {clone,clean} ... prog: error: ambiguous command: cl could match clean, clone An error is produced for arguments that could produce more than one sub-commands. fileType() ^^^^^^^^^^ The |Arguments.fileType| will convert an argument to :javatype:`File` object. It has several convenient verification features such as checking readability or existence of a given path. The command-line programs traditionally accept ``-`` as standard input. The |Arguments.fileType| supports this tradition too. To enable this, just use `acceptSystemIn()` method:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog") .defaultHelp(true); parser.addArgument("-i", "--in") .type(Arguments.fileType().acceptSystemIn().verifyCanRead()) .setDefault("-"); parser.addArgument("-o", "--out").type(Arguments.fileType()); try { Namespace ns = parser.parseArgs(args); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo -h usage: prog [-h] [-i IN] [-o OUT] optional arguments: -h, --help show this help message and exit -i IN, --in IN (default: -) -o OUT, --out OUT $ java Demo -i not-found usage: prog [-h] [-i IN] [-o OUT] prog: error: argument -i/--in: Insufficient permissions to read file: 'not-found' Argument groups ^^^^^^^^^^^^^^^ By default, :javadoc:`inf.ArgumentParser` groups command line arguments into "positional arguments" and "optional arguments" when displaying help messages. When there is a better conceptual grouping of arguments than this default one, appropriate groups can be created using the |ArgumentParser.addArgumentGroup|:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); ArgumentGroup group = parser.addArgumentGroup("group"); group.addArgument("--foo").help("foo help"); group.addArgument("bar").help("bar help"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo -h usage: prog [-h] [--foo FOO] bar positional arguments: optional arguments: -h, --help show this help message and exit group: --foo FOO foo help bar bar help |ArgumentParser.addArgumentGroup| returns :javadoc:`inf.ArgumentGroup` object which has |ArgumentGroup.addArgument| just like a :javadoc:`inf.ArgumentParser`. When an argument is added to the group, the parser treats it just like a normal argument, but displays the argument in a separate group for help messages. With the title string specified in |ArgumentParser.addArgumentGroup| and the description specified in |ArgumentGroup.description|, you can customize the help message:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog", false); ArgumentGroup group1 = parser.addArgumentGroup("group1") .description("group1 description"); group1.addArgument("foo").help("foo help"); ArgumentGroup group2 = parser.addArgumentGroup("group2") .description("group2 description"); group2.addArgument("--bar").help("bar help"); parser.printHelp(); } .. code-block:: console $ java Demo usage: prog [--bar BAR] foo group1: group1 description foo foo help group2: group2 description --bar BAR bar help Note that any arguments not in your user defined groups will end up back in the usual "positional arguments" and "optional arguments" sections. Mutual exclusion ^^^^^^^^^^^^^^^^ |ArgumentParser.addMutuallyExclusiveGroup| creates a mutually exclusive group. :javadoc:`inf.ArgumentParser` will make sure that only one of the arguments in the mutually exclusive group was present on the command line:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); MutuallyExclusiveGroup group = parser.addMutuallyExclusiveGroup(); group.addArgument("--foo").action(Arguments.storeTrue()); group.addArgument("--bar").action(Arguments.storeFalse()); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo --foo Namespace(foo=true, bar=true) $ java Demo --foo --bar usage: prog [-h] [--foo | --bar] prog: error: argument --bar: not allowed with argument --foo Specifying ``true`` to |MutuallyExclusiveGroup.required| indicates that at least one of the mutually exclusive arguments is required:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); MutuallyExclusiveGroup group = parser.addMutuallyExclusiveGroup("group") .required(true); group.addArgument("--foo").action(Arguments.storeTrue()); group.addArgument("--bar").action(Arguments.storeFalse()); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo usage: prog [-h] (--foo | --bar) prog: error: one of the arguments --foo --bar is required The :javadoc:`inf.MutuallyExclusiveGroup` support the title and description just like :javadoc:`inf.ArgumentGroup` object. If both title and description are not specified, the help message for this group is merged into the other optional arguments. With either or both title and description, the help message is in separate group:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); MutuallyExclusiveGroup group = parser.addMutuallyExclusiveGroup("group"); .description("group description"); group.addArgument("--foo").action(Arguments.storeTrue()); group.addArgument("--bar").action(Arguments.storeFalse()); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo -h usage: prog [-h] (--foo | --bar) optional arguments: -h, --help show this help message and exit group: group description --foo --bar Parser defaults ^^^^^^^^^^^^^^^ Most of the time, the attributes of the object returned by |ArgumentParser.parseArgs| will be fully determined by inspecting the command line arguments and the argument actions. |ArgumentParser.setDefault| allows some additional attributes that are determined without any inspection of the command line to be added:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("foo").type(Integer.class); parser.setDefault("bar", 42).setDefault("baz", "badger"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo 736 Namespace(baz=badger, foo=736, bar=42) Note that parser-level defaults always override argument-level defaults:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").setDefault("bar"); parser.setDefault("foo", "spam"); try { System.out.println(parser.parseArgs(args)); } catch (ArgumentParserException e) { parser.handleError(e); } } .. code-block:: console $ java Demo Namespace(foo=spam) Parser-level defaults can be particularly useful when working with multiple parsers. See :ref:`Sub-commands` for an example of this type. |ArgumentParser.getDefault| returns the default value for a attribute, as set by either |Argument.setDefault| or by |ArgumentParser.setDefault|:: public static void main(String[] args) { ArgumentParser parser = ArgumentParsers.newArgumentParser("prog"); parser.addArgument("--foo").setDefault("badger"); System.out.println(parser.getDefault("foo")); } .. code-block:: console $ java Demo badger Printing help ^^^^^^^^^^^^^ In most typical applications, |ArgumentParser.parseArgs| and |ArgumentParser.handleError| will take care of formatting and printing any usage or error messages. However, several formatting methods are available: * |ArgumentParser.printUsage| - Print a brief description of how the program should be invoked on the command line. * |ArgumentParser.printHelp| - Print a help message, including the program usage and information about the arguments registered with :javadoc:`inf.ArgumentParser`. .. |Argument.action| replace:: :javadocfunc:`inf.Argument.action(net.sourceforge.argparse4j.inf.ArgumentAction)` .. |Argument.choices| replace:: :javadocfunc:`inf.Argument.choices(E...)` .. |Argument.dest| replace:: :javadocfunc:`inf.Argument.dest(java.lang.String)` .. |Argument.help| replace:: :javadocfunc:`inf.Argument.help(java.lang.String)` .. |Argument.metavar| replace:: :javadocfunc:`inf.Argument.metavar(java.lang.String...)` .. |Argument.nargs| replace:: :javadocfunc:`inf.Argument.nargs(int)` .. |Argument.required| replace:: :javadocfunc:`inf.Argument.required(boolean)` .. |Argument.setConst| replace:: :javadocfunc:`inf.Argument.setConst(java.lang.Object)` .. |Argument.setDefault| replace:: :javadocfunc:`inf.Argument.setDefault(java.lang.Object)` .. |Argument.type| replace:: :javadocfunc:`inf.Argument.type(java.lang.Class)` .. |ArgumentGroup.addArgument| replace:: :javadocfunc:`inf.ArgumentGroup.addArgument(java.lang.String...)` .. |ArgumentGroup.description| replace:: :javadocfunc:`inf.ArgumentGroup.description(java.lang.String)` .. |ArgumentParser.addArgumentGroup| replace:: :javadocfunc:`inf.ArgumentParser.addArgumentGroup(java.lang.String)` .. |ArgumentParser.addArgument| replace:: :javadocfunc:`inf.ArgumentParser.addArgument(java.lang.String...)` .. |ArgumentParser.addMutuallyExclusiveGroup| replace:: :javadocfunc:`inf.ArgumentParser.addMutuallyExclusiveGroup()` .. |ArgumentParser.addSubparsers| replace:: :javadocfunc:`inf.ArgumentParser.addSubparsers()` .. |ArgumentParser.defaultHelp| replace:: :javadocfunc:`inf.ArgumentParser.defaultHelp(boolean)` .. |ArgumentParser.description| replace:: :javadocfunc:`inf.ArgumentParser.description(java.lang.String)` .. |ArgumentParser.epilog| replace:: :javadocfunc:`inf.ArgumentParser.epilog(java.lang.String)` .. |ArgumentParser.getDefault| replace:: :javadocfunc:`inf.ArgumentParser.getDefault(java.lang.String)` .. |ArgumentParser.handleError| replace:: :javadocfunc:`inf.ArgumentParser.handleError(net.sourceforge.argparse4j.inf.ArgumentParserException)` .. |ArgumentParser.parseArgs| replace:: :javadocfunc:`inf.ArgumentParser.parseArgs(java.lang.String[])` .. |ArgumentParser.printHelp| replace:: :javadocfunc:`inf.ArgumentParser.printHelp()` .. |ArgumentParser.printUsage| replace:: :javadocfunc:`inf.ArgumentParser.printUsage()` .. |ArgumentParser.setDefault| replace:: :javadocfunc:`inf.ArgumentParser.setDefault(java.lang.String, java.lang.Object)` .. |ArgumentParser.usage| replace:: :javadocfunc:`inf.ArgumentParser.usage(java.lang.String)` .. |ArgumentParser.version| replace:: :javadocfunc:`inf.ArgumentParser.version(java.lang.String)` .. |ArgumentParsers.newArgumentParser| replace:: :javadocfunc:`ArgumentParsers.newArgumentParser(java.lang.String)` .. |Arguments.appendConst| replace:: :javadocfunc:`impl.Arguments.appendConst()` .. |Arguments.append| replace:: :javadocfunc:`impl.Arguments.append()` .. |Arguments.count| replace:: :javadocfunc:`impl.Arguments.count()` .. |Arguments.enumType| replace:: :javadocfunc:`impl.Arguments.enumType(java.lang.Class)` .. |Arguments.fileType| replace:: :javadocfunc:`impl.Arguments.fileType()` .. |Arguments.help| replace:: :javadocfunc:`impl.Arguments.help()` .. |Arguments.range| replace:: :javadocfunc:`impl.Arguments.range(T, T)` .. |Arguments.storeConst| replace:: :javadocfunc:`impl.Arguments.storeConst()` .. |Arguments.storeFalse| replace:: :javadocfunc:`impl.Arguments.storeFalse()` .. |Arguments.storeTrue| replace:: :javadocfunc:`impl.Arguments.storeTrue()` .. |Arguments.store| replace:: :javadocfunc:`impl.Arguments.store()` .. |Arguments.version| replace:: :javadocfunc:`impl.Arguments.version()` .. |MutuallyExclusiveGroup.required| replace:: :javadocfunc:`inf.MutuallyExclusiveGroup.required(boolean)` .. |Namespace.getAttrs| replace:: :javadocfunc:`inf.Namespace.getAttrs()` .. |Subparser.dest| replace:: :javadocfunc:`inf.Subparser.dest(java.lang.String)` .. |Subparser.help| replace:: :javadocfunc:`inf.Subparser.help(java.lang.String)` .. |Subparser.setDefault| replace:: :javadocfunc:`inf.Subparser.setDefault(java.lang.String, java.lang.Object)` .. |Subparsers.addParser| replace:: :javadocfunc:`inf.Subparsers.addParser(java.lang.String)` .. |Subparsers.description| replace:: :javadocfunc:`inf.Subparsers.description(java.lang.String)` .. |Subparsers.dest| replace:: :javadocfunc:`inf.Subparsers.dest(java.lang.String)` .. |Subparsers.metavar| replace:: :javadocfunc:`inf.Subparsers.metavar(java.lang.String)` .. |Subparsers.title| replace:: :javadocfunc:`inf.Subparsers.title(java.lang.String)` argparse4j-argparse4j-0.4.4/src/test/000077500000000000000000000000001240010205600173555ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/000077500000000000000000000000001240010205600202765ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/000077500000000000000000000000001240010205600210645ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/000077500000000000000000000000001240010205600234075ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/000077500000000000000000000000001240010205600254515ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/ArgumentParsersTest.java000066400000000000000000000011571240010205600323020ustar00rootroot00000000000000package net.sourceforge.argparse4j; import static org.junit.Assert.*; import net.sourceforge.argparse4j.internal.ArgumentParserImpl; import org.junit.Test; public class ArgumentParsersTest { @Test public void testNewArgumentParser() { ArgumentParserImpl ap = (ArgumentParserImpl) ArgumentParsers .newArgumentParser("prog", false, "+", "@"); assertEquals("prog", ap.getProg()); assertEquals("+", ap.getPrefixChars()); assertEquals("@", ap.getFromFilePrefixChars()); // Check +h can be added because addHelp is false ap.addArgument("+h"); } } argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/helper/000077500000000000000000000000001240010205600267305ustar00rootroot00000000000000CJKTextWidthCounterTest.java000066400000000000000000000007071240010205600341740ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/helperpackage net.sourceforge.argparse4j.helper; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; public class CJKTextWidthCounterTest { private CJKTextWidthCounter counter; @Before public void setup() { counter = new CJKTextWidthCounter(); } @Test public void testWidth() { String s = "こんにちは世界€ Hello world"; assertEquals(16+12, counter.width(s)); } } argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/helper/PrefixPatternTest.java000066400000000000000000000023421240010205600332270ustar00rootroot00000000000000package net.sourceforge.argparse4j.helper; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.junit.Test; public class PrefixPatternTest { private PrefixPattern pat = new PrefixPattern("-+"); @Test public void testmatch() { assertTrue(pat.match("-f")); assertTrue(pat.match("+-f")); assertTrue(pat.match("+f")); assertTrue(!pat.match("f")); assertTrue(!pat.match("-")); assertTrue(!pat.match("--")); } @Test public void testmatchLongFlag() { assertTrue(pat.matchLongFlag("--flag")); assertTrue(pat.matchLongFlag("+-+flag")); assertTrue(!pat.matchLongFlag("-f")); assertTrue(!pat.matchLongFlag("-flag")); assertTrue(!pat.matchLongFlag("flag")); assertTrue(!pat.match("-")); assertTrue(!pat.match("--")); assertTrue(!pat.match("---")); } @Test public void testRemovePrefix() { assertEquals("foo", pat.removePrefix("--foo")); assertEquals("f", pat.removePrefix("+f")); assertEquals("foo", pat.removePrefix("foo")); assertEquals("-", pat.removePrefix("-")); assertEquals("--", pat.removePrefix("--")); } } argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/helper/ReflectHelperTest.java000066400000000000000000000013421240010205600331570ustar00rootroot00000000000000package net.sourceforge.argparse4j.helper; import static org.junit.Assert.*; import java.util.Arrays; import java.util.List; import net.sourceforge.argparse4j.helper.ReflectHelper; import org.junit.Test; public class ReflectHelperTest { @Test public void testList2Array() { int a1[] = (int[]) ReflectHelper.list2Array(int[].class, list(1, 2, 3)); assertArrayEquals(new int[] { 1, 2, 3 }, a1); int a2[][] = (int[][]) ReflectHelper.list2Array(int[][].class, list(list(1, 2), list(3, 4))); assertArrayEquals( new int[][] { new int[] { 1, 2 }, new int[] { 3, 4 } }, a2); } private List list(T... args) { return Arrays.asList(args); } } argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/helper/TextHelperTest.java000066400000000000000000000054471240010205600325310ustar00rootroot00000000000000package net.sourceforge.argparse4j.helper; import static org.junit.Assert.assertEquals; import java.util.Arrays; import org.junit.Test; public class TextHelperTest { @Test public void testConcat() { assertEquals("", TextHelper.concat(new String[] {}, 0, ",")); assertEquals("", TextHelper.concat(new String[] {""}, 0, ",")); assertEquals("alpha", TextHelper.concat(new String[] { "alpha" }, 0, ",")); assertEquals("1, 2, 3", TextHelper.concat(new Integer[] { 1, 2, 3 }, 0, ", ")); assertEquals("2, 3", TextHelper.concat(new Integer[] { 1, 2, 3 }, 1, ", ")); assertEquals("3", TextHelper.concat(new Integer[] { 1, 2, 3 }, 2, ", ")); assertEquals("", TextHelper.concat(new Integer[] { 1, 2, 3 }, 3, ", ")); assertEquals("", TextHelper.concat(Arrays.asList(), 0, ",")); assertEquals("", TextHelper.concat(Arrays.asList(""), 0, ",")); assertEquals("alpha", TextHelper.concat(Arrays.asList("alpha"), 0, ",")); assertEquals("1, 2, 3", TextHelper.concat(Arrays.asList(1, 2, 3), 0, ", ")); assertEquals("2, 3", TextHelper.concat(Arrays.asList(1, 2, 3), 1, ", ")); assertEquals("3", TextHelper.concat(Arrays.asList(1, 2, 3), 2, ", ")); assertEquals("", TextHelper.concat(Arrays.asList(1, 2, 3), 3, ", ")); } @Test public void testTextWrap() { String s = String.format( TextHelper.LOCALE_ROOT, "alpha bravo charlie delta echo foxtrot golf hotel india%n" + "juliet kilo lima"); assertEquals(String.format( TextHelper.LOCALE_ROOT, " alpha bravo%n" + " charlie delta%n" + " echo foxtrot%n" + " golf hotel%n" + " india%n" + " juliet kilo lima"), TextHelper.wrap( new ASCIITextWidthCounter(), s, 20, 0, " ", " ")); } @Test public void testAdjustSpace() { StringBuilder s1 = new StringBuilder(" Do you like Java language? "); assertEquals("Do you like Java language?", TextHelper.adjustSpace(s1, 30, 30).toString()); assertEquals("Do you like Java language?", TextHelper.adjustSpace(s1, 31, 30).toString()); StringBuilder s2 = new StringBuilder(); assertEquals("", TextHelper.adjustSpace(s2, 30, 30).toString()); StringBuilder s3 = new StringBuilder("The Argparse4j"); assertEquals("The Argparse4j", TextHelper.adjustSpace(s3, 20, 14).toString()); } } argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/impl/000077500000000000000000000000001240010205600264125ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/impl/action/000077500000000000000000000000001240010205600276675ustar00rootroot00000000000000AppendArgumentActionTest.java000066400000000000000000000025411240010205600353650ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/impl/actionpackage net.sourceforge.argparse4j.impl.action; import static org.junit.Assert.assertEquals; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.mock.MockArgument; import org.junit.Before; import org.junit.Test; public class AppendArgumentActionTest { private static class MyMockArgument extends MockArgument { @Override public String getDest() { return "dest"; } } private MyMockArgument arg = new MyMockArgument(); private AppendArgumentAction act = new AppendArgumentAction(); private Map attrs; @Before public void setup() { attrs = new HashMap(); } @Test public void testRun() throws ArgumentParserException { act.run(null, arg, attrs, null, "hello"); assertEquals(Arrays.asList("hello"), attrs.get("dest")); act.run(null, arg, attrs, null, "world"); assertEquals(Arrays.asList("hello", "world"), attrs.get("dest")); } @Test public void testRunWithDefaultNonList() throws ArgumentParserException { attrs.put("dest", "default"); act.run(null, arg, attrs, null, "hello"); assertEquals(Arrays.asList("hello"), attrs.get("dest")); } } AppendConstArgumentActionTest.java000066400000000000000000000026761240010205600364050ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/impl/actionpackage net.sourceforge.argparse4j.impl.action; import static org.junit.Assert.*; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.mock.MockArgument; import org.junit.Before; import org.junit.Test; public class AppendConstArgumentActionTest { private static class MyMockArgument extends MockArgument { @Override public String getDest() { return "dest"; } @Override public Object getConst() { return "const"; } } private MyMockArgument arg = new MyMockArgument(); private AppendConstArgumentAction act = new AppendConstArgumentAction(); private Map attrs; @Before public void setup() { attrs = new HashMap(); } @Test public void testRun() throws ArgumentParserException { act.run(null, arg, attrs, null, null); assertEquals(Arrays.asList("const"), attrs.get("dest")); act.run(null, arg, attrs, null, null); assertEquals(Arrays.asList("const", "const"), attrs.get("dest")); } @Test public void testRunWithDefaultNonList() throws ArgumentParserException { attrs.put("dest", "default"); act.run(null, arg, attrs, null, null); assertEquals(Arrays.asList("const"), attrs.get("dest")); } } CountArgumentActionTest.java000066400000000000000000000021201240010205600352370ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/impl/actionpackage net.sourceforge.argparse4j.impl.action; import static org.junit.Assert.*; import java.util.HashMap; import java.util.Map; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.mock.MockArgument; import org.junit.Before; import org.junit.Test; public class CountArgumentActionTest { private static class MyMockArgument extends MockArgument { @Override public String getDest() { return "dest"; } } private MyMockArgument arg; private Map attrs; private CountArgumentAction act; @Before public void setup() throws Exception { act = new CountArgumentAction(); arg = new MyMockArgument(); attrs = new HashMap(); attrs.put(arg.getDest(), 0); } @Test public void testRun() throws ArgumentParserException { act.run(null, arg, attrs, "-f", null); assertEquals(1, attrs.get(arg.getDest())); act.run(null, arg, attrs, "-f", null); assertEquals(2, attrs.get(arg.getDest())); } } argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/impl/choice/000077500000000000000000000000001240010205600276445ustar00rootroot00000000000000CollectionArgumentChoiceTest.java000066400000000000000000000036131240010205600362040ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/impl/choicepackage net.sourceforge.argparse4j.impl.choice; import static org.junit.Assert.*; import org.junit.Test; public class CollectionArgumentChoiceTest { private CollectionArgumentChoice choice = new CollectionArgumentChoice( 1, 2, 3); @Test public void testContains() { assertTrue(choice.contains(2)); assertFalse(choice.contains(0)); } @Test public void testContainsWithEmptyCollection() { CollectionArgumentChoice choice = new CollectionArgumentChoice(); assertFalse(choice.contains(0)); assertFalse(choice.contains("0")); } @Test public void testContainsWithWrongType() { try { choice.contains("2"); fail(); } catch (IllegalArgumentException e) { // success } } @Test public void testTextualFormat() { assertEquals("{1,2,3}", choice.textualFormat()); } @Test public void testToString() { assertEquals("{1,2,3}", choice.toString()); } @Test public void testSimpleEnum() { CollectionArgumentChoice c = new CollectionArgumentChoice(Simple.values()); assertTrue(c.contains(Simple.B)); } @Test public void testAbstractEnum() { CollectionArgumentChoice c = new CollectionArgumentChoice(Fancy.values()); assertTrue(c.contains(Fancy.B)); } private static enum Simple {A, B, C} private static enum Fancy { A { @Override String getFoo() { return "aaa"; } }, B { @Override String getFoo() { return "bbb"; } }, C { @Override String getFoo() { return "ccc"; } }; abstract String getFoo(); } } RangeArgumentChoiceTest.java000066400000000000000000000021361240010205600351440ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/impl/choicepackage net.sourceforge.argparse4j.impl.choice; import static org.junit.Assert.*; import org.junit.Test; public class RangeArgumentChoiceTest { private RangeArgumentChoice choice = new RangeArgumentChoice(0, 255); @Test public void testContains() { assertFalse(choice.contains(-1)); assertTrue(choice.contains(0)); assertTrue(choice.contains(10)); assertTrue(choice.contains(255)); assertFalse(choice.contains(256)); } @Test public void testContainsWithWrongType() { try { choice.contains("10"); fail(); } catch(IllegalArgumentException e) { // success } } @Test public void testTextualFormat() { assertEquals("{0..255}", choice.textualFormat()); assertEquals("{0.3..0.9}", new RangeArgumentChoice(0.3, 0.9).textualFormat()); assertEquals("{a..z}", new RangeArgumentChoice("a", "z").textualFormat()); } @Test public void testToString() { assertEquals("{0..255}", choice.toString()); } } argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/impl/type/000077500000000000000000000000001240010205600273735ustar00rootroot00000000000000ConstructorArgumentTypeTest.java000066400000000000000000000012271240010205600357130ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/impl/typepackage net.sourceforge.argparse4j.impl.type; import static org.junit.Assert.*; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.mock.MockArgument; import org.junit.Test; public class ConstructorArgumentTypeTest { @Test public void testConvert() throws ArgumentParserException { ConstructorArgumentType at = new ConstructorArgumentType(Integer.class); assertEquals((Integer)100, at.convert(null, null, "100")); try { at.convert(null, new MockArgument(), "0x100"); fail(); } catch(ArgumentParserException e) { } } } EnumArgumentTypeTest.java000066400000000000000000000014771240010205600343010ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/impl/typepackage net.sourceforge.argparse4j.impl.type; import static org.junit.Assert.*; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.mock.MockArgument; import org.junit.Test; public class EnumArgumentTypeTest { enum Foo { ALPHA, BRAVO, CHARLIE } @Test public void testConvert() throws ArgumentParserException { EnumArgumentType type = new EnumArgumentType(Foo.class); assertEquals(Foo.BRAVO, type.convert(null, null, "BRAVO")); try { type.convert(null, new MockArgument(), "DELTA"); } catch (ArgumentParserException e) { assertEquals( "argument null: could not convert 'DELTA' (choose from {ALPHA,BRAVO,CHARLIE})", e.getMessage()); } } } FileArgumentTypeTest.java000066400000000000000000000017561240010205600342540ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/impl/typepackage net.sourceforge.argparse4j.impl.type; import static org.junit.Assert.*; import java.io.File; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.mock.MockArgument; import org.junit.Test; public class FileArgumentTypeTest { @Test public void testConvert() throws ArgumentParserException { FileArgumentType type = new FileArgumentType(); File file = type.convert(null, null, "foobar"); assertEquals("foobar", file.getName()); file = new FileArgumentType().verifyCanRead().acceptSystemIn() .convert(null, null, "-"); assertEquals("-", file.getName()); try { new FileArgumentType().verifyCanRead().convert(null, new MockArgument(), "-"); } catch (ArgumentParserException e) { assertEquals( "argument null: Insufficient permissions to read file: '-'", e.getMessage()); } } } ReflectArgumentTypeTest.java000066400000000000000000000111541240010205600347520ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/impl/typepackage net.sourceforge.argparse4j.impl.type; import static org.junit.Assert.*; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.mock.MockArgument; import org.junit.Before; import org.junit.Test; public class ReflectArgumentTypeTest { private MockArgument ma; @Before public void setup() throws Exception { ma = new MockArgument(); } private ReflectArgumentType createRA(Class type) { return new ReflectArgumentType(type); } @Test public void testConvertInteger() throws ArgumentParserException { ReflectArgumentType at = createRA(Integer.class); assertEquals((Integer)100, at.convert(null, null, "100")); try { at.convert(null, ma, "0x100"); fail(); } catch(ArgumentParserException e) { assertEquals("argument null: could not convert '0x100' to Integer (For input string: \"0x100\")", e.getMessage()); } } enum Lang { PYTHON, CPP, JAVA } @Test public void testConvertEnum() throws ArgumentParserException { ReflectArgumentType at = createRA(Lang.class); assertEquals(Lang.CPP, at.convert(null, null, "CPP")); try { at.convert(null, ma, "C"); fail(); } catch(ArgumentParserException e) { assertTrue(e.getMessage().startsWith("argument null: could not convert 'C' to Lang (")); } } private static final class NoValueOfNoCtor { } @Test public void testConvertNoValueOfNoCtor() throws ArgumentParserException { ReflectArgumentType at = createRA(NoValueOfNoCtor.class); try { at.convert(null, ma, "foo"); fail(); } catch(IllegalArgumentException e) { assertEquals("reflect type conversion error", e.getMessage()); } } private static final class NoValueOf { public NoValueOf(String arg) { } } @Test public void testConvertNoValueOf() throws ArgumentParserException { ReflectArgumentType at = createRA(NoValueOf.class); assertNotNull(at.convert(null, null, "foo")); } private static final class NoCtor { public static NoCtor valueOf(String arg) { return new NoCtor(); } } @Test public void testConvertNoCtor() throws ArgumentParserException { ReflectArgumentType at = createRA(NoCtor.class); assertNotNull(at.convert(null, null, "foo")); } private static final class NonStaticValueOf { public String arg_; public NonStaticValueOf(String arg) { arg_ = "From ctor"; } public NonStaticValueOf valueOf(String arg) { NonStaticValueOf x = new NonStaticValueOf(arg); x.arg_ = "From valueOf"; return x; } } @Test public void testConvertNonStaticValueOf() throws ArgumentParserException { ReflectArgumentType at = createRA(NonStaticValueOf.class); assertEquals("From ctor", at.convert(null, null, "UNUSED").arg_); } private static final class WrongReturnTypeValueOf { public String arg_; public WrongReturnTypeValueOf(String arg) { arg_ = arg; } public static String valueOf(String arg) { return "Bad"; } } @Test public void testConvertWrongReturnTypeValueOf() throws ArgumentParserException { ReflectArgumentType at = createRA(WrongReturnTypeValueOf.class); assertEquals("Good", at.convert(null, null, "Good").arg_); } private static class Base { public static Derived valueOf(String arg) { return new Derived(); } } private static class Derived extends Base { } @Test public void testConvertSupertype() throws ArgumentParserException { ReflectArgumentType at = createRA(Base.class); assertEquals(Derived.class, at.convert(null, null, "foo").getClass()); } private static final class NonStringValueOf { public String arg_; public NonStringValueOf(String arg) { arg_ = arg; } public static NonStringValueOf valueOf(Object n) { return new NonStringValueOf("Bad"); } } @Test public void testConvertNonStringValueOf() throws ArgumentParserException { ReflectArgumentType at = createRA(NonStringValueOf.class); assertEquals("Good", at.convert(null, null, "Good").arg_); } } argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/inf/000077500000000000000000000000001240010205600262255ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/inf/NamespaceTest.java000066400000000000000000000011661240010205600316300ustar00rootroot00000000000000package net.sourceforge.argparse4j.inf; import static org.junit.Assert.*; import java.util.HashMap; import java.util.Map; import org.junit.Before; import org.junit.Test; public class NamespaceTest { @Before public void setUp() throws Exception { } @Test public void testGetString() { Map attrs = new HashMap(); attrs.put("string", "string"); attrs.put("integer", 1000000009); Namespace ns = new Namespace(attrs); assertEquals("string", ns.getString("string")); assertEquals("1000000009", ns.getString("integer")); } } argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/internal/000077500000000000000000000000001240010205600272655ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/internal/ArgumentImplTest.java000066400000000000000000000134601240010205600334000ustar00rootroot00000000000000package net.sourceforge.argparse4j.internal; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import net.sourceforge.argparse4j.ArgumentParsers; import net.sourceforge.argparse4j.helper.PrefixPattern; import net.sourceforge.argparse4j.inf.ArgumentParserException; import org.junit.Before; import org.junit.Test; public class ArgumentImplTest { private PrefixPattern prefix; @Before public void setup() { prefix = new PrefixPattern(ArgumentParsers.DEFAULT_PREFIX_CHARS); } @Test public void testArgumentWithName() { ArgumentImpl arg = new ArgumentImpl(prefix, "foo"); assertEquals("foo", arg.getName()); assertEquals("foo", arg.getDest()); assertEquals("foo", arg.textualName()); } @Test public void testArgumentWithNoNameOrFlags() { try { new ArgumentImpl(prefix); fail(); } catch(IllegalArgumentException e) { // success } } @Test public void testArgumentWithFlags() { ArgumentImpl arg = new ArgumentImpl(prefix, "-f", "--foo-bar", "--foo"); assertNull(arg.getName()); assertEquals("foo_bar", arg.getDest()); assertEquals("FOO_BAR", arg.resolveMetavar()[0]); } @Test public void testArgumentWithBadFlags() { try { new ArgumentImpl(prefix, "f", "-f"); fail("Exception must be thrown"); } catch (IllegalArgumentException e) { // success } } @Test public void testArgumentWithPrefix() { PrefixPattern prefix = new PrefixPattern("-+"); ArgumentImpl arg = new ArgumentImpl(prefix, "-f", "-+foo-bar", "++foo"); assertNull(arg.getName()); assertEquals("foo_bar", arg.getDest()); assertEquals("FOO_BAR", arg.resolveMetavar()[0]); } @Test public void testNargsWithZero() { ArgumentImpl arg = new ArgumentImpl(prefix, "--foo"); try { arg.nargs(0); fail(); } catch(IllegalArgumentException e) { } } @Test public void testResolveMetavar() { ArgumentImpl arg = new ArgumentImpl(prefix, "--foo"); assertEquals("FOO", arg.resolveMetavar()[0]); arg.dest("bar"); assertEquals("BAR", arg.resolveMetavar()[0]); arg.choices("alpha", "bravo"); assertEquals("{alpha,bravo}", arg.resolveMetavar()[0]); arg.metavar("baz"); assertEquals("baz", arg.resolveMetavar()[0]); arg = new ArgumentImpl(prefix, "foo"); assertEquals("foo", arg.resolveMetavar()[0]); arg.dest("bar"); assertEquals("bar", arg.resolveMetavar()[0]); arg.choices("alpha", "bravo"); assertEquals("{alpha,bravo}", arg.resolveMetavar()[0]); arg.metavar("baz"); assertEquals("baz", arg.resolveMetavar()[0]); } @Test public void testTextualName() { ArgumentImpl arg = new ArgumentImpl(prefix, "f"); assertEquals("f", arg.textualName()); arg = new ArgumentImpl(prefix, "-f", "--foo", "--foo-bar"); assertEquals("-f/--foo/--foo-bar", arg.textualName()); } @Test public void testFormatMetavar() { ArgumentImpl arg = new ArgumentImpl(prefix, "--foo"); assertEquals("FOO", arg.formatMetavar()); arg.dest("BAZ"); assertEquals("BAZ", arg.formatMetavar()); arg.metavar("BAR"); assertEquals("BAR", arg.formatMetavar()); arg.nargs(3); assertEquals("BAR BAR BAR", arg.formatMetavar()); arg.metavar("ALPHA", "BRAVO", "CHARLIE"); assertEquals("ALPHA BRAVO CHARLIE", arg.formatMetavar()); arg.nargs(4); assertEquals("ALPHA BRAVO CHARLIE CHARLIE", arg.formatMetavar()); arg.nargs("?"); assertEquals("[ALPHA]", arg.formatMetavar()); arg.nargs("*"); assertEquals("[ALPHA [BRAVO ...]]", arg.formatMetavar()); arg.nargs("+"); assertEquals("ALPHA [BRAVO ...]", arg.formatMetavar()); } @Test public void testConvert() throws ArgumentParserException { ArgumentImpl arg = new ArgumentImpl(prefix, "--foo"); assertEquals("hello", arg.convert(null, "hello")); arg.choices("world"); try { arg.convert(null, "hello"); fail(); } catch(ArgumentParserException e) { assertEquals("argument --foo: invalid choice: 'hello' (choose from {world})", e.getMessage()); } } @Test public void testPrimitiveTypes() throws ArgumentParserException { ArgumentImpl arg = new ArgumentImpl(prefix, "foo").type(int.class); assertEquals(Integer.MAX_VALUE, arg.convert(null, Integer.toString(Integer.MAX_VALUE))); arg.type(boolean.class); assertEquals(true, arg.convert(null, Boolean.toString(Boolean.TRUE))); arg.type(byte.class); assertEquals(Byte.MAX_VALUE, arg.convert(null, Byte.toString(Byte.MAX_VALUE))); arg.type(short.class); assertEquals(Short.MAX_VALUE, arg.convert(null, Short.toString(Short.MAX_VALUE))); arg.type(long.class); assertEquals(Long.MAX_VALUE, arg.convert(null, Long.toString(Long.MAX_VALUE))); arg.type(float.class); assertEquals(Float.MAX_VALUE, arg.convert(null, Float.toString(Float.MAX_VALUE))); arg.type(double.class); assertEquals(Double.MAX_VALUE, arg.convert(null, Double.toString(Double.MAX_VALUE))); try { arg.type(char.class); } catch(IllegalArgumentException e) { assertEquals("unexpected primitive type", e.getMessage()); } try { arg.type(void.class); } catch(IllegalArgumentException e) { assertEquals("unexpected primitive type", e.getMessage()); } } } ArgumentParserImplTest.java000066400000000000000000001415541240010205600345040ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/internalpackage net.sourceforge.argparse4j.internal; import static net.sourceforge.argparse4j.impl.Arguments.*; import static net.sourceforge.argparse4j.test.TestHelper.*; import static org.junit.Assert.*; import java.io.FileInputStream; import java.io.PrintWriter; import java.util.Map; import net.sourceforge.argparse4j.ArgumentParsers; import net.sourceforge.argparse4j.annotation.Arg; import net.sourceforge.argparse4j.helper.TextHelper; import net.sourceforge.argparse4j.impl.Arguments; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentAction; import net.sourceforge.argparse4j.inf.ArgumentGroup; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup; import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparsers; import net.sourceforge.argparse4j.internal.ArgumentParserImpl.Candidate; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class ArgumentParserImplTest { private ArgumentParserImpl ap; private String[] zeroargs; @BeforeClass public static void init() { ArgumentParsers.setTerminalWidthDetection(false); } @Before public void setup() { ap = new ArgumentParserImpl("argparse4j"); zeroargs = new String[]{}; } @Test public void testCtor() throws ArgumentParserException { ap = new ArgumentParserImpl("prog", false, "+", "@", null); assertEquals("prog", ap.getProg()); assertEquals("+", ap.getPrefixChars()); assertEquals("@", ap.getFromFilePrefixChars()); // Check +h can be added because addHelp is false ap.addArgument("+h"); } @Test public void testParseArgs() throws ArgumentParserException { ap.addArgument("--foo"); ap.addArgument("--bar").nargs("?").setConst("c"); ap.addArgument("suites").nargs("*"); Namespace res = ap.parseArgs(("--bar " + "--foo hello " + "cake dango mochi").split(" ")); assertEquals("hello", res.get("foo")); assertEquals("c", res.get("bar")); assertEquals(list("cake", "dango", "mochi"), res.get("suites")); } @Test public void testRequiredOptarg() throws ArgumentParserException { ap.addArgument("--foo").required(true); try { ap.parseArgs(new String[] {}); fail(); } catch (ArgumentParserException e) { assertEquals("argument --foo is required", e.getMessage()); } } @Test public void testEmbeddedValueWithNargsWrongValue() { ap.addArgument("--foo").nargs("+").choices("bar", "baz"); try { ap.parseArgs("--foo=abc".split(" ")); fail(); } catch(ArgumentParserException e) { assertEquals("argument --foo: invalid choice: 'abc' (choose from {bar,baz})", e.getMessage()); } } @Test public void testRequiredOptargWithSubcommand() throws ArgumentParserException { ap.addArgument("--foo").required(true); ap.addSubparsers().addParser("install"); try { ap.parseArgs("install".split(" ")); } catch (ArgumentParserException e) { assertEquals("argument --foo is required", e.getMessage()); } } @Test public void testTooFewArgumentForPosarg() throws ArgumentParserException { ap.addArgument("foo"); try { ap.parseArgs(new String[] {}); fail(); } catch (ArgumentParserException e) { assertEquals("too few arguments", e.getMessage()); } } @Test public void testTooFewArgumentForPosargWithNargs() throws ArgumentParserException { ap.addArgument("foo").nargs(3); try { ap.parseArgs(new String[] {}); fail(); } catch (ArgumentParserException e) { assertEquals("too few arguments", e.getMessage()); } } @Test public void testAddArgumentWithConflict() throws ArgumentParserException { try { ap.addArgument("--foo"); ap.addArgument("--foo"); fail(); } catch (IllegalArgumentException e) { } try { ap.addArgument("foo"); ap.addArgument("foo"); fail(); } catch (IllegalArgumentException e) { } } @Test public void testParseArgsWithPosargOutOfIndex() throws ArgumentParserException { ap.addArgument("foo").nargs("*"); Namespace res = ap.parseArgs(new String[] {}); assertEquals(list(), res.get("foo")); } @Test public void testParseArgsWithoutNegativeNumberLikeFlag() throws ArgumentParserException { ap.addArgument("-x"); ap.addArgument("foo").nargs("?"); Namespace res = ap.parseArgs("-x -1".split(" ")); assertEquals("-1", res.get("x")); res = ap.parseArgs("-x -1 -5".split(" ")); assertEquals("-1", res.get("x")); assertEquals("-5", res.get("foo")); } @Test public void testParseArgsWithNegativeNumberLikeFlag() throws ArgumentParserException { ap.addArgument("-1").dest("one"); ap.addArgument("foo").nargs("?"); Namespace res = ap.parseArgs("-1 X".split(" ")); assertEquals("X", res.get("one")); try { ap.parseArgs("-2".split(" ")); fail(); } catch (ArgumentParserException e) { assertEquals("unrecognized arguments: '-2'", e.getMessage()); } try { ap.parseArgs("-1 -1".split(" ")); fail(); } catch (ArgumentParserException e) { assertEquals("argument -1: expected one argument", e.getMessage()); } } @Test public void testParseArgsWithStoreTrueFalse() throws ArgumentParserException { ap.addArgument("--foo").action(storeTrue()); ap.addArgument("--bar").action(storeFalse()); ap.addArgument("--baz").action(storeFalse()); ap.addArgument("--sid").action(storeTrue()); Namespace res = ap.parseArgs("--foo --bar".split(" ")); assertEquals(true, res.get("foo")); assertEquals(false, res.get("bar")); assertEquals(true, res.get("baz")); assertEquals(false, res.get("sid")); } @Test public void testParseArgsWithStoreConst() throws ArgumentParserException { ap.addArgument("--foo").action(storeConst()).setConst("const"); ap.addArgument("bar"); Namespace res = ap.parseArgs("--foo bar".split(" ")); assertEquals("const", res.get("foo")); assertEquals("bar", res.get("bar")); } @Test public void testParseArgsWithAppend() throws ArgumentParserException { ap.addArgument("--foo").action(append()).nargs("*"); ap.addArgument("--bar").action(append()); Namespace res = ap.parseArgs("--foo a --foo b --bar c --bar d" .split(" ")); assertEquals(list(list("a"), list("b")), res.get("foo")); assertEquals(list("c", "d"), res.get("bar")); } @Test public void testParseArgsWithAppendConst() throws ArgumentParserException { ap.addArgument("--foo").action(appendConst()).setConst("X"); ap.addArgument("bar"); Namespace res = ap.parseArgs("--foo --foo bar".split(" ")); assertEquals(list("X", "X"), res.get("foo")); assertEquals("bar", res.get("bar")); } @Test public void testParseArgsWithCount() throws ArgumentParserException { ap.addArgument("-v", "--verbose").action(count()); ap.addArgument("--foo"); Namespace res = ap.parseArgs("-v -vv -vvvv".split(" ")); assertEquals(7, res.get("verbose")); } @Test public void testParseArgsWithConst() throws ArgumentParserException { ap.addArgument("--foo").setConst("X").nargs("?"); Namespace res = ap.parseArgs("--foo".split(" ")); assertEquals("X", res.get("foo")); } @Test public void testParseArgsWithQ() throws ArgumentParserException { ap.addArgument("--foo").nargs("?").setConst("c").setDefault("d"); ap.addArgument("bar").nargs("?").setDefault("d"); Namespace res = ap.parseArgs("XX --foo YY".split(" ")); assertEquals("YY", res.get("foo")); assertEquals("XX", res.get("bar")); res = ap.parseArgs("XX --foo".split(" ")); assertEquals("c", res.get("foo")); assertEquals("XX", res.get("bar")); res = ap.parseArgs(new String[] {}); assertEquals("d", res.get("foo")); assertEquals("d", res.get("bar")); } @Test public void testParseArgsWithConcatenatedShortOpts() throws ArgumentParserException { ap.addArgument("-1").action(storeTrue()); ap.addArgument("-2"); ap.addArgument("-3"); ap.addArgument("-ff"); ap.addArgument("-f"); ap.addArgument("-c").action(appendConst()).setConst(true); Namespace res = ap.parseArgs("-123=x -ff=a -fx -cccc".split(" ")); assertEquals(true, res.get("1")); assertEquals("3=x", res.get("2")); assertEquals("a", res.get("ff")); assertEquals("x", res.get("f")); assertEquals(list(true, true, true, true), res.get("c")); // If last option requires argument but the argument is not // embedded in the same term, it must take next term as an // argument. res = ap.parseArgs("-12 foo".split(" ")); assertEquals(true, res.get("1")); assertEquals("foo", res.get("2")); // If -12" " is given in the terminal, program get this res = ap.parseArgs(new String[] { "-12 "}); assertEquals(true, res.get("1")); assertEquals(" ", res.get("2")); // This is error case because the next term -fx is flag. try { res = ap.parseArgs("-12 -fx".split(" ")); fail(); } catch(ArgumentParserException e) { assertEquals("argument -2: expected one argument", e.getMessage()); } } @Test public void testParseArgsWithStringChoices() throws ArgumentParserException { ap.addArgument("--foo").choices("chocolate", "icecream", "froyo"); Namespace res = ap.parseArgs("--foo icecream".split(" ")); assertEquals("icecream", res.get("foo")); try { ap.parseArgs("--foo pudding".split(" ")); fail("Exception must be thrown"); } catch (ArgumentParserException e) { // success } } @Test public void testParseArgsWithNargs() throws ArgumentParserException { ap.addArgument("--foo").nargs(2); ap.addArgument("bar"); try { ap.parseArgs("--foo=3 4".split(" ")); fail("Exception must be thrown"); } catch (ArgumentParserException e) { // success } } @Test public void testParseArgsWithIntegerRange() throws ArgumentParserException { ap.addArgument("--port").type(Integer.class) .choices(range(1025, 65535)); Namespace res = ap.parseArgs("--port 3000".split(" ")); assertEquals(3000, res.get("port")); try { ap.parseArgs("--port 80".split(" ")); fail("Exception must be thrown"); } catch (ArgumentParserException e) { // success } } @Test public void testParseArgsWithFileInputStream() throws ArgumentParserException { ap.addArgument("--input").type(FileInputStream.class); try { ap.parseArgs("--input not_found.txt".split(" ")); fail("Exception must be thrown"); } catch (ArgumentParserException e) { // success } } @Test public void testParseArgsWithFromFilePrefixAndUnrecognizedArgs() throws ArgumentParserException { ap = new ArgumentParserImpl("argparse4j", true, ArgumentParsers.DEFAULT_PREFIX_CHARS, "@"); ap.addArgument("-a").action(Arguments.storeTrue()); ap.addArgument("-b").action(Arguments.storeTrue()); ap.addArgument("-c").action(Arguments.storeTrue()); ap.addArgument("-d").action(Arguments.storeTrue()); try { // If unrecognized arguments was found in arguments from file, add // additional help message. ap.parseArgs("-a @target/test-classes/args5.txt".split(" ")); fail(); } catch(ArgumentParserException e) { assertEquals(String.format( TextHelper.LOCALE_ROOT, "unrecognized arguments: '-x'%n" + "Checking trailing white spaces or new lines in @file may help."), e.getMessage()); } try { // -x is not from file, so no additional help. ap.parseArgs("@target/test-classes/args6.txt -x".split(" ")); fail(); } catch(ArgumentParserException e) { assertEquals("unrecognized arguments: '-x'", e.getMessage()); } try { // Check @file inside @file extends check range (overlap case). ap.parseArgs("@target/test-classes/args7.txt".split(" ")); fail(); } catch(ArgumentParserException e) { assertEquals(String.format( TextHelper.LOCALE_ROOT, "unrecognized arguments: '-x'%n" + "Checking trailing white spaces or new lines in @file may help."), e.getMessage()); } try { // Check range is updated by args5.txt (non-overlap case). ap.parseArgs("@target/test-classes/args6.txt @target/test-classes/args5.txt".split(" ")); fail(); } catch(ArgumentParserException e) { assertEquals(String.format( TextHelper.LOCALE_ROOT, "unrecognized arguments: '-x'%n" + "Checking trailing white spaces or new lines in @file may help."), e.getMessage()); } try { // Unrecognized non-flag arguments ap.parseArgs("@target/test-classes/args8.txt".split(" ")); } catch(ArgumentParserException e) { assertEquals(String.format( TextHelper.LOCALE_ROOT, "unrecognized arguments: ' b'%n" + "Checking trailing white spaces or new lines in @file may help."), e.getMessage()); } // Multiple fromFilePrefix ap = new ArgumentParserImpl("argparse4j", true, ArgumentParsers.DEFAULT_PREFIX_CHARS, "@/"); ap.addArgument("-a").action(Arguments.storeTrue()); try { ap.parseArgs("-a @target/test-classes/args5.txt".split(" ")); fail(); } catch(ArgumentParserException e) { assertEquals(String.format( TextHelper.LOCALE_ROOT, "unrecognized arguments: '-x'%n" + "Checking trailing white spaces or new lines in [@/]file may help."), e.getMessage()); } } @Test public void testParseArgsWithFromFilePrefix() throws ArgumentParserException { ap = new ArgumentParserImpl("argparse4j", true, ArgumentParsers.DEFAULT_PREFIX_CHARS, "@"); ap.addArgument("-f"); ap.addArgument("--baz").nargs(2); ap.addArgument("x"); ap.addArgument("y").nargs(2); Subparsers subparsers = ap.addSubparsers(); Subparser subparser = subparsers.addParser("add"); subparser.addArgument("--foo"); subparser.addArgument("--bar").action(Arguments.storeTrue()); Namespace res = ap.parseArgs("-f foo @target/test-classes/args.txt --baz alpha @target/test-classes/args2.txt x y1 @target/test-classes/args3.txt add --bar @target/test-classes/args4.txt".split(" ")); assertEquals("bar", res.getString("f")); assertEquals(list("alpha", "bravo"), res.getList("baz")); assertEquals("x", res.getString("x")); assertEquals(list("y1", "y2"), res.getList("y")); assertEquals("HELLO", res.getString("foo")); } @Test public void testParseArgsWithSubparsers() throws ArgumentParserException { ap.addArgument("-f"); Subparsers subparsers = ap.addSubparsers(); Subparser parserA = subparsers.addParser("install"); parserA.addArgument("pkg1"); parserA.setDefault("func", "install"); Subparser parserB = subparsers.addParser("search"); parserB.addArgument("pkg2"); parserB.setDefault("func", "search"); Namespace res = ap.parseArgs("install aria2".split(" ")); assertEquals("aria2", res.get("pkg1")); assertEquals("install", res.get("func")); } @Test public void testParseArgsWithSubparsersAlias() throws ArgumentParserException { Subparsers subparsers = ap.addSubparsers(); Subparser checkout = subparsers.addParser("checkout").aliases("co"); checkout.setDefault("func", "checkout"); Namespace res = ap.parseArgs("co".split(" ")); assertEquals("checkout", res.get("func")); } @Test public void testParseArgsWithSubparsersAmbiguousCommand() throws ArgumentParserException { Namespace res; Subparsers subparsers = ap.addSubparsers(); Subparser checkout = subparsers.addParser("clone") .setDefault("func", "clone"); Subparser clean = subparsers.addParser("clean") .setDefault("func", "clean"); res = ap.parseArgs("clo".split(" ")); assertEquals("clone", res.get("func")); res = ap.parseArgs("cle".split(" ")); assertEquals("clean", res.get("func")); try { ap.parseArgs("cl".split(" ")); fail(); } catch(ArgumentParserException e) { assertEquals("ambiguous command: cl could match clean, clone", e.getMessage()); } } @Test public void testParseArgsWithDefaults() throws ArgumentParserException { ap.addArgument("-f").setDefault("foo"); ap.addArgument("-g").setDefault("bar"); ap.addArgument("-i").setDefault("alpha"); ap.setDefault("foo", "FOO"); Namespace res = ap.parseArgs("-i input".split(" ")); assertEquals("FOO", res.get("foo")); assertEquals("bar", res.get("g")); assertEquals("input", res.get("i")); } @Test public void testParseArgsWithNargsEmptyList() throws ArgumentParserException { ap.addArgument("--foo").nargs("*"); ap.addArgument("--bar").nargs("*").setDefault("bar"); ap.addArgument("--baz").nargs("*").action(append()); ap.addArgument("--buzz").nargs("*").action(append()).setDefault("buzz"); Namespace res = ap.parseArgs(zeroargs); assertEquals(null, res.get("foo")); assertEquals("bar", res.get("bar")); assertEquals(null, res.get("baz")); assertEquals("buzz", res.get("buzz")); // Make sure that empty list overwrites previous arguments. res = ap.parseArgs("--foo 1 2 --foo".split(" ")); assertEquals(list(), res.get("foo")); // Make sure that empty list overwrites default value. res = ap.parseArgs("--bar".split(" ")); assertEquals(list(), res.get("bar")); // Make sure that empty list is appended res = ap.parseArgs("--baz".split(" ")); assertEquals(list(list()), res.get("baz")); // Make sure that empty list overwrites default value res = ap.parseArgs("--buzz".split(" ")); assertEquals(list(list()), res.get("buzz")); // sanity check: Make sure that given list overwrites default value res = ap.parseArgs("--buzz 1 2".split(" ")); assertEquals(list(list("1", "2")), res.get("buzz")); } @Test public void testParseArgsWithPosargNargsEmptyList() throws ArgumentParserException { Namespace res; ap.addArgument("foo").nargs("*"); res = ap.parseArgs(zeroargs); assertEquals(list(), res.get("foo")); ap = new ArgumentParserImpl("argparse4j"); ap.addArgument("foo").nargs("*").setDefault("foo"); // Make sure that default value is kept res = ap.parseArgs(zeroargs); assertEquals("foo", res.get("foo")); // Make sure that given argument list overwrites default. res = ap.parseArgs("a b".split(" ")); assertEquals(list("a", "b"), res.get("foo")); ap = new ArgumentParserImpl("argparse4j"); ap.addArgument("foo").nargs("*").action(append()); // Make sure that empty list is returned. res = ap.parseArgs(zeroargs); assertEquals(list(), res.get("foo")); ap = new ArgumentParserImpl("argparse4j"); ap.addArgument("foo").nargs("*").action(append()).setDefault("foo"); // Make sure that default stays intact without positional argument res = ap.parseArgs(zeroargs); assertEquals("foo", res.get("foo")); // Make sure that given argument list overwrites default. res = ap.parseArgs("a b".split(" ")); assertEquals(list(list("a", "b")), res.get("foo")); } @Test public void testParseArgsWithsPosargNargsDefaults() throws ArgumentParserException { class MockAction implements ArgumentAction { boolean invoked; @Override public void run(ArgumentParser parser, Argument arg, Map attrs, String flag, Object value) throws ArgumentParserException { invoked = true; } @Override public void onAttach(Argument arg) {} @Override public boolean consumeArgument() { return true; } } ap.addArgument("f").nargs("*").setDefault(list("default")); MockAction action = new MockAction(); ap.addArgument("b").nargs("*").setDefault(false).action(action); Namespace res = ap.parseArgs(new String[] {}); assertEquals(list("default"), res.get("f")); assertEquals(false, action.invoked); } @Test public void testParseArgsWithDefaultControlSuppress() throws ArgumentParserException { ap.addArgument("-f"); ap.addArgument("-g").setDefault(SUPPRESS); Namespace res = ap.parseArgs(new String[] {}); assertTrue(res.getAttrs().containsKey("f")); assertFalse(res.getAttrs().containsKey("g")); } @Test public void testParseArgsWithUnrecognizedArgs() throws ArgumentParserException { ap.addArgument("foo"); try { ap.parseArgs("alpha bravo charlie".split(" ")); fail(); } catch (ArgumentParserException e) { assertEquals("unrecognized arguments: 'bravo charlie'", e.getMessage()); } } @Test public void testParseArgsWithSeparator() throws ArgumentParserException { ap.addArgument("--foo"); ap.addArgument("-2"); ap.addArgument("bar"); ap.addArgument("car"); Namespace res = ap.parseArgs("-- -2 --".split(" ")); assertEquals("-2", res.get("bar")); assertEquals("--", res.get("car")); } @Test public void testParseArgsWithMutexGroup() throws ArgumentParserException { MutuallyExclusiveGroup group = ap.addMutuallyExclusiveGroup("mutex"); group.addArgument("--foo"); group.addArgument("--bar"); Namespace res = ap.parseArgs("--foo bar".split(" ")); assertEquals("bar", res.get("foo")); } @Test public void testParseArgsWithMutexGroupDuplicate() throws ArgumentParserException { MutuallyExclusiveGroup group = ap.addMutuallyExclusiveGroup("mutex"); group.addArgument("--foo"); group.addArgument("--bar"); try { ap.parseArgs("--foo bar --bar baz".split(" ")); fail(); } catch(ArgumentParserException e) { assertEquals("argument --bar: not allowed with argument --foo", e.getMessage()); } } @Test public void testParseArgsWithMutexGroupRequired() throws ArgumentParserException { MutuallyExclusiveGroup group = ap.addMutuallyExclusiveGroup("mutex").required(true); group.addArgument("--foo"); group.addArgument("--bar"); Namespace res = ap.parseArgs("--foo bar".split(" ")); assertEquals("bar", res.get("foo")); } @Test public void testParseArgsWithMutexGroupRequiredFail() throws ArgumentParserException { MutuallyExclusiveGroup group = ap.addMutuallyExclusiveGroup("mutex").required(true); group.addArgument("--foo"); group.addArgument("--bar"); try { ap.parseArgs(new String []{}); fail(); } catch(ArgumentParserException e) { assertEquals("one of the arguments --foo --bar is required", e.getMessage()); } } @Test public void testParseArgsWithMutexGroupConcatDuplicate() throws ArgumentParserException { MutuallyExclusiveGroup group = ap.addMutuallyExclusiveGroup("mutex").required(true); group.addArgument("-a").action(Arguments.storeTrue()); group.addArgument("-b").action(Arguments.storeTrue()); ap.addArgument("-c").action(Arguments.storeTrue()); try { ap.parseArgs("-acb".split(" ")); } catch(ArgumentParserException e) { assertEquals("argument -b: not allowed with argument -a", e.getMessage()); } } @Test public void testParseArgsWithMutexGroupConcat() throws ArgumentParserException { MutuallyExclusiveGroup group = ap.addMutuallyExclusiveGroup("mutex").required(true); group.addArgument("-a").action(Arguments.storeTrue()); group.addArgument("-b").action(Arguments.storeTrue()); ap.addArgument("-c"); Namespace res = ap.parseArgs("-acfoo".split(" ")); assertEquals(true, res.getBoolean("a")); assertEquals("foo", res.get("c")); } @Test public void testParseArgsWithCommandAfterSeparator() throws ArgumentParserException { Subparsers subparsers = ap.addSubparsers(); subparsers.addParser("install"); try { ap.parseArgs("-- install".split(" ")); fail(); } catch(ArgumentParserException e) { assertEquals("unrecognized arguments: 'install'", e.getMessage()); } } @Test public void testParseArgsWithoutSubcommand() throws ArgumentParserException { Subparsers subparsers = ap.addSubparsers(); subparsers.addParser("install"); try { ap.parseArgs(new String[]{}); fail(); } catch(ArgumentParserException e) { assertEquals("too few arguments", e.getMessage()); } } @Test public void testParseArgsWithMutualExclusiveGroupAndSuppressHelp() throws ArgumentParserException { MutuallyExclusiveGroup mutex1 = ap.addMutuallyExclusiveGroup("mutex1") .required(true); mutex1.addArgument("-a").help(Arguments.SUPPRESS); Argument b = mutex1.addArgument("-b"); // Check the suppressed argument is not shown in the error message try { ap.parseArgs(new String[]{}); fail(); } catch(ArgumentParserException e) { assertEquals("one of the arguments -b is required", e.getMessage()); } b.help(Arguments.SUPPRESS); try { ap.parseArgs(new String[]{}); fail(); } catch(ArgumentParserException e) { assertEquals("one of the arguments is required", e.getMessage()); } } @Test public void testParseArgsWithAmbiguousOpts() throws ArgumentParserException { Namespace res; ap.addArgument("-a").action(storeTrue()); ap.addArgument("-b"); ap.addArgument("-aaa").action(storeTrue()); ap.addArgument("-bbb").action(storeTrue()); // Exact match -aaa res = ap.parseArgs("-aaa".split(" ")); assertTrue(res.getBoolean("aaa")); // Exact match -a res = ap.parseArgs("-a".split(" ")); assertTrue(res.getBoolean("a")); // -aa is ambiguous try { res = ap.parseArgs("-aa".split(" ")); fail(); } catch(ArgumentParserException e) { assertEquals("ambiguous option: -aa could match -a, -aaa", e.getMessage()); } // Exact match -b res = ap.parseArgs("-bx".split(" ")); assertEquals("x", res.get("b")); // Exact match -bbb res = ap.parseArgs("-bbb".split(" ")); assertTrue(res.getBoolean("bbb")); try { res = ap.parseArgs("-bb".split(" ")); fail(); } catch(ArgumentParserException e) { assertEquals("ambiguous option: -bb could match -b, -bbb", e.getMessage()); } } @Test public void testParseArgsWithDeferredException() throws ArgumentParserException { ap = new ArgumentParserImpl("argparse4j"); ap.addArgument("-a").required(true); ap.addArgument("b"); ap.addMutuallyExclusiveGroup().required(true).addArgument("-c"); ap.addSubparsers().addParser("install"); try { ap.parseArgs("install -h".split(" ")); } catch(HelpScreenException e) { // Success } catch(ArgumentParserException e) { fail(); } } @Test public void testSubparserInheritPrefixChars() throws ArgumentParserException { ap = new ArgumentParserImpl("argparse4j", true, "+"); ap.addSubparsers().addParser("install").addArgument("+f"); ap.addSubparsers().addParser("check", true, "-").addArgument("-f"); try { ap.addSubparsers().addParser("test", true, "-").addArgument("+f", "++f"); fail(); } catch(IllegalArgumentException e) { assertEquals("invalid option string '+f': must start with a character '-'", e.getMessage()); } } @Test public void testSubparsersDest() throws ArgumentParserException { Subparsers subparsers = ap.addSubparsers().dest("command"); subparsers.addParser("install").addArgument("--command") .setDefault("default"); Namespace res = ap.parseArgs("install".split(" ")); assertEquals("install", res.get("command")); } @Test public void testArgumentParserWithoutAddHelp() throws ArgumentParserException { ArgumentParserImpl ap = new ArgumentParserImpl("argparse4j", false); try { ap.parseArgs("-h".split(" ")); fail(); } catch (ArgumentParserException e) { assertEquals("unrecognized arguments: '-h'", e.getMessage()); } } @Test public void testSubparserWithoutAddHelp() throws ArgumentParserException { Subparsers subparsers = ap.addSubparsers(); subparsers.addParser("install", false, ArgumentParsers.DEFAULT_PREFIX_CHARS); try { ap.parseArgs("install -h".split(" ")); fail(); } catch (ArgumentParserException e) { assertEquals("unrecognized arguments: '-h'", e.getMessage()); } } @Test public void testGetDefault() throws ArgumentParserException { ap.addArgument("--foo").setDefault("alpha"); ap.setDefault("foo", "bravo"); ap.setDefault("bar", "charlie"); assertEquals("alpha", ap.getDefault("foo")); assertEquals("charlie", ap.getDefault("bar")); } @Test public void testParseArgsWithUserData() throws ArgumentParserException { class Out { @Arg(dest = "null") public String x; @Arg(dest = "username", ignoreError = true) private int y; @Arg(dest = "username") public String name; @Arg public String host; private int[] ints; @Arg(dest = "attrs") private void setInts(int ints[]) { this.ints = ints; } public int[] getInts() { return ints; } @Arg(dest = "attrs", ignoreError = true) public void setY(int y) { this.y = y; } } ap.addArgument("--username"); ap.addArgument("--host"); ap.addArgument("--attrs").nargs("*").type(Integer.class); Out out = new Out(); ap.parseArgs("--username alice --host example.com --attrs 1 2 3".split(" "), out); assertEquals("alice", out.name); assertEquals("example.com", out.host); assertArrayEquals(new int[] { 1, 2, 3 }, out.getInts()); // Test inheritance class SubOut extends Out { @Arg public int port; } ap.addArgument("--port").type(Integer.class); SubOut subOut = new SubOut(); ap.parseArgs("--username alice --host example.com --port 8080 --attrs 1 2 3".split(" "), subOut); assertEquals("alice", subOut.name); assertEquals("example.com", subOut.host); assertArrayEquals(new int[] { 1, 2, 3 }, subOut.getInts()); assertEquals(8080, subOut.port); } @Test public void testFormatUsage() { assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j [-h]%n"), ap.formatUsage()); ap.addArgument("-a"); ap.addArgument("-b").required(true); MutuallyExclusiveGroup group = ap.addMutuallyExclusiveGroup("mutex").required(true); group.addArgument("-c").required(true); group.addArgument("-d").required(true); ap.addArgument("file"); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j [-h] [-a A] -b B (-c C | -d D) file%n"), ap.formatUsage()); Subparser foosub = ap.addSubparsers().addParser("foo"); foosub.addArgument("hash"); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j [-h] [-a A] -b B (-c C | -d D) file {foo} ...%n"), ap.formatUsage()); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j -b B (-c C | -d D) file foo [-h] hash%n"), foosub.formatUsage()); Subparser bazsub = foosub.addSubparsers().addParser("baz"); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j -b B (-c C | -d D) file foo hash baz [-h]%n"), bazsub.formatUsage()); } @Test public void testUsage() { ap.usage("<${prog}> [OPTIONS] ${prog}FILES"); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: [OPTIONS] argparse4jFILES%n"), ap.formatUsage()); } @Test public void testFormatHelpWithArgumentGroup() throws ArgumentParserException { ap.description("This is argparser4j.").epilog("This is epilog."); ArgumentGroup group = ap.addArgumentGroup("group1") .description("group1 description"); group.addArgument("--foo"); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j [-h] [--foo FOO]%n" + "%n" + "This is argparser4j.%n" + "%n" + "optional arguments:%n" + " -h, --help show this help message and exit%n" + "%n" + "group1:%n" + " group1 description%n" + "%n" + " --foo FOO%n" + "%n" + "This is epilog.%n"), ap.formatHelp()); } @Test public void testFormatHelpWithArgumentGroupWithoutTitleAndDescription() throws ArgumentParserException { ap.description("This is argparser4j.").epilog("This is epilog."); ArgumentGroup group = ap.addArgumentGroup(""); group.addArgument("--foo"); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j [-h] [--foo FOO]%n" + "%n" + "This is argparser4j.%n" + "%n" + "optional arguments:%n" + " -h, --help show this help message and exit%n" + "%n" + " --foo FOO%n" + "%n" + "This is epilog.%n"), ap.formatHelp()); } @Test public void testFormatHelpWithArgumentGroupWithoutHelp() throws ArgumentParserException { ArgumentParserImpl ap = new ArgumentParserImpl("argparse4j", false); ArgumentGroup group1 = ap.addArgumentGroup("group1").description( "group1 description"); group1.addArgument("foo").help("foo help"); ArgumentGroup group2 = ap.addArgumentGroup("group2").description( "group2 description"); group2.addArgument("--bar").help("bar help"); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j [--bar BAR] foo%n" + "%n" + "group1:%n" + " group1 description%n" + "%n" + " foo foo help%n" + "%n" + "group2:%n" + " group2 description%n" + "%n" + " --bar BAR bar help%n"), ap.formatHelp()); } @Test public void testFormatHelpWithMutexGroup() throws ArgumentParserException { ap.description("This is argparser4j.").epilog("This is epilog."); MutuallyExclusiveGroup group = ap.addMutuallyExclusiveGroup("group1") .description("group1 description"); group.addArgument("--foo"); group.addArgument("--bar"); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j [-h] [--foo FOO | --bar BAR]%n" + "%n" + "This is argparser4j.%n" + "%n" + "optional arguments:%n" + " -h, --help show this help message and exit%n" + "%n" + "group1:%n" + " group1 description%n" + "%n" + " --foo FOO%n" + " --bar BAR%n" + "%n" + "This is epilog.%n"), ap.formatHelp()); } @Test public void testFormatHelpWithMutexGroupWithoutTitleAndDescription() throws ArgumentParserException { ap.description("This is argparser4j.").epilog("This is epilog."); MutuallyExclusiveGroup group = ap.addMutuallyExclusiveGroup(); group.addArgument("--foo"); ap.addArgument("-b").action(Arguments.storeTrue()); // Without title and description, options in mutually exclusive group // is merged into other optional arguments. assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j [-h] [-b] [--foo FOO]%n" + "%n" + "This is argparser4j.%n" + "%n" + "optional arguments:%n" + " -h, --help show this help message and exit%n" + " --foo FOO%n" + " -b%n" + "%n" + "This is epilog.%n"), ap.formatHelp()); } @Test public void testFormatHelp() throws ArgumentParserException { ap.description("This is argparser4j.").epilog("This is epilog."); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j [-h]%n" + "%n" + "This is argparser4j.%n" + "%n" + "optional arguments:%n" + " -h, --help show this help message and exit%n" + "%n" + "This is epilog.%n"), ap.formatHelp()); } @Test public void testFormatHelpWithDefaultHelp() throws ArgumentParserException { ap.defaultHelp(true).addArgument("--foo").setDefault("alpha"); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j [-h] [--foo FOO]%n" + "%n" + "optional arguments:%n" + " -h, --help show this help message and exit%n" + " --foo FOO (default: alpha)%n"), ap.formatHelp()); } @Test public void testFormatHelpWithSuppress() throws ArgumentParserException { ArgumentGroup group = ap.addArgumentGroup("group"); group.addArgument("--foo"); group.addArgument("--bar").help(Arguments.SUPPRESS); ap.addArgument("-a").help(Arguments.SUPPRESS).required(true); ap.addArgument("-b"); MutuallyExclusiveGroup mutex1 = ap.addMutuallyExclusiveGroup("mutex1"); mutex1.addArgument("-c").help(Arguments.SUPPRESS); mutex1.addArgument("-d"); MutuallyExclusiveGroup mutex2 = ap.addMutuallyExclusiveGroup("mutex2") .required(true); mutex2.addArgument("-e").help(Arguments.SUPPRESS); mutex2.addArgument("-f"); mutex2.addArgument("-g"); ap.addArgument("s"); ap.addArgument("t"); ap.addArgument("u").help(Arguments.SUPPRESS); Subparsers subparsers = ap.addSubparsers(); Subparser sap = subparsers.addParser("add"); sap.addArgument("-i").help(Arguments.SUPPRESS); sap.addArgument("-j"); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j [-h] [--foo FOO] [-b B] [-d D] (-f F | -g G) s t {add}%n" + " ...%n" + "%n" + "positional arguments:%n" + " s%n" + " t%n" + " {add}%n" + "%n" + "optional arguments:%n" + " -h, --help show this help message and exit%n" + " -b B%n" + "%n" + "group:%n" + " --foo FOO%n" + "%n" + "mutex1:%n" + " -d D%n" + "%n" + "mutex2:%n" + " -f F%n" + " -g G%n"), ap.formatHelp()); // Check upper parsers's suppressed required arguments are not shown. assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j (-f F | -g G) s t add [-h] [-j J]%n" + "%n" + "optional arguments:%n" + " -h, --help show this help message and exit%n" + " -j J%n"), sap.formatHelp()); } @Test public void testSubparserFormatHelp() throws ArgumentParserException { ap.addArgument("--bar"); Subparsers subparsers = ap.addSubparsers(); Subparser parser = subparsers.addParser("install"); parser.description("This is sub-command of argparser4j.").epilog( "This is epilog of sub-command."); parser.addArgument("--foo"); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j install [-h] [--foo FOO]%n" + "%n" + "This is sub-command of argparser4j.%n" + "%n" + "optional arguments:%n" + " -h, --help show this help message and exit%n" + " --foo FOO%n" + "%n" + "This is epilog of sub-command.%n"), parser.formatHelp()); } @Test public void testSubparserFormatHelpWithDefaultHelp() throws ArgumentParserException { ap.addArgument("--bar"); Subparsers subparsers = ap.addSubparsers(); Subparser parser = subparsers.addParser("install").defaultHelp(true); parser.addArgument("--foo").setDefault("alpha"); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j install [-h] [--foo FOO]%n" + "%n" + "optional arguments:%n" + " -h, --help show this help message and exit%n" + " --foo FOO (default: alpha)%n"), parser.formatHelp()); } @Test public void testFormatHelpWithSubparserTitleDescription() throws ArgumentParserException { Subparsers subparsers = ap.addSubparsers().help("subcommand help") .title("mysubcommands").description("valid subcommands"); subparsers.addParser("install").help("install help"); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j [-h] {install} ...%n" + "%n" + "optional arguments:%n" + " -h, --help show this help message and exit%n" + "%n" + "mysubcommands:%n" + " valid subcommands%n" + "%n" + " {install} subcommand help%n" + " install install help%n"), ap.formatHelp()); } @Test public void testFormatHelpWithSubparserAlias() throws ArgumentParserException { Subparsers subparsers = ap.addSubparsers().help("subcommand help") .title("mysubcommands").description("valid subcommands"); subparsers.addParser("clone").help("clone help"); subparsers.addParser("checkout").aliases("co").help("checkout help"); subparsers.addParser("remove").aliases("rm","del").help("remove help"); assertEquals(String.format( TextHelper.LOCALE_ROOT, "usage: argparse4j [-h] {clone,checkout,co,remove,rm,del} ...%n" + "%n" + "optional arguments:%n" + " -h, --help show this help message and exit%n" + "%n" + "mysubcommands:%n" + " valid subcommands%n" + "%n" + " {clone,checkout,co,remove,rm,del}%n" + " subcommand help%n" + " clone clone help%n" + " checkout (co) checkout help%n" + " remove (rm,del) remove help%n"), ap.formatHelp()); } @Test public void testPrintHelp() throws ArgumentParserException { String h = "Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do"; ap.addArgument("bar").help(h); ap.addArgument("verylonglongpositionalargument").help(h); ap.addArgument("-f", "--foo").help(h); ap.addArgument("-1", "--1").metavar("X").nargs(2).help(h); ap.addArgument("-2").metavar("X").nargs("*").help(h); ap.addArgument("-3").metavar("X").nargs("+").help(h); ap.addArgument("-4").metavar("X").nargs("?").help(h); Subparsers subparsers = ap.addSubparsers().help("sub-command help"); Subparser parserA = subparsers.addParser("install"); parserA.help("parserA help"); Subparser parserB = subparsers.addParser("search"); // StringWriter out = new StringWriter(); ap.printHelp(new PrintWriter(System.out)); } @Test public void testFormatVersion() throws ArgumentParserException { ap.version("${prog} version 7.8.7 (Dreamliner)"); assertEquals("argparse4j version 7.8.7 (Dreamliner)", ap.formatVersion()); } @Test public void testCandidateEquality() { Candidate foo = new Candidate(15, "foo"); Candidate fooCopy = new Candidate(15, "foo"); Candidate bar = new Candidate(15, "bar"); Candidate foo2 = new Candidate(16, "foo"); assertTrue(foo.equals(foo)); assertTrue(foo.equals(fooCopy)); assertFalse(foo.equals(bar)); assertFalse(foo.equals(foo2)); assertFalse(foo.equals(null)); assertFalse(foo.equals("foo")); Candidate subNull = new Candidate(15, null); assertFalse(foo.equals(subNull)); assertFalse(subNull.equals(foo)); assertEquals(foo.hashCode(), fooCopy.hashCode()); assertFalse(foo.hashCode() == foo2.hashCode()); assertFalse(foo.hashCode() == bar.hashCode()); assertFalse(foo.hashCode() == subNull.hashCode()); } @Test (expected=HelpScreenException.class) public void testHelpThrowsHelpScreenException() throws ArgumentParserException { ap.parseArgs(new String[]{"--help"}); } } SubparsersImplTest.java000066400000000000000000000033021240010205600336620ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/internalpackage net.sourceforge.argparse4j.internal; import static org.junit.Assert.*; import org.junit.Test; public class SubparsersImplTest { @Test public void testFormatShortSyntax() { SubparsersImpl subparsers = new SubparsersImpl(new ArgumentParserImpl( "prog")); assertEquals("{}", subparsers.formatShortSyntax()); subparsers.addParser("install"); assertEquals("{install}", subparsers.formatShortSyntax()); subparsers.addParser("checkout"); assertEquals("{install,checkout}", subparsers.formatShortSyntax()); subparsers.metavar("COMMAND"); assertEquals("COMMAND", subparsers.formatShortSyntax()); } @Test public void testAddParserNotUnique() { SubparsersImpl subparsers = new SubparsersImpl(new ArgumentParserImpl( "prog")); SubparserImpl subparser = subparsers.addParser("checkout"); try { subparsers.addParser("checkout"); } catch(IllegalArgumentException e) { assertEquals("command 'checkout' has been already used", e.getMessage()); } } @Test public void testAddAlias() { SubparsersImpl subparsers = new SubparsersImpl(new ArgumentParserImpl( "prog")); SubparserImpl subparser = subparsers.addParser("checkout"); subparsers.addAlias(subparser, "co", "out"); assertTrue(subparsers.getCommands().contains("co")); assertTrue(subparsers.getCommands().contains("out")); try { subparsers.addAlias(subparser, "co"); } catch(IllegalArgumentException e) { assertEquals("command 'co' has been already used", e.getMessage()); } } } argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/mock/000077500000000000000000000000001240010205600264025ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/mock/MockArgument.java000066400000000000000000000065221240010205600316460ustar00rootroot00000000000000package net.sourceforge.argparse4j.mock; import java.util.Collection; import net.sourceforge.argparse4j.inf.Argument; import net.sourceforge.argparse4j.inf.ArgumentAction; import net.sourceforge.argparse4j.inf.ArgumentChoice; import net.sourceforge.argparse4j.inf.ArgumentType; import net.sourceforge.argparse4j.inf.FeatureControl; public class MockArgument implements Argument { @Override public Argument nargs(int n) { // TODO Auto-generated method stub return null; } @Override public Argument nargs(String n) { // TODO Auto-generated method stub return null; } @Override public Argument setConst(Object value) { // TODO Auto-generated method stub return null; } @Override public Argument setConst(E... values) { // TODO Auto-generated method stub return null; } @Override public Argument setDefault(Object value) { // TODO Auto-generated method stub return null; } @Override public Argument setDefault(E... values) { // TODO Auto-generated method stub return null; } @Override public Argument setDefault(FeatureControl ctrl) { // TODO Auto-generated method stub return null; } @Override public Argument type(Class type) { // TODO Auto-generated method stub return null; } @Override public Argument type(ArgumentType type) { // TODO Auto-generated method stub return null; } @Override public Argument required(boolean required) { // TODO Auto-generated method stub return null; } @Override public Argument action(ArgumentAction action) { // TODO Auto-generated method stub return null; } @Override public Argument choices(ArgumentChoice choice) { // TODO Auto-generated method stub return null; } @Override public Argument choices(Collection values) { // TODO Auto-generated method stub return null; } @Override public Argument choices(E... values) { // TODO Auto-generated method stub return null; } @Override public Argument dest(String dest) { // TODO Auto-generated method stub return null; } @Override public Argument metavar(String... metavar) { // TODO Auto-generated method stub return null; } @Override public Argument help(String help) { // TODO Auto-generated method stub return null; } @Override public Argument help(FeatureControl help) { return null; } @Override public String textualName() { // TODO Auto-generated method stub return null; } @Override public String getDest() { // TODO Auto-generated method stub return null; } @Override public Object getConst() { // TODO Auto-generated method stub return null; } @Override public Object getDefault() { // TODO Auto-generated method stub return null; } @Override public FeatureControl getDefaultControl() { // TODO Auto-generated method stub return null; } @Override public FeatureControl getHelpControl() { return null; } } argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/test/000077500000000000000000000000001240010205600264305ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/java/net/sourceforge/argparse4j/test/TestHelper.java000066400000000000000000000004541240010205600313550ustar00rootroot00000000000000package net.sourceforge.argparse4j.test; import java.util.Arrays; import java.util.List; public class TestHelper { /** * Returns args as List * * @param args * @return */ public static List list(T... args) { return Arrays.asList(args); } } argparse4j-argparse4j-0.4.4/src/test/resources/000077500000000000000000000000001240010205600213675ustar00rootroot00000000000000argparse4j-argparse4j-0.4.4/src/test/resources/args.txt000066400000000000000000000000071240010205600230610ustar00rootroot00000000000000-f bar argparse4j-argparse4j-0.4.4/src/test/resources/args2.txt000066400000000000000000000000061240010205600231420ustar00rootroot00000000000000bravo argparse4j-argparse4j-0.4.4/src/test/resources/args3.txt000066400000000000000000000000031240010205600231400ustar00rootroot00000000000000y2 argparse4j-argparse4j-0.4.4/src/test/resources/args4.txt000066400000000000000000000000141240010205600231430ustar00rootroot00000000000000--foo HELLO argparse4j-argparse4j-0.4.4/src/test/resources/args5.txt000066400000000000000000000000061240010205600231450ustar00rootroot00000000000000-a -x argparse4j-argparse4j-0.4.4/src/test/resources/args6.txt000066400000000000000000000000031240010205600231430ustar00rootroot00000000000000-a argparse4j-argparse4j-0.4.4/src/test/resources/args7.txt000066400000000000000000000000501240010205600231460ustar00rootroot00000000000000-a @target/test-classes/args6.txt -b -x argparse4j-argparse4j-0.4.4/src/test/resources/args8.txt000066400000000000000000000000061240010205600231500ustar00rootroot00000000000000-a b