diff options
| author | EmulatedSeasons <89668582+EmulatedSeasons@users.noreply.github.com> | 2023-12-29 01:38:34 -0500 |
|---|---|---|
| committer | EmulatedSeasons <89668582+EmulatedSeasons@users.noreply.github.com> | 2023-12-29 01:38:34 -0500 |
| commit | b7b97d32cbb6fbc928078ebe3a00714cbbebea86 (patch) | |
| tree | c6546748ec5b32345319c54993a8a00b6fef7546 /kernel/std/printf.c | |
| parent | d3774de3691a90d7bc2eddce6581c89968c65895 (diff) | |
got grub memory map and added to kernel printf
Diffstat (limited to 'kernel/std/printf.c')
| -rw-r--r-- | kernel/std/printf.c | 124 |
1 files changed, 118 insertions, 6 deletions
diff --git a/kernel/std/printf.c b/kernel/std/printf.c index c383cad..fe45892 100644 --- a/kernel/std/printf.c +++ b/kernel/std/printf.c @@ -3,7 +3,8 @@ #include <stdarg.h>
#include <stdio.h>
#include <string.h>
-
+#include <stdint.h>
+
static bool print(const char* data, size_t length) {
const unsigned char* bytes = (const unsigned char*) data;
for (size_t i = 0; i < length; i++)
@@ -11,13 +12,82 @@ static bool print(const char* data, size_t length) { return false;
return true;
}
-
+
+// for %d and %x.
+static const char* itoa(unsigned int num, char* str, unsigned int base) {
+ asm("xchgw %bx, %bx");
+ int cou = 0; // nt
+
+ if (num == 0) { // 0
+ str[cou] = '0';
+ str[++cou] = '\0';
+ return str;
+ }
+
+ while (num)
+ {
+ unsigned int rem = (num % base);
+ // brings the number up to ascii 0 + the digit
+ if (rem > 9) {
+ str[cou] = rem + '7'; // 7 = 55 + 10(A) = 65
+ } else {
+ str[cou] = rem + '0';
+ }
+ num /= base;
+ ++cou;
+ }
+
+ // reverse the string
+ for (int i = 0; i < cou; i++) {
+ char temp = str[i];
+ str[i] = str[cou - i - 1];
+ str[cou - 1] = temp;
+ }
+
+ str[cou] = '\0';
+ return str;
+}
+
+// have no idea if there's a better way to do this. for %lx
+static const char* itoa_u64(unsigned long long num, char* str, int base) {
+ int cou = 0; // nt
+
+ if (num == 0) { // 0
+ str[cou] = '0';
+ str[++cou] = '\0';
+ return str;
+ }
+
+ while (num)
+ {
+ unsigned long long rem = num % base;
+ // brings the number up to ascii 0 + the digit
+ if (rem > 9) {
+ str[cou] = rem + '7'; // 7 = 55 + 10(A) = 65
+ } else {
+ str[cou] = rem + '0';
+ }
+ num /= base;
+ ++cou;
+ }
+
+ // reverse the string
+ for (int i = 0; i < cou; i++) {
+ char temp = str[i];
+ str[i] = str[cou - i - 1];
+ str[cou - 1] = temp;
+ }
+
+ str[cou] = '\0';
+ return str;
+}
+
int printf(const char* restrict format, ...) {
va_list parameters;
va_start(parameters, format);
int written = 0;
-
+
while (*format != '\0') {
size_t maxrem = INT_MAX - written;
@@ -37,9 +107,9 @@ int printf(const char* restrict format, ...) { written += amount;
continue;
}
-
+
const char* format_begun_at = format++;
-
+
if (*format == 'c') {
format++;
char c = (char) va_arg(parameters, int /* char promotes to int */);
@@ -50,6 +120,48 @@ int printf(const char* restrict format, ...) { if (!print(&c, sizeof(c)))
return -1;
written++;
+ } else if (*format == 'd') {
+ format++;
+ char str[20]; // probably a long enough buffer
+ unsigned int d = va_arg(parameters, unsigned int);
+ itoa(d, str, 10);
+ size_t len = strlen(str);
+ if (maxrem < len) {
+ // TODO: Set errno to EOVERFLOW.
+ return -1;
+ }
+ if (!print(str, len))
+ return -1;
+ written += len;
+ } else if (*format == 'x') {
+ format++;
+ char str[20]; // probably a long enough buffer
+ unsigned int d = va_arg(parameters, unsigned int);
+ itoa(d, str, 16);
+ size_t len = strlen(str);
+ if (maxrem < len) {
+ // TODO: Set errno to EOVERFLOW.
+ return -1;
+ }
+ if (!print(str, len))
+ return -1;
+ written += len;
+ } else if (*format == 'l') { // for %lx and others that start with l
+ format++;
+ if (*format == 'x') {
+ format++;
+ char str[20]; // probably a long enough buffer
+ unsigned long long d = va_arg(parameters, unsigned long long);
+ itoa_u64(d, str, 16);
+ size_t len = strlen(str);
+ if (maxrem < len) {
+ // TODO: Set errno to EOVERFLOW.
+ return -1;
+ }
+ if (!print(str, len))
+ return -1;
+ written += len;
+ }
} else if (*format == 's') {
format++;
const char* str = va_arg(parameters, const char*);
@@ -74,7 +186,7 @@ int printf(const char* restrict format, ...) { format += len;
}
}
-
+
va_end(parameters);
return written;
}
\ No newline at end of file |
