[5279] | 1 | /*
|
---|
| 2 | /* Copyright (c) 1987-1997 Free Software Foundation, Inc.
|
---|
| 3 | /* Java Port Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
|
---|
| 4 | /*
|
---|
| 5 | /* This program is free software; you can redistribute it and/or modify
|
---|
[10209] | 6 | /* it under the terms of the GNU Library General Public License as published
|
---|
[5279] | 7 | /* by the Free Software Foundation; either version 2 of the License or
|
---|
| 8 | /* (at your option) any later version.
|
---|
| 9 | /*
|
---|
| 10 | /* This program is distributed in the hope that it will be useful, but
|
---|
| 11 | /* WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 12 | /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
| 13 | /* GNU Library General Public License for more details.
|
---|
| 14 | /*
|
---|
| 15 | /* You should have received a copy of the GNU Library General Public License
|
---|
[10209] | 16 | /* along with this program; see the file COPYING.LIB. If not, write to
|
---|
| 17 | /* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
|
---|
[5279] | 18 | /* Boston, MA 02111-1307 USA
|
---|
| 19 | /**************************************************************************/
|
---|
| 20 |
|
---|
| 21 | package gnu.getopt;
|
---|
| 22 |
|
---|
| 23 | import java.text.MessageFormat;
|
---|
| 24 | import java.util.HashMap;
|
---|
| 25 | import java.util.Map;
|
---|
[12892] | 26 | import java.util.function.Function;
|
---|
[5279] | 27 |
|
---|
| 28 | /**************************************************************************/
|
---|
| 29 |
|
---|
| 30 | /**
|
---|
| 31 | * This is a Java port of GNU getopt, a class for parsing command line
|
---|
| 32 | * arguments passed to programs. It it based on the C getopt() functions
|
---|
| 33 | * in glibc 2.0.6 and should parse options in a 100% compatible manner.
|
---|
| 34 | * If it does not, that is a bug. The programmer's interface is also
|
---|
| 35 | * very compatible.
|
---|
| 36 | * <p>
|
---|
| 37 | * To use Getopt, create a Getopt object with a argv array passed to the
|
---|
| 38 | * main method, then call the getopt() method in a loop. It will return an
|
---|
| 39 | * int that contains the value of the option character parsed from the
|
---|
| 40 | * command line. When there are no more options to be parsed, it
|
---|
| 41 | * returns -1.
|
---|
| 42 | * <p>
|
---|
| 43 | * A command line option can be defined to take an argument. If an
|
---|
| 44 | * option has an argument, the value of that argument is stored in an
|
---|
| 45 | * instance variable called optarg, which can be accessed using the
|
---|
| 46 | * getOptarg() method. If an option that requires an argument is
|
---|
| 47 | * found, but there is no argument present, then an error message is
|
---|
| 48 | * printed. Normally getopt() returns a '?' in this situation, but
|
---|
| 49 | * that can be changed as described below.
|
---|
| 50 | * <p>
|
---|
| 51 | * If an invalid option is encountered, an error message is printed
|
---|
| 52 | * to the standard error and getopt() returns a '?'. The value of the
|
---|
| 53 | * invalid option encountered is stored in the instance variable optopt
|
---|
| 54 | * which can be retrieved using the getOptopt() method. To suppress
|
---|
| 55 | * the printing of error messages for this or any other error, set
|
---|
[10209] | 56 | * the value of the opterr instance variable to false using the
|
---|
[5279] | 57 | * setOpterr() method.
|
---|
| 58 | * <p>
|
---|
| 59 | * Between calls to getopt(), the instance variable optind is used to
|
---|
| 60 | * keep track of where the object is in the parsing process. After all
|
---|
| 61 | * options have been returned, optind is the index in argv of the first
|
---|
| 62 | * non-option argument. This variable can be accessed with the getOptind()
|
---|
| 63 | * method.
|
---|
| 64 | * <p>
|
---|
| 65 | * Note that this object expects command line options to be passed in the
|
---|
[10209] | 66 | * traditional Unix manner. That is, proceeded by a '-' character.
|
---|
[5279] | 67 | * Multiple options can follow the '-'. For example "-abc" is equivalent
|
---|
| 68 | * to "-a -b -c". If an option takes a required argument, the value
|
---|
| 69 | * of the argument can immediately follow the option character or be
|
---|
| 70 | * present in the next argv element. For example, "-cfoo" and "-c foo"
|
---|
| 71 | * both represent an option character of 'c' with an argument of "foo"
|
---|
| 72 | * assuming c takes a required argument. If an option takes an argument
|
---|
| 73 | * that is not required, then any argument must immediately follow the
|
---|
| 74 | * option character in the same argv element. For example, if c takes
|
---|
| 75 | * a non-required argument, then "-cfoo" represents option character 'c'
|
---|
| 76 | * with an argument of "foo" while "-c foo" represents the option
|
---|
| 77 | * character 'c' with no argument, and a first non-option argv element
|
---|
| 78 | * of "foo".
|
---|
| 79 | * <p>
|
---|
| 80 | * The user can stop getopt() from scanning any further into a command line
|
---|
[10209] | 81 | * by using the special argument "--" by itself. For example:
|
---|
[5279] | 82 | * "-a -- -d" would return an option character of 'a', then return -1
|
---|
| 83 | * The "--" is discarded and "-d" is pointed to by optind as the first
|
---|
| 84 | * non-option argv element.
|
---|
| 85 | * <p>
|
---|
| 86 | * Here is a basic example of using Getopt:
|
---|
| 87 | * <p>
|
---|
| 88 | * <pre>
|
---|
| 89 | * Getopt g = new Getopt("testprog", argv, "ab:c::d");
|
---|
| 90 | * //
|
---|
| 91 | * int c;
|
---|
| 92 | * String arg;
|
---|
| 93 | * while ((c = g.getopt()) != -1)
|
---|
| 94 | * {
|
---|
| 95 | * switch(c)
|
---|
| 96 | * {
|
---|
| 97 | * case 'a':
|
---|
| 98 | * case 'd':
|
---|
| 99 | * System.out.print("You picked " + (char)c + "\n");
|
---|
| 100 | * break;
|
---|
| 101 | * //
|
---|
| 102 | * case 'b':
|
---|
| 103 | * case 'c':
|
---|
| 104 | * arg = g.getOptarg();
|
---|
[10209] | 105 | * System.out.print("You picked " + (char)c +
|
---|
[5279] | 106 | * " with an argument of " +
|
---|
| 107 | * ((arg != null) ? arg : "null") + "\n");
|
---|
| 108 | * break;
|
---|
| 109 | * //
|
---|
| 110 | * case '?':
|
---|
| 111 | * break; // getopt() already printed an error
|
---|
| 112 | * //
|
---|
| 113 | * default:
|
---|
| 114 | * System.out.print("getopt() returned " + c + "\n");
|
---|
| 115 | * }
|
---|
| 116 | * }
|
---|
| 117 | * </pre>
|
---|
| 118 | * <p>
|
---|
| 119 | * In this example, a new Getopt object is created with three params.
|
---|
| 120 | * The first param is the program name. This is for printing error
|
---|
| 121 | * messages in the form "program: error message". In the C version, this
|
---|
| 122 | * value is taken from argv[0], but in Java the program name is not passed
|
---|
| 123 | * in that element, thus the need for this parameter. The second param is
|
---|
| 124 | * the argument list that was passed to the main() method. The third
|
---|
| 125 | * param is the list of valid options. Each character represents a valid
|
---|
| 126 | * option. If the character is followed by a single colon, then that
|
---|
| 127 | * option has a required argument. If the character is followed by two
|
---|
| 128 | * colons, then that option has an argument that is not required.
|
---|
| 129 | * <p>
|
---|
| 130 | * Note in this example that the value returned from getopt() is cast to
|
---|
| 131 | * a char prior to printing. This is required in order to make the value
|
---|
| 132 | * display correctly as a character instead of an integer.
|
---|
| 133 | * <p>
|
---|
| 134 | * If the first character in the option string is a colon, for example
|
---|
| 135 | * ":abc::d", then getopt() will return a ':' instead of a '?' when it
|
---|
| 136 | * encounters an option with a missing required argument. This allows the
|
---|
| 137 | * caller to distinguish between invalid options and valid options that
|
---|
| 138 | * are simply incomplete.
|
---|
| 139 | * <p>
|
---|
| 140 | * In the traditional Unix getopt(), -1 is returned when the first non-option
|
---|
| 141 | * charcter is encountered. In GNU getopt(), the default behavior is to
|
---|
| 142 | * allow options to appear anywhere on the command line. The getopt()
|
---|
| 143 | * method permutes the argument to make it appear to the caller that all
|
---|
| 144 | * options were at the beginning of the command line, and all non-options
|
---|
| 145 | * were at the end. For example, calling getopt() with command line args
|
---|
[10209] | 146 | * of "-a foo bar -d" returns options 'a' and 'd', then sets optind to
|
---|
[5279] | 147 | * point to "foo". The program would read the last two argv elements as
|
---|
[10209] | 148 | * "foo" and "bar", just as if the user had typed "-a -d foo bar".
|
---|
| 149 | * <p>
|
---|
[5279] | 150 | * The user can force getopt() to stop scanning the command line with
|
---|
| 151 | * the special argument "--" by itself. Any elements occuring before the
|
---|
| 152 | * "--" are scanned and permuted as normal. Any elements after the "--"
|
---|
[10209] | 153 | * are returned as is as non-option argv elements. For example,
|
---|
| 154 | * "foo -a -- bar -d" would return option 'a' then -1. optind would point
|
---|
[5279] | 155 | * to "foo", "bar" and "-d" as the non-option argv elements. The "--"
|
---|
| 156 | * is discarded by getopt().
|
---|
| 157 | * <p>
|
---|
| 158 | * There are two ways this default behavior can be modified. The first is
|
---|
| 159 | * to specify traditional Unix getopt() behavior (which is also POSIX
|
---|
| 160 | * behavior) in which scanning stops when the first non-option argument
|
---|
| 161 | * encountered. (Thus "-a foo bar -d" would return 'a' as an option and
|
---|
| 162 | * have "foo", "bar", and "-d" as non-option elements). The second is to
|
---|
| 163 | * allow options anywhere, but to return all elements in the order they
|
---|
| 164 | * occur on the command line. When a non-option element is ecountered,
|
---|
| 165 | * an integer 1 is returned and the value of the non-option element is
|
---|
| 166 | * stored in optarg is if it were the argument to that option. For
|
---|
| 167 | * example, "-a foo -d", returns first 'a', then 1 (with optarg set to
|
---|
| 168 | * "foo") then 'd' then -1. When this "return in order" functionality
|
---|
| 169 | * is enabled, the only way to stop getopt() from scanning all command
|
---|
| 170 | * line elements is to use the special "--" string by itself as described
|
---|
| 171 | * above. An example is "-a foo -b -- bar", which would return 'a', then
|
---|
| 172 | * integer 1 with optarg set to "foo", then 'b', then -1. optind would
|
---|
| 173 | * then point to "bar" as the first non-option argv element. The "--"
|
---|
| 174 | * is discarded.
|
---|
| 175 | * <p>
|
---|
[10209] | 176 | * The POSIX/traditional behavior is enabled by either setting the
|
---|
[5279] | 177 | * property "gnu.posixly_correct" or by putting a '+' sign as the first
|
---|
[10209] | 178 | * character of the option string. The difference between the two
|
---|
[5279] | 179 | * methods is that setting the gnu.posixly_correct property also forces
|
---|
| 180 | * certain error messages to be displayed in POSIX format. To enable
|
---|
| 181 | * the "return in order" functionality, put a '-' as the first character
|
---|
[10209] | 182 | * of the option string. Note that after determining the proper
|
---|
[5279] | 183 | * behavior, Getopt strips this leading '+' or '-', meaning that a ':'
|
---|
| 184 | * placed as the second character after one of those two will still cause
|
---|
| 185 | * getopt() to return a ':' instead of a '?' if a required option
|
---|
| 186 | * argument is missing.
|
---|
| 187 | * <p>
|
---|
| 188 | * In addition to traditional single character options, GNU Getopt also
|
---|
| 189 | * supports long options. These are preceeded by a "--" sequence and
|
---|
| 190 | * can be as long as desired. Long options provide a more user-friendly
|
---|
| 191 | * way of entering command line options. For example, in addition to a
|
---|
[10209] | 192 | * "-h" for help, a program could support also "--help".
|
---|
[5279] | 193 | * <p>
|
---|
[10209] | 194 | * Like short options, long options can also take a required or non-required
|
---|
[5279] | 195 | * argument. Required arguments can either be specified by placing an
|
---|
| 196 | * equals sign after the option name, then the argument, or by putting the
|
---|
| 197 | * argument in the next argv element. For example: "--outputdir=foo" and
|
---|
| 198 | * "--outputdir foo" both represent an option of "outputdir" with an
|
---|
| 199 | * argument of "foo", assuming that outputdir takes a required argument.
|
---|
| 200 | * If a long option takes a non-required argument, then the equals sign
|
---|
| 201 | * form must be used to specify the argument. In this case,
|
---|
| 202 | * "--outputdir=foo" would represent option outputdir with an argument of
|
---|
| 203 | * "foo" while "--outputdir foo" would represent the option outputdir
|
---|
| 204 | * with no argument and a first non-option argv element of "foo".
|
---|
| 205 | * <p>
|
---|
[10209] | 206 | * Long options can also be specified using a special POSIX argument
|
---|
| 207 | * format (one that I highly discourage). This form of entry is
|
---|
[5279] | 208 | * enabled by placing a "W;" (yes, 'W' then a semi-colon) in the valid
|
---|
| 209 | * option string. This causes getopt to treat the name following the
|
---|
| 210 | * "-W" as the name of the long option. For example, "-W outputdir=foo"
|
---|
| 211 | * would be equivalent to "--outputdir=foo". The name can immediately
|
---|
| 212 | * follow the "-W" like so: "-Woutputdir=foo". Option arguments are
|
---|
[10209] | 213 | * handled identically to normal long options. If a string follows the
|
---|
[5279] | 214 | * "-W" that does not represent a valid long option, then getopt() returns
|
---|
| 215 | * 'W' and the caller must decide what to do. Otherwise getopt() returns
|
---|
| 216 | * a long option value as described below.
|
---|
| 217 | * <p>
|
---|
| 218 | * While long options offer convenience, they can also be tedious to type
|
---|
| 219 | * in full. So it is permissible to abbreviate the option name to as
|
---|
| 220 | * few characters as required to uniquely identify it. If the name can
|
---|
| 221 | * represent multiple long options, then an error message is printed and
|
---|
[10209] | 222 | * getopt() returns a '?'.
|
---|
[5279] | 223 | * <p>
|
---|
[10209] | 224 | * If an invalid option is specified or a required option argument is
|
---|
[5279] | 225 | * missing, getopt() prints an error and returns a '?' or ':' exactly
|
---|
| 226 | * as for short options. Note that when an invalid long option is
|
---|
| 227 | * encountered, the optopt variable is set to integer 0 and so cannot
|
---|
| 228 | * be used to identify the incorrect option the user entered.
|
---|
| 229 | * <p>
|
---|
| 230 | * Long options are defined by LongOpt objects. These objects are created
|
---|
| 231 | * with a contructor that takes four params: a String representing the
|
---|
| 232 | * object name, a integer specifying what arguments the option takes
|
---|
| 233 | * (the value is one of LongOpt.NO_ARGUMENT, LongOpt.REQUIRED_ARGUMENT,
|
---|
| 234 | * or LongOpt.OPTIONAL_ARGUMENT), a StringBuffer flag object (described
|
---|
| 235 | * below), and an integer value (described below).
|
---|
| 236 | * <p>
|
---|
| 237 | * To enable long option parsing, create an array of LongOpt's representing
|
---|
| 238 | * the legal options and pass it to the Getopt() constructor. WARNING: If
|
---|
| 239 | * all elements of the array are not populated with LongOpt objects, the
|
---|
| 240 | * getopt() method will throw a NullPointerException.
|
---|
| 241 | * <p>
|
---|
| 242 | * When getopt() is called and a long option is encountered, one of two
|
---|
[10209] | 243 | * things can be returned. If the flag field in the LongOpt object
|
---|
[5279] | 244 | * representing the long option is non-null, then the integer value field
|
---|
| 245 | * is stored there and an integer 0 is returned to the caller. The val
|
---|
| 246 | * field can then be retrieved from the flag field. Note that since the
|
---|
| 247 | * flag field is a StringBuffer, the appropriate String to integer converions
|
---|
| 248 | * must be performed in order to get the actual int value stored there.
|
---|
| 249 | * If the flag field in the LongOpt object is null, then the value field
|
---|
| 250 | * of the LongOpt is returned. This can be the character of a short option.
|
---|
[10209] | 251 | * This allows an app to have both a long and short option sequence
|
---|
[5279] | 252 | * (say, "-h" and "--help") that do the exact same thing.
|
---|
| 253 | * <p>
|
---|
[10209] | 254 | * With long options, there is an alternative method of determining
|
---|
[5279] | 255 | * which option was selected. The method getLongind() will return the
|
---|
| 256 | * the index in the long option array (NOT argv) of the long option found.
|
---|
| 257 | * So if multiple long options are configured to return the same value,
|
---|
[10209] | 258 | * the application can use getLongind() to distinguish between them.
|
---|
[5279] | 259 | * <p>
|
---|
| 260 | * Here is an expanded Getopt example using long options and various
|
---|
| 261 | * techniques described above:
|
---|
| 262 | * <p>
|
---|
| 263 | * <pre>
|
---|
| 264 | * int c;
|
---|
| 265 | * String arg;
|
---|
| 266 | * LongOpt[] longopts = new LongOpt[3];
|
---|
[10209] | 267 | * //
|
---|
[5279] | 268 | * StringBuffer sb = new StringBuffer();
|
---|
| 269 | * longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h');
|
---|
[10209] | 270 | * longopts[1] = new LongOpt("outputdir", LongOpt.REQUIRED_ARGUMENT, sb, 'o');
|
---|
[5279] | 271 | * longopts[2] = new LongOpt("maximum", LongOpt.OPTIONAL_ARGUMENT, null, 2);
|
---|
[10209] | 272 | * //
|
---|
[5279] | 273 | * Getopt g = new Getopt("testprog", argv, "-:bc::d:hW;", longopts);
|
---|
| 274 | * g.setOpterr(false); // We'll do our own error handling
|
---|
| 275 | * //
|
---|
| 276 | * while ((c = g.getopt()) != -1)
|
---|
| 277 | * switch (c)
|
---|
| 278 | * {
|
---|
| 279 | * case 0:
|
---|
| 280 | * arg = g.getOptarg();
|
---|
| 281 | * System.out.println("Got long option with value '" +
|
---|
| 282 | * (char)(new Integer(sb.toString())).intValue()
|
---|
| 283 | * + "' with argument " +
|
---|
| 284 | * ((arg != null) ? arg : "null"));
|
---|
| 285 | * break;
|
---|
| 286 | * //
|
---|
| 287 | * case 1:
|
---|
| 288 | * System.out.println("I see you have return in order set and that " +
|
---|
| 289 | * "a non-option argv element was just found " +
|
---|
| 290 | * "with the value '" + g.getOptarg() + "'");
|
---|
| 291 | * break;
|
---|
| 292 | * //
|
---|
| 293 | * case 2:
|
---|
| 294 | * arg = g.getOptarg();
|
---|
| 295 | * System.out.println("I know this, but pretend I didn't");
|
---|
| 296 | * System.out.println("We picked option " +
|
---|
| 297 | * longopts[g.getLongind()].getName() +
|
---|
[10209] | 298 | * " with value " +
|
---|
[5279] | 299 | * ((arg != null) ? arg : "null"));
|
---|
| 300 | * break;
|
---|
| 301 | * //
|
---|
| 302 | * case 'b':
|
---|
| 303 | * System.out.println("You picked plain old option " + (char)c);
|
---|
| 304 | * break;
|
---|
| 305 | * //
|
---|
| 306 | * case 'c':
|
---|
| 307 | * case 'd':
|
---|
| 308 | * arg = g.getOptarg();
|
---|
[10209] | 309 | * System.out.println("You picked option '" + (char)c +
|
---|
[5279] | 310 | * "' with argument " +
|
---|
| 311 | * ((arg != null) ? arg : "null"));
|
---|
| 312 | * break;
|
---|
| 313 | * //
|
---|
| 314 | * case 'h':
|
---|
| 315 | * System.out.println("I see you asked for help");
|
---|
| 316 | * break;
|
---|
| 317 | * //
|
---|
| 318 | * case 'W':
|
---|
| 319 | * System.out.println("Hmmm. You tried a -W with an incorrect long " +
|
---|
| 320 | * "option name");
|
---|
| 321 | * break;
|
---|
| 322 | * //
|
---|
| 323 | * case ':':
|
---|
| 324 | * System.out.println("Doh! You need an argument for option " +
|
---|
| 325 | * (char)g.getOptopt());
|
---|
| 326 | * break;
|
---|
| 327 | * //
|
---|
| 328 | * case '?':
|
---|
[10209] | 329 | * System.out.println("The option '" + (char)g.getOptopt() +
|
---|
[5279] | 330 | * "' is not valid");
|
---|
| 331 | * break;
|
---|
| 332 | * //
|
---|
| 333 | * default:
|
---|
| 334 | * System.out.println("getopt() returned " + c);
|
---|
| 335 | * break;
|
---|
| 336 | * }
|
---|
| 337 | * //
|
---|
| 338 | * for (int i = g.getOptind(); i < argv.length ; i++)
|
---|
| 339 | * System.out.println("Non option argv element: " + argv[i] + "\n");
|
---|
| 340 | * </pre>
|
---|
| 341 | * <p>
|
---|
| 342 | * There is an alternative form of the constructor used for long options
|
---|
| 343 | * above. This takes a trailing boolean flag. If set to false, Getopt
|
---|
| 344 | * performs identically to the example, but if the boolean flag is true
|
---|
| 345 | * then long options are allowed to start with a single '-' instead of
|
---|
| 346 | * "--". If the first character of the option is a valid short option
|
---|
| 347 | * character, then the option is treated as if it were the short option.
|
---|
| 348 | * Otherwise it behaves as if the option is a long option. Note that
|
---|
| 349 | * the name given to this option - long_only - is very counter-intuitive.
|
---|
| 350 | * It does not cause only long options to be parsed but instead enables
|
---|
| 351 | * the behavior described above.
|
---|
[10209] | 352 | * <p>
|
---|
| 353 | * Note that the functionality and variable names used are driven from
|
---|
| 354 | * the C lib version as this object is a port of the C code, not a
|
---|
[5279] | 355 | * new implementation. This should aid in porting existing C/C++ code,
|
---|
| 356 | * as well as helping programmers familiar with the glibc version to
|
---|
| 357 | * adapt to the Java version even if it seems very non-Java at times.
|
---|
| 358 | * <p>
|
---|
| 359 | * In this release I made all instance variables protected due to
|
---|
| 360 | * overwhelming public demand. Any code which relied on optarg,
|
---|
| 361 | * opterr, optind, or optopt being public will need to be modified to
|
---|
| 362 | * use the appropriate access methods.
|
---|
| 363 | * <p>
|
---|
| 364 | * Please send all bug reports, requests, and comments to
|
---|
| 365 | * <a href="mailto:arenn@urbanophile.com">arenn@urbanophile.com</a>.
|
---|
| 366 | *
|
---|
| 367 | * @version 1.0.7
|
---|
| 368 | *
|
---|
| 369 | * @author Roland McGrath (roland@gnu.ai.mit.edu)
|
---|
| 370 | * @author Ulrich Drepper (drepper@cygnus.com)
|
---|
| 371 | * @author Aaron M. Renn (arenn@urbanophile.com)
|
---|
| 372 | *
|
---|
| 373 | * @see LongOpt
|
---|
| 374 | */
|
---|
| 375 | public class Getopt extends Object
|
---|
| 376 | {
|
---|
| 377 |
|
---|
| 378 | /**************************************************************************/
|
---|
| 379 |
|
---|
| 380 | /*
|
---|
| 381 | * Class Variables
|
---|
| 382 | */
|
---|
| 383 |
|
---|
[10209] | 384 | /**
|
---|
[5279] | 385 | * Describe how to deal with options that follow non-option ARGV-elements.
|
---|
| 386 | *
|
---|
| 387 | * If the caller did not specify anything,
|
---|
[10209] | 388 | * the default is REQUIRE_ORDER if the property
|
---|
[5279] | 389 | * gnu.posixly_correct is defined, PERMUTE otherwise.
|
---|
| 390 | *
|
---|
| 391 | * The special argument `--' forces an end of option-scanning regardless
|
---|
| 392 | * of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
---|
| 393 | * `--' can cause `getopt' to return -1 with `optind' != ARGC.
|
---|
| 394 | *
|
---|
| 395 | * REQUIRE_ORDER means don't recognize them as options;
|
---|
| 396 | * stop option processing when the first non-option is seen.
|
---|
| 397 | * This is what Unix does.
|
---|
| 398 | * This mode of operation is selected by either setting the property
|
---|
| 399 | * gnu.posixly_correct, or using `+' as the first character
|
---|
| 400 | * of the list of option characters.
|
---|
| 401 | */
|
---|
| 402 | protected static final int REQUIRE_ORDER = 1;
|
---|
| 403 |
|
---|
| 404 | /**
|
---|
| 405 | * PERMUTE is the default. We permute the contents of ARGV as we scan,
|
---|
| 406 | * so that eventually all the non-options are at the end. This allows options
|
---|
| 407 | * to be given in any order, even with programs that were not written to
|
---|
| 408 | * expect this.
|
---|
| 409 | */
|
---|
| 410 | protected static final int PERMUTE = 2;
|
---|
| 411 |
|
---|
| 412 | /**
|
---|
| 413 | * RETURN_IN_ORDER is an option available to programs that were written
|
---|
| 414 | * to expect options and other ARGV-elements in any order and that care about
|
---|
| 415 | * the ordering of the two. We describe each non-option ARGV-element
|
---|
| 416 | * as if it were the argument of an option with character code 1.
|
---|
| 417 | * Using `-' as the first character of the list of option characters
|
---|
| 418 | * selects this mode of operation.
|
---|
| 419 | */
|
---|
| 420 | protected static final int RETURN_IN_ORDER = 3;
|
---|
| 421 |
|
---|
| 422 | /**************************************************************************/
|
---|
| 423 |
|
---|
| 424 | /*
|
---|
| 425 | * Instance Variables
|
---|
| 426 | */
|
---|
[10209] | 427 |
|
---|
[5279] | 428 | /**
|
---|
| 429 | * For communication from `getopt' to the caller.
|
---|
| 430 | * When `getopt' finds an option that takes an argument,
|
---|
| 431 | * the argument value is returned here.
|
---|
| 432 | * Also, when `ordering' is RETURN_IN_ORDER,
|
---|
| 433 | * each non-option ARGV-element is returned here.
|
---|
| 434 | */
|
---|
| 435 | protected String optarg;
|
---|
| 436 |
|
---|
| 437 | /**
|
---|
| 438 | * Index in ARGV of the next element to be scanned.
|
---|
| 439 | * This is used for communication to and from the caller
|
---|
| 440 | * and for communication between successive calls to `getopt'.
|
---|
| 441 | *
|
---|
| 442 | * On entry to `getopt', zero means this is the first call; initialize.
|
---|
| 443 | *
|
---|
| 444 | * When `getopt' returns -1, this is the index of the first of the
|
---|
| 445 | * non-option elements that the caller should itself scan.
|
---|
| 446 | *
|
---|
| 447 | * Otherwise, `optind' communicates from one call to the next
|
---|
[10209] | 448 | * how much of ARGV has been scanned so far.
|
---|
[5279] | 449 | */
|
---|
| 450 | protected int optind = 0;
|
---|
| 451 |
|
---|
[10209] | 452 | /**
|
---|
[5279] | 453 | * Callers store false here to inhibit the error message
|
---|
[10209] | 454 | * for unrecognized options.
|
---|
[5279] | 455 | */
|
---|
| 456 | protected boolean opterr = true;
|
---|
| 457 |
|
---|
[10209] | 458 | /**
|
---|
[5279] | 459 | * When an unrecognized option is encountered, getopt will return a '?'
|
---|
| 460 | * and store the value of the invalid option here.
|
---|
| 461 | */
|
---|
| 462 | protected int optopt = '?';
|
---|
| 463 |
|
---|
[10209] | 464 | /**
|
---|
[5279] | 465 | * The next char to be scanned in the option-element
|
---|
| 466 | * in which the last option character we returned was found.
|
---|
| 467 | * This allows us to pick up the scan where we left off.
|
---|
| 468 | *
|
---|
| 469 | * If this is zero, or a null string, it means resume the scan
|
---|
[10209] | 470 | * by advancing to the next ARGV-element.
|
---|
[5279] | 471 | */
|
---|
| 472 | protected String nextchar;
|
---|
| 473 |
|
---|
| 474 | /**
|
---|
| 475 | * This is the string describing the valid short options.
|
---|
| 476 | */
|
---|
| 477 | protected String optstring;
|
---|
| 478 |
|
---|
| 479 | /**
|
---|
[10209] | 480 | * This is an array of LongOpt objects which describ the valid long
|
---|
[5279] | 481 | * options.
|
---|
| 482 | */
|
---|
| 483 | protected LongOpt[] long_options;
|
---|
| 484 |
|
---|
| 485 | /**
|
---|
| 486 | * This flag determines whether or not we are parsing only long args
|
---|
| 487 | */
|
---|
| 488 | protected boolean long_only;
|
---|
| 489 |
|
---|
| 490 | /**
|
---|
| 491 | * Stores the index into the long_options array of the long option found
|
---|
| 492 | */
|
---|
| 493 | protected int longind;
|
---|
| 494 |
|
---|
| 495 | /**
|
---|
| 496 | * The flag determines whether or not we operate in strict POSIX compliance
|
---|
| 497 | */
|
---|
| 498 | protected boolean posixly_correct;
|
---|
| 499 |
|
---|
| 500 | /**
|
---|
| 501 | * A flag which communicates whether or not checkLongOption() did all
|
---|
| 502 | * necessary processing for the current option
|
---|
| 503 | */
|
---|
| 504 | protected boolean longopt_handled;
|
---|
| 505 |
|
---|
| 506 | /**
|
---|
| 507 | * The index of the first non-option in argv[]
|
---|
| 508 | */
|
---|
| 509 | protected int first_nonopt = 1;
|
---|
| 510 |
|
---|
| 511 | /**
|
---|
| 512 | * The index of the last non-option in argv[]
|
---|
| 513 | */
|
---|
| 514 | protected int last_nonopt = 1;
|
---|
| 515 |
|
---|
| 516 | /**
|
---|
| 517 | * Flag to tell getopt to immediately return -1 the next time it is
|
---|
| 518 | * called.
|
---|
| 519 | */
|
---|
| 520 | private boolean endparse = false;
|
---|
| 521 |
|
---|
| 522 | /**
|
---|
| 523 | * Saved argument list passed to the program
|
---|
| 524 | */
|
---|
| 525 | protected String[] argv;
|
---|
| 526 |
|
---|
| 527 | /**
|
---|
| 528 | * Determines whether we permute arguments or not
|
---|
| 529 | */
|
---|
| 530 | protected int ordering;
|
---|
| 531 |
|
---|
| 532 | /**
|
---|
| 533 | * Name to print as the program name in error messages. This is necessary
|
---|
| 534 | * since Java does not place the program name in argv[0]
|
---|
| 535 | */
|
---|
| 536 | protected String progname;
|
---|
| 537 |
|
---|
| 538 | /**
|
---|
| 539 | * The localized strings are kept in a separate file
|
---|
| 540 | */
|
---|
| 541 | private OptI18n _messages = new OptI18n(); // ResourceBundle.getBundle("gnu/getopt/MessagesBundle", Locale.getDefault());
|
---|
| 542 |
|
---|
| 543 | /**************************************************************************/
|
---|
| 544 |
|
---|
| 545 | /*
|
---|
| 546 | * Constructors
|
---|
| 547 | */
|
---|
| 548 |
|
---|
| 549 | /**
|
---|
| 550 | * Construct a basic Getopt instance with the given input data. Note that
|
---|
| 551 | * this handles "short" options only.
|
---|
| 552 | *
|
---|
| 553 | * @param progname The name to display as the program name when printing errors
|
---|
| 554 | * @param argv The String array passed as the command line to the program.
|
---|
| 555 | * @param optstring A String containing a description of the valid args for this program
|
---|
| 556 | */
|
---|
| 557 | public
|
---|
| 558 | Getopt(String progname, String[] argv, String optstring)
|
---|
| 559 | {
|
---|
| 560 | this(progname, argv, optstring, null, false);
|
---|
| 561 | }
|
---|
| 562 |
|
---|
| 563 | /**************************************************************************/
|
---|
| 564 |
|
---|
| 565 | /**
|
---|
| 566 | * Construct a Getopt instance with given input data that is capable of
|
---|
| 567 | * parsing long options as well as short.
|
---|
| 568 | *
|
---|
| 569 | * @param progname The name to display as the program name when printing errors
|
---|
| 570 | * @param argv The String array passed as the command ilne to the program
|
---|
| 571 | * @param optstring A String containing a description of the valid short args for this program
|
---|
| 572 | * @param long_options An array of LongOpt objects that describes the valid long args for this program
|
---|
| 573 | */
|
---|
| 574 | public
|
---|
[10209] | 575 | Getopt(String progname, String[] argv, String optstring,
|
---|
[5279] | 576 | LongOpt[] long_options)
|
---|
| 577 | {
|
---|
| 578 | this(progname, argv, optstring, long_options, false);
|
---|
| 579 | }
|
---|
| 580 |
|
---|
| 581 | /**************************************************************************/
|
---|
| 582 |
|
---|
[12892] | 583 | private static Function<String, String> tr = Function.identity();
|
---|
| 584 |
|
---|
| 585 | /**
|
---|
| 586 | * Set the global translation handler for Getopt.
|
---|
| 587 | *
|
---|
| 588 | * This needs to be done before any call to {@link Getopt} or {@link LongOpt}
|
---|
| 589 | * constructor.
|
---|
| 590 | * @param tr function that takes messages in English and returns the localized message
|
---|
| 591 | */
|
---|
| 592 | public static void setI18nHandler(Function<String, String> tr) {
|
---|
| 593 | Getopt.tr = tr;
|
---|
| 594 | }
|
---|
| 595 |
|
---|
[5279] | 596 | static class OptI18n {
|
---|
[12892] | 597 |
|
---|
| 598 | private final Map<String, String> trns = new HashMap<>();
|
---|
| 599 |
|
---|
[5279] | 600 | public OptI18n() {
|
---|
| 601 | add("getopt.ambigious", tr("{0}: option ''{1}'' is ambiguous"));
|
---|
[5337] | 602 | add("getopt.arguments1", tr("{0}: option ''--{1}'' does not allow an argument"));
|
---|
| 603 | add("getopt.arguments2", tr("{0}: option ''{1}{2}'' does not allow an argument"));
|
---|
[5279] | 604 | add("getopt.requires", tr("{0}: option ''{1}'' requires an argument"));
|
---|
| 605 | add("getopt.unrecognized", tr("{0}: unrecognized option ''--{1}''"));
|
---|
| 606 | add("getopt.unrecognized2", tr("{0}: unrecognized option ''{1}{2}''"));
|
---|
| 607 | add("getopt.illegal", tr("{0}: illegal option -- {1}"));
|
---|
| 608 | add("getopt.invalid", tr("{0}: invalid option -- {1}"));
|
---|
| 609 | add("getopt.requires2", tr("{0}: option requires an argument -- {1}"));
|
---|
| 610 | add("getopt.invalidValue", tr("Invalid value {0} for parameter ''has_arg''"));
|
---|
| 611 | }
|
---|
| 612 |
|
---|
[12892] | 613 | private String tr(String s) {
|
---|
| 614 | return Getopt.tr.apply(s);
|
---|
| 615 | }
|
---|
[5279] | 616 |
|
---|
| 617 | private void add(String key, String value) {
|
---|
| 618 | trns.put(key, value);
|
---|
| 619 | }
|
---|
| 620 |
|
---|
| 621 | public String getString(String s) {
|
---|
| 622 | String val = trns.get(s);
|
---|
| 623 | if (val == null) throw new IllegalArgumentException();
|
---|
| 624 | return val.replace("'", "''");
|
---|
| 625 | }
|
---|
| 626 | }
|
---|
| 627 |
|
---|
| 628 | /**
|
---|
| 629 | * Construct a Getopt instance with given input data that is capable of
|
---|
| 630 | * parsing long options and short options. Contrary to what you might
|
---|
[10209] | 631 | * think, the flag 'long_only' does not determine whether or not we
|
---|
[5279] | 632 | * scan for only long arguments. Instead, a value of true here allows
|
---|
| 633 | * long arguments to start with a '-' instead of '--' unless there is a
|
---|
| 634 | * conflict with a short option name.
|
---|
| 635 | *
|
---|
| 636 | * @param progname The name to display as the program name when printing errors
|
---|
| 637 | * @param argv The String array passed as the command ilne to the program
|
---|
| 638 | * @param optstring A String containing a description of the valid short args for this program
|
---|
| 639 | * @param long_options An array of LongOpt objects that describes the valid long args for this program
|
---|
| 640 | * @param long_only true if long options that do not conflict with short options can start with a '-' as well as '--'
|
---|
| 641 | */
|
---|
| 642 | public
|
---|
[10209] | 643 | Getopt(String progname, String[] argv, String optstring,
|
---|
[5279] | 644 | LongOpt[] long_options, boolean long_only)
|
---|
| 645 | {
|
---|
| 646 | if (optstring.length() == 0)
|
---|
| 647 | optstring = " ";
|
---|
| 648 |
|
---|
| 649 | // This function is essentially _getopt_initialize from GNU getopt
|
---|
| 650 | this.progname = progname;
|
---|
| 651 | this.argv = argv;
|
---|
| 652 | this.optstring = optstring;
|
---|
| 653 | this.long_options = long_options;
|
---|
| 654 | this.long_only = long_only;
|
---|
| 655 |
|
---|
| 656 | // Check for property "gnu.posixly_correct" to determine whether to
|
---|
| 657 | // strictly follow the POSIX standard. This replaces the "POSIXLY_CORRECT"
|
---|
| 658 | // environment variable in the C version
|
---|
[13647] | 659 | try {
|
---|
[5279] | 660 | if (System.getProperty("gnu.posixly_correct", null) == null)
|
---|
| 661 | posixly_correct = false;
|
---|
| 662 | else
|
---|
| 663 | {
|
---|
| 664 | posixly_correct = true;
|
---|
| 665 | _messages = new OptI18n();//ResourceBundle.getBundle("gnu/getopt/MessagesBundle",
|
---|
| 666 | // Locale.US);
|
---|
| 667 | }
|
---|
[13647] | 668 | } catch (SecurityException e) {
|
---|
| 669 | System.err.println(e.getMessage());
|
---|
| 670 | }
|
---|
[5279] | 671 |
|
---|
| 672 | // Determine how to handle the ordering of options and non-options
|
---|
| 673 | if (optstring.charAt(0) == '-')
|
---|
| 674 | {
|
---|
| 675 | ordering = RETURN_IN_ORDER;
|
---|
| 676 | if (optstring.length() > 1)
|
---|
| 677 | this.optstring = optstring.substring(1);
|
---|
| 678 | }
|
---|
| 679 | else if (optstring.charAt(0) == '+')
|
---|
| 680 | {
|
---|
| 681 | ordering = REQUIRE_ORDER;
|
---|
| 682 | if (optstring.length() > 1)
|
---|
| 683 | this.optstring = optstring.substring(1);
|
---|
| 684 | }
|
---|
| 685 | else if (posixly_correct)
|
---|
| 686 | {
|
---|
| 687 | ordering = REQUIRE_ORDER;
|
---|
| 688 | }
|
---|
| 689 | else
|
---|
| 690 | {
|
---|
| 691 | ordering = PERMUTE; // The normal default case
|
---|
| 692 | }
|
---|
| 693 | }
|
---|
| 694 |
|
---|
| 695 | /**************************************************************************/
|
---|
[10209] | 696 |
|
---|
[5279] | 697 | /*
|
---|
| 698 | * Instance Methods
|
---|
| 699 | */
|
---|
| 700 |
|
---|
| 701 | /**
|
---|
| 702 | * In GNU getopt, it is possible to change the string containg valid options
|
---|
| 703 | * on the fly because it is passed as an argument to getopt() each time. In
|
---|
| 704 | * this version we do not pass the string on every call. In order to allow
|
---|
| 705 | * dynamic option string changing, this method is provided.
|
---|
| 706 | *
|
---|
| 707 | * @param optstring The new option string to use
|
---|
| 708 | */
|
---|
| 709 | public void
|
---|
| 710 | setOptstring(String optstring)
|
---|
| 711 | {
|
---|
| 712 | if (optstring.length() == 0)
|
---|
| 713 | optstring = " ";
|
---|
| 714 |
|
---|
| 715 | this.optstring = optstring;
|
---|
| 716 | }
|
---|
| 717 |
|
---|
| 718 | /**************************************************************************/
|
---|
| 719 |
|
---|
| 720 | /**
|
---|
| 721 | * optind it the index in ARGV of the next element to be scanned.
|
---|
| 722 | * This is used for communication to and from the caller
|
---|
| 723 | * and for communication between successive calls to `getopt'.
|
---|
| 724 | *
|
---|
| 725 | * When `getopt' returns -1, this is the index of the first of the
|
---|
| 726 | * non-option elements that the caller should itself scan.
|
---|
| 727 | *
|
---|
| 728 | * Otherwise, `optind' communicates from one call to the next
|
---|
[10209] | 729 | * how much of ARGV has been scanned so far.
|
---|
[5279] | 730 | */
|
---|
| 731 | public int
|
---|
| 732 | getOptind()
|
---|
| 733 | {
|
---|
| 734 | return(optind);
|
---|
| 735 | }
|
---|
| 736 |
|
---|
| 737 | /**************************************************************************/
|
---|
| 738 |
|
---|
| 739 | /**
|
---|
| 740 | * This method allows the optind index to be set manually. Normally this
|
---|
| 741 | * is not necessary (and incorrect usage of this method can lead to serious
|
---|
[10209] | 742 | * lossage), but optind is a public symbol in GNU getopt, so this method
|
---|
[5279] | 743 | * was added to allow it to be modified by the caller if desired.
|
---|
| 744 | *
|
---|
| 745 | * @param optind The new value of optind
|
---|
| 746 | */
|
---|
| 747 | public void
|
---|
| 748 | setOptind(int optind)
|
---|
| 749 | {
|
---|
| 750 | this.optind = optind;
|
---|
| 751 | }
|
---|
| 752 |
|
---|
| 753 | /**************************************************************************/
|
---|
| 754 |
|
---|
| 755 | /**
|
---|
| 756 | * Since in GNU getopt() the argument vector is passed back in to the
|
---|
| 757 | * function every time, the caller can swap out argv on the fly. Since
|
---|
| 758 | * passing argv is not required in the Java version, this method allows
|
---|
| 759 | * the user to override argv. Note that incorrect use of this method can
|
---|
| 760 | * lead to serious lossage.
|
---|
| 761 | *
|
---|
| 762 | * @param argv New argument list
|
---|
| 763 | */
|
---|
| 764 | public void
|
---|
| 765 | setArgv(String[] argv)
|
---|
| 766 | {
|
---|
| 767 | this.argv = argv;
|
---|
| 768 | }
|
---|
| 769 |
|
---|
| 770 | /**************************************************************************/
|
---|
| 771 |
|
---|
[10209] | 772 | /**
|
---|
[5279] | 773 | * For communication from `getopt' to the caller.
|
---|
| 774 | * When `getopt' finds an option that takes an argument,
|
---|
| 775 | * the argument value is returned here.
|
---|
| 776 | * Also, when `ordering' is RETURN_IN_ORDER,
|
---|
| 777 | * each non-option ARGV-element is returned here.
|
---|
| 778 | * No set method is provided because setting this variable has no effect.
|
---|
| 779 | */
|
---|
| 780 | public String
|
---|
| 781 | getOptarg()
|
---|
| 782 | {
|
---|
| 783 | return(optarg);
|
---|
| 784 | }
|
---|
| 785 |
|
---|
| 786 | /**************************************************************************/
|
---|
| 787 |
|
---|
| 788 | /**
|
---|
| 789 | * Normally Getopt will print a message to the standard error when an
|
---|
| 790 | * invalid option is encountered. This can be suppressed (or re-enabled)
|
---|
[10209] | 791 | * by calling this method. There is no get method for this variable
|
---|
[5279] | 792 | * because if you can't remember the state you set this to, why should I?
|
---|
| 793 | */
|
---|
| 794 | public void
|
---|
| 795 | setOpterr(boolean opterr)
|
---|
| 796 | {
|
---|
| 797 | this.opterr = opterr;
|
---|
| 798 | }
|
---|
| 799 |
|
---|
| 800 | /**************************************************************************/
|
---|
| 801 |
|
---|
| 802 | /**
|
---|
| 803 | * When getopt() encounters an invalid option, it stores the value of that
|
---|
| 804 | * option in optopt which can be retrieved with this method. There is
|
---|
| 805 | * no corresponding set method because setting this variable has no effect.
|
---|
| 806 | */
|
---|
| 807 | public int
|
---|
| 808 | getOptopt()
|
---|
| 809 | {
|
---|
| 810 | return(optopt);
|
---|
| 811 | }
|
---|
| 812 |
|
---|
| 813 | /**************************************************************************/
|
---|
| 814 |
|
---|
| 815 | /**
|
---|
| 816 | * Returns the index into the array of long options (NOT argv) representing
|
---|
| 817 | * the long option that was found.
|
---|
| 818 | */
|
---|
| 819 | public int
|
---|
| 820 | getLongind()
|
---|
| 821 | {
|
---|
| 822 | return(longind);
|
---|
| 823 | }
|
---|
| 824 |
|
---|
| 825 | /**************************************************************************/
|
---|
| 826 |
|
---|
| 827 | /**
|
---|
| 828 | * Exchange the shorter segment with the far end of the longer segment.
|
---|
| 829 | * That puts the shorter segment into the right place.
|
---|
| 830 | * It leaves the longer segment in the right place overall,
|
---|
| 831 | * but it consists of two parts that need to be swapped next.
|
---|
| 832 | * This method is used by getopt() for argument permutation.
|
---|
| 833 | */
|
---|
| 834 | protected void
|
---|
| 835 | exchange(String[] argv)
|
---|
| 836 | {
|
---|
| 837 | int bottom = first_nonopt;
|
---|
| 838 | int middle = last_nonopt;
|
---|
| 839 | int top = optind;
|
---|
| 840 | String tem;
|
---|
| 841 |
|
---|
| 842 | while (top > middle && middle > bottom)
|
---|
| 843 | {
|
---|
| 844 | if (top - middle > middle - bottom)
|
---|
| 845 | {
|
---|
[10209] | 846 | // Bottom segment is the short one.
|
---|
[5279] | 847 | int len = middle - bottom;
|
---|
| 848 | int i;
|
---|
| 849 |
|
---|
[10209] | 850 | // Swap it with the top part of the top segment.
|
---|
[5279] | 851 | for (i = 0; i < len; i++)
|
---|
| 852 | {
|
---|
| 853 | tem = argv[bottom + i];
|
---|
| 854 | argv[bottom + i] = argv[top - (middle - bottom) + i];
|
---|
| 855 | argv[top - (middle - bottom) + i] = tem;
|
---|
| 856 | }
|
---|
[10209] | 857 | // Exclude the moved bottom segment from further swapping.
|
---|
[5279] | 858 | top -= len;
|
---|
| 859 | }
|
---|
| 860 | else
|
---|
| 861 | {
|
---|
| 862 | // Top segment is the short one.
|
---|
| 863 | int len = top - middle;
|
---|
| 864 | int i;
|
---|
| 865 |
|
---|
[10209] | 866 | // Swap it with the bottom part of the bottom segment.
|
---|
[5279] | 867 | for (i = 0; i < len; i++)
|
---|
| 868 | {
|
---|
| 869 | tem = argv[bottom + i];
|
---|
| 870 | argv[bottom + i] = argv[middle + i];
|
---|
| 871 | argv[middle + i] = tem;
|
---|
| 872 | }
|
---|
[10209] | 873 | // Exclude the moved top segment from further swapping.
|
---|
[5279] | 874 | bottom += len;
|
---|
| 875 | }
|
---|
| 876 | }
|
---|
| 877 |
|
---|
[10209] | 878 | // Update records for the slots the non-options now occupy.
|
---|
[5279] | 879 |
|
---|
| 880 | first_nonopt += (optind - last_nonopt);
|
---|
| 881 | last_nonopt = optind;
|
---|
| 882 | }
|
---|
| 883 |
|
---|
| 884 | /**************************************************************************/
|
---|
| 885 |
|
---|
| 886 | /**
|
---|
| 887 | * Check to see if an option is a valid long option. Called by getopt().
|
---|
| 888 | * Put in a separate method because this needs to be done twice. (The
|
---|
| 889 | * C getopt authors just copy-pasted the code!).
|
---|
| 890 | *
|
---|
| 891 | * @param longind A buffer in which to store the 'val' field of found LongOpt
|
---|
| 892 | *
|
---|
| 893 | * @return Various things depending on circumstances
|
---|
| 894 | */
|
---|
| 895 | protected int
|
---|
| 896 | checkLongOption()
|
---|
| 897 | {
|
---|
| 898 | LongOpt pfound = null;
|
---|
| 899 | int nameend;
|
---|
| 900 | boolean ambig;
|
---|
| 901 | boolean exact;
|
---|
[10209] | 902 |
|
---|
[5279] | 903 | longopt_handled = true;
|
---|
| 904 | ambig = false;
|
---|
| 905 | exact = false;
|
---|
| 906 | longind = -1;
|
---|
| 907 |
|
---|
| 908 | nameend = nextchar.indexOf("=");
|
---|
| 909 | if (nameend == -1)
|
---|
| 910 | nameend = nextchar.length();
|
---|
[10209] | 911 |
|
---|
[5279] | 912 | // Test all lnog options for either exact match or abbreviated matches
|
---|
| 913 | for (int i = 0; i < long_options.length; i++)
|
---|
| 914 | {
|
---|
| 915 | if (long_options[i].getName().startsWith(nextchar.substring(0, nameend)))
|
---|
| 916 | {
|
---|
| 917 | if (long_options[i].getName().equals(nextchar.substring(0, nameend)))
|
---|
| 918 | {
|
---|
| 919 | // Exact match found
|
---|
| 920 | pfound = long_options[i];
|
---|
| 921 | longind = i;
|
---|
| 922 | exact = true;
|
---|
| 923 | break;
|
---|
| 924 | }
|
---|
| 925 | else if (pfound == null)
|
---|
| 926 | {
|
---|
| 927 | // First nonexact match found
|
---|
| 928 | pfound = long_options[i];
|
---|
| 929 | longind = i;
|
---|
| 930 | }
|
---|
| 931 | else
|
---|
| 932 | {
|
---|
| 933 | // Second or later nonexact match found
|
---|
| 934 | ambig = true;
|
---|
| 935 | }
|
---|
| 936 | }
|
---|
| 937 | } // for
|
---|
[10209] | 938 |
|
---|
[5279] | 939 | // Print out an error if the option specified was ambiguous
|
---|
| 940 | if (ambig && !exact)
|
---|
| 941 | {
|
---|
| 942 | if (opterr)
|
---|
| 943 | {
|
---|
| 944 | Object[] msgArgs = { progname, argv[optind] };
|
---|
| 945 | System.err.println(MessageFormat.format(
|
---|
[10209] | 946 | _messages.getString("getopt.ambigious"),
|
---|
[5279] | 947 | msgArgs));
|
---|
| 948 | }
|
---|
| 949 |
|
---|
| 950 | nextchar = "";
|
---|
| 951 | optopt = 0;
|
---|
| 952 | ++optind;
|
---|
[10209] | 953 |
|
---|
[5279] | 954 | return('?');
|
---|
| 955 | }
|
---|
[10209] | 956 |
|
---|
[5279] | 957 | if (pfound != null)
|
---|
| 958 | {
|
---|
| 959 | ++optind;
|
---|
[10209] | 960 |
|
---|
[5279] | 961 | if (nameend != nextchar.length())
|
---|
| 962 | {
|
---|
| 963 | if (pfound.has_arg != LongOpt.NO_ARGUMENT)
|
---|
| 964 | {
|
---|
| 965 | if (nextchar.substring(nameend).length() > 1)
|
---|
| 966 | optarg = nextchar.substring(nameend+1);
|
---|
| 967 | else
|
---|
| 968 | optarg = "";
|
---|
| 969 | }
|
---|
| 970 | else
|
---|
| 971 | {
|
---|
| 972 | if (opterr)
|
---|
| 973 | {
|
---|
| 974 | // -- option
|
---|
| 975 | if (argv[optind - 1].startsWith("--"))
|
---|
| 976 | {
|
---|
| 977 | Object[] msgArgs = { progname, pfound.name };
|
---|
| 978 | System.err.println(MessageFormat.format(
|
---|
[10209] | 979 | _messages.getString("getopt.arguments1"),
|
---|
[5279] | 980 | msgArgs));
|
---|
| 981 | }
|
---|
| 982 | // +option or -option
|
---|
| 983 | else
|
---|
| 984 | {
|
---|
[10209] | 985 | Object[] msgArgs = { progname,
|
---|
| 986 | Character.toString(argv[optind-1].charAt(0)),
|
---|
[5279] | 987 | pfound.name };
|
---|
| 988 | System.err.println(MessageFormat.format(
|
---|
[10209] | 989 | _messages.getString("getopt.arguments2"),
|
---|
[5279] | 990 | msgArgs));
|
---|
| 991 | }
|
---|
| 992 | }
|
---|
[10209] | 993 |
|
---|
[5279] | 994 | nextchar = "";
|
---|
| 995 | optopt = pfound.val;
|
---|
[10209] | 996 |
|
---|
[5279] | 997 | return('?');
|
---|
| 998 | }
|
---|
| 999 | } // if (nameend)
|
---|
| 1000 | else if (pfound.has_arg == LongOpt.REQUIRED_ARGUMENT)
|
---|
| 1001 | {
|
---|
| 1002 | if (optind < argv.length)
|
---|
| 1003 | {
|
---|
| 1004 | optarg = argv[optind];
|
---|
| 1005 | ++optind;
|
---|
| 1006 | }
|
---|
| 1007 | else
|
---|
| 1008 | {
|
---|
| 1009 | if (opterr)
|
---|
| 1010 | {
|
---|
| 1011 | Object[] msgArgs = { progname, argv[optind-1] };
|
---|
| 1012 | System.err.println(MessageFormat.format(
|
---|
[10209] | 1013 | _messages.getString("getopt.requires"),
|
---|
[5279] | 1014 | msgArgs));
|
---|
| 1015 | }
|
---|
[10209] | 1016 |
|
---|
[5279] | 1017 | nextchar = "";
|
---|
| 1018 | optopt = pfound.val;
|
---|
| 1019 | if (optstring.charAt(0) == ':')
|
---|
| 1020 | return(':');
|
---|
| 1021 | else
|
---|
| 1022 | return('?');
|
---|
| 1023 | }
|
---|
| 1024 | } // else if (pfound)
|
---|
[10209] | 1025 |
|
---|
[5279] | 1026 | nextchar = "";
|
---|
| 1027 |
|
---|
| 1028 | if (pfound.flag != null)
|
---|
| 1029 | {
|
---|
| 1030 | pfound.flag.setLength(0);
|
---|
| 1031 | pfound.flag.append(pfound.val);
|
---|
[10209] | 1032 |
|
---|
[5279] | 1033 | return(0);
|
---|
| 1034 | }
|
---|
| 1035 |
|
---|
| 1036 | return(pfound.val);
|
---|
| 1037 | } // if (pfound != null)
|
---|
[10209] | 1038 |
|
---|
[5279] | 1039 | longopt_handled = false;
|
---|
| 1040 |
|
---|
| 1041 | return(0);
|
---|
| 1042 | }
|
---|
| 1043 |
|
---|
| 1044 | /**************************************************************************/
|
---|
| 1045 |
|
---|
| 1046 | /**
|
---|
| 1047 | * This method returns a char that is the current option that has been
|
---|
| 1048 | * parsed from the command line. If the option takes an argument, then
|
---|
| 1049 | * the internal variable 'optarg' is set which is a String representing
|
---|
| 1050 | * the the value of the argument. This value can be retrieved by the
|
---|
| 1051 | * caller using the getOptarg() method. If an invalid option is found,
|
---|
| 1052 | * an error message is printed and a '?' is returned. The name of the
|
---|
| 1053 | * invalid option character can be retrieved by calling the getOptopt()
|
---|
| 1054 | * method. When there are no more options to be scanned, this method
|
---|
| 1055 | * returns -1. The index of first non-option element in argv can be
|
---|
| 1056 | * retrieved with the getOptind() method.
|
---|
| 1057 | *
|
---|
| 1058 | * @return Various things as described above
|
---|
| 1059 | */
|
---|
| 1060 | public int
|
---|
| 1061 | getopt()
|
---|
| 1062 | {
|
---|
| 1063 | optarg = null;
|
---|
| 1064 |
|
---|
| 1065 | if (endparse == true)
|
---|
| 1066 | return(-1);
|
---|
| 1067 |
|
---|
| 1068 | if ((nextchar == null) || (nextchar.equals("")))
|
---|
| 1069 | {
|
---|
| 1070 | // If we have just processed some options following some non-options,
|
---|
| 1071 | // exchange them so that the options come first.
|
---|
| 1072 | if (last_nonopt > optind)
|
---|
| 1073 | last_nonopt = optind;
|
---|
| 1074 | if (first_nonopt > optind)
|
---|
| 1075 | first_nonopt = optind;
|
---|
| 1076 |
|
---|
| 1077 | if (ordering == PERMUTE)
|
---|
| 1078 | {
|
---|
| 1079 | // If we have just processed some options following some non-options,
|
---|
| 1080 | // exchange them so that the options come first.
|
---|
| 1081 | if ((first_nonopt != last_nonopt) && (last_nonopt != optind))
|
---|
| 1082 | exchange(argv);
|
---|
| 1083 | else if (last_nonopt != optind)
|
---|
| 1084 | first_nonopt = optind;
|
---|
| 1085 |
|
---|
| 1086 | // Skip any additional non-options
|
---|
| 1087 | // and extend the range of non-options previously skipped.
|
---|
| 1088 | while ((optind < argv.length) && (argv[optind].equals("") ||
|
---|
| 1089 | (argv[optind].charAt(0) != '-') || argv[optind].equals("-")))
|
---|
| 1090 | {
|
---|
| 1091 | optind++;
|
---|
| 1092 | }
|
---|
[10209] | 1093 |
|
---|
[5279] | 1094 | last_nonopt = optind;
|
---|
| 1095 | }
|
---|
| 1096 |
|
---|
| 1097 | // The special ARGV-element `--' means premature end of options.
|
---|
| 1098 | // Skip it like a null option,
|
---|
| 1099 | // then exchange with previous non-options as if it were an option,
|
---|
| 1100 | // then skip everything else like a non-option.
|
---|
| 1101 | if ((optind != argv.length) && argv[optind].equals("--"))
|
---|
| 1102 | {
|
---|
| 1103 | optind++;
|
---|
| 1104 |
|
---|
| 1105 | if ((first_nonopt != last_nonopt) && (last_nonopt != optind))
|
---|
| 1106 | exchange (argv);
|
---|
| 1107 | else if (first_nonopt == last_nonopt)
|
---|
| 1108 | first_nonopt = optind;
|
---|
| 1109 |
|
---|
| 1110 | last_nonopt = argv.length;
|
---|
| 1111 |
|
---|
| 1112 | optind = argv.length;
|
---|
| 1113 | }
|
---|
| 1114 |
|
---|
| 1115 | // If we have done all the ARGV-elements, stop the scan
|
---|
| 1116 | // and back over any non-options that we skipped and permuted.
|
---|
| 1117 | if (optind == argv.length)
|
---|
| 1118 | {
|
---|
| 1119 | // Set the next-arg-index to point at the non-options
|
---|
| 1120 | // that we previously skipped, so the caller will digest them.
|
---|
| 1121 | if (first_nonopt != last_nonopt)
|
---|
| 1122 | optind = first_nonopt;
|
---|
| 1123 |
|
---|
| 1124 | return(-1);
|
---|
| 1125 | }
|
---|
| 1126 |
|
---|
| 1127 | // If we have come to a non-option and did not permute it,
|
---|
| 1128 | // either stop the scan or describe it to the caller and pass it by.
|
---|
[10209] | 1129 | if (argv[optind].equals("") || (argv[optind].charAt(0) != '-') ||
|
---|
[5279] | 1130 | argv[optind].equals("-"))
|
---|
| 1131 | {
|
---|
| 1132 | if (ordering == REQUIRE_ORDER)
|
---|
| 1133 | return(-1);
|
---|
| 1134 |
|
---|
| 1135 | optarg = argv[optind++];
|
---|
| 1136 | return(1);
|
---|
| 1137 | }
|
---|
[10209] | 1138 |
|
---|
[5279] | 1139 | // We have found another option-ARGV-element.
|
---|
| 1140 | // Skip the initial punctuation.
|
---|
| 1141 | if (argv[optind].startsWith("--"))
|
---|
| 1142 | nextchar = argv[optind].substring(2);
|
---|
| 1143 | else
|
---|
| 1144 | nextchar = argv[optind].substring(1);
|
---|
| 1145 | }
|
---|
| 1146 |
|
---|
| 1147 | // Decode the current option-ARGV-element.
|
---|
| 1148 |
|
---|
| 1149 | /* Check whether the ARGV-element is a long option.
|
---|
| 1150 |
|
---|
| 1151 | If long_only and the ARGV-element has the form "-f", where f is
|
---|
| 1152 | a valid short option, don't consider it an abbreviated form of
|
---|
| 1153 | a long option that starts with f. Otherwise there would be no
|
---|
| 1154 | way to give the -f short option.
|
---|
| 1155 |
|
---|
| 1156 | On the other hand, if there's a long option "fubar" and
|
---|
| 1157 | the ARGV-element is "-fu", do consider that an abbreviation of
|
---|
| 1158 | the long option, just like "--fu", and not "-f" with arg "u".
|
---|
| 1159 |
|
---|
| 1160 | This distinction seems to be the most useful approach. */
|
---|
| 1161 | if ((long_options != null) && (argv[optind].startsWith("--")
|
---|
[10209] | 1162 | || (long_only && ((argv[optind].length() > 2) ||
|
---|
[5279] | 1163 | (optstring.indexOf(argv[optind].charAt(1)) == -1)))))
|
---|
| 1164 | {
|
---|
| 1165 | int c = checkLongOption();
|
---|
| 1166 |
|
---|
| 1167 | if (longopt_handled)
|
---|
| 1168 | return(c);
|
---|
[10209] | 1169 |
|
---|
[5279] | 1170 | // Can't find it as a long option. If this is not getopt_long_only,
|
---|
| 1171 | // or the option starts with '--' or is not a valid short
|
---|
| 1172 | // option, then it's an error.
|
---|
| 1173 | // Otherwise interpret it as a short option.
|
---|
| 1174 | if (!long_only || argv[optind].startsWith("--")
|
---|
| 1175 | || (optstring.indexOf(nextchar.charAt(0)) == -1))
|
---|
| 1176 | {
|
---|
| 1177 | if (opterr)
|
---|
| 1178 | {
|
---|
| 1179 | if (argv[optind].startsWith("--"))
|
---|
| 1180 | {
|
---|
| 1181 | Object[] msgArgs = { progname, nextchar };
|
---|
| 1182 | System.err.println(MessageFormat.format(
|
---|
[10209] | 1183 | _messages.getString("getopt.unrecognized"),
|
---|
[5279] | 1184 | msgArgs));
|
---|
| 1185 | }
|
---|
| 1186 | else
|
---|
| 1187 | {
|
---|
[10209] | 1188 | Object[] msgArgs = { progname,
|
---|
| 1189 | Character.toString(argv[optind].charAt(0)),
|
---|
[5279] | 1190 | nextchar };
|
---|
| 1191 | System.err.println(MessageFormat.format(
|
---|
[10209] | 1192 | _messages.getString("getopt.unrecognized2"),
|
---|
[5279] | 1193 | msgArgs));
|
---|
| 1194 | }
|
---|
| 1195 | }
|
---|
| 1196 |
|
---|
| 1197 | nextchar = "";
|
---|
| 1198 | ++optind;
|
---|
| 1199 | optopt = 0;
|
---|
[10209] | 1200 |
|
---|
[5279] | 1201 | return('?');
|
---|
| 1202 | }
|
---|
| 1203 | } // if (longopts)
|
---|
| 1204 |
|
---|
| 1205 | // Look at and handle the next short option-character */
|
---|
| 1206 | int c = nextchar.charAt(0); //**** Do we need to check for empty str?
|
---|
| 1207 | if (nextchar.length() > 1)
|
---|
| 1208 | nextchar = nextchar.substring(1);
|
---|
| 1209 | else
|
---|
| 1210 | nextchar = "";
|
---|
[10209] | 1211 |
|
---|
[5279] | 1212 | String temp = null;
|
---|
| 1213 | if (optstring.indexOf(c) != -1)
|
---|
| 1214 | temp = optstring.substring(optstring.indexOf(c));
|
---|
| 1215 |
|
---|
| 1216 | if (nextchar.equals(""))
|
---|
| 1217 | ++optind;
|
---|
| 1218 |
|
---|
| 1219 | if ((temp == null) || (c == ':'))
|
---|
| 1220 | {
|
---|
| 1221 | if (opterr)
|
---|
| 1222 | {
|
---|
| 1223 | if (posixly_correct)
|
---|
| 1224 | {
|
---|
| 1225 | // 1003.2 specifies the format of this message
|
---|
[10209] | 1226 | Object[] msgArgs = { progname,
|
---|
| 1227 | Character.toString((char)c) };
|
---|
[5279] | 1228 | System.err.println(MessageFormat.format(
|
---|
| 1229 | _messages.getString("getopt.illegal"), msgArgs));
|
---|
| 1230 | }
|
---|
| 1231 | else
|
---|
| 1232 | {
|
---|
[10209] | 1233 | Object[] msgArgs = { progname,
|
---|
| 1234 | Character.toString((char)c) };
|
---|
[5279] | 1235 | System.err.println(MessageFormat.format(
|
---|
| 1236 | _messages.getString("getopt.invalid"), msgArgs));
|
---|
| 1237 | }
|
---|
| 1238 | }
|
---|
| 1239 |
|
---|
| 1240 | optopt = c;
|
---|
| 1241 |
|
---|
| 1242 | return('?');
|
---|
| 1243 | }
|
---|
| 1244 |
|
---|
| 1245 | // Convenience. Treat POSIX -W foo same as long option --foo
|
---|
| 1246 | if ((temp.charAt(0) == 'W') && (temp.length() > 1) && (temp.charAt(1) == ';'))
|
---|
| 1247 | {
|
---|
| 1248 | if (!nextchar.equals(""))
|
---|
| 1249 | {
|
---|
| 1250 | optarg = nextchar;
|
---|
| 1251 | }
|
---|
| 1252 | // No further cars in this argv element and no more argv elements
|
---|
| 1253 | else if (optind == argv.length)
|
---|
| 1254 | {
|
---|
| 1255 | if (opterr)
|
---|
| 1256 | {
|
---|
[10209] | 1257 | // 1003.2 specifies the format of this message.
|
---|
| 1258 | Object[] msgArgs = { progname,
|
---|
| 1259 | Character.toString((char)c) };
|
---|
[5279] | 1260 | System.err.println(MessageFormat.format(
|
---|
| 1261 | _messages.getString("getopt.requires2"), msgArgs));
|
---|
| 1262 | }
|
---|
| 1263 |
|
---|
| 1264 | optopt = c;
|
---|
| 1265 | if (optstring.charAt(0) == ':')
|
---|
| 1266 | return(':');
|
---|
| 1267 | else
|
---|
| 1268 | return('?');
|
---|
| 1269 | }
|
---|
| 1270 | else
|
---|
| 1271 | {
|
---|
| 1272 | // We already incremented `optind' once;
|
---|
[10209] | 1273 | // increment it again when taking next ARGV-elt as argument.
|
---|
[5279] | 1274 | nextchar = argv[optind];
|
---|
| 1275 | optarg = argv[optind];
|
---|
| 1276 | }
|
---|
| 1277 |
|
---|
| 1278 | c = checkLongOption();
|
---|
| 1279 |
|
---|
| 1280 | if (longopt_handled)
|
---|
| 1281 | return(c);
|
---|
| 1282 | else
|
---|
| 1283 | // Let the application handle it
|
---|
| 1284 | {
|
---|
| 1285 | nextchar = null;
|
---|
| 1286 | ++optind;
|
---|
| 1287 | return('W');
|
---|
| 1288 | }
|
---|
| 1289 | }
|
---|
| 1290 |
|
---|
| 1291 | if ((temp.length() > 1) && (temp.charAt(1) == ':'))
|
---|
| 1292 | {
|
---|
| 1293 | if ((temp.length() > 2) && (temp.charAt(2) == ':'))
|
---|
| 1294 | // This is an option that accepts and argument optionally
|
---|
| 1295 | {
|
---|
| 1296 | if (!nextchar.equals(""))
|
---|
| 1297 | {
|
---|
| 1298 | optarg = nextchar;
|
---|
| 1299 | ++optind;
|
---|
| 1300 | }
|
---|
| 1301 | else
|
---|
| 1302 | {
|
---|
| 1303 | optarg = null;
|
---|
| 1304 | }
|
---|
| 1305 |
|
---|
| 1306 | nextchar = null;
|
---|
| 1307 | }
|
---|
| 1308 | else
|
---|
| 1309 | {
|
---|
| 1310 | if (!nextchar.equals(""))
|
---|
| 1311 | {
|
---|
| 1312 | optarg = nextchar;
|
---|
| 1313 | ++optind;
|
---|
| 1314 | }
|
---|
| 1315 | else if (optind == argv.length)
|
---|
| 1316 | {
|
---|
| 1317 | if (opterr)
|
---|
| 1318 | {
|
---|
| 1319 | // 1003.2 specifies the format of this message
|
---|
[10209] | 1320 | Object[] msgArgs = { progname,
|
---|
| 1321 | Character.toString((char)c) };
|
---|
[5279] | 1322 | System.err.println(MessageFormat.format(
|
---|
| 1323 | _messages.getString("getopt.requires2"), msgArgs));
|
---|
| 1324 | }
|
---|
| 1325 |
|
---|
| 1326 | optopt = c;
|
---|
[10209] | 1327 |
|
---|
[5279] | 1328 | if (optstring.charAt(0) == ':')
|
---|
| 1329 | return(':');
|
---|
| 1330 | else
|
---|
| 1331 | return('?');
|
---|
| 1332 | }
|
---|
| 1333 | else
|
---|
| 1334 | {
|
---|
| 1335 | optarg = argv[optind];
|
---|
| 1336 | ++optind;
|
---|
| 1337 |
|
---|
| 1338 | // Ok, here's an obscure Posix case. If we have o:, and
|
---|
| 1339 | // we get -o -- foo, then we're supposed to skip the --,
|
---|
| 1340 | // end parsing of options, and make foo an operand to -o.
|
---|
| 1341 | // Only do this in Posix mode.
|
---|
| 1342 | if ((posixly_correct) && optarg.equals("--"))
|
---|
| 1343 | {
|
---|
| 1344 | // If end of argv, error out
|
---|
| 1345 | if (optind == argv.length)
|
---|
| 1346 | {
|
---|
| 1347 | if (opterr)
|
---|
| 1348 | {
|
---|
| 1349 | // 1003.2 specifies the format of this message
|
---|
[10209] | 1350 | Object[] msgArgs = { progname,
|
---|
| 1351 | Character.toString((char)c) };
|
---|
[5279] | 1352 | System.err.println(MessageFormat.format(
|
---|
| 1353 | _messages.getString("getopt.requires2"), msgArgs));
|
---|
| 1354 | }
|
---|
| 1355 |
|
---|
| 1356 | optopt = c;
|
---|
[10209] | 1357 |
|
---|
[5279] | 1358 | if (optstring.charAt(0) == ':')
|
---|
| 1359 | return(':');
|
---|
| 1360 | else
|
---|
| 1361 | return('?');
|
---|
| 1362 | }
|
---|
| 1363 |
|
---|
| 1364 | // Set new optarg and set to end
|
---|
| 1365 | // Don't permute as we do on -- up above since we
|
---|
| 1366 | // know we aren't in permute mode because of Posix.
|
---|
| 1367 | optarg = argv[optind];
|
---|
| 1368 | ++optind;
|
---|
| 1369 | first_nonopt = optind;
|
---|
| 1370 | last_nonopt = argv.length;
|
---|
| 1371 | endparse = true;
|
---|
| 1372 | }
|
---|
| 1373 | }
|
---|
| 1374 |
|
---|
| 1375 | nextchar = null;
|
---|
| 1376 | }
|
---|
| 1377 | }
|
---|
| 1378 |
|
---|
| 1379 | return(c);
|
---|
| 1380 | }
|
---|
| 1381 |
|
---|
| 1382 | } // Class Getopt
|
---|
| 1383 |
|
---|
| 1384 |
|
---|