in flex-compiler-oem/src/main/java/flex2/compiler/config/CommandLineConfigurator.java [55:327]
public static void parse( final ConfigurationBuffer buffer,
final String defaultvar,
final String[] args)
throws ConfigurationException
{
assert defaultvar == null || buffer.isValidVar( defaultvar ) : "coding error: config must provide default var " + defaultvar;
Map<String, String> aliases = getAliases( buffer );
final int START = 1;
final int ARGS = 2;
final int EXEC = 3;
final int DONE = 4;
int i = 0, iStart = 0, iEnd = 0;
String var = null;
int varArgCount = -2;
List<String> argList = new LinkedList<String>();
Set<String> vars = new HashSet<String>();
boolean append = false;
boolean dash = true;
int mode = START;
while (mode != DONE)
{
switch (mode)
{
case START:
{
iStart = i;
if (args.length == i)
{
mode = DONE;
break;
}
// expect -var, --, or the beginning of default args
mode = ARGS;
varArgCount = -2;
if (args[i].equals("--"))
{
dash = false;
if (defaultvar != null)
var = defaultvar;
else
mode = START;
++i;
}
else if (dash && args[i].startsWith("+"))
{
String token = null;
int c = (args[i].length() > 1 && args[i].charAt( 1 ) == '+')? 2 : 1; // gnu-style?
int equals = args[i].indexOf( '=' );
String rest = null;
if (equals != -1)
{
rest = args[i].substring( equals + 1 );
token = args[i++].substring( c, equals );
}
else
{
token = args[i++].substring( c );
}
if (equals != -1)
{
iEnd = i;
buffer.setToken( token, rest );
buffer.addPosition(token, iStart, iEnd);
}
else
{
if (i == args.length)
{
throw new ConfigurationException.Token( ConfigurationException.Token.INSUFFICIENT_ARGS,
token, var, source, -1 );
}
rest = args[i++];
iEnd = i;
buffer.setToken( token, rest );
buffer.addPosition(token, iStart, iEnd);
}
mode = START;
break;
}
else if (dash && isAnArgument(args[i]))
{
int c = (args[i].length() > 1 && args[i].charAt( 1 ) == '-')? 2 : 1; // gnu-style?
int plusequals = args[i].indexOf( "+=" );
int equals = args[i].indexOf( '=' );
String rest = null;
if (plusequals != -1)
{
rest = args[i].substring( plusequals + 2 );
var = args[i++].substring( c, plusequals );
append = true;
}
else if (equals != -1)
{
rest = args[i].substring( equals + 1 );
var = args[i++].substring( c, equals );
}
else
{
var = args[i++].substring( c );
}
if (aliases.containsKey( var ))
var = aliases.get( var );
if (!buffer.isValidVar( var ))
{
throw new ConfigurationException.UnknownVariable( var, source, -1 );
}
if (equals != -1)
{
if ((rest == null) || (rest.length() == 0))
{
iEnd = i;
buffer.clearVar( var, source, -1 );
buffer.addPosition(var, iStart, iEnd);
mode = START;
}
else
{
String seps = null;
if (buffer.getInfo(var).isPath())
{
seps = "[," + File.pathSeparatorChar + "]";
}
else {
seps = ",";
}
String[] tokens = rest.split(seps);
argList.addAll(Arrays.asList(tokens));
varArgCount = buffer.getVarArgCount( var );
mode = EXEC;
}
}
}
else
{
// asdoc sets default var as no-default-arg - it has no default vars
if (defaultvar != null && !defaultvar.equals("no-default-arg"))
{
// don't increment i, let ARGS pick it up.
var = defaultvar;
}
else
{
throw new ConfigurationException.UnexpectedDefaults( null, null, -1 );
}
}
break;
}
case ARGS:
{
if (varArgCount == -2)
{
if (isBoolean( buffer, var ))
{
varArgCount = 0;
mode = EXEC;
break;
}
else
{
varArgCount = buffer.getVarArgCount( var );
}
}
assert varArgCount >= -1; // just in case the getVarArgCount author was insane.
if (args.length == i)
{
mode = EXEC;
break;
}
boolean greedy = buffer.getInfo( var ).isGreedy();
// accumulating non-command arguments...
// check for a terminator on our accumulated parameter list
if (!greedy && dash && isAnArgument(args[i]))
{
if (varArgCount == -1)
{
// we were accumulating an unlimited set of args, a new var terminates that.
mode = EXEC;
break;
}
throw new ConfigurationException.IncorrectArgumentCount( varArgCount, argList.size(), var, source, -1 );
}
// this test is a little hairy:
// "The key is that the parameter before the "default" parameter takes an
// unlimited number of parameters: mxmlc -rsl 1.swf 2.swf test.mxml" -dloverin
if ((varArgCount == -1)
&& !greedy
&& (defaultvar != null)
&& !defaultvar.equals(var)
&& !vars.contains( defaultvar )
&& ((args.length - i) > 1)
&& buffer.getInfo( defaultvar ) != null)
{
// look for a terminating argument, if none,
// then the end of the list cannot be determined (it's ambiguous)
boolean ok = false;
for (int j = i + 1; j < args.length; ++j)
{
if (dash && isAnArgument(args[j]))
{
ok = true;
break;
}
}
if (!ok)
{
throw new ConfigurationException.AmbiguousParse( defaultvar, var, source, -1 );
}
}
argList.add( args[i++] );
if (argList.size() == varArgCount)
{
mode = EXEC;
}
break;
}
case EXEC:
{
if ((varArgCount != -1) && (argList.size() != varArgCount))
{
throw new ConfigurationException.IncorrectArgumentCount( varArgCount, argList.size(), var, source, -1 );
}
if (varArgCount == 0) // boolean flag fakery...
argList.add( "true" );
if (vars.contains( var ))
{
if ((defaultvar != null) && (var != null) && var.equals( defaultvar ))
{
// we could perhaps accumulate the defaults spread out through
// the rest of the flags, but for now we'll call this illegal.
throw new ConfigurationException.InterspersedDefaults( var, source, -1 );
}
}
iEnd = i;
buffer.setVar( var, new LinkedList<String>( argList ), source, -1, null, append );
buffer.addPosition(var, iStart, iEnd);
append = false;
vars.add( var );
argList.clear();
mode = START;
break;
}
case DONE:
{
assert false;
break;
}
}
}
}