#include "kapi/cio.hpp" #include #include #include #include #include #include #include #include namespace kstd::os { namespace { struct write_buffer final : kstd::bits::format::output_buffer { using output_stream = kapi::cio::output_stream; constexpr auto static size = 128uz; write_buffer(write_buffer const &) = delete; write_buffer(write_buffer &&) = delete; auto operator=(write_buffer const &) -> write_buffer & = delete; auto operator=(write_buffer &&) -> write_buffer & = delete; explicit write_buffer(output_stream stream) : m_stream{stream} {} ~write_buffer() noexcept final { flush(); } auto flush() noexcept -> void { if (m_position > 0) { std::string_view chunk{m_buffer.data(), m_position}; kapi::cio::write(m_stream, chunk); m_position = 0; } } auto push(std::string_view text) -> void final { std::ranges::for_each(text, [this](auto c) { this->push(c); }); } auto push(char character) -> void final { if (m_position >= size) { flush(); } m_buffer.at(m_position++) = character; } private: output_stream m_stream; std::array m_buffer{}; std::size_t m_position{}; }; } // namespace auto vprint(print_sink sink, std::string_view format, kstd::format_args args) -> void { auto writer = write_buffer{(sink == print_sink::stderr) ? kapi::cio::output_stream::stderr : kapi::cio::output_stream::stdout}; kstd::bits::format::vformat_to(writer, format, args); // auto context = kstd::format_context{.writer = write_buffer::callback, .user_data = &writer, .args = args}; // auto parse_context = kstd::format_parse_context{format, args.size()}; // auto it = parse_context.begin(); // auto end = parse_context.end(); // while (it != end) // { // if (*it != '{' && *it != '}') // { // auto start = it; // while (it != end && *it != '{' && *it != '}') // { // std::advance(it, 1); // } // parse_context.advance_to(it); // context.push(std::string_view(start, it - start)); // continue; // } // if (*it == '{') // { // std::advance(it, 1); // if (it != end && *it == '{') // { // context.push('{'); // std::advance(it, 1); // parse_context.advance_to(it); // continue; // } // parse_context.advance_to(it); // auto index = 0uz; // if (it != end && *it >= '0' && *it <= '9') // { // while (it != end && *it >= '0' && *it <= '9') // { // index = index * 10 + static_cast(*it - '0'); // std::advance(it, 1); // } // parse_context.check_arg_id(index); // } // else // { // index = parse_context.next_arg_id(); // } // if (it != end && *it == ':') // { // std::advance(it, 1); // } // parse_context.advance_to(it); // if (index < args.size()) // { // auto const & arg = args[index]; // switch (arg.type) // { // case kstd::bits::format::arg_type::boolean: // { // auto fmt = kstd::formatter{}; // auto const parsed = fmt.parse(parse_context); // parse_context.advance_to(parsed); // fmt.format(arg.value.boolean, context); // break; // } // case kstd::bits::format::arg_type::character: // { // auto fmt = kstd::formatter{}; // auto const parsed = fmt.parse(parse_context); // parse_context.advance_to(parsed); // fmt.format(arg.value.character, context); // break; // } // case kstd::bits::format::arg_type::integer: // { // auto fmt = kstd::formatter{}; // auto const parsed = fmt.parse(parse_context); // parse_context.advance_to(parsed); // fmt.format(arg.value.integer, context); // break; // } // case kstd::bits::format::arg_type::unsigned_integer: // { // auto fmt = kstd::formatter{}; // auto const parsed = fmt.parse(parse_context); // parse_context.advance_to(parsed); // fmt.format(arg.value.unsigned_integer, context); // break; // } // case kstd::bits::format::arg_type::string_view: // { // auto fmt = kstd::formatter{}; // auto const parsed = fmt.parse(parse_context); // parse_context.advance_to(parsed); // fmt.format(arg.value.string_view, context); // break; // } // case kstd::bits::format::arg_type::c_string: // { // auto fmt = kstd::formatter{}; // auto const parsed = fmt.parse(parse_context); // parse_context.advance_to(parsed); // fmt.format(arg.value.c_string, context); // break; // } // case kstd::bits::format::arg_type::pointer: // { // auto fmt = kstd::formatter{}; // auto const parsed = fmt.parse(parse_context); // parse_context.advance_to(parsed); // fmt.format(arg.value.pointer, context); // break; // } // case kstd::bits::format::arg_type::user_defined: // { // if (arg.value.user_defined.format) // { // arg.value.user_defined.format(arg.value.user_defined.pointer, parse_context, context); // } // else // { // context.push("{?}"); // } // break; // } // default: // { // context.push("{fmt-err: unknown-type}"); // break; // } // } // } // 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 if (*it == '}') // { // 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); // } // } // } } } // namespace kstd::os