int ch = ci.peekCh();
if (ch == '#') {
ci.nextCh();
String parameter = parseParameter(ci);
if (ci.nextCh() != '}') {
throw new ShellSyntaxException("Unmatched \"{\"");
}
String value = variable(parameter);
return (value != null) ? Integer.toString(value.length()) : "0";
}
String parameter = parseParameter(ci);
ch = ci.nextCh();
int operator = NONE;
switch (ch) {
case -1:
throw new ShellSyntaxException("Unmatched \"{\"");
case '}':
break;
case '#':
if (ci.peekCh() == '#') {
ci.nextCh();
operator = DHASH;
} else {
operator = HASH;
}
break;
case '%':
if (ci.peekCh() == '%') {
ci.nextCh();
operator = DPERCENT;
} else {
operator = PERCENT;
}
break;
case ':':
switch (ci.peekCh()) {
case '=':
operator = COLONEQUALS;
break;
case '+':
operator = COLONPLUS;
break;
case '?':
operator = COLONQUERY;
break;
case '-':
operator = COLONMINUS;
break;
default:
throw new ShellSyntaxException("bad substitution operator");
}
ci.nextCh();
break;
case '=':
operator = EQUALS;
break;
case '?':
operator = QUERY;
break;
case '+':
operator = PLUS;
break;
case '-':
operator = MINUS;
break;
default:
throw new ShellSyntaxException("unrecognized substitution operator (\"" + (char) ch + "\")");
}
String value = variable(parameter);
if (operator == NONE) {
return (value != null) ? value : "";
}
String word = dollarBacktickExpand(ci, '}').toString();
if (ci.nextCh() != '}') {
throw new ShellSyntaxException("Unmatched \"{\"");
}
switch (operator) {
case MINUS:
return (value == null) ? word : value;
case COLONMINUS: