in log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java [348:566]
public void parse(
final String pattern,
final List<PatternConverter> patternConverters,
final List<FormattingInfo> formattingInfos,
final boolean disableAnsi,
final boolean noConsoleNoAnsi,
final boolean convertBackslashes) {
Objects.requireNonNull(pattern, "pattern");
final StringBuilder currentLiteral = new StringBuilder(BUF_SIZE);
final int patternLength = pattern.length();
ParserState state = ParserState.LITERAL_STATE;
char c;
int i = 0;
FormattingInfo formattingInfo = FormattingInfo.getDefault();
while (i < patternLength) {
c = pattern.charAt(i++);
switch (state) {
case LITERAL_STATE:
// In literal state, the last char is always a literal.
if (i == patternLength) {
currentLiteral.append(c);
continue;
}
if (c == ESCAPE_CHAR) {
// peek at the next char.
switch (pattern.charAt(i)) {
case ESCAPE_CHAR:
currentLiteral.append(c);
i++; // move pointer
break;
default:
if (currentLiteral.length() != 0) {
patternConverters.add(
literalPattern(currentLiteral.toString(), convertBackslashes));
formattingInfos.add(FormattingInfo.getDefault());
}
currentLiteral.setLength(0);
currentLiteral.append(c); // append %
state = ParserState.CONVERTER_STATE;
formattingInfo = FormattingInfo.getDefault();
}
} else {
currentLiteral.append(c);
}
break;
case CONVERTER_STATE:
currentLiteral.append(c);
switch (c) {
case '0':
// a '0' directly after the % sign indicates zero-padding
formattingInfo = new FormattingInfo(
formattingInfo.isLeftAligned(),
formattingInfo.getMinLength(),
formattingInfo.getMaxLength(),
formattingInfo.isLeftTruncate(),
true);
break;
case '-':
formattingInfo = new FormattingInfo(
true,
formattingInfo.getMinLength(),
formattingInfo.getMaxLength(),
formattingInfo.isLeftTruncate(),
formattingInfo.isZeroPad());
break;
case '.':
state = ParserState.DOT_STATE;
break;
default:
if (c >= '0' && c <= '9') {
formattingInfo = new FormattingInfo(
formattingInfo.isLeftAligned(),
c - '0',
formattingInfo.getMaxLength(),
formattingInfo.isLeftTruncate(),
formattingInfo.isZeroPad());
state = ParserState.MIN_STATE;
} else {
i = finalizeConverter(
c,
pattern,
i,
currentLiteral,
formattingInfo,
converterRules,
patternConverters,
formattingInfos,
disableAnsi,
noConsoleNoAnsi,
convertBackslashes);
// Next pattern is assumed to be a literal.
state = ParserState.LITERAL_STATE;
formattingInfo = FormattingInfo.getDefault();
currentLiteral.setLength(0);
}
} // switch
break;
case MIN_STATE:
currentLiteral.append(c);
if (c >= '0' && c <= '9') {
// Multiply the existing value and add the value of the number just encountered.
formattingInfo = new FormattingInfo(
formattingInfo.isLeftAligned(),
formattingInfo.getMinLength() * DECIMAL + c - '0',
formattingInfo.getMaxLength(),
formattingInfo.isLeftTruncate(),
formattingInfo.isZeroPad());
} else if (c == '.') {
state = ParserState.DOT_STATE;
} else {
i = finalizeConverter(
c,
pattern,
i,
currentLiteral,
formattingInfo,
converterRules,
patternConverters,
formattingInfos,
disableAnsi,
noConsoleNoAnsi,
convertBackslashes);
state = ParserState.LITERAL_STATE;
formattingInfo = FormattingInfo.getDefault();
currentLiteral.setLength(0);
}
break;
case DOT_STATE:
currentLiteral.append(c);
switch (c) {
case '-':
formattingInfo = new FormattingInfo(
formattingInfo.isLeftAligned(),
formattingInfo.getMinLength(),
formattingInfo.getMaxLength(),
false,
formattingInfo.isZeroPad());
break;
default:
if (c >= '0' && c <= '9') {
formattingInfo = new FormattingInfo(
formattingInfo.isLeftAligned(),
formattingInfo.getMinLength(),
c - '0',
formattingInfo.isLeftTruncate(),
formattingInfo.isZeroPad());
state = ParserState.MAX_STATE;
} else {
LOGGER.error("Error occurred in position " + i
+ ".\n Was expecting digit, instead got char \"" + c + "\".");
state = ParserState.LITERAL_STATE;
}
}
break;
case MAX_STATE:
currentLiteral.append(c);
if (c >= '0' && c <= '9') {
// Multiply the existing value and add the value of the number just encountered.
formattingInfo = new FormattingInfo(
formattingInfo.isLeftAligned(),
formattingInfo.getMinLength(),
formattingInfo.getMaxLength() * DECIMAL + c - '0',
formattingInfo.isLeftTruncate(),
formattingInfo.isZeroPad());
} else {
i = finalizeConverter(
c,
pattern,
i,
currentLiteral,
formattingInfo,
converterRules,
patternConverters,
formattingInfos,
disableAnsi,
noConsoleNoAnsi,
convertBackslashes);
state = ParserState.LITERAL_STATE;
formattingInfo = FormattingInfo.getDefault();
currentLiteral.setLength(0);
}
break;
} // switch
}
// while
if (currentLiteral.length() != 0) {
patternConverters.add(literalPattern(currentLiteral.toString(), convertBackslashes));
formattingInfos.add(FormattingInfo.getDefault());
}
}