From d1e190a0f402e94eaa6eaff9a00ac3001ebbaff6 Mon Sep 17 00:00:00 2001 From: Baptiste Wicht Date: Tue, 11 Mar 2014 22:00:40 +0100 Subject: [PATCH] Update printf --- cpp.mk | 4 +- kernel/include/console.hpp | 6 +- kernel/src/console.cpp | 175 +---------------------------- kernel/src/interrupts.cpp | 20 ++-- kernel/src/kalloc.cpp | 22 ++-- kernel/src/kernel_utils.cpp | 2 +- kernel/src/scheduler.cpp | 20 ++-- printf/include/printf_dec.hpp | 20 ++++ printf/include/printf_def.hpp | 205 ++++++++++++++++++++++++++++++++++ tlib/include/print.hpp | 5 +- tlib/src/print.cpp | 195 +------------------------------- 11 files changed, 272 insertions(+), 402 deletions(-) create mode 100644 printf/include/printf_dec.hpp create mode 100644 printf/include/printf_def.hpp diff --git a/cpp.mk b/cpp.mk index d808158d..539864ca 100644 --- a/cpp.mk +++ b/cpp.mk @@ -4,7 +4,7 @@ OC=x86_64-elf-objcopy AR=x86_64-elf-ar WARNING_FLAGS=-Wall -Wextra -pedantic -Wold-style-cast -COMMON_CPP_FLAGS=-masm=intel -I../../tstl/include/ -I../tstl/include/ -I../tlib/include/ -Iinclude/ -nostdlib -g -Os -std=c++11 -fno-stack-protector -fno-exceptions -funsigned-char -fno-rtti -ffreestanding -fomit-frame-pointer -mno-red-zone -mno-3dnow -mno-mmx -fno-asynchronous-unwind-tables +COMMON_CPP_FLAGS=-masm=intel -I../../tstl/include/ -I../printf/include/ -I../tstl/include/ -I../tlib/include/ -Iinclude/ -nostdlib -g -Os -std=c++11 -fno-stack-protector -fno-exceptions -funsigned-char -fno-rtti -ffreestanding -fomit-frame-pointer -mno-red-zone -mno-3dnow -mno-mmx -fno-asynchronous-unwind-tables DISABLE_SSE_FLAGS=-mno-sse -mno-sse2 -mno-sse3 -mno-sse4 -mno-sse4.1 -mno-sse4.2 ENABLE_SSE_FLAGS=-msse -msse2 -msse3 -msse4 -msse4.1 -msse4.2 @@ -25,5 +25,5 @@ KERNEL_LINK_FLAGS=$(COMMON_LINK_FLAGS) -T linker.ld LIB_FLAGS=$(CPP_FLAGS_64) $(WARNING_FLAGS) -mcmodel=small -fPIC -ffunction-sections -fdata-sections LIB_LINK_FLAGS=$(CPP_FLAGS_64) $(WARNING_FLAGS) -mcmodel=small -fPIC -Wl,-gc-sections -PROGRAM_FLAGS=$(CPP_FLAGS_64) $(WARNING_FLAGS) -I../../tlib/include/ -static -L../../tlib/ -ltlib -mcmodel=small -fPIC +PROGRAM_FLAGS=$(CPP_FLAGS_64) $(WARNING_FLAGS) -I../../tlib/include/ -I../../printf/include/ -static -L../../tlib/ -ltlib -mcmodel=small -fPIC PROGRAM_LINK_FLAGS=$(CPP_FLAGS_64) $(WARNING_FLAGS) $(COMMON_LINK_FLAGS) -static -L../../tlib/ -ltlib -mcmodel=small -fPIC -z max-page-size=0x1000 -T ../linker.ld -Wl,-gc-sections diff --git a/kernel/include/console.hpp b/kernel/include/console.hpp index 9bc7c897..7e9b16d2 100644 --- a/kernel/include/console.hpp +++ b/kernel/include/console.hpp @@ -8,6 +8,8 @@ #ifndef CONSOLE_H #define CONSOLE_H +#include + #include #include #include @@ -40,8 +42,6 @@ void k_print(int16_t number); void k_print(int32_t number); void k_print(int64_t number); -void k_printf(const char* fmt, ...); - template typename std::enable_if_t<(sizeof...(Arguments) == 0)> k_print_line(const Arguments&... args){ k_print('\n'); @@ -53,4 +53,6 @@ typename std::enable_if_t<(sizeof...(Arguments) > 0)> k_print_line(const Argumen k_print('\n'); } +#include "printf_dec.hpp" + #endif diff --git a/kernel/src/console.cpp b/kernel/src/console.cpp index bad71d9e..e193b0f9 100644 --- a/kernel/src/console.cpp +++ b/kernel/src/console.cpp @@ -214,177 +214,8 @@ void wipeout(){ current_column = 0; } -void k_printf(const char* fmt, ...){ - va_list va; - va_start(va, fmt); +#include "printf_def.hpp" - char ch; - - while ((ch=*(fmt++))) { - if(ch != '%'){ - k_print(ch); - } else { - ch = *(fmt++); - - size_t min_width = 0; - while(ch >= '0' && ch <= '9'){ - min_width = 10 * min_width + (ch - '0'); - ch = *(fmt++); - } - - size_t min_digits = 0; - if(ch == '.'){ - ch = *(fmt++); - - while(ch >= '0' && ch <= '9'){ - min_digits = 10 * min_digits + (ch - '0'); - ch = *(fmt++); - } - } - - auto prev = current_column; - - //Signed decimal - if(ch == 'd'){ - auto arg = va_arg(va, int64_t); - - if(min_digits > 0){ - size_t d = std::digits(arg); - if(min_digits > d){ - min_digits -= d; - - if(arg < 0){ - arg *= -1; - k_print('-'); - } - - while(min_digits > 0){ - while(min_digits > 0){ - k_print('0'); - --min_digits; - } - } - } - } - - k_print(arg); - } - //Unsigned Decimal - else if(ch == 'u'){ - auto arg = va_arg(va, uint64_t); - - if(min_digits > 0){ - size_t d = std::digits(arg); - if(min_digits > d){ - min_digits -= d; - while(min_digits > 0){ - while(min_digits > 0){ - k_print('0'); - --min_digits; - } - } - } - } - - k_print(arg); - } - //Hexadecimal - else if(ch == 'h'){ - k_print("0x"); - - uint8_t buffer[20]; - - auto arg = va_arg(va, uint64_t); - size_t i = 0; - - while(arg / 16 != 0){ - buffer[i++] = arg % 16; - arg /= 16; - } - - buffer[i] = arg; - - if(min_digits > 0 && min_digits > i){ - min_digits -= i + 1; - while(min_digits > 0){ - k_print('0'); - --min_digits; - } - } - - while(true){ - uint8_t digit = buffer[i]; - - if(digit < 10){ - k_print(static_cast('0' + digit)); - } else { - switch(digit){ - case 10: - k_print('A'); - break; - case 11: - k_print('B'); - break; - case 12: - k_print('C'); - break; - case 13: - k_print('D'); - break; - case 14: - k_print('E'); - break; - case 15: - k_print('F'); - break; - } - } - - if(i == 0){ - break; - } - - --i; - } - } - //Memory - else if(ch == 'm'){ - auto memory= va_arg(va, uint64_t); - - if(memory >= 1024 * 1024 * 1024){ - k_print(memory / (1024 * 1024 * 1024)); - k_print("GiB"); - } else if(memory >= 1024 * 1024){ - k_print(memory / (1024 * 1024)); - k_print("MiB"); - } else if(memory >= 1024){ - k_print(memory / 1024); - k_print("KiB"); - } else { - k_print(memory); - k_print("B"); - } - } - //String - else if(ch == 's'){ - auto arg = va_arg(va, const char*); - k_print(arg); - } - - if(min_width > 0){ - size_t width = current_column - prev; - - if(min_width > width){ - min_width -= width; - - while(min_width > 0){ - k_print(' '); - --min_width; - } - } - } - } - } - - va_end(va); +void __printf(const std::string& str){ + k_print(str); } diff --git a/kernel/src/interrupts.cpp b/kernel/src/interrupts.cpp index 0f802f78..a48b027a 100644 --- a/kernel/src/interrupts.cpp +++ b/kernel/src/interrupts.cpp @@ -224,16 +224,16 @@ const char* exceptions_title[32] { extern "C" { void _fault_handler(interrupt::fault_regs regs){ - k_printf("Exception %u (%s) occured\n", regs.error_no, exceptions_title[regs.error_no]); - k_printf("error_code=%u\n", regs.error_code); - k_printf("rip=%h\n", regs.rip); - k_printf("rflags=%h\n", regs.rflags); - k_printf("cs=%h\n", regs.cs); - k_printf("rsp=%h\n", regs.rsp); - k_printf("ss=%h\n", regs.ss); - k_printf("pid=%u\n", scheduler::get_pid()); - k_printf("cr2=%h\n", get_cr2()); - k_printf("cr3=%h\n", get_cr3()); + printf("Exception %u (%s) occured\n", regs.error_no, exceptions_title[regs.error_no]); + printf("error_code=%u\n", regs.error_code); + printf("rip=%h\n", regs.rip); + printf("rflags=%h\n", regs.rflags); + printf("cs=%h\n", regs.cs); + printf("rsp=%h\n", regs.rsp); + printf("ss=%h\n", regs.ss); + printf("pid=%u\n", scheduler::get_pid()); + printf("cr2=%h\n", get_cr2()); + printf("cr3=%h\n", get_cr3()); //TODO Improve that with kind of blue screen diff --git a/kernel/src/kalloc.cpp b/kernel/src/kalloc.cpp index a8c4c08a..6356d1a3 100644 --- a/kernel/src/kalloc.cpp +++ b/kernel/src/kalloc.cpp @@ -151,21 +151,21 @@ void debug_malloc(const char* point = nullptr){ k_print(" next: "); do { - k_printf("%u%h -> ", static_cast(it->is_free()), reinterpret_cast(it)); + printf("%u%h -> ", static_cast(it->is_free()), reinterpret_cast(it)); it = it->next(); } while(it != malloc_head); - k_printf("%h\n", malloc_head); + printf("%h\n", malloc_head); it = malloc_head; k_print("prev: "); do { - k_printf("%h <- ", reinterpret_cast(it)); + printf("%h <- ", reinterpret_cast(it)); it = it->prev(); } while(it != malloc_head); - k_printf("%h\n", malloc_head); + printf("%h\n", malloc_head); } } @@ -414,7 +414,7 @@ void* kalloc::k_malloc(uint64_t bytes){ auto block_start = reinterpret_cast(current) + sizeof(malloc_header_chunk); if(TRACE_MALLOC){ - k_printf("m %u(%u) %h ", bytes, current->size(), block_start); + printf("m %u(%u) %h ", bytes, current->size(), block_start); } return reinterpret_cast(block_start); @@ -429,7 +429,7 @@ void kalloc::k_free(void* block){ } if(TRACE_MALLOC){ - k_printf("f %u %h ", free_header->size(), reinterpret_cast(block)); + printf("f %u %h ", free_header->size(), reinterpret_cast(block)); } //Less memory is used @@ -472,7 +472,7 @@ void kalloc::debug(){ auto it = malloc_head; - k_printf("malloc overhead: %u\n", META_SIZE); + printf("malloc overhead: %u\n", META_SIZE); k_print("Free blocks:"); do { if(!it->is_free()){ @@ -484,14 +484,14 @@ void kalloc::debug(){ ++inconsistent; } - k_printf("b(%u) ", it->size()); + printf("b(%u) ", it->size()); memory_free += it->size(); it = it->next(); } while(it != malloc_head); k_print_line(); - k_printf("memory free in malloc chain: %m (%u)\n", memory_free, memory_free); - k_printf("There are %u non free blocks in the free list\n", non_free_blocks); - k_printf("There are %u inconsistent sized blocks in the free list\n", inconsistent); + printf("memory free in malloc chain: %m (%u)\n", memory_free, memory_free); + printf("There are %u non free blocks in the free list\n", non_free_blocks); + printf("There are %u inconsistent sized blocks in the free list\n", inconsistent); } diff --git a/kernel/src/kernel_utils.cpp b/kernel/src/kernel_utils.cpp index 4cb58767..6d61038c 100644 --- a/kernel/src/kernel_utils.cpp +++ b/kernel/src/kernel_utils.cpp @@ -41,5 +41,5 @@ void out_word(uint16_t _port, uint16_t _data){ } void print_stack(const char* s, size_t check){ - k_printf("%s stack: %u (16B-a:%u) \n", s, check, static_cast(check % 16)); + printf("%s stack: %u (16B-a:%u) \n", s, check, static_cast(check % 16)); } diff --git a/kernel/src/scheduler.cpp b/kernel/src/scheduler.cpp index 0dd157ff..923018dd 100644 --- a/kernel/src/scheduler.cpp +++ b/kernel/src/scheduler.cpp @@ -93,7 +93,7 @@ void gc_task(){ auto& desc = process.process; if(DEBUG_SCHEDULER){ - k_printf("Clean process %u\n", desc.pid); + printf("Clean process %u\n", desc.pid); } //1. Release physical memory of PML4T @@ -266,7 +266,7 @@ void switch_to_process(size_t pid){ current_pid = pid; if(DEBUG_SCHEDULER){ - k_printf("Switch to %u\n", current_pid); + printf("Switch to %u\n", current_pid); } auto& process = pcb[current_pid]; @@ -363,7 +363,7 @@ bool allocate_user_memory(scheduler::process_t& process, size_t address, size_t (physical_memory / paging::PAGE_SIZE + 1) * paging::PAGE_SIZE; if(DEBUG_SCHEDULER){ - k_printf("Map(p%u) virtual:%h into phys: %h\n", process.pid, first_page, aligned_physical_memory); + printf("Map(p%u) virtual:%h into phys: %h\n", process.pid, first_page, aligned_physical_memory); } @@ -396,7 +396,7 @@ bool create_paging(char* buffer, scheduler::process_t& process){ process.paging_size = paging::PAGE_SIZE; if(DEBUG_SCHEDULER){ - k_printf("Process %u cr3:%h\n", process.pid, process.physical_cr3); + printf("Process %u cr3:%h\n", process.pid, process.physical_cr3); } clear_physical_memory(process.physical_cr3, 1); @@ -442,7 +442,7 @@ bool create_paging(char* buffer, scheduler::process_t& process){ physical_pointer phys_ptr(segment.physical, pages); if(DEBUG_SCHEDULER){ - k_printf("Copy to physical:%h\n", segment.physical); + printf("Copy to physical:%h\n", segment.physical); } auto memory_start = phys_ptr.get() + left_padding; @@ -672,7 +672,7 @@ void scheduler::sbrk(size_t inc){ auto virtual_start = process.brk_start; if(DEBUG_SCHEDULER){ - k_printf("Map(p%u) virtual:%h into phys: %h\n", process.pid, virtual_start, physical); + printf("Map(p%u) virtual:%h into phys: %h\n", process.pid, virtual_start, physical); } //Map the memory inside the process memory space @@ -710,7 +710,7 @@ void scheduler::await_termination(pid_t pid){ void scheduler::kill_current_process(){ if(DEBUG_SCHEDULER){ - k_printf("Kill %u\n", current_pid); + printf("Kill %u\n", current_pid); } //Notify parent if waiting @@ -801,7 +801,7 @@ void scheduler::block_process(pid_t pid){ thor_assert(pcb[pid].state == process_state::RUNNING, "Can only block RUNNING processes"); if(DEBUG_SCHEDULER){ - k_printf("Block process %u\n", pid); + printf("Block process %u\n", pid); } pcb[pid].state = process_state::BLOCKED; @@ -814,7 +814,7 @@ void scheduler::unblock_process(pid_t pid){ thor_assert(pcb[pid].state == process_state::BLOCKED || pcb[pid].state == process_state::WAITING, "Can only unblock BLOCKED/WAITING processes"); if(DEBUG_SCHEDULER){ - k_printf("Unblock process %u\n", pid); + printf("Unblock process %u\n", pid); } pcb[pid].state = process_state::READY; @@ -825,7 +825,7 @@ void scheduler::sleep_ms(pid_t pid, size_t time){ thor_assert(pcb[pid].state == process_state::RUNNING, "Only RUNNING processes can sleep"); if(DEBUG_SCHEDULER){ - k_printf("Put %u to sleep\n", pid); + printf("Put %u to sleep\n", pid); } pcb[pid].state = process_state::SLEEPING; diff --git a/printf/include/printf_dec.hpp b/printf/include/printf_dec.hpp new file mode 100644 index 00000000..22c4e5f3 --- /dev/null +++ b/printf/include/printf_dec.hpp @@ -0,0 +1,20 @@ +//======================================================================= +// Copyright Baptiste Wicht 2013-2014. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +//Is made to be included as is in a header file +// +//Implement is provided in printf_def.hpp which must be included in +//source file + +std::string sprintf(const std::string& format, ...); +std::string vsprintf(const std::string& format, va_list va); + +void printf(const std::string& format, ...); +void vprintf(const std::string& format, va_list va); + +//Definition of this function must be provided +void __printf(const std::string& formatted); diff --git a/printf/include/printf_def.hpp b/printf/include/printf_def.hpp new file mode 100644 index 00000000..737ccf0c --- /dev/null +++ b/printf/include/printf_def.hpp @@ -0,0 +1,205 @@ +//======================================================================= +// Copyright Baptiste Wicht 2013-2014. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +std::string vsprintf(const std::string& format, va_list va){ + std::string s(format.size()); + + char ch; + int fi = 0; + + while ((ch = format[fi++])) { + if(ch != '%'){ + s += ch; + } else { + ch = format[fi++]; + + size_t min_width = 0; + while(ch >= '0' && ch <= '9'){ + min_width = 10 * min_width + (ch - '0'); + ch = format[fi++]; + } + + size_t min_digits = 0; + if(ch == '.'){ + ch = format[fi++]; + + while(ch >= '0' && ch <= '9'){ + min_digits = 10 * min_digits + (ch - '0'); + ch = format[fi++]; + } + } + + auto prev = s.size(); + + //Signed decimal + if(ch == 'd'){ + auto arg = va_arg(va, int64_t); + + if(min_digits > 0){ + size_t d = std::digits(arg); + if(min_digits > d){ + min_digits -= d; + + if(arg < 0){ + arg *= -1; + s += '-'; + } + + while(min_digits > 0){ + while(min_digits > 0){ + arg += '0'; + --min_digits; + } + } + } + } + + s += std::to_string(arg); + } + //Unsigned Decimal + else if(ch == 'u'){ + auto arg = va_arg(va, uint64_t); + + if(min_digits > 0){ + size_t d = std::digits(arg); + if(min_digits > d){ + min_digits -= d; + while(min_digits > 0){ + while(min_digits > 0){ + arg += '0'; + --min_digits; + } + } + } + } + + s += std::to_string(arg); + } + //Hexadecimal + else if(ch == 'h'){ + s += "0x"; + + uint8_t buffer[20]; + + auto arg = va_arg(va, uint64_t); + size_t i = 0; + + while(arg / 16 != 0){ + buffer[i++] = arg % 16; + arg /= 16; + } + + buffer[i] = arg; + + if(min_digits > 0 && min_digits > i){ + min_digits -= i + 1; + while(min_digits > 0){ + arg += '0'; + --min_digits; + } + } + + while(true){ + uint8_t digit = buffer[i]; + + if(digit < 10){ + s += static_cast('0' + digit); + } else { + switch(digit){ + case 10: + s += 'A'; + break; + case 11: + s += 'B'; + break; + case 12: + s += 'C'; + break; + case 13: + s += 'D'; + break; + case 14: + s += 'E'; + break; + case 15: + s += 'F'; + break; + } + } + + if(i == 0){ + break; + } + + --i; + } + } + //Memory + else if(ch == 'm'){ + auto memory= va_arg(va, uint64_t); + + if(memory >= 1024 * 1024 * 1024){ + s += std::to_string(memory / (1024 * 1024 * 1024)); + s += "GiB"; + } else if(memory >= 1024 * 1024){ + s += std::to_string(memory / (1024 * 1024)); + s += "MiB"; + } else if(memory >= 1024){ + s += std::to_string(memory / 1024); + s += "KiB"; + } else { + s += std::to_string(memory); + s += "B"; + } + } + //String + else if(ch == 's'){ + auto arg = va_arg(va, const char*); + s += arg; + } + + if(min_width > 0){ + size_t width = s.size() - prev; + + if(min_width > width){ + min_width -= width; + + while(min_width > 0){ + s += ' '; + --min_width; + } + } + } + } + } + + return std::move(s); +} + +std::string sprintf(const std::string& format, ...){ + va_list va; + va_start(va, format); + + auto s = vsprintf(format, va); + + va_end(va); + + return std::move(s); +} + +void printf(const std::string& format, va_list va){ + __printf(vsprintf(format, va)); +} + +void printf(const std::string& format, ...){ + va_list va; + va_start(va, format); + + printf(format, va); + + va_end(va); +} diff --git a/tlib/include/print.hpp b/tlib/include/print.hpp index 8d658376..3476ab6a 100644 --- a/tlib/include/print.hpp +++ b/tlib/include/print.hpp @@ -10,6 +10,8 @@ //TODO Rename in console +#include + #include #include @@ -39,7 +41,6 @@ void clear(); size_t get_columns(); size_t get_rows(); -std::string sprintf(const std::string& format, ...); -void printf(const std::string& format, ...); +#include "printf_dec.hpp" #endif diff --git a/tlib/src/print.cpp b/tlib/src/print.cpp index e82954a5..1669d401 100644 --- a/tlib/src/print.cpp +++ b/tlib/src/print.cpp @@ -112,197 +112,8 @@ void print_line(const std::string& s){ print_line(); } -std::string vsprintf(const std::string& format, va_list va){ - std::string s(format.size()); +#include "printf_def.hpp" - char ch; - int fi = 0; - - while ((ch = format[fi++])) { - if(ch != '%'){ - s += ch; - } else { - ch = format[fi++]; - - size_t min_width = 0; - while(ch >= '0' && ch <= '9'){ - min_width = 10 * min_width + (ch - '0'); - ch = format[fi++]; - } - - size_t min_digits = 0; - if(ch == '.'){ - ch = format[fi++]; - - while(ch >= '0' && ch <= '9'){ - min_digits = 10 * min_digits + (ch - '0'); - ch = format[fi++]; - } - } - - auto prev = s.size(); - - //Signed decimal - if(ch == 'd'){ - auto arg = va_arg(va, int64_t); - - if(min_digits > 0){ - size_t d = std::digits(arg); - if(min_digits > d){ - min_digits -= d; - - if(arg < 0){ - arg *= -1; - s += '-'; - } - - while(min_digits > 0){ - while(min_digits > 0){ - arg += '0'; - --min_digits; - } - } - } - } - - s += std::to_string(arg); - } - //Unsigned Decimal - else if(ch == 'u'){ - auto arg = va_arg(va, uint64_t); - - if(min_digits > 0){ - size_t d = std::digits(arg); - if(min_digits > d){ - min_digits -= d; - while(min_digits > 0){ - while(min_digits > 0){ - arg += '0'; - --min_digits; - } - } - } - } - - s += std::to_string(arg); - } - //Hexadecimal - else if(ch == 'h'){ - s += "0x"; - - uint8_t buffer[20]; - - auto arg = va_arg(va, uint64_t); - size_t i = 0; - - while(arg / 16 != 0){ - buffer[i++] = arg % 16; - arg /= 16; - } - - buffer[i] = arg; - - if(min_digits > 0 && min_digits > i){ - min_digits -= i + 1; - while(min_digits > 0){ - arg += '0'; - --min_digits; - } - } - - while(true){ - uint8_t digit = buffer[i]; - - if(digit < 10){ - s += static_cast('0' + digit); - } else { - switch(digit){ - case 10: - s += 'A'; - break; - case 11: - s += 'B'; - break; - case 12: - s += 'C'; - break; - case 13: - s += 'D'; - break; - case 14: - s += 'E'; - break; - case 15: - s += 'F'; - break; - } - } - - if(i == 0){ - break; - } - - --i; - } - } - //Memory - else if(ch == 'm'){ - auto memory= va_arg(va, uint64_t); - - if(memory >= 1024 * 1024 * 1024){ - s += std::to_string(memory / (1024 * 1024 * 1024)); - s += "GiB"; - } else if(memory >= 1024 * 1024){ - s += std::to_string(memory / (1024 * 1024)); - s += "MiB"; - } else if(memory >= 1024){ - s += std::to_string(memory / 1024); - s += "KiB"; - } else { - s += std::to_string(memory); - s += "B"; - } - } - //String - else if(ch == 's'){ - auto arg = va_arg(va, const char*); - s += arg; - } - - if(min_width > 0){ - size_t width = s.size() - prev; - - if(min_width > width){ - min_width -= width; - - while(min_width > 0){ - s += ' '; - --min_width; - } - } - } - } - } - - return std::move(s); -} - -std::string sprintf(const std::string& format, ...){ - va_list va; - va_start(va, format); - - auto s = vsprintf(format, va); - - va_end(va); - - return std::move(s); -} - -void printf(const std::string& format, ...){ - va_list va; - va_start(va, format); - - print(vsprintf(format, va)); - - va_end(va); +void __printf(const std::string& formatted){ + print(formatted); }