Created
April 17, 2019 00:34
-
-
Save luisenriquecorona/c8a6126df722a0e1aebc945946c7af16 to your computer and use it in GitHub Desktop.
A class to implement Unix-style (single-character) command-line argument parsing. Originally patterned after (but not using code from) the Unix getopt(3) program, this has been redesigned to be more Java-friendly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.darwinsys.lang; | |
import com.darwinsys.util.Debug; | |
import java.util.Map; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.ArrayList; | |
import java.util.Iterator; | |
/** A class to implement Unix-style (single-character) command-line argument | |
* parsing. Originally patterned after (but not using code from) the Unix | |
* getopt(3) program, this has been redesigned to be more Java-friendly. | |
* <p> | |
* This is <em>not</em> threadsafe; it is expected to be used only from main( ). | |
* <p> | |
* For another way of dealing with command lines, see the | |
* <a href="http://jakarta.apache.org/commons/cli/">Jakarta Commons | |
* Command Line Interface</a>. | |
* @author Ian F. Darwin, [email protected] | |
* @version $Id: ch02,v 1.4 2004/05/04 20:11:12 ian Exp $ | |
*/ | |
public class GetOpt { | |
/** The list of file names found after args */ | |
protected List fileNameArguments; | |
/** The set of characters to look for */ | |
protected GetOptDesc[] options; | |
/** Where we are in the options */ | |
protected int optind = 0; | |
/** Public constant for "no more options" */ | |
public static final int DONE = 0; | |
/** Internal flag - whether we are done all the options */ | |
protected boolean done = false; | |
/** The current option argument. */ | |
protected String optarg; | |
/** Retrieve the current option argument */ | |
public String optarg( ) { | |
return optarg; | |
} | |
/* Construct a GetOpt parser, given the option specifications | |
* in an array of GetOptDesc objects. This is the preferred constructor. | |
*/ | |
public GetOpt(GetOptDesc[] options) { | |
this.options = options; | |
} | |
/* Construct a GetOpt parser, storing the set of option characters. | |
* This is a legacy constructor for backward compatibility. | |
*/ | |
public GetOpt(String patt) { | |
// Pass One: just count the letters | |
int n = 0; | |
for (int i = 0; i<patt.length( ); i++) { | |
if (patt.charAt(i) != ':') | |
++n; | |
} | |
if (n == 0) | |
throw new IllegalArgumentException( | |
"No option letters found in " + patt); | |
// Pass Two: construct an array of GetOptDesc objects. | |
options = new GetOptDesc[n]; | |
for (int i = 0, ix = 0; i<patt.length( ); i++) { | |
char c = patt.charAt(i); | |
boolean argTakesValue = false; | |
if (i < patt.length( ) - 1 && patt.charAt(i+1) == ':') { | |
argTakesValue = true; | |
++i; | |
} | |
options[ix++] = new GetOptDesc(c, null, argTakesValue); | |
Debug.println("getopt", | |
"CONSTR: options[" + ix + "] = " + c + ", " + argTakesValue); | |
} | |
} | |
/** Reset this GetOpt parser */ | |
public void rewind( ) { | |
fileNameArguments = null; | |
done = false; | |
optind = 0; | |
} | |
/** Array used to convert a char to a String */ | |
private static char[] strConvArray = { 0 }; | |
/** | |
* Modern way of using GetOpt: call this once and get all options. | |
* <p> | |
* This parses the options and returns a Map whose keys are the found options. | |
* Normally followed by a call to getFilenameList( ). | |
* @return a Map whose keys are Strings of length 1 (containing the char | |
* from the option that was matched) and whose value is a String | |
* containing the value, or null for a non-option argument. | |
*/ | |
public Map parseArguments(String[] argv) { | |
Map optionsAndValues = new HashMap( ); | |
fileNameArguments = new ArrayList( ); | |
for (int i = 0; i < argv.length; i++) { | |
Debug.println("getopt", "parseArg: i=" + i + ": arg " + argv[i]); | |
char c = getopt(argv); | |
if (c != DONE) { | |
strConvArray[0] = c; | |
optionsAndValues.put(new String(strConvArray), optarg); | |
// If this arg takes an option, we must skip it here. | |
if (optarg != null) | |
++i; | |
} else { | |
fileNameArguments.add(argv[i]); | |
} | |
} | |
return optionsAndValues; | |
} | |
/** Get the list of filename-like arguments after options */ | |
public List getFilenameList( ) { | |
if (fileNameArguments == null) { | |
throw new IllegalArgumentException( | |
"Illegal call to getFilenameList( ) before parseOptions( )"); | |
} | |
return fileNameArguments; | |
} | |
/** The true heart of getopt, whether used old way or new way: | |
* returns one argument; call repeatedly until it returns DONE. | |
*/ | |
public char getopt(String argv[]) { | |
Debug.println("getopt", | |
"optind=" + optind + ", argv.length="+argv.length); | |
if (optind == (argv.length)-1) { | |
done = true; | |
} | |
// If we are (now) finished, bail. | |
if (done) { | |
return DONE; | |
} | |
// TODO - two-pass, 1st check long args, 2nd check for | |
// char, may be multi char as in "-no outfile" == "-n -o outfile". | |
// Pick off the next command-line argument; check if it starts "-". | |
// If so, look it up in the list. | |
String thisArg = argv[optind++]; | |
if (thisArg.startsWith("-")) { | |
optarg = null; | |
for (int i=0; i<options.length; i++) { | |
if ( options[i].argLetter == thisArg.charAt(1) || | |
(options[i].argName != null && | |
options[i].argName == thisArg.substring(1))) { // found it | |
// If it needs an option argument, get it. | |
if (options[i].takesArgument) { | |
if (optind < argv.length) { | |
optarg = argv[optind]; | |
++optind; | |
} else { | |
throw new IllegalArgumentException( | |
"Option " + options[i].argLetter + | |
" needs value but found end of arg list"); | |
} | |
} | |
return options[i].argLetter; | |
} | |
} | |
// Began with "-" but not matched, so must be error. | |
return '?'; | |
} else { | |
// Found non-argument non-option word in argv: end of options. | |
done = true; | |
return DONE; | |
} | |
} | |
/** Return optind, the index into args of the last option we looked at */ | |
public int getOptInd( ) { | |
return optind; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment