Class Options


  • public class Options
    extends java.lang.Object
    The Options class:
    • parses command-line options and sets fields in your program accordingly,
    • creates usage messages (such as printed by a --help option), and
    • creates documentation suitable for a manual or manpage.
    Thus, the programmer is freed from writing duplicative, boilerplate code. The user documentation is automatically generated and never gets out of sync with the rest of the program.

    The programmer does not have to write any code, only declare and document variables. For each field that you want to set from a command-line argument, you write Javadoc and an @Option annotation. Then, at run time, the field is automatically set from a command-line option of the same name. Also, at build time, usage messages and printed documentation are generated automatically.

    Suppose your program should support the command-line arguments --outfile, -o (shorthand for --outfile), --ignore-case, -i, (shorthand for --ignore-case), and --temperature. This code does so:

     import org.plumelib.options.*;
    
     public class MyProgram {
    
       @Option("-o <filename> the output file ")
       public static File outfile = new File("/tmp/foobar");
    
       @Option("-i ignore case")
       public static boolean ignore_case;
    
       @Option("set the initial temperature")
       public static double temperature = 75.0;
    
       public static void main(String[] args) {
         MyProgram myInstance = new MyProgram();
         Options options = new Options("MyProgram [options] infile outfile",
                                       myInstance, MyUtilityClass.class);
         String[] remainingArgs = options.parse(true, args);
         ...
       }
     }
     
    In the code above, the call to parse(boolean, String[]) sets fields in object myInstance and sets static fields in class MyUtilityClass. It returns the original command line, with all options removed. If a command-line argument is incorrect, it prints a usage message and terminates the program. The program can also explicitly create or print a usage message; see usage(String...) and printUsage().

    For examples of generated HTML documentation, see the documentation for Lookup, Randoop, and Javarifier.

    @Option indicates a command-line option

    The @Option annotation on a field specifies brief user documentation and, optionally, a one-character short name that a user may supply on the command line. The long name is taken from the name of the variable. When the name contains an underscore, the user may substitute a hyphen on the command line instead; for example, the --multi-word-variable command-line option would set the variable multi_word_variable.

    A user of your program supplies command-line options in the form "--name=value" or "-name value". The value (after the "=" or " ") is mandatory for all options except booleans. Booleans are set to true if no value is specified. Booleans support "--no-optionname" which is equivalent to "--optionname=false".

    A user may provide an option multiple times on the command line. If the field is a list, each entry is added to the list. If the field is not a list, then only the last occurrence is used (subsequent occurrences override the previous value).

    All arguments that start with "-" are processed as options. By default, the entire command line is scanned for options. To terminate option processing at the first non-option argument, see setParseAfterArg(boolean). Also, the special option "--" always terminates option processing; "--" is discarded, but no subsequent parts of the command line are scanned for options.

    Unpublicized options

    The @Unpublicized annotation causes an option not to be displayed in the usage message. This can be useful for options that are preliminary, experimental, or for internal purposes only. The @Unpublicized annotation must be specified in addition to the @Option annotation.

    The usage message can optionally include unpublicized options; see usage(boolean,String...).

    Option groups

    In a usage message or manual, it is useful to group related options and give the group a name. For examples of this, see the documentation for Lookup, Randoop, and Javarifier.

    If you wish to use option groups, then every option must be in some group. Declare related fields adjacent to one another in your .java file. Write @OptionGroup on the first field in each group.

    The group name (the first argument of an @OptionGroup annotation) must be unique among all classes and objects passed to the Options(String, Object...) constructor.

    If an option group itself is unpublicized:

    • The default usage message omits the group and all options belonging to it.
    • An unpublicized option group (that has any publicized options) is included in documentation for a manual.
    If an option group is not unpublicized but contains only unpublicized options, it will not be included in the default usage message.

    Option aliases

    The @Option annotation has an optional parameter aliases, which accepts an array of strings. Each string in the array is an alias for the option being defined and can be used in place of an option's long name or short name.

    One example is that a program might support "--optimize" and "--optimise" which are interchangeable. Another example is that a program might support "--help" and "-help" with the same meaning:

         // The user may supply --help, -h, or -help, all of which mean the same thing and set this variable.
         @Option(value="-h Print a help message", aliases={"-help"})
         public static boolean help;
    Aliases should start with a single dash or double dash. If there is only a single, one-character alias, it can be put at the beginning of the value field or in the aliases field. It is the programmer's responsibility to ensure that no alias is the same as other options or aliases.

    Generating documentation for a manual or manpage

    It is helpful to include a summary of all command-line options in amanual, manpage, or the class Javadoc for a class that has a main method. The OptionsDoclet class generates HTML documentation.

    Supported field types

    A field with an @Option annotation may be of the following types:

    • Primitive types: boolean, byte, char, short, int, long, float, double.
    • Primitive type wrappers: Boolean, Byte, Char, Short, Integer, Long, Float, Double. Use of a wrapper type allows the argument to have no default value.
    • Reference types that have a constructor with a single string parameter.
    • java.util.regex.Pattern.
    • enums.
    • Lists of any of the above reference types.

    Customization

    Option processing can be customized in a number of ways.

    • If setUseSingleDash(boolean) is true, then the long names take the form "-longname" instead of "--longname". It defaults to false.
    • If setParseAfterArg(boolean) is true, then options are searched for throughout a command line, to its end. If it is false, then processing stops at the first non-option argument. It defaults to true.
    • If spaceSeparatedLists is true, then when an argument contains spaces, it is treated as multiple elements to be added to a list. It defaults to false.
    • The programmer may set usageSynopsis to masquerade as another program.
    • If useDashes is false, then usage messages advertise long options with underscores (as in --my_option_name) instead of dashes (as in --my-option-name). The user can always specify either; this just affects usage messages. It defaults to false.

    Limitations

    • Short options are only supported as separate entries (e.g., "-a -b") and not as a single group (e.g., "-ab").
    • If you have a boolean option named exactly "long", you must use "--long=false" to turn it off; "--no-long" is not supported.
    See Also:
    Option, OptionGroup, Unpublicized, OptionsDoclet
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      static class  Options.ArgException
      Indicates an exception encountered during argument processing.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static boolean spaceSeparatedLists
      Whether to treat arguments to lists as space-separated.
      @Nullable java.lang.String usageSynopsis
      Synopsis of usage.
      boolean useDashes
      In usage messages, use dashes (hyphens) to split words in option names.
      boolean useSingleDash
      When true, long options take the form -longOption with a single dash, rather than the default --longOption with two dashes.
    • Constructor Summary

      Constructors 
      Constructor Description
      Options​(@UnknownInitialization java.lang.Object... args)
      Prepare for option processing.
      Options​(java.lang.String usageSynopsis, @UnknownInitialization java.lang.Object... args)
      Prepare for option processing.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void enableDebugLogging​(boolean enabled)
      Enable or disable debug logging.
      java.lang.String getOptionsString()
      Returns a string containing all of the options that were set and their arguments.
      java.lang.String[] parse​(boolean showUsageOnError, java.lang.String[] args)
      Sets option variables from the given command line; if any command-line argument is illegal, prints the usage message and terminates the program.
      java.lang.String[] parse​(java.lang.String[] args)
      Sets option variables from the given command line.
      java.lang.String[] parse​(java.lang.String message, java.lang.String[] args)
      Sets option variables from the given command line; if any command-line argument is illegal, prints the given message and terminates the program.
      void printUsage()
      Prints, to standard output, usage information.
      void printUsage​(java.io.PrintStream ps)
      Prints usage information to the given PrintStream.
      void setParseAfterArg​(boolean val)
      If true, Options will parse arguments even after a non-option command-line argument.
      java.lang.String settings()
      Returns a string containing the current setting for each option, in command-line format that can be parsed by Options.
      java.lang.String settings​(boolean showUnpublicized)
      Returns a string containing the current setting for each option, in command-line format that can be parsed by Options.
      void setUseSingleDash​(boolean val)
      If true, long options (those derived from field names) are expected with a single dash prefix as in -long-option rather than --long-option.
      static java.lang.String[] tokenize​(java.lang.String args)
      Splits the argument string into an array of tokens (command-line flags and arguments), respecting single and double quotes.
      java.lang.String toString()
      Return a description of all of the known options.
      java.lang.String usage​(boolean showUnpublicized, java.lang.String... groupNames)
      Returns a usage message for command-line options.
      java.lang.String usage​(java.lang.String... groupNames)
      Returns a usage message for command-line options.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Field Detail

      • useSingleDash

        public boolean useSingleDash
        When true, long options take the form -longOption with a single dash, rather than the default --longOption with two dashes.
      • spaceSeparatedLists

        public static boolean spaceSeparatedLists
        Whether to treat arguments to lists as space-separated. Defaults to false.

        When true, an argument to an option of list type is split, on whitespace, into multiple arguments each of which is added to the list. When false, each argument to an option of list type is treated as a single element, no matter what characters it contains.

        For example, when this is true, a command line containing --my-option="foo bar" is equivalent to --my-option="foo" --my-option="bar". Both of them have the effect of adding two elements, "foo" and "bar", to the list my_option.

      • usageSynopsis

        public @Nullable java.lang.String usageSynopsis
        Synopsis of usage. Example: "prog [options] arg1 arg2 ..."

        This field is public so that clients can reset it. Setting it enables one program to masquerade as another program, based on parsed options.

      • useDashes

        public boolean useDashes
        In usage messages, use dashes (hyphens) to split words in option names. This only applies to fields whose name contains an underscore. On the command line, a user may use either the underscores or dashes in the option name; this only controls which one is advertised in usage messages.
    • Constructor Detail

      • Options

        public Options​(@UnknownInitialization java.lang.Object... args)
        Prepare for option processing. Creates an object that will set fields in all the given arguments. An argument to this method may be a Class, in which case its static fields are set. The names of all the options (that is, the fields annotated with @Option) must be unique across all the arguments.
        Parameters:
        args - the classes whose options to process
      • Options

        public Options​(java.lang.String usageSynopsis,
                       @UnknownInitialization java.lang.Object... args)
        Prepare for option processing. Creates an object that will set fields in all the given arguments. An argument to this method may be a Class, in which case it must be fully initalized and its static fields are set. The names of all the options (that is, the fields annotated with @Option) must be unique across all the arguments.
        Parameters:
        usageSynopsis - a synopsis of how to call your program
        args - the classes whose options to process
    • Method Detail

      • enableDebugLogging

        public void enableDebugLogging​(boolean enabled)
        Enable or disable debug logging.
        Parameters:
        enabled - whether to enable or disable logging
      • setParseAfterArg

        public void setParseAfterArg​(boolean val)
        If true, Options will parse arguments even after a non-option command-line argument. Setting this to true is useful to permit users to write options at the end of a command line. Setting this to false is useful to avoid processing arguments that are actually options/arguments for another program that this one will invoke. The default is true.
        Parameters:
        val - whether to parse arguments after a non-option command-line argument
      • setUseSingleDash

        public void setUseSingleDash​(boolean val)
        If true, long options (those derived from field names) are expected with a single dash prefix as in -long-option rather than --long-option. The default is false and long options will be parsed with a double dash prefix as in --longOption.
        Parameters:
        val - whether to parse long options with a single dash, as in -longOption
      • parse

        public java.lang.String[] parse​(java.lang.String[] args)
                                 throws Options.ArgException
        Sets option variables from the given command line.
        Parameters:
        args - the commandline to be parsed
        Returns:
        all non-option arguments
        Throws:
        Options.ArgException - if the command line contains unknown option or misused options
      • tokenize

        public static java.lang.String[] tokenize​(java.lang.String args)
        Splits the argument string into an array of tokens (command-line flags and arguments), respecting single and double quotes.

        This method is only appropriate when the String[] version of the arguments is not available — for example, for the premain method of a Java agent.

        Parameters:
        args - the command line to be tokenized
        Returns:
        a string array analogous to the argument to main.
      • parse

        public java.lang.String[] parse​(java.lang.String message,
                                        java.lang.String[] args)
        Sets option variables from the given command line; if any command-line argument is illegal, prints the given message and terminates the program.

        If an error occurs, prints the exception's message, prints the given message, and then terminates the program. The program is terminated rather than throwing an error to create cleaner output.

        Parameters:
        message - a message to print, such as "Pass --help for a list of all command-line arguments."
        args - the command line to parse
        Returns:
        all non-option arguments
        See Also:
        parse(String[])
      • parse

        public java.lang.String[] parse​(boolean showUsageOnError,
                                        java.lang.String[] args)
        Sets option variables from the given command line; if any command-line argument is illegal, prints the usage message and terminates the program.

        If an error occurs and showUsageOnError is true, prints the exception's message, prints usage inoframtion, and then terminates the program. The program is terminated rather than throwing an error to create cleaner output.

        Parameters:
        showUsageOnError - if a command-line argument is incorrect, print a usage message
        args - the command line to parse
        Returns:
        all non-option arguments
        See Also:
        parse(String[])
      • printUsage

        public void printUsage​(java.io.PrintStream ps)
        Prints usage information to the given PrintStream. Uses the usage synopsis passed into the constructor, if any.
        Parameters:
        ps - where to print usage information
      • printUsage

        public void printUsage()
        Prints, to standard output, usage information.
      • usage

        public java.lang.String usage​(java.lang.String... groupNames)
        Returns a usage message for command-line options.
        Parameters:
        groupNames - the list of option groups to include in the usage message. If empty and option groups are being used, will return usage for all option groups that are not unpublicized. If empty and option groups are not being used, will return usage for all options that are not unpublicized.
        Returns:
        the command-line usage message
      • usage

        public java.lang.String usage​(boolean showUnpublicized,
                                      java.lang.String... groupNames)
        Returns a usage message for command-line options.
        Parameters:
        showUnpublicized - if true, treat all unpublicized options and option groups as publicized
        groupNames - the list of option groups to include in the usage message. If empty and option groups are being used, will return usage for all option groups that are not unpublicized. If empty and option groups are not being used, will return usage for all options that are not unpublicized.
        Returns:
        the command-line usage message
      • getOptionsString

        public java.lang.String getOptionsString()
        Returns a string containing all of the options that were set and their arguments. This is essentially the contents of args[] with all non-options removed. It can be used for calling a subprocess or for debugging.
        Returns:
        options, similarly to supplied on the command line
        See Also:
        settings()
      • settings

        public java.lang.String settings()
        Returns a string containing the current setting for each option, in command-line format that can be parsed by Options. Contains every known option even if the option was not specified on the command line. Never contains duplicates.
        Returns:
        a command line that can be tokenized with tokenize(java.lang.String), containing the current setting for each option
      • settings

        public java.lang.String settings​(boolean showUnpublicized)
        Returns a string containing the current setting for each option, in command-line format that can be parsed by Options. Contains every known option even if the option was not specified on the command line. Never contains duplicates.
        Parameters:
        showUnpublicized - if true, treat all unpublicized options and option groups as publicized
        Returns:
        a command line that can be tokenized with tokenize(java.lang.String), containing the current setting for each option
      • toString

        @SideEffectFree
        public java.lang.String toString​(@GuardSatisfied Options this)
        Return a description of all of the known options. Each option is described on its own line in the output.
        Overrides:
        toString in class java.lang.Object
        Returns:
        a description of all of the known options