520 static std::vector<FormatInstruction>
compile(
521 const std::string& pattern,
524 std::vector<FormatInstruction> instructions;
526 buffer.reserve(pattern.size());
527 bool strip_ansi =
false;
529 for (
size_t i = 0; i < pattern.size(); ++i) {
533 if (!buffer.empty()) {
539 bool left_align =
false;
540 bool center_align =
false;
541 bool truncate =
false;
545 while ((i + 1) < pattern.size() && (
546 std::isdigit(pattern[i + 1]) ||
547 pattern[i + 1] ==
'-' ||
548 pattern[i + 1] ==
'=')) {
549 char next = pattern[++i];
552 }
else if (next ==
'=') {
554 }
else if (std::isdigit(next)) {
555 width = width * 10 + (next -
'0');
559 if ((i + 1) < pattern.size() && pattern[i + 1] ==
'!') {
566 if ((i + 1) < pattern.size()) {
567 char next = pattern[++i];
571 instructions.emplace_back(context, FormatType::Year, width, left_align, center_align, truncate, strip_ansi);
574 if ((i + 1) < pattern.size() && pattern[i + 1] ==
's') {
575 instructions.emplace_back(context, FormatType::MilliSecondTimeStamp, width, left_align, center_align, truncate, strip_ansi);
579 instructions.emplace_back(context, FormatType::Month, width, left_align, center_align, truncate, strip_ansi);
582 instructions.emplace_back(context, FormatType::Day, width, left_align, center_align, truncate, strip_ansi);
585 instructions.emplace_back(context, FormatType::Hour, width, left_align, center_align, truncate, strip_ansi);
588 instructions.emplace_back(context, FormatType::Minute, width, left_align, center_align, truncate, strip_ansi);
591 if ((i + 1) < pattern.size() && pattern[i + 1] ==
'C') {
596 instructions.emplace_back(context, FormatType::Second, width, left_align, center_align, truncate, strip_ansi);
599 if ((i + 1) < pattern.size() && pattern[i + 1] ==
'c') {
604 instructions.emplace_back(context, FormatType::Millisecond, width, left_align, center_align, truncate, strip_ansi);
607 instructions.emplace_back(context, FormatType::TwoDigitYear, width, left_align, center_align, truncate, strip_ansi);
610 instructions.emplace_back(context, FormatType::DateTime, width, left_align, center_align, truncate, strip_ansi);
613 instructions.emplace_back(context, FormatType::ShortDate, width, left_align, center_align, truncate, strip_ansi);
617 instructions.emplace_back(context, FormatType::TimeISO8601, width, left_align, center_align, truncate, strip_ansi);
620 instructions.emplace_back(context, FormatType::DateISO8601, width, left_align, center_align, truncate, strip_ansi);
623 if ((i + 1) < pattern.size() && pattern[i + 1] ==
'c') {
628 instructions.emplace_back(context, FormatType::TimeStamp, width, left_align, center_align, truncate, strip_ansi);
632 if ((i + 1) < pattern.size() && pattern[i + 1] ==
'C') {
637 instructions.emplace_back(context, FormatType::TimeStamp, width, left_align, center_align, truncate, strip_ansi);
641 if ((i + 1) < pattern.size() && pattern[i + 1] ==
's') {
642 instructions.emplace_back(context, FormatType::FileName, width, left_align, center_align, truncate, strip_ansi);
646 instructions.emplace_back(context, FormatType::AbbreviatedMonthName, width, left_align, center_align, truncate, strip_ansi);
649 instructions.emplace_back(context, FormatType::FullMonthName, width, left_align, center_align, truncate, strip_ansi);
652 instructions.emplace_back(context, FormatType::AbbreviatedWeekdayName, width, left_align, center_align, truncate, strip_ansi);
655 instructions.emplace_back(context, FormatType::FullWeekdayName, width, left_align, center_align, truncate, strip_ansi);
660 instructions.emplace_back(context, FormatType::LogLevel, width, left_align, center_align, truncate, strip_ansi);
663 instructions.emplace_back(context, FormatType::ShortLogLevel, width, left_align, center_align, truncate, strip_ansi);
668 instructions.emplace_back(context, FormatType::ThreadId, width, left_align, center_align, truncate, strip_ansi);
673 if ((i + 1) < pattern.size() && pattern[i + 1] ==
'{') {
674 size_t end = pattern.find(
'}', i + 2);
675 if (end != std::string::npos) {
676 std::string key = pattern.substr(i + 2, end - i - 2);
677 instructions.emplace_back(context, FormatType::MappedDiagnosticContextValue, width, left_align, center_align, truncate, strip_ansi, key);
682 instructions.emplace_back(context, FormatType::MappedDiagnosticContext, width, left_align, center_align, truncate, strip_ansi);
685 instructions.emplace_back(context, FormatType::NestedDiagnosticContext, width, left_align, center_align, truncate, strip_ansi);
690 if ((i + 1) < pattern.size() && pattern[i + 1] ==
'f' && (i + 2) < pattern.size() && pattern[i + 2] ==
'n') {
691 instructions.emplace_back(context, FormatType::FullFileName, width, left_align, center_align, truncate, strip_ansi);
695 if ((i + 1) < pattern.size() && pattern[i + 1] ==
'n') {
696 instructions.emplace_back(context, FormatType::FileName, width, left_align, center_align, truncate, strip_ansi);
700 instructions.emplace_back(context, FormatType::FileName, width, left_align, center_align, truncate, strip_ansi);
703 instructions.emplace_back(context, FormatType::FullFileName, width, left_align, center_align, truncate, strip_ansi);
706 instructions.emplace_back(context, FormatType::SourceFileAndLine, width, left_align, center_align, truncate, strip_ansi);
709 instructions.emplace_back(context, FormatType::LineNumber, width, left_align, center_align, truncate, strip_ansi);
712 instructions.emplace_back(context, FormatType::FunctionName, width, left_align, center_align, truncate, strip_ansi);
717 instructions.emplace_back(context, FormatType::StartColor, 0,
false,
false,
false, strip_ansi);
720 instructions.emplace_back(context, FormatType::EndColor, 0,
false,
false,
false, strip_ansi);
725 instructions.emplace_back(context, FormatType::Message, width, left_align, center_align, truncate, strip_ansi);
730 if ((i + 2) < pattern.size() && pattern[i + 1] ==
'(') {
731 size_t end = pattern.find(
')', i + 2);
732 if (end == std::string::npos) {
736 std::string params = pattern.substr(i + 2, end - i - 2);
737 auto no_args_instructions =
compile(params, CompileContext::NoArgsFallback);
738 instructions.insert(instructions.end(), no_args_instructions.begin(), no_args_instructions.end());
755 if (!buffer.empty()) {