0001: /**************************************************************************
0002: /* Getopt.java -- Java port of GNU getopt from glibc 2.0.6
0003: /*
0004: /* Copyright (c) 1987-1997 Free Software Foundation, Inc.
0005: /* Java Port Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
0006: /*
0007: /* This program is free software; you can redistribute it and/or modify
0008: /* it under the terms of the GNU Library General Public License as published
0009: /* by the Free Software Foundation; either version 2 of the License or
0010: /* (at your option) any later version.
0011: /*
0012: /* This program is distributed in the hope that it will be useful, but
0013: /* WITHOUT ANY WARRANTY; without even the implied warranty of
0014: /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0015: /* GNU Library General Public License for more details.
0016: /*
0017: /* You should have received a copy of the GNU Library General Public License
0018: /* along with this program; see the file COPYING.LIB. If not, write to
0019: /* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
0020: /* Boston, MA 02111-1307 USA
0021: /**************************************************************************/package gnu.getopt;
0022:
0023: import java.util.Locale;
0024: import java.util.ResourceBundle;
0025: import java.util.PropertyResourceBundle;
0026: import java.text.MessageFormat;
0027:
0028: /**************************************************************************/
0029:
0030: /**
0031: * This is a Java port of GNU getopt, a class for parsing command line
0032: * arguments passed to programs. It it based on the C getopt() functions
0033: * in glibc 2.0.6 and should parse options in a 100% compatible manner.
0034: * If it does not, that is a bug. The programmer's interface is also
0035: * very compatible.
0036: * <p>
0037: * To use Getopt, create a Getopt object with a argv array passed to the
0038: * main method, then call the getopt() method in a loop. It will return an
0039: * int that contains the value of the option character parsed from the
0040: * command line. When there are no more options to be parsed, it
0041: * returns -1.
0042: * <p>
0043: * A command line option can be defined to take an argument. If an
0044: * option has an argument, the value of that argument is stored in an
0045: * instance variable called optarg, which can be accessed using the
0046: * getOptarg() method. If an option that requires an argument is
0047: * found, but there is no argument present, then an error message is
0048: * printed. Normally getopt() returns a '?' in this situation, but
0049: * that can be changed as described below.
0050: * <p>
0051: * If an invalid option is encountered, an error message is printed
0052: * to the standard error and getopt() returns a '?'. The value of the
0053: * invalid option encountered is stored in the instance variable optopt
0054: * which can be retrieved using the getOptopt() method. To suppress
0055: * the printing of error messages for this or any other error, set
0056: * the value of the opterr instance variable to false using the
0057: * setOpterr() method.
0058: * <p>
0059: * Between calls to getopt(), the instance variable optind is used to
0060: * keep track of where the object is in the parsing process. After all
0061: * options have been returned, optind is the index in argv of the first
0062: * non-option argument. This variable can be accessed with the getOptind()
0063: * method.
0064: * <p>
0065: * Note that this object expects command line options to be passed in the
0066: * traditional Unix manner. That is, proceeded by a '-' character.
0067: * Multiple options can follow the '-'. For example "-abc" is equivalent
0068: * to "-a -b -c". If an option takes a required argument, the value
0069: * of the argument can immediately follow the option character or be
0070: * present in the next argv element. For example, "-cfoo" and "-c foo"
0071: * both represent an option character of 'c' with an argument of "foo"
0072: * assuming c takes a required argument. If an option takes an argument
0073: * that is not required, then any argument must immediately follow the
0074: * option character in the same argv element. For example, if c takes
0075: * a non-required argument, then "-cfoo" represents option character 'c'
0076: * with an argument of "foo" while "-c foo" represents the option
0077: * character 'c' with no argument, and a first non-option argv element
0078: * of "foo".
0079: * <p>
0080: * The user can stop getopt() from scanning any further into a command line
0081: * by using the special argument "--" by itself. For example:
0082: * "-a -- -d" would return an option character of 'a', then return -1
0083: * The "--" is discarded and "-d" is pointed to by optind as the first
0084: * non-option argv element.
0085: * <p>
0086: * Here is a basic example of using Getopt:
0087: * <p>
0088: * <pre>
0089: * Getopt g = new Getopt("testprog", argv, "ab:c::d");
0090: * //
0091: * int c;
0092: * String arg;
0093: * while ((c = g.getopt()) != -1)
0094: * {
0095: * switch(c)
0096: * {
0097: * case 'a':
0098: * case 'd':
0099: * System.out.print("You picked " + (char)c + "\n");
0100: * break;
0101: * //
0102: * case 'b':
0103: * case 'c':
0104: * arg = g.getOptarg();
0105: * System.out.print("You picked " + (char)c +
0106: * " with an argument of " +
0107: * ((arg != null) ? arg : "null") + "\n");
0108: * break;
0109: * //
0110: * case '?':
0111: * break; // getopt() already printed an error
0112: * //
0113: * default:
0114: * System.out.print("getopt() returned " + c + "\n");
0115: * }
0116: * }
0117: * </pre>
0118: * <p>
0119: * In this example, a new Getopt object is created with three params.
0120: * The first param is the program name. This is for printing error
0121: * messages in the form "program: error message". In the C version, this
0122: * value is taken from argv[0], but in Java the program name is not passed
0123: * in that element, thus the need for this parameter. The second param is
0124: * the argument list that was passed to the main() method. The third
0125: * param is the list of valid options. Each character represents a valid
0126: * option. If the character is followed by a single colon, then that
0127: * option has a required argument. If the character is followed by two
0128: * colons, then that option has an argument that is not required.
0129: * <p>
0130: * Note in this example that the value returned from getopt() is cast to
0131: * a char prior to printing. This is required in order to make the value
0132: * display correctly as a character instead of an integer.
0133: * <p>
0134: * If the first character in the option string is a colon, for example
0135: * ":abc::d", then getopt() will return a ':' instead of a '?' when it
0136: * encounters an option with a missing required argument. This allows the
0137: * caller to distinguish between invalid options and valid options that
0138: * are simply incomplete.
0139: * <p>
0140: * In the traditional Unix getopt(), -1 is returned when the first non-option
0141: * charcter is encountered. In GNU getopt(), the default behavior is to
0142: * allow options to appear anywhere on the command line. The getopt()
0143: * method permutes the argument to make it appear to the caller that all
0144: * options were at the beginning of the command line, and all non-options
0145: * were at the end. For example, calling getopt() with command line args
0146: * of "-a foo bar -d" returns options 'a' and 'd', then sets optind to
0147: * point to "foo". The program would read the last two argv elements as
0148: * "foo" and "bar", just as if the user had typed "-a -d foo bar".
0149: * <p>
0150: * The user can force getopt() to stop scanning the command line with
0151: * the special argument "--" by itself. Any elements occuring before the
0152: * "--" are scanned and permuted as normal. Any elements after the "--"
0153: * are returned as is as non-option argv elements. For example,
0154: * "foo -a -- bar -d" would return option 'a' then -1. optind would point
0155: * to "foo", "bar" and "-d" as the non-option argv elements. The "--"
0156: * is discarded by getopt().
0157: * <p>
0158: * There are two ways this default behavior can be modified. The first is
0159: * to specify traditional Unix getopt() behavior (which is also POSIX
0160: * behavior) in which scanning stops when the first non-option argument
0161: * encountered. (Thus "-a foo bar -d" would return 'a' as an option and
0162: * have "foo", "bar", and "-d" as non-option elements). The second is to
0163: * allow options anywhere, but to return all elements in the order they
0164: * occur on the command line. When a non-option element is ecountered,
0165: * an integer 1 is returned and the value of the non-option element is
0166: * stored in optarg is if it were the argument to that option. For
0167: * example, "-a foo -d", returns first 'a', then 1 (with optarg set to
0168: * "foo") then 'd' then -1. When this "return in order" functionality
0169: * is enabled, the only way to stop getopt() from scanning all command
0170: * line elements is to use the special "--" string by itself as described
0171: * above. An example is "-a foo -b -- bar", which would return 'a', then
0172: * integer 1 with optarg set to "foo", then 'b', then -1. optind would
0173: * then point to "bar" as the first non-option argv element. The "--"
0174: * is discarded.
0175: * <p>
0176: * The POSIX/traditional behavior is enabled by either setting the
0177: * property "gnu.posixly_correct" or by putting a '+' sign as the first
0178: * character of the option string. The difference between the two
0179: * methods is that setting the gnu.posixly_correct property also forces
0180: * certain error messages to be displayed in POSIX format. To enable
0181: * the "return in order" functionality, put a '-' as the first character
0182: * of the option string. Note that after determining the proper
0183: * behavior, Getopt strips this leading '+' or '-', meaning that a ':'
0184: * placed as the second character after one of those two will still cause
0185: * getopt() to return a ':' instead of a '?' if a required option
0186: * argument is missing.
0187: * <p>
0188: * In addition to traditional single character options, GNU Getopt also
0189: * supports long options. These are preceeded by a "--" sequence and
0190: * can be as long as desired. Long options provide a more user-friendly
0191: * way of entering command line options. For example, in addition to a
0192: * "-h" for help, a program could support also "--help".
0193: * <p>
0194: * Like short options, long options can also take a required or non-required
0195: * argument. Required arguments can either be specified by placing an
0196: * equals sign after the option name, then the argument, or by putting the
0197: * argument in the next argv element. For example: "--outputdir=foo" and
0198: * "--outputdir foo" both represent an option of "outputdir" with an
0199: * argument of "foo", assuming that outputdir takes a required argument.
0200: * If a long option takes a non-required argument, then the equals sign
0201: * form must be used to specify the argument. In this case,
0202: * "--outputdir=foo" would represent option outputdir with an argument of
0203: * "foo" while "--outputdir foo" would represent the option outputdir
0204: * with no argument and a first non-option argv element of "foo".
0205: * <p>
0206: * Long options can also be specified using a special POSIX argument
0207: * format (one that I highly discourage). This form of entry is
0208: * enabled by placing a "W;" (yes, 'W' then a semi-colon) in the valid
0209: * option string. This causes getopt to treat the name following the
0210: * "-W" as the name of the long option. For example, "-W outputdir=foo"
0211: * would be equivalent to "--outputdir=foo". The name can immediately
0212: * follow the "-W" like so: "-Woutputdir=foo". Option arguments are
0213: * handled identically to normal long options. If a string follows the
0214: * "-W" that does not represent a valid long option, then getopt() returns
0215: * 'W' and the caller must decide what to do. Otherwise getopt() returns
0216: * a long option value as described below.
0217: * <p>
0218: * While long options offer convenience, they can also be tedious to type
0219: * in full. So it is permissible to abbreviate the option name to as
0220: * few characters as required to uniquely identify it. If the name can
0221: * represent multiple long options, then an error message is printed and
0222: * getopt() returns a '?'.
0223: * <p>
0224: * If an invalid option is specified or a required option argument is
0225: * missing, getopt() prints an error and returns a '?' or ':' exactly
0226: * as for short options. Note that when an invalid long option is
0227: * encountered, the optopt variable is set to integer 0 and so cannot
0228: * be used to identify the incorrect option the user entered.
0229: * <p>
0230: * Long options are defined by LongOpt objects. These objects are created
0231: * with a contructor that takes four params: a String representing the
0232: * object name, a integer specifying what arguments the option takes
0233: * (the value is one of LongOpt.NO_ARGUMENT, LongOpt.REQUIRED_ARGUMENT,
0234: * or LongOpt.OPTIONAL_ARGUMENT), a StringBuffer flag object (described
0235: * below), and an integer value (described below).
0236: * <p>
0237: * To enable long option parsing, create an array of LongOpt's representing
0238: * the legal options and pass it to the Getopt() constructor. WARNING: If
0239: * all elements of the array are not populated with LongOpt objects, the
0240: * getopt() method will throw a NullPointerException.
0241: * <p>
0242: * When getopt() is called and a long option is encountered, one of two
0243: * things can be returned. If the flag field in the LongOpt object
0244: * representing the long option is non-null, then the integer value field
0245: * is stored there and an integer 0 is returned to the caller. The val
0246: * field can then be retrieved from the flag field. Note that since the
0247: * flag field is a StringBuffer, the appropriate String to integer converions
0248: * must be performed in order to get the actual int value stored there.
0249: * If the flag field in the LongOpt object is null, then the value field
0250: * of the LongOpt is returned. This can be the character of a short option.
0251: * This allows an app to have both a long and short option sequence
0252: * (say, "-h" and "--help") that do the exact same thing.
0253: * <p>
0254: * With long options, there is an alternative method of determining
0255: * which option was selected. The method getLongind() will return the
0256: * the index in the long option array (NOT argv) of the long option found.
0257: * So if multiple long options are configured to return the same value,
0258: * the application can use getLongind() to distinguish between them.
0259: * <p>
0260: * Here is an expanded Getopt example using long options and various
0261: * techniques described above:
0262: * <p>
0263: * <pre>
0264: * int c;
0265: * String arg;
0266: * LongOpt[] longopts = new LongOpt[3];
0267: * //
0268: * StringBuffer sb = new StringBuffer();
0269: * longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h');
0270: * longopts[1] = new LongOpt("outputdir", LongOpt.REQUIRED_ARGUMENT, sb, 'o');
0271: * longopts[2] = new LongOpt("maximum", LongOpt.OPTIONAL_ARGUMENT, null, 2);
0272: * //
0273: * Getopt g = new Getopt("testprog", argv, "-:bc::d:hW;", longopts);
0274: * g.setOpterr(false); // We'll do our own error handling
0275: * //
0276: * while ((c = g.getopt()) != -1)
0277: * switch (c)
0278: * {
0279: * case 0:
0280: * arg = g.getOptarg();
0281: * System.out.println("Got long option with value '" +
0282: * (char)(new Integer(sb.toString())).intValue()
0283: * + "' with argument " +
0284: * ((arg != null) ? arg : "null"));
0285: * break;
0286: * //
0287: * case 1:
0288: * System.out.println("I see you have return in order set and that " +
0289: * "a non-option argv element was just found " +
0290: * "with the value '" + g.getOptarg() + "'");
0291: * break;
0292: * //
0293: * case 2:
0294: * arg = g.getOptarg();
0295: * System.out.println("I know this, but pretend I didn't");
0296: * System.out.println("We picked option " +
0297: * longopts[g.getLongind()].getName() +
0298: * " with value " +
0299: * ((arg != null) ? arg : "null"));
0300: * break;
0301: * //
0302: * case 'b':
0303: * System.out.println("You picked plain old option " + (char)c);
0304: * break;
0305: * //
0306: * case 'c':
0307: * case 'd':
0308: * arg = g.getOptarg();
0309: * System.out.println("You picked option '" + (char)c +
0310: * "' with argument " +
0311: * ((arg != null) ? arg : "null"));
0312: * break;
0313: * //
0314: * case 'h':
0315: * System.out.println("I see you asked for help");
0316: * break;
0317: * //
0318: * case 'W':
0319: * System.out.println("Hmmm. You tried a -W with an incorrect long " +
0320: * "option name");
0321: * break;
0322: * //
0323: * case ':':
0324: * System.out.println("Doh! You need an argument for option " +
0325: * (char)g.getOptopt());
0326: * break;
0327: * //
0328: * case '?':
0329: * System.out.println("The option '" + (char)g.getOptopt() +
0330: * "' is not valid");
0331: * break;
0332: * //
0333: * default:
0334: * System.out.println("getopt() returned " + c);
0335: * break;
0336: * }
0337: * //
0338: * for (int i = g.getOptind(); i < argv.length ; i++)
0339: * System.out.println("Non option argv element: " + argv[i] + "\n");
0340: * </pre>
0341: * <p>
0342: * There is an alternative form of the constructor used for long options
0343: * above. This takes a trailing boolean flag. If set to false, Getopt
0344: * performs identically to the example, but if the boolean flag is true
0345: * then long options are allowed to start with a single '-' instead of
0346: * "--". If the first character of the option is a valid short option
0347: * character, then the option is treated as if it were the short option.
0348: * Otherwise it behaves as if the option is a long option. Note that
0349: * the name given to this option - long_only - is very counter-intuitive.
0350: * It does not cause only long options to be parsed but instead enables
0351: * the behavior described above.
0352: * <p>
0353: * Note that the functionality and variable names used are driven from
0354: * the C lib version as this object is a port of the C code, not a
0355: * new implementation. This should aid in porting existing C/C++ code,
0356: * as well as helping programmers familiar with the glibc version to
0357: * adapt to the Java version even if it seems very non-Java at times.
0358: * <p>
0359: * In this release I made all instance variables protected due to
0360: * overwhelming public demand. Any code which relied on optarg,
0361: * opterr, optind, or optopt being public will need to be modified to
0362: * use the appropriate access methods.
0363: * <p>
0364: * Please send all bug reports, requests, and comments to
0365: * <a href="mailto:arenn@urbanophile.com">arenn@urbanophile.com</a>.
0366: *
0367: * @version 1.0.5
0368: *
0369: * @author Roland McGrath (roland@gnu.ai.mit.edu)
0370: * @author Ulrich Drepper (drepper@cygnus.com)
0371: * @author Aaron M. Renn (arenn@urbanophile.com)
0372: *
0373: * @see LongOpt
0374: */
0375: public class Getopt extends Object {
0376:
0377: /**************************************************************************/
0378:
0379: /*
0380: * Class Variables
0381: */
0382:
0383: /**
0384: * Describe how to deal with options that follow non-option ARGV-elements.
0385: *
0386: * If the caller did not specify anything,
0387: * the default is REQUIRE_ORDER if the property
0388: * gnu.posixly_correct is defined, PERMUTE otherwise.
0389: *
0390: * The special argument `--' forces an end of option-scanning regardless
0391: * of the value of `ordering'. In the case of RETURN_IN_ORDER, only
0392: * `--' can cause `getopt' to return -1 with `optind' != ARGC.
0393: *
0394: * REQUIRE_ORDER means don't recognize them as options;
0395: * stop option processing when the first non-option is seen.
0396: * This is what Unix does.
0397: * This mode of operation is selected by either setting the property
0398: * gnu.posixly_correct, or using `+' as the first character
0399: * of the list of option characters.
0400: */
0401: protected static final int REQUIRE_ORDER = 1;
0402:
0403: /**
0404: * PERMUTE is the default. We permute the contents of ARGV as we scan,
0405: * so that eventually all the non-options are at the end. This allows options
0406: * to be given in any order, even with programs that were not written to
0407: * expect this.
0408: */
0409: protected static final int PERMUTE = 2;
0410:
0411: /**
0412: * RETURN_IN_ORDER is an option available to programs that were written
0413: * to expect options and other ARGV-elements in any order and that care about
0414: * the ordering of the two. We describe each non-option ARGV-element
0415: * as if it were the argument of an option with character code 1.
0416: * Using `-' as the first character of the list of option characters
0417: * selects this mode of operation.
0418: */
0419: protected static final int RETURN_IN_ORDER = 3;
0420:
0421: /**************************************************************************/
0422:
0423: /*
0424: * Instance Variables
0425: */
0426:
0427: /**
0428: * For communication from `getopt' to the caller.
0429: * When `getopt' finds an option that takes an argument,
0430: * the argument value is returned here.
0431: * Also, when `ordering' is RETURN_IN_ORDER,
0432: * each non-option ARGV-element is returned here.
0433: */
0434: protected String optarg;
0435:
0436: /**
0437: * Index in ARGV of the next element to be scanned.
0438: * This is used for communication to and from the caller
0439: * and for communication between successive calls to `getopt'.
0440: *
0441: * On entry to `getopt', zero means this is the first call; initialize.
0442: *
0443: * When `getopt' returns -1, this is the index of the first of the
0444: * non-option elements that the caller should itself scan.
0445: *
0446: * Otherwise, `optind' communicates from one call to the next
0447: * how much of ARGV has been scanned so far.
0448: */
0449: protected int optind = 0;
0450:
0451: /**
0452: * Callers store false here to inhibit the error message
0453: * for unrecognized options.
0454: */
0455: protected boolean opterr = true;
0456:
0457: /**
0458: * When an unrecognized option is encountered, getopt will return a '?'
0459: * and store the value of the invalid option here.
0460: */
0461: protected int optopt = '?';
0462:
0463: /**
0464: * The next char to be scanned in the option-element
0465: * in which the last option character we returned was found.
0466: * This allows us to pick up the scan where we left off.
0467: *
0468: * If this is zero, or a null string, it means resume the scan
0469: * by advancing to the next ARGV-element.
0470: */
0471: protected String nextchar;
0472:
0473: /**
0474: * This is the string describing the valid short options.
0475: */
0476: protected String optstring;
0477:
0478: /**
0479: * This is an array of LongOpt objects which describ the valid long
0480: * options.
0481: */
0482: protected LongOpt[] long_options;
0483:
0484: /**
0485: * This flag determines whether or not we are parsing only long args
0486: */
0487: protected boolean long_only;
0488:
0489: /**
0490: * Stores the index into the long_options array of the long option found
0491: */
0492: protected int longind;
0493:
0494: /**
0495: * The flag determines whether or not we operate in strict POSIX compliance
0496: */
0497: protected boolean posixly_correct;
0498:
0499: /**
0500: * A flag which communicates whether or not checkLongOption() did all
0501: * necessary processing for the current option
0502: */
0503: protected boolean longopt_handled;
0504:
0505: /**
0506: * The index of the first non-option in argv[]
0507: */
0508: protected int first_nonopt = 1;
0509:
0510: /**
0511: * The index of the last non-option in argv[]
0512: */
0513: protected int last_nonopt = 1;
0514:
0515: /**
0516: * Saved argument list passed to the program
0517: */
0518: protected String[] argv;
0519:
0520: /**
0521: * Determines whether we permute arguments or not
0522: */
0523: protected int ordering;
0524:
0525: /**
0526: * Name to print as the program name in error messages. This is necessary
0527: * since Java does not place the program name in argv[0]
0528: */
0529: protected String progname;
0530:
0531: /**
0532: * The localized strings are kept in a separate file
0533: */
0534: private ResourceBundle _messages = PropertyResourceBundle
0535: .getBundle("gnu/getopt/MessagesBundle", Locale.getDefault());
0536:
0537: /**************************************************************************/
0538:
0539: /*
0540: * Constructors
0541: */
0542:
0543: /**
0544: * Construct a basic Getopt instance with the given input data. Note that
0545: * this handles "short" options only.
0546: *
0547: * @param progname The name to display as the program name when printing errors
0548: * @param argv The String array passed as the command line to the program.
0549: * @param optstring A String containing a description of the valid args for this program
0550: */
0551: public Getopt(String progname, String[] argv, String optstring) {
0552: this (progname, argv, optstring, null, false);
0553: }
0554:
0555: /**************************************************************************/
0556:
0557: /**
0558: * Construct a Getopt instance with given input data that is capable of
0559: * parsing long options as well as short.
0560: *
0561: * @param progname The name to display as the program name when printing errors
0562: * @param argv The String array passed as the command ilne to the program
0563: * @param optstring A String containing a description of the valid short args for this program
0564: * @param long_options An array of LongOpt objects that describes the valid long args for this program
0565: */
0566: public Getopt(String progname, String[] argv, String optstring,
0567: LongOpt[] long_options) {
0568: this (progname, argv, optstring, long_options, false);
0569: }
0570:
0571: /**************************************************************************/
0572:
0573: /**
0574: * Construct a Getopt instance with given input data that is capable of
0575: * parsing long options and short options. Contrary to what you might
0576: * think, the flag 'long_only' does not determine whether or not we
0577: * scan for only long arguments. Instead, a value of true here allows
0578: * long arguments to start with a '-' instead of '--' unless there is a
0579: * conflict with a short option name.
0580: *
0581: * @param progname The name to display as the program name when printing errors
0582: * @param argv The String array passed as the command ilne to the program
0583: * @param optstring A String containing a description of the valid short args for this program
0584: * @param long_options An array of LongOpt objects that describes the valid long args for this program
0585: * @param long_only true if long options that do not conflict with short options can start with a '-' as well as '--'
0586: */
0587: public Getopt(String progname, String[] argv, String optstring,
0588: LongOpt[] long_options, boolean long_only) {
0589: if (optstring.length() == 0)
0590: optstring = " ";
0591:
0592: // This function is essentially _getopt_initialize from GNU getopt
0593: this .progname = progname;
0594: this .argv = argv;
0595: this .optstring = optstring;
0596: this .long_options = long_options;
0597: this .long_only = long_only;
0598:
0599: // Check for property "gnu.posixly_correct" to determine whether to
0600: // strictly follow the POSIX standard. This replaces the "POSIXLY_CORRECT"
0601: // environment variable in the C version
0602: if (System.getProperty("gnu.posixly_correct", null) == null)
0603: posixly_correct = false;
0604: else {
0605: posixly_correct = true;
0606: _messages = PropertyResourceBundle.getBundle(
0607: "gnu/getopt/MessagesBundle", Locale.US);
0608: }
0609:
0610: // Determine how to handle the ordering of options and non-options
0611: if (optstring.charAt(0) == '-') {
0612: ordering = RETURN_IN_ORDER;
0613: if (optstring.length() > 1)
0614: this .optstring = optstring.substring(1);
0615: } else if (optstring.charAt(0) == '+') {
0616: ordering = REQUIRE_ORDER;
0617: if (optstring.length() > 1)
0618: this .optstring = optstring.substring(1);
0619: } else if (posixly_correct) {
0620: ordering = REQUIRE_ORDER;
0621: } else {
0622: ordering = PERMUTE; // The normal default case
0623: }
0624: }
0625:
0626: /**************************************************************************/
0627:
0628: /*
0629: * Instance Methods
0630: */
0631:
0632: /**
0633: * In GNU getopt, it is possible to change the string containg valid options
0634: * on the fly because it is passed as an argument to getopt() each time. In
0635: * this version we do not pass the string on every call. In order to allow
0636: * dynamic option string changing, this method is provided.
0637: *
0638: * @param optstring The new option string to use
0639: */
0640: public void setOptstring(String optstring) {
0641: if (optstring.length() == 0)
0642: optstring = " ";
0643:
0644: this .optstring = optstring;
0645: }
0646:
0647: /**************************************************************************/
0648:
0649: /**
0650: * optind it the index in ARGV of the next element to be scanned.
0651: * This is used for communication to and from the caller
0652: * and for communication between successive calls to `getopt'.
0653: *
0654: * When `getopt' returns -1, this is the index of the first of the
0655: * non-option elements that the caller should itself scan.
0656: *
0657: * Otherwise, `optind' communicates from one call to the next
0658: * how much of ARGV has been scanned so far.
0659: */
0660: public int getOptind() {
0661: return (optind);
0662: }
0663:
0664: /**************************************************************************/
0665:
0666: /**
0667: * This method allows the optind index to be set manually. Normally this
0668: * is not necessary (and incorrect usage of this method can lead to serious
0669: * lossage), but optind is a public symbol in GNU getopt, so this method
0670: * was added to allow it to be modified by the caller if desired.
0671: *
0672: * @param optind The new value of optind
0673: */
0674: public void setOptind(int optind) {
0675: this .optind = optind;
0676: }
0677:
0678: /**************************************************************************/
0679:
0680: /**
0681: * Since in GNU getopt() the argument vector is passed back in to the
0682: * function every time, the caller can swap out argv on the fly. Since
0683: * passing argv is not required in the Java version, this method allows
0684: * the user to override argv. Note that incorrect use of this method can
0685: * lead to serious lossage.
0686: *
0687: * @param argv New argument list
0688: */
0689: public void setArgv(String[] argv) {
0690: this .argv = argv;
0691: }
0692:
0693: /**************************************************************************/
0694:
0695: /**
0696: * For communication from `getopt' to the caller.
0697: * When `getopt' finds an option that takes an argument,
0698: * the argument value is returned here.
0699: * Also, when `ordering' is RETURN_IN_ORDER,
0700: * each non-option ARGV-element is returned here.
0701: * No set method is provided because setting this variable has no effect.
0702: */
0703: public String getOptarg() {
0704: return (optarg);
0705: }
0706:
0707: /**************************************************************************/
0708:
0709: /**
0710: * Normally Getopt will print a message to the standard error when an
0711: * invalid option is encountered. This can be suppressed (or re-enabled)
0712: * by calling this method. There is no get method for this variable
0713: * because if you can't remember the state you set this to, why should I?
0714: */
0715: public void setOpterr(boolean opterr) {
0716: this .opterr = opterr;
0717: }
0718:
0719: /**************************************************************************/
0720:
0721: /**
0722: * When getopt() encounters an invalid option, it stores the value of that
0723: * option in optopt which can be retrieved with this method. There is
0724: * no corresponding set method because setting this variable has no effect.
0725: */
0726: public int getOptopt() {
0727: return (optopt);
0728: }
0729:
0730: /**************************************************************************/
0731:
0732: /**
0733: * Returns the index into the array of long options (NOT argv) representing
0734: * the long option that was found.
0735: */
0736: public int getLongind() {
0737: return (longind);
0738: }
0739:
0740: /**************************************************************************/
0741:
0742: /**
0743: * Exchange the shorter segment with the far end of the longer segment.
0744: * That puts the shorter segment into the right place.
0745: * It leaves the longer segment in the right place overall,
0746: * but it consists of two parts that need to be swapped next.
0747: * This method is used by getopt() for argument permutation.
0748: */
0749: protected void exchange(String[] argv) {
0750: int bottom = first_nonopt;
0751: int middle = last_nonopt;
0752: int top = optind;
0753: String tem;
0754:
0755: while (top > middle && middle > bottom) {
0756: if (top - middle > middle - bottom) {
0757: // Bottom segment is the short one.
0758: int len = middle - bottom;
0759: int i;
0760:
0761: // Swap it with the top part of the top segment.
0762: for (i = 0; i < len; i++) {
0763: tem = argv[bottom + i];
0764: argv[bottom + i] = argv[top - (middle - bottom) + i];
0765: argv[top - (middle - bottom) + i] = tem;
0766: }
0767: // Exclude the moved bottom segment from further swapping.
0768: top -= len;
0769: } else {
0770: // Top segment is the short one.
0771: int len = top - middle;
0772: int i;
0773:
0774: // Swap it with the bottom part of the bottom segment.
0775: for (i = 0; i < len; i++) {
0776: tem = argv[bottom + i];
0777: argv[bottom + i] = argv[middle + i];
0778: argv[middle + i] = tem;
0779: }
0780: // Exclude the moved top segment from further swapping.
0781: bottom += len;
0782: }
0783: }
0784:
0785: // Update records for the slots the non-options now occupy.
0786:
0787: first_nonopt += (optind - last_nonopt);
0788: last_nonopt = optind;
0789: }
0790:
0791: /**************************************************************************/
0792:
0793: /**
0794: * Check to see if an option is a valid long option. Called by getopt().
0795: * Put in a separate method because this needs to be done twice. (The
0796: * C getopt authors just copy-pasted the code!).
0797: *
0798: * @param longind A buffer in which to store the 'val' field of found LongOpt
0799: *
0800: * @return Various things depending on circumstances
0801: */
0802: protected int checkLongOption() {
0803: LongOpt pfound = null;
0804: int nameend;
0805: boolean ambig;
0806: boolean exact;
0807:
0808: longopt_handled = true;
0809: ambig = false;
0810: exact = false;
0811: longind = -1;
0812:
0813: nameend = nextchar.indexOf("=");
0814: if (nameend == -1)
0815: nameend = nextchar.length();
0816:
0817: // Test all lnog options for either exact match or abbreviated matches
0818: for (int i = 0; i < long_options.length; i++) {
0819: if (long_options[i].getName().startsWith(
0820: nextchar.substring(0, nameend))) {
0821: if (long_options[i].getName().equals(
0822: nextchar.substring(0, nameend))) {
0823: // Exact match found
0824: pfound = long_options[i];
0825: longind = i;
0826: exact = true;
0827: break;
0828: } else if (pfound == null) {
0829: // First nonexact match found
0830: pfound = long_options[i];
0831: longind = i;
0832: } else {
0833: // Second or later nonexact match found
0834: ambig = true;
0835: }
0836: }
0837: } // for
0838:
0839: // Print out an error if the option specified was ambiguous
0840: if (ambig && !exact) {
0841: if (opterr) {
0842: Object[] msgArgs = { progname, argv[optind] };
0843: System.err.println(MessageFormat.format(_messages
0844: .getString("getopt.ambigious"), msgArgs));
0845: }
0846:
0847: nextchar = "";
0848: optopt = 0;
0849: ++optind;
0850:
0851: return ('?');
0852: }
0853:
0854: if (pfound != null) {
0855: ++optind;
0856:
0857: if (nameend != nextchar.length()) {
0858: if (pfound.has_arg != LongOpt.NO_ARGUMENT) {
0859: if (nextchar.substring(nameend).length() > 1)
0860: optarg = nextchar.substring(nameend + 1);
0861: else
0862: optarg = "";
0863: } else {
0864: if (opterr) {
0865: // -- option
0866: if (argv[optind - 1].startsWith("--")) {
0867: Object[] msgArgs = { progname, pfound.name };
0868: System.err
0869: .println(MessageFormat
0870: .format(
0871: _messages
0872: .getString("getopt.arguments1"),
0873: msgArgs));
0874: }
0875: // +option or -option
0876: else {
0877: Object[] msgArgs = {
0878: progname,
0879: new Character(argv[optind - 1]
0880: .charAt(0)).toString(),
0881: pfound.name };
0882: System.err
0883: .println(MessageFormat
0884: .format(
0885: _messages
0886: .getString("getopt.arguments2"),
0887: msgArgs));
0888: }
0889: }
0890:
0891: nextchar = "";
0892: optopt = pfound.val;
0893:
0894: return ('?');
0895: }
0896: } // if (nameend)
0897: else if (pfound.has_arg == LongOpt.REQUIRED_ARGUMENT) {
0898: if (optind < argv.length) {
0899: optarg = argv[optind];
0900: ++optind;
0901: } else {
0902: if (opterr) {
0903: Object[] msgArgs = { progname, argv[optind - 1] };
0904: System.err.println(MessageFormat.format(
0905: _messages.getString("getopt.requires"),
0906: msgArgs));
0907: }
0908:
0909: nextchar = "";
0910: optopt = pfound.val;
0911: if (optstring.charAt(0) == ':')
0912: return (':');
0913: else
0914: return ('?');
0915: }
0916: } // else if (pfound)
0917:
0918: nextchar = "";
0919:
0920: if (pfound.flag != null) {
0921: pfound.flag.setLength(0);
0922: pfound.flag.append(pfound.val);
0923:
0924: return (0);
0925: }
0926:
0927: return (pfound.val);
0928: } // if (pfound != null)
0929:
0930: longopt_handled = false;
0931:
0932: return (0);
0933: }
0934:
0935: /**************************************************************************/
0936:
0937: /**
0938: * This method returns a char that is the current option that has been
0939: * parsed from the command line. If the option takes an argument, then
0940: * the internal variable 'optarg' is set which is a String representing
0941: * the the value of the argument. This value can be retrieved by the
0942: * caller using the getOptarg() method. If an invalid option is found,
0943: * an error message is printed and a '?' is returned. The name of the
0944: * invalid option character can be retrieved by calling the getOptopt()
0945: * method. When there are no more options to be scanned, this method
0946: * returns -1. The index of first non-option element in argv can be
0947: * retrieved with the getOptind() method.
0948: *
0949: * @return Various things as described above
0950: */
0951: public int getopt() {
0952: optarg = null;
0953:
0954: if ((nextchar == null) || (nextchar.equals(""))) {
0955: // If we have just processed some options following some non-options,
0956: // exchange them so that the options come first.
0957: if (last_nonopt > optind)
0958: last_nonopt = optind;
0959: if (first_nonopt > optind)
0960: first_nonopt = optind;
0961:
0962: if (ordering == PERMUTE) {
0963: // If we have just processed some options following some non-options,
0964: // exchange them so that the options come first.
0965: if ((first_nonopt != last_nonopt)
0966: && (last_nonopt != optind))
0967: exchange(argv);
0968: else if (last_nonopt != optind)
0969: first_nonopt = optind;
0970:
0971: // Skip any additional non-options
0972: // and extend the range of non-options previously skipped.
0973: while ((optind < argv.length)
0974: && (argv[optind].equals("")
0975: || (argv[optind].charAt(0) != '-') || argv[optind]
0976: .equals("-"))) {
0977: optind++;
0978: }
0979:
0980: last_nonopt = optind;
0981: }
0982:
0983: // The special ARGV-element `--' means premature end of options.
0984: // Skip it like a null option,
0985: // then exchange with previous non-options as if it were an option,
0986: // then skip everything else like a non-option.
0987: if ((optind != argv.length) && argv[optind].equals("--")) {
0988: optind++;
0989:
0990: if ((first_nonopt != last_nonopt)
0991: && (last_nonopt != optind))
0992: exchange(argv);
0993: else if (first_nonopt == last_nonopt)
0994: first_nonopt = optind;
0995:
0996: last_nonopt = argv.length;
0997:
0998: optind = argv.length;
0999: }
1000:
1001: // If we have done all the ARGV-elements, stop the scan
1002: // and back over any non-options that we skipped and permuted.
1003: if (optind == argv.length) {
1004: // Set the next-arg-index to point at the non-options
1005: // that we previously skipped, so the caller will digest them.
1006: if (first_nonopt != last_nonopt)
1007: optind = first_nonopt;
1008:
1009: return (-1);
1010: }
1011:
1012: // If we have come to a non-option and did not permute it,
1013: // either stop the scan or describe it to the caller and pass it by.
1014: if (argv[optind].equals("")
1015: || (argv[optind].charAt(0) != '-')
1016: || argv[optind].equals("-")) {
1017: if (ordering == REQUIRE_ORDER)
1018: return (-1);
1019:
1020: optarg = argv[optind++];
1021: return (1);
1022: }
1023:
1024: // We have found another option-ARGV-element.
1025: // Skip the initial punctuation.
1026: if (argv[optind].startsWith("--"))
1027: nextchar = argv[optind].substring(2);
1028: else
1029: nextchar = argv[optind].substring(1);
1030: }
1031:
1032: // Decode the current option-ARGV-element.
1033:
1034: /* Check whether the ARGV-element is a long option.
1035:
1036: If long_only and the ARGV-element has the form "-f", where f is
1037: a valid short option, don't consider it an abbreviated form of
1038: a long option that starts with f. Otherwise there would be no
1039: way to give the -f short option.
1040:
1041: On the other hand, if there's a long option "fubar" and
1042: the ARGV-element is "-fu", do consider that an abbreviation of
1043: the long option, just like "--fu", and not "-f" with arg "u".
1044:
1045: This distinction seems to be the most useful approach. */
1046: if ((long_options != null)
1047: && (argv[optind].startsWith("--") || (long_only && ((argv[optind]
1048: .length() > 2) || (optstring
1049: .indexOf(argv[optind].charAt(1)) == -1))))) {
1050: int c = checkLongOption();
1051:
1052: if (longopt_handled)
1053: return (c);
1054:
1055: // Can't find it as a long option. If this is not getopt_long_only,
1056: // or the option starts with '--' or is not a valid short
1057: // option, then it's an error.
1058: // Otherwise interpret it as a short option.
1059: if (!long_only || argv[optind].startsWith("--")
1060: || (optstring.indexOf(nextchar.charAt(0)) == -1)) {
1061: if (opterr) {
1062: if (argv[optind].startsWith("--")) {
1063: Object[] msgArgs = { progname, nextchar };
1064: System.err
1065: .println(MessageFormat
1066: .format(
1067: _messages
1068: .getString("getopt.unrecognized"),
1069: msgArgs));
1070: } else {
1071: Object[] msgArgs = {
1072: progname,
1073: new Character(argv[optind].charAt(0))
1074: .toString(), nextchar };
1075: System.err
1076: .println(MessageFormat
1077: .format(
1078: _messages
1079: .getString("getopt.unrecognized2"),
1080: msgArgs));
1081: }
1082: }
1083:
1084: nextchar = "";
1085: ++optind;
1086: optopt = 0;
1087:
1088: return ('?');
1089: }
1090: } // if (longopts)
1091:
1092: // Look at and handle the next short option-character */
1093: int c = nextchar.charAt(0); //**** Do we need to check for empty str?
1094: if (nextchar.length() > 1)
1095: nextchar = nextchar.substring(1);
1096: else
1097: nextchar = "";
1098:
1099: String temp = null;
1100: if (optstring.indexOf(c) != -1)
1101: temp = optstring.substring(optstring.indexOf(c));
1102:
1103: if (nextchar.equals(""))
1104: ++optind;
1105:
1106: if ((temp == null) || (c == ':')) {
1107: if (opterr) {
1108: if (posixly_correct) {
1109: // 1003.2 specifies the format of this message
1110: Object[] msgArgs = { progname,
1111: new Character((char) c).toString() };
1112: System.err.println(MessageFormat.format(_messages
1113: .getString("getopt.illegal"), msgArgs));
1114: } else {
1115: Object[] msgArgs = { progname,
1116: new Character((char) c).toString() };
1117: System.err.println(MessageFormat.format(_messages
1118: .getString("getopt.invalid"), msgArgs));
1119: }
1120: }
1121:
1122: optopt = c;
1123:
1124: return ('?');
1125: }
1126:
1127: // Convenience. Treat POSIX -W foo same as long option --foo
1128: if ((temp.charAt(0) == 'W') && (temp.length() > 1)
1129: && (temp.charAt(1) == ';')) {
1130: if (!nextchar.equals("")) {
1131: optarg = nextchar;
1132: }
1133: // No further cars in this argv element and no more argv elements
1134: else if (optind == argv.length) {
1135: if (opterr) {
1136: // 1003.2 specifies the format of this message.
1137: Object[] msgArgs = { progname,
1138: new Character((char) c).toString() };
1139: System.err.println(MessageFormat.format(_messages
1140: .getString("getopt.requires2"), msgArgs));
1141: }
1142:
1143: optopt = c;
1144: if (optstring.charAt(0) == ':')
1145: return (':');
1146: else
1147: return ('?');
1148: } else {
1149: // We already incremented `optind' once;
1150: // increment it again when taking next ARGV-elt as argument.
1151: nextchar = argv[optind];
1152: optarg = argv[optind];
1153: }
1154:
1155: c = checkLongOption();
1156:
1157: if (longopt_handled)
1158: return (c);
1159: else
1160: // Let the application handle it
1161: {
1162: nextchar = null;
1163: ++optind;
1164: return ('W');
1165: }
1166: }
1167:
1168: if ((temp.length() > 1) && (temp.charAt(1) == ':')) {
1169: if ((temp.length() > 2) && (temp.charAt(2) == ':'))
1170: // This is an option that accepts and argument optionally
1171: {
1172: if (!nextchar.equals("")) {
1173: optarg = nextchar;
1174: ++optind;
1175: } else {
1176: optarg = null;
1177: }
1178:
1179: nextchar = null;
1180: } else {
1181: if (!nextchar.equals("")) {
1182: optarg = nextchar;
1183: ++optind;
1184: } else if (optind == argv.length) {
1185: if (opterr) {
1186: // 1003.2 specifies the format of this message
1187: Object[] msgArgs = { progname,
1188: new Character((char) c).toString() };
1189: System.err.println(MessageFormat
1190: .format(_messages
1191: .getString("getopt.requires2"),
1192: msgArgs));
1193: }
1194:
1195: optopt = c;
1196:
1197: if (optstring.charAt(0) == ':')
1198: return (':');
1199: else
1200: return ('?');
1201: } else {
1202: optarg = argv[optind];
1203: ++optind;
1204: }
1205:
1206: nextchar = null;
1207: }
1208: }
1209:
1210: return (c);
1211: }
1212:
1213: } // Class Getopt
|