Package name.kevinlocke.ultragetopt

Provides classes for parsing and processing command-line options including compatibility with many getopt implementations in addition to a substantial amount of customizability.

See:
          Description

Interface Summary
GetoptErrorFormatter Formatter for Getopt error messages.
 

Class Summary
BSDGetoptErrorFormatter Error formatter designed to mimic the output of getopt on a BSD system.
CommandLineOption Class representing a command-line option.
DarwinGetoptErrorFormatter Error formatter designed to mimic the output of getopt on a Darwin (Mac OS) system.
GNUGetoptErrorFormatter Error formatter designed to mimic the output of getopt from the GNU C Library.
OptionArgumentPair Class representing a command-line option and its argument (if any).
POSIXGetoptErrorFormatter Error formatter designed to mimic the output of getopt as described in POSIX (via the Single Unix Specification).
UltraGetopt Main class of the UltraGetopt system.
 

Enum Summary
ArgumentDisposition Argument requirement status for options.
UltraGetopt.Behavior Different behavior options for UltraGetopt.
 

Exception Summary
AmbiguousOptionException Exception signaling that an option could be matched against multiple accepted options.
CommandLineException Superclass for all exceptions resulting from parsing of the command-line.
ExtraArgumentException Exception signaling that an option which does not take an argument was given an argument.
InvalidOptionException Exception signaling that an option was determined to be invalid by the optionEncountered method.
MissingArgumentException Exception signaling that an option which requires an argument was not given any arguments.
UnrecognizedOptionException Exception signaling that an option encountered on the command-line was not recognized (not listed in the set of accepted options).
 

Package name.kevinlocke.ultragetopt Description

Provides classes for parsing and processing command-line options including compatibility with many getopt implementations in addition to a substantial amount of customizability. This is the Java imagining of UltraGetopt, a versatile getopt replacement written in C.

This class is designed to provide command-line parsing facilities which follow the expected behavior for command-line option syntax as well as to provide an interface which allows program authors to customize its behavior to fit the specific needs of their program. By default UltraGetopt will attempt to guess the conventions for the operating system on which it is being run and tune its behavior accordingly. However, program authors are also able to specify any set of behaviors that they desire and UltraGetopt will honor those behavior on any system on which it is run. In addition, UltraGetopt should be easy to use and flexible enough to work with almost any set of requirements. For any suggestions about how to improve this package to better achieve these goals, please contact the author.

Terminology Used in this Documentation

As an example for description, consider the following program invocation:
vim --noplugin -i ~/.viminfo -d file1 file2
Command-line Arguments
Also sometimes called just "arguments", these are any strings which appear after the program name on the command line. In the above example, the command-line arguments are "--noplugin", "-i", "~/.viminfo", "-d", "file1", and "file2".
Command-line Options
These are command-line arguments which are intended to have an effect on the behavior of the program being invoked. They are usually prefixed by one or more leader characters to separate them from other command-line options. Conventionally, options (or options which do not take any arguments) have also been called "flags". In the above example, the options are "--noplugin", "-i", and "-d".
Short Option
These are command-line options consisting of a single character. They are usually denoted by a single leader character. In the above example, the only short option is "-i".
Long Option
These are command-line options consisting of a word or multiple (typically hyphenated) words. They may be prefixed by a single leader character or multiple characters depending on the conventions of the system or development group.
Option Arguments
These are strings which directly follow an argument that modify the effect which the option has on the program. For example, a command-line option may tell the program to direct its output to a file and the option argument would be the filename where output should be sent. Conventionally, options can either be attached to the end of an option, separated by a space, or connected to the option by an assigner character. In the above example, the only option argument is "~/.viminfo" which is an argument to option "-i".
Non-option Arguments
These are all command-line arguments which are not either an option or an option argument. In the above example, "file1" and "file2" are both non-option arguments. Note that if option "-d" were defined as requiring an argument "file1" would be the option argument for "-d" and "file2" would be the only non-option argument.
Leader Character
This is a term which is likely non-standard, I use it to denote the character or characters which prefix an option. In the above example, the leader character is a '-', which is conventional for Unix and Unix-like systems. On MS-DOS and OS/2 systems, the convention is to use a '/' single character as the leader for both short and long options.
Assigner Character
This term is also likely non-standard. I use it to denote the character which is used to associate an option argument with an option. On many Unix and Unix-like systems a '=' is typically used as an assigner character (e.g. --outfile=log.txt would be interpreted as the option "--outfile" with an argument "log.txt"). MS-DOS and OS/2 typically use a ':' character as an assigner (e.g. /outfile:log.txt).

