aboutsummaryrefslogtreecommitdiff
path: root/kernel/kstd
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-03-20 11:19:05 +0100
committerFelix Morgner <felix.morgner@ost.ch>2026-03-20 11:19:05 +0100
commit4f942e014dab44ccb8850c5921b81d4bd777d831 (patch)
treec496d44a061544a5240aee56616b51801455a851 /kernel/kstd
parent1865f7a162a496592e236ffcff171e7e7bc47ee2 (diff)
downloadteachos-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.cpp137
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);
+ }
}
}
}