/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @author jrose
*/
public class CommandLineParser {
}
// Convert options string into optLines dictionary.
continue loadOptmap;
}
}
continue loadOptmap;
}
throw new RuntimeException("duplicate option: "
}
}
}
}
}
}
/**
* Remove a set of command-line options from args,
* storing them in the properties map in a canonicalized form.
*/
//System.out.println(args+" // "+properties);
// State machine for parsing a command line.
for (;;) {
// One trip through this loop per argument.
// Multiple trips per option only if several options per argument.
if (pbp.hasPrevious()) {
} else {
// No more arguments at all.
break doArgs;
}
// One time through this loop for each matching arg prefix.
// Match some prefix of the argument to a key in optmap.
for (;;) {
break findOpt;
}
if (optlen == 0) {
break tryOpt;
}
// Decide on a smaller prefix to search for.
// pfxmap.lastKey is no shorter than any prefix in optmap.
// (Note: We could cut opt down to its common prefix with
// pfxmap.lastKey, but that wouldn't save many cycles.)
}
// Execute the option processing specs for this opt.
// If no actions are taken, then look for a shorter prefix.
boolean didAction = false;
boolean isError = false;
continue eachSpec;
}
break eachSpec;
}
int sidx = 0;
// Deal with '+'/'*' prefixes (spec conditions).
boolean ok;
switch (specop) {
case '+':
// + means we want an non-empty val suffix.
break;
case '*':
// * means we accept empty or non-empty
ok = true;
break;
default:
// No condition prefix means we require an exact
// match, as indicated by an empty val suffix.
break;
}
if (!ok) {
continue eachSpec;
}
switch (specop) {
case '.': // terminate the option sequence
break doArgs;
case '?': // abort the option sequence
isError = true;
break eachSpec;
case '@': // change the effective opt name
break;
case '>': // shift remaining arg val to next arg
val = "";
break;
case '!': // negation option
didAction = true;
break;
case '$': // normal "boolean" option
// If there is a given spec token, store it.
} else {
boolval = "1";
} else {
// Increment any previous value as a numeral.
}
}
didAction = true;
break;
case '=': // "string" option
case '&': // "collection" option
// Read an option.
if (pbp.hasPrevious()) {
} else {
isError = true;
break eachSpec;
}
if (append) {
// Append new val to old with embedded delim.
delim = " ";
}
}
}
didAction = true;
break;
default:
throw new RuntimeException("bad spec for "
}
}
// Done processing specs.
continue doArgs;
}
// The specs should have done something, but did not.
// Remove anything pushed during these specs.
}
if (isError) {
throw new IllegalArgumentException(resultString);
}
if (optlen == 0) {
// We cannot try a shorter matching option.
break tryOpt;
}
}
// If we come here, there was no matching option.
// So, push back the argument, and return to caller.
break doArgs;
}
// Report number of arguments consumed.
// Report any unconsumed partial argument.
while (pbp.hasPrevious()) {
}
//System.out.println(args+" // "+properties+" -> "+resultString);
return resultString;
}
}