More Information

For more information about command-line conventions and getopt, see

Example Usage

For the following examples, consider a generic program which takes options to increase or decrease the amount of output as well as redirecting its output to a file and optionally reading commands from a file (or stdin if none is given).

Typical Usage

As a demonstration of the typical usage of UltraGetopt, consider a simple program which reunites Pangea. It takes options to indicate when the reuniting should take place, to output progress reports, and to apply extra force (which may be necessary). It also takes a list of governments to be informed of the pending action.
import java.util.List;
import java.util.Map;

import name.kevinlocke.ultragetopt.ArgumentDisposition;
import name.kevinlocke.ultragetopt.CommandLineException;
import name.kevinlocke.ultragetopt.CommandLineOption;
import name.kevinlocke.ultragetopt.UltraGetopt;

public class ReunitePangea {
    private static CommandLineOption[] acceptedopts = {
        new CommandLineOption('f', "force", ArgumentDisposition.NO_ARGUMENT),
        new CommandLineOption('p', "progress", ArgumentDisposition.OPTIONAL_ARGUMENT),
        new CommandLineOption('w', "when", ArgumentDisposition.REQUIRED_ARGUMENT),
    };

    public static void main(String[] args) {
        UltraGetopt getopt = null;
        try {
            getopt = new UltraGetopt(args, acceptedopts);
        } catch (CommandLineException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }

        Map<String,String> options = getopt.getOptionsByName();
        List<String> nonoptargs = getopt.getNonOptionArguments();

        if (options.containsKey("force"))
            // Apply extra force
        
        if (options.containsKey("progress")) {
            if (options.get("progress") != null)
                // Send progress reports to file
            else
                // Send progress reports to stdout
        }
        
        if (options.containsKey("when"))
            // Wait for the appropriate time
        
        for (String government : nonoptargs)
            // Contact government to let them know what's happening

        // Move continents into place
    }
}

Self-Documenting Options

It is also possible to extend the CommandLineOption class to add custom functionality. One example would be to provide self-documenting options. Consider the following program:
import java.util.Map;

import name.kevinlocke.ultragetopt.ArgumentDisposition;
import name.kevinlocke.ultragetopt.CommandLineException;
import name.kevinlocke.ultragetopt.CommandLineOption;
import name.kevinlocke.ultragetopt.UltraGetopt;

public class JettisonEngine {
    private static class DocumentedOption extends CommandLineOption {
        private String argname;
        private String helpmsg;
        
        public DocumentedOption(char shortopt, String longopt,
                ArgumentDisposition arg, String argname, String helpmsg) {
            super(shortopt, longopt, arg);
            this.argname = argname;
            this.helpmsg = helpmsg;
        }
        
        public void printHelp() {
            String longandarg = longopt;
            if (argreq == ArgumentDisposition.OPTIONAL_ARGUMENT)
                longandarg += "[="+argname+"]";
            else if (argreq == ArgumentDisposition.REQUIRED_ARGUMENT)
                longandarg += " <"+argname+">";

            String[] lines = helpmsg.split("\n");

            System.out.printf("%4s,%-20s%s%n",
                UltraGetopt.getDefaultShortLeaders()[0]+shortopt,
                UltraGetopt.getDefaultLongLeaders()[0]+longandarg,
                lines[0]);

            for (int i=1; i<lines.length; i++)
                System.out.printf("%25s%s%n", " ", lines[i]);
        }
    }
    
    private static DocumentedOption[] acceptedopts = {
        new DocumentedOption('a', "all", ArgumentDisposition.NO_ARGUMENT,
                "", "Jettison all engines"),
        new DocumentedOption('e', "engine", ArgumentDisposition.REQUIRED_ARGUMENT,
                "number", "Specify which engine to jettison"),
        new DocumentedOption('h', "help", ArgumentDisposition.NO_ARGUMENT,
                "", "Print this help message (you may need more)"),
        new DocumentedOption('m', "message", ArgumentDisposition.REQUIRED_ARGUMENT,
                "msg", "Message to read to the crew"),
    };

