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