in src/log4net/Util/PatternParser.cs [183:302]
private void ParseInternal(string pattern, string[] matches)
{
int offset = 0;
while(offset < pattern.Length)
{
int i = pattern.IndexOf('%', offset);
if (i < 0 || i == pattern.Length - 1)
{
ProcessLiteral(pattern.Substring(offset));
offset = pattern.Length;
}
else
{
if (pattern[i+1] == '%')
{
// Escaped
ProcessLiteral(pattern.Substring(offset, i - offset + 1));
offset = i + 2;
}
else
{
ProcessLiteral(pattern.Substring(offset, i - offset));
offset = i + 1;
FormattingInfo formattingInfo = new FormattingInfo();
// Process formatting options
// Look for the align flag
if (offset < pattern.Length)
{
if (pattern[offset] == '-')
{
// Seen align flag
formattingInfo.LeftAlign = true;
offset++;
}
}
// Look for the minimum length
while (offset < pattern.Length && char.IsDigit(pattern[offset]))
{
// Seen digit
if (formattingInfo.Min < 0)
{
formattingInfo.Min = 0;
}
formattingInfo.Min = (formattingInfo.Min * 10) + int.Parse(pattern[offset].ToString(), NumberFormatInfo.InvariantInfo);
offset++;
}
// Look for the separator between min and max
if (offset < pattern.Length)
{
if (pattern[offset] == '.')
{
// Seen separator
offset++;
}
}
// Look for the maximum length
while (offset < pattern.Length && char.IsDigit(pattern[offset]))
{
// Seen digit
if (formattingInfo.Max == int.MaxValue)
{
formattingInfo.Max = 0;
}
formattingInfo.Max = (formattingInfo.Max * 10) + int.Parse(pattern[offset].ToString(), NumberFormatInfo.InvariantInfo);
offset++;
}
int remainingStringLength = pattern.Length - offset;
// Look for pattern
for(int m=0; m<matches.Length; m++)
{
string key = matches[m];
if (key.Length <= remainingStringLength)
{
if (string.Compare(pattern, offset, key, 0, key.Length) == 0)
{
// Found match
offset = offset + matches[m].Length;
string option = null;
// Look for option
if (offset < pattern.Length)
{
if (pattern[offset] == '{')
{
// Seen option start
offset++;
int optEnd = pattern.IndexOf('}', offset);
if (optEnd < 0)
{
// error
}
else
{
option = pattern.Substring(offset, optEnd - offset);
offset = optEnd + 1;
}
}
}
ProcessConverter(matches[m], option, formattingInfo);
break;
}
}
}
}
}
}
}