CeDOS - Commit c1610cfb

User stdio now more efficient, using fewer system calls
Celina Kalus
Tue, 14 Mar 2023 19:31:39 +0100
3 files changed, 90 insertions(+), 46 deletions(-)
M include/string.hinclude/string.h

@@ -32,4 +32,7 @@ * \return \p ptr is returned.

*/ void *memset (void *ptr, int value, size_t num); +unsigned int strlen (const char *str); +char *strcpy(char *destination, const char *source); + #endif
M src/apps/stdio.csrc/apps/stdio.c

@@ -2,60 +2,103 @@ #include "cedos.h"

#include "stdio.h" #include <stdarg.h> +#include "string.h" char user_numeric[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; char user_hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; -int print_char(char c) { - sc_file_write(0, &c, 1); +int print(char *buffer, int num) { + return sc_file_write(0, buffer, num); } -char read_char() { - char c; - sc_file_read(1, &c, 1); - return c; +int read_char(char *buffer, int num) { + return sc_file_read(1, buffer, num); } -void print_hex_char(uint8_t c) { +/*void print_hex_char(uint8_t c) { print_char(user_hex[c >> 4]); print_char(user_hex[c & 0x0F]); +}*/ + +int sprint_hex_char(uint8_t c, char *buffer) { + buffer[0] = user_hex[c >> 4]; + buffer[1] = user_hex[c & 0x0F]; + return 2; } -void print_uint32(uint32_t value) { +int sprint_uint32(uint32_t value, char *buffer) { uint8_t* mem = (uint8_t*)(&value); for (int i = 0; i < 4; i++) { - print_hex_char(mem[3-i]); + sprint_hex_char(mem[3-i], buffer); + buffer += 2; } } -void rek_print_uint(unsigned int value) { +int rek_sprint_uint(unsigned int value, char *buffer) { if (value > 0) { - rek_print_uint(value / 10); - print_char(user_numeric[value % 10]); + int i = rek_sprint_uint(value / 10, buffer); + buffer[i] = user_numeric[value % 10]; + return i + 1; + } else { + return 0; } } -void print_uint(unsigned int value) { +int sprint_uint(unsigned int value, char *buffer) { if (value == 0) { - print_char('0'); - return; + buffer[0] = '0'; + return 1; + } else { + return rek_sprint_uint(value, buffer++); } - - rek_print_uint(value); } -void print_int(int value) { +int sprint_int(int value, char *buffer) { if (value < 0) { - print_char('-'); - print_int(-value); - return; + buffer[0] = '-'; + return sprint_int(-value, buffer++) + 1; } else if (value == 0) { - print_char('0'); - return; + buffer[0] = '0'; + return 1; + } else { + return rek_sprint_uint((unsigned int)value, buffer); } +} + +/*void rek_print_uint(unsigned int value) { + if (value > 0) { + rek_print_uint(value / 10); + print_char(user_numeric[value % 10]); + } +}*/ - rek_print_uint((unsigned int)value); +void print_uint(unsigned int value) { + char buffer[16]; + int size = sprint_uint(value, buffer); + print(buffer, size); +} + +void print_int(int value) { + char buffer[16]; + int size = sprint_int(value, buffer); + print(buffer, size); +} + +void print_uint32(uint32_t value) { + char buffer[16]; + int size = sprint_uint32(value, buffer); + print(buffer, size); +} + +void print_string(char *str) { + int length = 0; + while (str[length]) { length++; } + print(str, length); +} + +void print_char(char c) { + print(&c, 1); } int printf(const char *fmt, ...) {

@@ -63,36 +106,28 @@ va_list args;

va_start(args, fmt); uint32_t index = 0; - enum { - STATE_DEFAULT, - STATE_ARGUMENT, - } state = STATE_DEFAULT; + while (*fmt) { + int i = 0; + while (fmt[i] != '\0' && fmt[i] != '%') { i++; } + if (i > 0) { print(fmt, i); } + if (fmt[i] == '\0') { break; } + fmt = fmt + i + 1; - while (*fmt) { - if (state == STATE_ARGUMENT && *fmt == 'X') { + if (*fmt == 'X') { print_uint32(va_arg(args, uint32_t)); - state = STATE_DEFAULT; - } else if (state == STATE_ARGUMENT && *fmt == 'i') { + } else if (*fmt == 'i') { print_int(va_arg(args, int)); - state = STATE_DEFAULT; - } else if (state == STATE_ARGUMENT && *fmt == 'u') { + } else if (*fmt == 'u') { print_uint(va_arg(args, unsigned int)); - state = STATE_DEFAULT; - } else if (state == STATE_ARGUMENT && *fmt == 'p') { + } else if (*fmt == 'p') { print_uint32(va_arg(args, uint32_t)); - state = STATE_DEFAULT; - } else if (state == STATE_ARGUMENT && *fmt == 's') { + } else if (*fmt == 's') { const char* string = va_arg(args, const char*); - while (*string) { print_char(*string++); } - state = STATE_DEFAULT; - } else if (state == STATE_ARGUMENT && *fmt == 'c') { + print_string(string); + } else if (*fmt == 'c') { print_char(va_arg(args, int)); - state = STATE_DEFAULT; - } else if (state == STATE_ARGUMENT && *fmt == '%') { + } else if (*fmt == '%') { print_char('%'); - state = STATE_DEFAULT; - } else if (*fmt == '%') { - state = STATE_ARGUMENT; } else { print_char(*fmt); }
M src/kernel/string.csrc/kernel/string.c

@@ -28,4 +28,10 @@ for (uint32_t i = 0; i < num; i++) {

((uint8_t*)ptr)[i] = (uint8_t)value; } return ptr; +} + +unsigned int strlen (const char *str) { + int i = 0; + while (str[i]) { i++; } + return i; }