diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-03-20 11:19:05 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-03-20 11:19:05 +0100 |
| commit | 4f942e014dab44ccb8850c5921b81d4bd777d831 (patch) | |
| tree | c496d44a061544a5240aee56616b51801455a851 /kernel/kstd | |
| parent | 1865f7a162a496592e236ffcff171e7e7bc47ee2 (diff) | |
| download | teachos-4f942e014dab44ccb8850c5921b81d4bd777d831.tar.xz teachos-4f942e014dab44ccb8850c5921b81d4bd777d831.zip | |
kstd: rework formatting to be closer to std
Diffstat (limited to 'kernel/kstd')
| -rw-r--r-- | kernel/kstd/print.cpp | 137 |
1 files changed, 88 insertions, 49 deletions
diff --git a/kernel/kstd/print.cpp b/kernel/kstd/print.cpp index c7d26ba..44f80a7 100644 --- a/kernel/kstd/print.cpp +++ b/kernel/kstd/print.cpp @@ -70,74 +70,113 @@ namespace kstd::os auto writer = write_buffer{(sink == print_sink::stderr) ? kapi::cio::output_stream::stderr : kapi::cio::output_stream::stdout}; auto context = kstd::format_context{.writer = write_buffer::callback, .user_data = &writer}; + auto parse_context = kstd::format_parse_context{format, args.size()}; - auto current = format.begin(); - auto end = format.end(); - auto next_automatic_index = 0uz; + auto it = parse_context.begin(); + auto end = parse_context.end(); - while (current != end) + while (it != end) { - if (*current != '{') + if (*it != '{' && *it != '}') { - auto start = current; - while (current != end && *current != '{') + auto start = it; + while (it != end && *it != '{' && *it != '}') { - std::advance(current, 1); + std::advance(it, 1); } - context.push(std::string_view(start, current - start)); + parse_context.advance_to(it); + context.push(std::string_view(start, it - start)); continue; } - if (std::next(current) != end && *(std::next(current)) == '{') + if (*it == '{') { - context.push('{'); - std::advance(current, 2); - continue; - } + std::advance(it, 1); + if (it != end && *it == '{') + { + context.push('{'); + std::advance(it, 1); + parse_context.advance_to(it); + continue; + } - std::advance(current, 1); + parse_context.advance_to(it); + auto index = 0uz; - auto index = 0uz; - if (current != end && *current >= '0' && *current <= '9') - { - while (current != end && *current >= '0' && *current <= '9') + if (it != end && *it >= '0' && *it <= '9') { - index = index * 10 + static_cast<std::size_t>(*current - '0'); - std::advance(current, 1); + while (it != end && *it >= '0' && *it <= '9') + { + index = index * 10 + static_cast<std::size_t>(*it - '0'); + std::advance(it, 1); + } + parse_context.check_arg_id(index); + } + else + { + index = parse_context.next_arg_id(); } - } - else - { - index = next_automatic_index++; - } - auto remaining_fmt = std::string_view{current, static_cast<std::size_t>(std::distance(current, end))}; + if (it != end && *it == ':') + { + std::advance(it, 1); + } - auto const arg = args.get(index); - if (arg.format) - { - auto const after_specs = arg.format(arg.value, remaining_fmt, context); - auto const consumed = remaining_fmt.size() - after_specs.size(); - std::advance(current, consumed); - } - else - { - context.push("{?}"); - while (current != end && *current != '}') - std::advance(current, 1); - } + parse_context.advance_to(it); - if (current != end && *current == '}') - { - std::advance(current, 1); + if (index < args.size()) + { + auto const & arg = args[index]; + if (arg.format_function) + { + arg.format_function(arg.value_pointer, parse_context, context); + } + else + { + context.push("{?}"); + } + } + else + { + context.push("{fmt-err: bound}"); + } + + it = parse_context.begin(); + + if (it != end && *it == '}') + { + std::advance(it, 1); + parse_context.advance_to(it); + } + else + { + context.push("{fmt-err: unconsumed}"); + while (it != end && *it != '}') + { + std::advance(it, 1); + } + + if (it != end) + { + std::advance(it, 1); + parse_context.advance_to(it); + } + } } - else + else if (*it == '}') { - context.push("{fmt-err}"); - while (current != end && *current != '}') - std::advance(current, 1); - if (current != end) - std::advance(current, 1); + std::advance(it, 1); + if (it != end && *it == '}') + { + context.push('}'); + std::advance(it, 1); + parse_context.advance_to(it); + } + else + { + context.push("{fmt-err: unescaped}"); + parse_context.advance_to(it); + } } } } |
