A command line specifying all three options might look like this:
java argparser.SimpleExample -theta 7.8 -debug -file /ai/lloyd/bar
The application creates an instance of ArgParser and then adds descriptions of the allowed options using {@link #addOption addOption}. The method {@link #matchAllArgs(String[]) matchAllArgs} is then used to matchthese options against the command line arguments. Values associated with each option are returned in the value
field of special ``holder'' classes (e.g., {@link argparser.DoubleHolder DoubleHolder}, {@link argparser.StringHolder StringHolder}, etc.).
The first argument to {@link #addOption addOption} is a string thatspecifies (1) the option's name, (2) a conversion code for its associated value (e.g., %f
for floating point, %s
for a string, %v
for a boolean flag), and (3) an optional description (following the #
character) which is used for generating help messages. The second argument is the holder object through which the value is returned. This may be either a type-specific object (such as {@link argparser.DoubleHolder DoubleHolder} or {@link argparser.StringHolder StringHolder}), an array of the appropriate type, or an instance of java.util.Vector
.
By default, arguments that don't match the specified options, are out of range, or are otherwise formatted incorrectly, will cause matchAllArgs
to print a message and exit the program. Alternatively, an application can use {@link #matchAllArgs(String[],int,int) matchAllArgs(args,idx,exitFlags)} to obtainan array of unmatched arguments which can then be processed separately
-name
that expects to be provided with one of three string values (john
, mary
, or jane
), an option -index
that expects to be supplied with a integer value in the range 1 to 256, an option -size
that expects to be supplied with integer values of either 1, 2, 4, 8, or 16, and an option -foo
that expects to be supplied with floating point values in the ranges -99 < foo <= -50, or 50 <= foo < 99. StringHolder name = new StringHolder(); IntHolder index = new IntHolder(); IntHolder size = new IntHolder(); DoubleHolder foo = new DoubleHolder(); parser.addOption ("-name %s {john,mary,jane}", name); parser.addOption ("-index %d {[1,256]}", index); parser.addOption ("-size %d {1,2,4,8,16}", size); parser.addOption ("-foo %f {(-99,-50],[50,99)}", foo);If an argument value does not lie within a specified range, an error is generated.
parser.addOption ("-v,--verbose %v #print lots of info"); parser.addOption ("-of,-outfile,-outputFile %s #output file");
parser.addOption ("-file %s #file name");will cause the parser to look for two strings in the argument list of the form
-file someFileNameHowever, if there is no white space separting the option's name from it's conversion code, then values associated with that option will be assumed to be part of the same argument string as the option itself. For example,
parser.addOption ("-file=%s #file name");will cause the parser to look for a single string in the argument list of the form
-file=someFileNameSuch an option is called a "single word" option.
In cases where an option has multiple names, then this single word behavior is invoked if there is no white space between the last indicated name and the conversion code. However, previous names in the list will still be given multi-word behavior if there is white space between the name and the following comma. For example,
parser.addOption ("-nb=,-number ,-n%d #number of blocks");will cause the parser to look for one, two, and one word constructions of the forms
-nb=N -number N -nN
-velocity
which should be followed by three numbers denoting the x, y, and z components of a velocity vector. We can require multiple values for an option by placing a multiplier specification, of the form X
N, where N is an integer, after the conversion code (or range specification, if present). For example, double[] pos = new double[3]; addOption ("-position %fX3 #position of the object", pos);will cause the parser to look for
-position xx yy zzin the argument list, where
xx
, yy
, and zz
are numbers. The values are stored in the array pos
. Options requiring multiple values must use arrays to return their values, and cannot be used in single word format. java.util.Vector
to serve as the value holder. Then every time the option appears in the argument list, the parser will create a value holder of appropriate type, set it to the current value, and store the holder in the vector. For example, the construction Vector vec = new Vector(10); parser.addOption ("-foo %f", vec); parser.matchAllArgs(args);when supplied with an argument list that contains
-foo 1.2 -foo 1000 -foo -78will create three instances of {@link argparser.DoubleHolder DoubleHolder}, initialized to
1.2
, 1000
, and -78
, and store them in vec
. #
character. The string returned by {@link #getHelpMessage getHelpMessage} forthe first example above would be Usage: java argparser.SimpleExample Options include: -help,-? displays help information -theta <float> theta value (in degrees) -file <string> name of the operating file -debug enables display of debugging infoThe options
-help
and -?
are including in the parser by default as help options, and they automatically cause the help message to be printed. To exclude these options, one should use the constructor {@link #ArgParser(String,boolean) ArgParser(synopsis,false)}. Help options can also be specified by the application using {@link #addOption addOption} and the conversion code %h
. Help optionscan be disabled using {@link #setHelpOptionsEnabled setHelpOptionsEnabled(false)}. A description of the required values for an option can be specified explicitly by placing a second First, the method {@link #matchAllArgs(String[],int,int) matchAllArgs(args,idx,exitFlags)} returns an array ofall unmatched arguments, which can then be handled specially: If we need more control over the parsing, we can parse arguments one at a time using {@link #matchArg matchArg}: #
character in the specification string. Everything between the first and second #
characters then becomes the value description, and everything after the second #
character becomes the option description. For example, if the -theta
option above was specified with parser.addOption ("-theta %f #NUMBER#theta value (in degrees)",theta);
instead of parser.addOption ("-theta %f #theta value (in degrees)", theta);
then the corresponding entry in the help message would look like -theta NUMBER theta value (in degrees)
Custom Argument Parsing
An application may find it necessary to handle arguments that don't fit into the framework of this class. There are a couple of ways to do this. String[] unmatched = parser.matchAllArgs (args, 0, parser.EXIT_ON_ERROR); for (int i = 0; i < unmatched.length; i++) { ... handle unmatched arguments ... }
For instance, this would be useful for an applicatoon that accepts an arbitrary number of input file names. The options can be parsed using matchAllArgs
, and the remaining unmatched arguments give the file names. int idx = 0; while (idx < args.length) { try { idx = parser.matchArg (args, idx); if (parser.getUnmatchedArgument() != null) { ... handle this unmatched argument ourselves ... } } catch (ArgParserException e) { // malformed or erroneous argument parser.printErrorAndExit (e.getMessage()); } }
{@link #matchArg matchArg(args,idx)} matches one option at locationidx
in the argument list, and then returns the location value that should be used for the next match. If an argument does not match any option, {@link #getUnmatchedArgument getUnmatchedArgument} will return a copy of theunmatched argument. Reading Arguments From a File
The method {@link #prependArgs prependArgs} can be used to automaticallyread in a set of arguments from a file and prepend them onto an existing argument list. Argument words correspond to white-space-delimited strings, and the file may contain the comment character #
(which comments out everything to the end of the current line). A typical usage looks like this: ... create parser and add options ... args = parser.prependArgs (new File(".configFile"), args); parser.matchAllArgs (args);
This makes it easy to generate simple configuration files for an application.
@author John E. Lloyd, Fall 2004
|
|