aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2020-07-23 20:13:25 +0200
committerMarvin Borner2020-07-23 20:13:25 +0200
commita0b8c61b09200aa3f9e27878cb866648a7d26502 (patch)
tree31de26c3c491d3fee719a1d9d5aad2b2ce879e2a
parent99e183a2f569729d722d83503cb851d6198fc1fe (diff)
Added formatted print function
-rw-r--r--Makefile3
-rw-r--r--src/lib/conv.c28
-rw-r--r--src/lib/inc/arg.h11
-rw-r--r--src/lib/inc/conv.h2
-rw-r--r--src/lib/inc/print.h13
-rw-r--r--src/lib/print.c95
-rw-r--r--src/main.c3
7 files changed, 153 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index eb9e863..5954371 100644
--- a/Makefile
+++ b/Makefile
@@ -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;
+}
diff --git a/src/main.c b/src/main.c
index 947c0e1..a4b290c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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) {
};