summaryrefslogtreecommitdiff
path: root/kc
diff options
context:
space:
mode:
authorAda Christine <adachristine18@gmail.com>2022-02-06 16:31:19 +0000
committerAda Christine <adachristine18@gmail.com>2022-02-06 16:31:19 +0000
commit2067ca185220348b70b35c96e175dfb87cc05592 (patch)
tree860578e275ec43cef12f4bfb355d258b918ea135 /kc
parent7b91c46a8ebf38b2c1c80c1f1e63c4d4dfd10640 (diff)
we have kprintf()
Diffstat (limited to 'kc')
-rw-r--r--kc/core/Makefile2
-rw-r--r--kc/core/kprint.c131
-rw-r--r--kc/core/kprint.h4
3 files changed, 135 insertions, 2 deletions
diff --git a/kc/core/Makefile b/kc/core/Makefile
index b0f4035..6874179 100644
--- a/kc/core/Makefile
+++ b/kc/core/Makefile
@@ -13,7 +13,7 @@ SOBJS :=
GOBJS := entry_x86_64.o reloc_x86_64.o kprint.o serial.o port.o \
kc_main.o main.o memory.o memset.o memcpy.o memmove.o memcmp.o cpu.o \
vm_tree.o exceptions.o panic.o msr.o task.o cpu_task.o \
- kcc_memory.o
+ kcc_memory.o string.o
IOBJS :=
# __attribute__((interrupt)) requires -mgeneral-regs-only
diff --git a/kc/core/kprint.c b/kc/core/kprint.c
index 2f4da01..596d110 100644
--- a/kc/core/kprint.c
+++ b/kc/core/kprint.c
@@ -1,7 +1,9 @@
#include "kprint.h"
#include "serial.h"
-#include <stdarg.h>
+#include <kc/lib.h>
+
+#include <stdint.h>
__attribute__((optimize("O3")))
int kputchar(int c)
@@ -20,3 +22,130 @@ int kputs(const char *s)
return 0;
}
+static char *convert_scalar(
+ uint64_t value,
+ unsigned base,
+ char *buffer,
+ size_t bufsz)
+{
+ static const char *stringdigits = "0123456789abcdef";
+
+ // the string will be built from the lower-to-higher value, and the
+ // result pointer will point to the first character of the string in
+ // the supplied buffer
+
+ // gotta zero the buffer
+ memset(buffer, 0, bufsz);
+
+ // the string is being built backwards, so the pointer needs to be
+ // at the last byte of the string
+ char *result = buffer + bufsz - 1;
+
+ // result >= buffer condition ensures we don't overflow
+
+ while (value > 0 && result >= buffer)
+ {
+ *--result = stringdigits[value % base];
+ value /= base;
+ }
+
+ return result;
+}
+
+int kvprintf(const char *restrict format, va_list arguments)
+{
+ int count = 0;
+
+ while (*format)
+ {
+ if (*format != '%')
+ {
+ kputchar(*format++);
+ count++;
+ continue;
+ }
+
+ switch (*++format)
+ {
+ case 0:
+ return count;
+ case '%':
+ count++;
+ kputchar('%');
+ break;
+ case 's':
+ {
+ const char *s = va_arg(arguments, const char *);
+ count += strlen(s);
+ kputs(s);
+ break;
+ }
+
+ case 'x':
+ {
+ char buffer[65];
+ char *s = convert_scalar(
+ va_arg(arguments, uint64_t),
+ 16,
+ buffer,
+ sizeof(buffer));
+ count += strlen(s);
+ kputs(s);
+ break;
+ }
+ case 'd':
+ {
+ char buffer[65];
+ char *s = convert_scalar(
+ va_arg(arguments, uint64_t),
+ 10,
+ buffer,
+ sizeof(buffer));
+ count += strlen(s);
+ kputs(s);
+ break;
+ }
+ case 'o':
+ {
+ char buffer[65];
+ char *s = convert_scalar(
+ va_arg(arguments, uint64_t),
+ 8,
+ buffer,
+ sizeof(buffer));
+ count += strlen(s);
+ kputs(s);
+ break;
+ }
+ case 'b':
+ {
+ char buffer[65];
+ char *s = convert_scalar(
+ va_arg(arguments, uint64_t),
+ 2,
+ buffer,
+ sizeof(buffer));
+ count += strlen(s);
+ kputs(s);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ format++;
+ }
+
+ va_end(arguments);
+ return count;
+}
+
+int kprintf(const char *restrict format, ...)
+{
+ va_list arguments;
+ va_start (arguments, format);
+
+ return kvprintf(format, arguments);
+}
+
diff --git a/kc/core/kprint.h b/kc/core/kprint.h
index 5b307a2..0c547ea 100644
--- a/kc/core/kprint.h
+++ b/kc/core/kprint.h
@@ -1,5 +1,9 @@
#pragma once
+#include <stdarg.h>
+
int kputchar(int c);
int kputs(const char *s);
+int kprintf(const char *restrict format, ...);
+int kvprintf(const char *restrict format, va_list arguments);