diff options
author | Marvin Borner | 2020-07-23 20:13:25 +0200 |
---|---|---|
committer | Marvin Borner | 2020-07-23 20:13:25 +0200 |
commit | a0b8c61b09200aa3f9e27878cb866648a7d26502 (patch) | |
tree | 31de26c3c491d3fee719a1d9d5aad2b2ce879e2a | |
parent | 99e183a2f569729d722d83503cb851d6198fc1fe (diff) |
Added formatted print function
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | src/lib/conv.c | 28 | ||||
-rw-r--r-- | src/lib/inc/arg.h | 11 | ||||
-rw-r--r-- | src/lib/inc/conv.h | 2 | ||||
-rw-r--r-- | src/lib/inc/print.h | 13 | ||||
-rw-r--r-- | src/lib/print.c | 95 | ||||
-rw-r--r-- | src/main.c | 3 |
7 files changed, 153 insertions, 2 deletions
@@ -10,7 +10,8 @@ COBJS = src/main.o \ src/lib/str.o \ src/lib/mem.o \ src/lib/math.o \ - src/lib/conv.o + src/lib/conv.o \ + src/lib/print.o CC = cross/opt/bin/i686-elf-gcc LD = cross/opt/bin/i686-elf-ld AS = nasm diff --git a/src/lib/conv.c b/src/lib/conv.c index 89d1786..3bde4ec 100644 --- a/src/lib/conv.c +++ b/src/lib/conv.c @@ -114,3 +114,31 @@ char *itoa(int n) strinv(ret); return ret; } + +char *conv_base(int value, char *result, int base, int is_signed) +{ + if (base < 2 || base > 36) { + *result = '\0'; + return result; + } + + char *ptr = result, *ptr1 = result, tmp_char; + int tmp_value; + + do { + tmp_value = value; + value /= base; + *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" + [35 + (tmp_value - value * base)]; + } while (value); + + if (is_signed && tmp_value < 0) + *ptr++ = '-'; + *ptr-- = '\0'; + while (ptr1 < ptr) { + tmp_char = *ptr; + *ptr-- = *ptr1; + *ptr1++ = tmp_char; + } + return result; +} diff --git a/src/lib/inc/arg.h b/src/lib/inc/arg.h new file mode 100644 index 0000000..73e592d --- /dev/null +++ b/src/lib/inc/arg.h @@ -0,0 +1,11 @@ +// MIT License, Copyright (c) 2020 Marvin Borner + +#ifndef ARG_H +#define ARG_H + +typedef __builtin_va_list va_list; +#define va_start __builtin_va_start +#define va_end __builtin_va_end +#define va_arg __builtin_va_arg + +#endif diff --git a/src/lib/inc/conv.h b/src/lib/inc/conv.h index 8295756..d878deb 100644 --- a/src/lib/inc/conv.h +++ b/src/lib/inc/conv.h @@ -10,4 +10,6 @@ char *htoa(u32 n); int htoi(char *str); char *itoa(int n); +char *conv_base(int value, char *result, int base, int is_signed); + #endif diff --git a/src/lib/inc/print.h b/src/lib/inc/print.h new file mode 100644 index 0000000..1a2419b --- /dev/null +++ b/src/lib/inc/print.h @@ -0,0 +1,13 @@ +// MIT License, Copyright (c) 2020 Marvin Borner +// I may (re)move this in the future // TODO + +#ifndef PRINT_H +#define PRINT_H + +#include <arg.h> + +int printf(const char *format, ...); +int vprintf(const char *format, va_list ap); +int vsprintf(char *str, const char *format, va_list ap); + +#endif diff --git a/src/lib/print.c b/src/lib/print.c new file mode 100644 index 0000000..9379f68 --- /dev/null +++ b/src/lib/print.c @@ -0,0 +1,95 @@ +#include <arg.h> +#include <conv.h> +#include <def.h> +#include <mem.h> +#include <serial.h> +#include <str.h> + +static void append(char *dest, char *src, int index) +{ + for (u32 i = index; i < strlen(src) + index; i++) + dest[i] = src[i - index]; + dest[index + strlen(src)] = 0; +} + +int vsprintf(char *str, const char *format, va_list ap) +{ + u8 ready_to_format = 0; + + int i = 0; + char buf = 0; + char format_buffer[20] = "\0"; + + for (; *format; format++) { + if (ready_to_format) { + ready_to_format = 0; + + if (*format == '%') { + str[i] = '%'; + continue; + } + + buf = *format; + + // TODO: Improve this repetitive code + if (buf == 's') { + char *string = va_arg(ap, char *); + append(str, string, i); + i = strlen(str); + } else if (buf == 'x') { + conv_base(va_arg(ap, u32), format_buffer, 16, 0); + append(str, format_buffer, i); + i = strlen(str); + } else if (buf == 'd' || buf == 'i') { + conv_base(va_arg(ap, s32), format_buffer, 10, 1); + append(str, format_buffer, i); + i = strlen(str); + } else if (buf == 'u') { + conv_base(va_arg(ap, u32), format_buffer, 10, 0); + append(str, format_buffer, i); + i = strlen(str); + } else if (buf == 'o') { + conv_base(va_arg(ap, u32), format_buffer, 8, 0); + append(str, format_buffer, i); + i = strlen(str); + } else if (buf == 'b') { + conv_base(va_arg(ap, u32), format_buffer, 2, 0); + append(str, format_buffer, i); + i = strlen(str); + } else if (buf == 'c') { + str[i] = (char)va_arg(ap, int); + i++; + } + } else { + if (*format == '%') + ready_to_format = 1; + else { + str[i] = *format; + i++; + } + } + + format_buffer[0] = '\0'; + } + + return strlen(str); +} + +int vprintf(const char *format, va_list ap) +{ + char buf[1024]; + memset(buf, 0, 1024); + int len = vsprintf(buf, format, ap); + serial_print(buf); // TODO: Remove temporary serial print + return len; +} + +int printf(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + int len = vprintf(format, ap); + va_end(ap); + + return len; +} @@ -4,6 +4,7 @@ #include <def.h> #include <interrupts.h> #include <keyboard.h> +#include <print.h> #include <serial.h> #include <vesa.h> @@ -23,7 +24,7 @@ void main(struct mem_info *mem_info, struct vid_info *vid_info) vesa_fill(terminal_background); serial_install(); - serial_print("hello\n"); + printf("hello"); while (1) { }; |