| 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 |
| 6 | | /* it under the terms of the GNU Library General Public License as published |
| 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 |
| 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, |
| 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; |
| 26 | | import java.util.function.Function; |
| 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 |
| 56 | | * the value of the opterr instance variable to false using the |
| 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 |
| 66 | | * traditional Unix manner. That is, proceeded by a '-' character. |
| 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 |
| 81 | | * by using the special argument "--" by itself. For example: |
| 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(); |
| 105 | | * System.out.print("You picked " + (char)c + |
| 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 |
| 146 | | * of "-a foo bar -d" returns options 'a' and 'd', then sets optind to |
| 147 | | * point to "foo". The program would read the last two argv elements as |
| 148 | | * "foo" and "bar", just as if the user had typed "-a -d foo bar". |
| 149 | | * <p> |
| 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 "--" |
| 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 |
| 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> |
| 176 | | * The POSIX/traditional behavior is enabled by either setting the |
| 177 | | * property "gnu.posixly_correct" or by putting a '+' sign as the first |
| 178 | | * character of the option string. The difference between the two |
| 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 |
| 182 | | * of the option string. Note that after determining the proper |
| 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 |
| 192 | | * "-h" for help, a program could support also "--help". |
| 193 | | * <p> |
| 194 | | * Like short options, long options can also take a required or non-required |
| 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> |
| 206 | | * Long options can also be specified using a special POSIX argument |
| 207 | | * format (one that I highly discourage). This form of entry is |
| 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 |
| 213 | | * handled identically to normal long options. If a string follows the |
| 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 |
| 222 | | * getopt() returns a '?'. |
| 223 | | * <p> |
| 224 | | * If an invalid option is specified or a required option argument is |
| 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 |
| 243 | | * things can be returned. If the flag field in the LongOpt object |
| 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. |
| 251 | | * This allows an app to have both a long and short option sequence |
| 252 | | * (say, "-h" and "--help") that do the exact same thing. |
| 253 | | * <p> |
| 254 | | * With long options, there is an alternative method of determining |
| 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, |
| 258 | | * the application can use getLongind() to distinguish between them. |
| 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]; |
| 267 | | * // |
| 268 | | * StringBuffer sb = new StringBuffer(); |
| 269 | | * longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'); |
| 270 | | * longopts[1] = new LongOpt("outputdir", LongOpt.REQUIRED_ARGUMENT, sb, 'o'); |
| 271 | | * longopts[2] = new LongOpt("maximum", LongOpt.OPTIONAL_ARGUMENT, null, 2); |
| 272 | | * // |
| 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() + |
| 298 | | * " with value " + |
| 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(); |
| 309 | | * System.out.println("You picked option '" + (char)c + |
| 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 '?': |
| 329 | | * System.out.println("The option '" + (char)g.getOptopt() + |
| 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. |
| 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 |
| 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 | | |
| 384 | | /** |
| 385 | | * Describe how to deal with options that follow non-option ARGV-elements. |
| 386 | | * |
| 387 | | * If the caller did not specify anything, |
| 388 | | * the default is REQUIRE_ORDER if the property |
| 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 | | */ |
| 427 | | |
| 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 |
| 448 | | * how much of ARGV has been scanned so far. |
| 449 | | */ |
| 450 | | protected int optind = 0; |
| 451 | | |
| 452 | | /** |
| 453 | | * Callers store false here to inhibit the error message |
| 454 | | * for unrecognized options. |
| 455 | | */ |
| 456 | | protected boolean opterr = true; |
| 457 | | |
| 458 | | /** |
| 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 | | |
| 464 | | /** |
| 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 |
| 470 | | * by advancing to the next ARGV-element. |
| 471 | | */ |
| 472 | | protected String nextchar; |
| 473 | | |
| 474 | | /** |
| 475 | | * This is the string describing the valid short options. |
| 476 | | */ |
| 477 | | protected String optstring; |
| 478 | | |
| 479 | | /** |
| 480 | | * This is an array of LongOpt objects which describ the valid long |
| 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 |
| 575 | | Getopt(String progname, String[] argv, String optstring, |
| 576 | | LongOpt[] long_options) |
| 577 | | { |
| 578 | | this(progname, argv, optstring, long_options, false); |
| 579 | | } |
| 580 | | |
| 581 | | /**************************************************************************/ |
| 582 | | |
| 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 | | |
| 596 | | static class OptI18n { |
| 597 | | |
| 598 | | private final Map<String, String> trns = new HashMap<>(); |
| 599 | | |
| 600 | | public OptI18n() { |
| 601 | | add("getopt.ambigious", tr("{0}: option ''{1}'' is ambiguous")); |
| 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")); |
| 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 | | |
| 613 | | private String tr(String s) { |
| 614 | | return Getopt.tr.apply(s); |
| 615 | | } |
| 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 |
| 631 | | * think, the flag 'long_only' does not determine whether or not we |
| 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 |
| 643 | | Getopt(String progname, String[] argv, String optstring, |
| 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 |
| 659 | | try { |
| 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 | | } |
| 668 | | } catch (SecurityException e) { |
| 669 | | System.err.println(e.getMessage()); |
| 670 | | } |
| 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 | | /**************************************************************************/ |
| 696 | | |
| 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 |
| 729 | | * how much of ARGV has been scanned so far. |
| 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 |
| 742 | | * lossage), but optind is a public symbol in GNU getopt, so this method |
| 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 | | |
| 772 | | /** |
| 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) |
| 791 | | * by calling this method. There is no get method for this variable |
| 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 | | { |
| 846 | | // Bottom segment is the short one. |
| 847 | | int len = middle - bottom; |
| 848 | | int i; |
| 849 | | |
| 850 | | // Swap it with the top part of the top segment. |
| 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 | | } |
| 857 | | // Exclude the moved bottom segment from further swapping. |
| 858 | | top -= len; |
| 859 | | } |
| 860 | | else |
| 861 | | { |
| 862 | | // Top segment is the short one. |
| 863 | | int len = top - middle; |
| 864 | | int i; |
| 865 | | |
| 866 | | // Swap it with the bottom part of the bottom segment. |
| 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 | | } |
| 873 | | // Exclude the moved top segment from further swapping. |
| 874 | | bottom += len; |
| 875 | | } |
| 876 | | } |
| 877 | | |
| 878 | | // Update records for the slots the non-options now occupy. |
| 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; |
| 902 | | |
| 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(); |
| 911 | | |
| 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 |
| 938 | | |
| 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( |
| 946 | | _messages.getString("getopt.ambigious"), |
| 947 | | msgArgs)); |
| 948 | | } |
| 949 | | |
| 950 | | nextchar = ""; |
| 951 | | optopt = 0; |
| 952 | | ++optind; |
| 953 | | |
| 954 | | return('?'); |
| 955 | | } |
| 956 | | |
| 957 | | if (pfound != null) |
| 958 | | { |
| 959 | | ++optind; |
| 960 | | |
| 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( |
| 979 | | _messages.getString("getopt.arguments1"), |
| 980 | | msgArgs)); |
| 981 | | } |
| 982 | | // +option or -option |
| 983 | | else |
| 984 | | { |
| 985 | | Object[] msgArgs = { progname, |
| 986 | | Character.toString(argv[optind-1].charAt(0)), |
| 987 | | pfound.name }; |
| 988 | | System.err.println(MessageFormat.format( |
| 989 | | _messages.getString("getopt.arguments2"), |
| 990 | | msgArgs)); |
| 991 | | } |
| 992 | | } |
| 993 | | |
| 994 | | nextchar = ""; |
| 995 | | optopt = pfound.val; |
| 996 | | |
| 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( |
| 1013 | | _messages.getString("getopt.requires"), |
| 1014 | | msgArgs)); |
| 1015 | | } |
| 1016 | | |
| 1017 | | nextchar = ""; |
| 1018 | | optopt = pfound.val; |
| 1019 | | if (optstring.charAt(0) == ':') |
| 1020 | | return(':'); |
| 1021 | | else |
| 1022 | | return('?'); |
| 1023 | | } |
| 1024 | | } // else if (pfound) |
| 1025 | | |
| 1026 | | nextchar = ""; |
| 1027 | | |
| 1028 | | if (pfound.flag != null) |
| 1029 | | { |
| 1030 | | pfound.flag.setLength(0); |
| 1031 | | pfound.flag.append(pfound.val); |
| 1032 | | |
| 1033 | | return(0); |
| 1034 | | } |
| 1035 | | |
| 1036 | | return(pfound.val); |
| 1037 | | } // if (pfound != null) |
| 1038 | | |
| 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 | | } |
| 1093 | | |
| 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. |
| 1129 | | if (argv[optind].equals("") || (argv[optind].charAt(0) != '-') || |
| 1130 | | argv[optind].equals("-")) |
| 1131 | | { |
| 1132 | | if (ordering == REQUIRE_ORDER) |
| 1133 | | return(-1); |
| 1134 | | |
| 1135 | | optarg = argv[optind++]; |
| 1136 | | return(1); |
| 1137 | | } |
| 1138 | | |
| 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("--") |
| 1162 | | || (long_only && ((argv[optind].length() > 2) || |
| 1163 | | (optstring.indexOf(argv[optind].charAt(1)) == -1))))) |
| 1164 | | { |
| 1165 | | int c = checkLongOption(); |
| 1166 | | |
| 1167 | | if (longopt_handled) |
| 1168 | | return(c); |
| 1169 | | |
| 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( |
| 1183 | | _messages.getString("getopt.unrecognized"), |
| 1184 | | msgArgs)); |
| 1185 | | } |
| 1186 | | else |
| 1187 | | { |
| 1188 | | Object[] msgArgs = { progname, |
| 1189 | | Character.toString(argv[optind].charAt(0)), |
| 1190 | | nextchar }; |
| 1191 | | System.err.println(MessageFormat.format( |
| 1192 | | _messages.getString("getopt.unrecognized2"), |
| 1193 | | msgArgs)); |
| 1194 | | } |
| 1195 | | } |
| 1196 | | |
| 1197 | | nextchar = ""; |
| 1198 | | ++optind; |
| 1199 | | optopt = 0; |
| 1200 | | |
| 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 = ""; |
| 1211 | | |
| 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 |
| 1226 | | Object[] msgArgs = { progname, |
| 1227 | | Character.toString((char)c) }; |
| 1228 | | System.err.println(MessageFormat.format( |
| 1229 | | _messages.getString("getopt.illegal"), msgArgs)); |
| 1230 | | } |
| 1231 | | else |
| 1232 | | { |
| 1233 | | Object[] msgArgs = { progname, |
| 1234 | | Character.toString((char)c) }; |
| 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 | | { |
| 1257 | | // 1003.2 specifies the format of this message. |
| 1258 | | Object[] msgArgs = { progname, |
| 1259 | | Character.toString((char)c) }; |
| 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; |
| 1273 | | // increment it again when taking next ARGV-elt as argument. |
| 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 |
| 1320 | | Object[] msgArgs = { progname, |
| 1321 | | Character.toString((char)c) }; |
| 1322 | | System.err.println(MessageFormat.format( |
| 1323 | | _messages.getString("getopt.requires2"), msgArgs)); |
| 1324 | | } |
| 1325 | | |
| 1326 | | optopt = c; |
| 1327 | | |
| 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 |
| 1350 | | Object[] msgArgs = { progname, |
| 1351 | | Character.toString((char)c) }; |
| 1352 | | System.err.println(MessageFormat.format( |
| 1353 | | _messages.getString("getopt.requires2"), msgArgs)); |
| 1354 | | } |
| 1355 | | |
| 1356 | | optopt = c; |
| 1357 | | |
| 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 | | |