in log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java [333:491]
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());
}
}