    public static void main(String[] args) {
        UltraGetopt getopt = null;
        try {
            getopt = new UltraGetopt(args, acceptedopts);
        } catch (CommandLineException e) {
            System.err.println(e.getMessage());
            System.err.println("Run `JettisonEngine -h' for usage information");
            System.exit(1);
        }

        Map<String,String> options = getopt.getOptionsByName();

        if (options.containsKey("help")) {
            System.out.println("Usage:  JettisonEngine [options]");
            System.out.println("Jettison one or more of the engines.\n");
            System.out.println("JettisonEngine supports the following options:");
            for (DocumentedOption option : acceptedopts)
                option.printHelp();
            return;
        }
        
        // Jettison the engine(s)
    }
}

Option Callbacks

Another method of handling options can be accomplished by extending the CommandLineOption class to implement the optionEncountered callback mechanism. This function will be called as each option is encountered on the command line when the options are parsed in the UltraGetopt constructor.
import java.util.Map;

import name.kevinlocke.ultragetopt.ArgumentDisposition;
import name.kevinlocke.ultragetopt.CommandLineException;
import name.kevinlocke.ultragetopt.CommandLineOption;
import name.kevinlocke.ultragetopt.UltraGetopt;

public class TimeMachine {
    private static class ActionOption extends CommandLineOption {
        private String argname;
        private String helpmsg;
        
        public ActionOption(char shortopt, String longopt,
                ArgumentDisposition arg, String argname, String helpmsg) {
            super(shortopt, longopt, arg);
            this.argname = argname;
            this.helpmsg = helpmsg;
        }
        
        public void printHelp() {
            String longandarg = longopt;
            if (argreq == ArgumentDisposition.OPTIONAL_ARGUMENT)
                longandarg += "[="+argname+"]";
            else if (argreq == ArgumentDisposition.REQUIRED_ARGUMENT)
                longandarg += " <"+argname+">";
                
            String[] lines = helpmsg.split("\n");
                
            System.out.printf("%4s,%-20s%s%n",
                UltraGetopt.getDefaultShortLeaders()[0]+shortopt,
                UltraGetopt.getDefaultLongLeaders()[0]+longandarg,
                lines[0]);
            
            for (int i=1; i<lines.length; i++)
                System.out.printf("%25s%s%n", " ", lines[i]);
        }
                
        @Override
        public boolean optionEncountered(String argument) {
            switch (shortopt) {
            case 'h':
                // Stop processing right here and print a help message
                return false;
            case 'l':
                // Pause for given timespan (or 60 minutes)
                break;
            case 'r':
                // Revert the specified temporal paradox (or the most recent)
                break;
            case 't':
                // Travel to the given time
                break;
            default:
                // Not an option that we are processing here
                break;
            }
            return true;
        }
    }
    
    private static ActionOption[] acceptedopts = {
        new ActionOption('h', "help", ArgumentDisposition.NO_ARGUMENT,
                "", "Print this help message"),
        new ActionOption('l', "layover", ArgumentDisposition.OPTIONAL_ARGUMENT,
                "mins", "Pause for sightseeing (default: 60)"),
        new ActionOption('r', "revert", ArgumentDisposition.OPTIONAL_ARGUMENT,
                "which", "Revert temporal paradox\n" +
                "(default: most recent, relatively speaking)"),
        new ActionOption('t', "time", ArgumentDisposition.REQUIRED_ARGUMENT,
                "date", "Specify a destination in time"),
    };

    public static void main(String[] args) {
        UltraGetopt getopt = null;
        try {
            getopt = new UltraGetopt(args, acceptedopts);
        } catch (CommandLineException e) {
            System.err.println(e.getMessage());
            System.err.println("Run `TimeMachine -h' for usage information");
            System.exit(1);
        }

        Map<String,String> options = getopt.getOptionsByName();

        if (options.containsKey("help")) {
            System.out.println("Usage:  TimeMachine <sequence>");
            System.out.println("Travel through time.");
            System.out.println("WARNING:  May not function at less than 88mph.\n");
            System.out.println("TimeMachine supports the following options:");
            for (ActionOption option : acceptedopts)
                option.printHelp();
            return;
        }
        
        // We hope you have enjoyed your trip
    }
}

Related Documentation

The following classes are used by the name.kevinlocke.ultragetopt API: For more information, please see