in src/com/facebook/buck/core/macros/MacroFinderAutomaton.java [166:279]
private State consumeChar(char c, int index) {
switch (this.state) {
case SEARCHING:
switch (c) {
case '\\':
returnState = State.SEARCHING;
return State.IN_ESCAPE_SEQUENCE;
case '$':
currentResultBuilder =
ImmutableMacroMatchResult.builder().setStartIndex(index).setEscaped(false);
return State.FOUND_DOLLAR;
default:
return State.SEARCHING;
}
case IN_ESCAPE_SEQUENCE:
// We want to capture the escaped macro, but mark it as escaped
switch (c) {
case '$':
currentResultBuilder =
ImmutableMacroMatchResult.builder().setStartIndex(index - 1).setEscaped(true);
return State.FOUND_DOLLAR;
default:
return returnState;
}
case FOUND_DOLLAR:
switch (c) {
case '(':
parenthesesDepth += 1;
return State.READING_MACRO_NAME;
case '\\':
returnState = State.SEARCHING;
return State.IN_ESCAPE_SEQUENCE;
case '$':
currentResultBuilder =
ImmutableMacroMatchResult.builder().setStartIndex(index).setEscaped(false);
return State.FOUND_DOLLAR;
default:
return State.SEARCHING;
}
case READING_MACRO_NAME:
switch (c) {
case ')':
parenthesesDepth -= 1;
currentResultBuilder
.setMacroInput(ImmutableList.of())
.setMacroType(takeBuffer())
.setEndIndex(index + 1);
return State.FOUND_MACRO;
case '\t':
case ' ':
case '\n':
case '\r':
currentResultBuilder.setMacroType(takeBuffer());
return State.READING_ARGS;
default:
buffer.append(c);
return State.READING_MACRO_NAME;
}
case READING_ARGS:
switch (c) {
case ' ':
currentResultBuilder.addMacroInput(takeBuffer());
return State.READING_ARGS;
case '\\':
returnState = State.READING_ARGS;
return State.IN_ESCAPE_ARG_SEQUENCE;
case '\'':
case '"':
startQuote = c;
return State.READING_QUOTED_ARGS;
case '(':
parenthesesDepth += 1;
buffer.append(c);
return State.READING_ARGS;
case ')':
parenthesesDepth -= 1;
if (parenthesesDepth == 0) {
currentResultBuilder.addMacroInput(takeBuffer()).setEndIndex(index + 1);
return State.FOUND_MACRO;
} else {
buffer.append(c);
}
return State.READING_ARGS;
default:
buffer.append(c);
return State.READING_ARGS;
}
case READING_QUOTED_ARGS:
switch (c) {
case '\\':
returnState = State.READING_QUOTED_ARGS;
return State.IN_ESCAPE_ARG_SEQUENCE;
case '"':
case '\'':
if (c == startQuote) {
startQuote = '\0';
return State.READING_ARGS;
} else {
buffer.append(c);
return State.READING_QUOTED_ARGS;
}
default:
buffer.append(c);
return State.READING_QUOTED_ARGS;
}
case IN_ESCAPE_ARG_SEQUENCE:
buffer.append(c);
return returnState;
case FOUND_MACRO:
throw new IllegalStateException(
"The state must be reset to searching before more input may be consumed");
}
throw new IllegalStateException("Unknown state " + state);
}