From 6a5543bb8f1f535ca49737bcd7be0cafca3b2a08 Mon Sep 17 00:00:00 2001 From: hachem Date: Mon, 12 Oct 2026 23:08:48 +0200 Subject: feat: lib sea --- sysroot/usr/lib/libc/stdio.c | 211 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 sysroot/usr/lib/libc/stdio.c (limited to 'sysroot/usr/lib/libc/stdio.c') diff --git a/sysroot/usr/lib/libc/stdio.c b/sysroot/usr/lib/libc/stdio.c new file mode 100644 index 0000000..d0e7ad7 --- /dev/null +++ b/sysroot/usr/lib/libc/stdio.c @@ -0,0 +1,211 @@ +#include +#include +#include +#include + +int putchar(int character) +{ + char byte = (char)character; + if (write(1, &byte, 1) != 1) + return EOF; + return (unsigned char)byte; +} + +int getchar(void) +{ + char byte; + if (read(0, &byte, 1) <= 0) + return EOF; + return (unsigned char)byte; +} + +int puts(const char* string) +{ + (void)write(1, string, strlen(string)); + (void)write(1, "\n", 1); + return 0; +} + +static int format_unsigned(char* buffer, unsigned long value, int base, int upper) +{ + const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef"; + char temp[32]; + int count = 0; + if (value == 0) + temp[count++] = '0'; + while (value > 0) + { + temp[count++] = digits[value % (unsigned)base]; + value /= (unsigned)base; + } + for (int i = 0; i < count; i++) + buffer[i] = temp[count - 1 - i]; + return count; +} + +static int format_signed(char* buffer, long value) +{ + int negative = value < 0; + unsigned long magnitude = negative ? (unsigned long)(-value) : (unsigned long)value; + int count = 0; + if (negative) + buffer[count++] = '-'; + return count + format_unsigned(buffer + count, magnitude, 10, 0); +} + +#define PRINTF_BUFFER 256 + +// yoinked straight off open source +int printf(const char* format, ...) +{ + char out[PRINTF_BUFFER]; + int filled = 0; + int total = 0; + va_list args; + va_start(args, format); + +#define FLUSH() \ + do { \ + if (filled > 0) \ + { \ + (void)write(1, out, filled); \ + filled = 0; \ + } \ + } while (0) +#define EMIT(ch) \ + do { \ + if (filled == PRINTF_BUFFER) \ + FLUSH(); \ + out[filled++] = (char)(ch); \ + total++; \ + } while (0) + + for (const char* cursor = format; *cursor; cursor++) + { + if (*cursor != '%') + { + EMIT(*cursor); + continue; + } + + cursor++; + if (*cursor == '%') + { + EMIT('%'); + continue; + } + + int zero_pad = 0; + if (*cursor == '0') + { + zero_pad = 1; + cursor++; + } + int width = 0; + while (*cursor >= '0' && *cursor <= '9') + { + width = width * 10 + (*cursor - '0'); + cursor++; + } + int is_long = 0; + while (*cursor == 'l') + { + is_long = 1; + cursor++; + } + + char conversion = *cursor; + if (conversion == 's') + { + const char* string = va_arg(args, const char*); + if (!string) + string = "(null)"; + int length = (int)strlen(string); + for (int i = length; i < width; i++) + EMIT(' '); + for (int i = 0; i < length; i++) + EMIT(string[i]); + continue; + } + if (conversion == 'c') + { + int character = va_arg(args, int); + for (int i = 1; i < width; i++) + EMIT(' '); + EMIT(character); + continue; + } + + char number[34]; + int length = 0; + if (conversion == 'd' || conversion == 'i') + { + long value = is_long ? va_arg(args, long) : (long)va_arg(args, int); + length = format_signed(number, value); + } + else if (conversion == 'u') + { + unsigned long value = is_long ? va_arg(args, unsigned long) : (unsigned long)va_arg(args, unsigned int); + length = format_unsigned(number, value, 10, 0); + } + else if (conversion == 'x' || conversion == 'X') + { + unsigned long value = is_long ? va_arg(args, unsigned long) : (unsigned long)va_arg(args, unsigned int); + length = format_unsigned(number, value, 16, conversion == 'X'); + } + else if (conversion == 'p') + { + unsigned long value = (unsigned long)va_arg(args, void*); + EMIT('0'); + EMIT('x'); + length = format_unsigned(number, value, 16, 0); + } + else + { + EMIT('%'); + EMIT(conversion); + continue; + } + + for (int i = length; i < width; i++) + EMIT(zero_pad ? '0' : ' '); + for (int i = 0; i < length; i++) + EMIT(number[i]); + } + + FLUSH(); + va_end(args); + return total; + +#undef EMIT +#undef FLUSH +} + +int readline(char* buffer, int max_length) +{ + int length = 0; + for (;;) + { + char character; + if (read(0, &character, 1) <= 0) + break; + if (character == '\n') + break; + if (character == '\b') + { + if (length > 0) + { + length--; + (void)write(1, "\b \b", 3); + } + continue; + } + if (length < max_length - 1) + { + buffer[length++] = character; + (void)write(1, &character, 1); + } + } + buffer[length] = 0; + return length; +} -- cgit v1.3