feat: added printf

This commit is contained in:
2021-02-06 16:44:35 +01:00
parent a4651ca9d9
commit 7ff33d611c
5 changed files with 129 additions and 56 deletions

84
kernel/libc/kprintf.c Normal file
View File

@@ -0,0 +1,84 @@
//
// Created by rick on 06-02-21.
//
#include "kprintf.h"
#include "libc.h"
#include <libc/string.h>
#include <libc/va_list.h>
#include <kprint.h>
#include <libk.h>
#include <types.h>
/*
* Integer to string
*/
void print_int(u32 value, u32 width, char* buf, u32 *ptr, u8 base) {
// u32 in binary is 32 digits, so never longer than 33 digits
char msg[33];
itoa(value, msg, base);
u32 digits = strlen(msg);
if (digits < width) {
for (u32 i = 0; i < (width - digits); ++i) {
buf[*ptr] = '0';
*ptr += 1;
}
}
for (u32 i = 0; i < digits; ++i) {
buf[*ptr] = msg[i];
*ptr += 1;
}
}
u32 vasprintf(char *buf, const char *fmt, va_list args) {
u32 ptr = 0;
for (int i = 0; i < strlen(fmt); ++i) {
if (fmt[i] != '%') {
buf[ptr++] = fmt[i];
continue;
}
++i;
u32 arg_width = 0;
while (fmt[i] >= '0' && fmt[i] <= '9') {
arg_width *= 10;
arg_width += fmt[i] - '0';
++i;
}
switch (fmt[i]) {
case 's': { // string
char *s_fmt = (char *) va_arg(args, char*);
while (*s_fmt) {
buf[ptr++] = *s_fmt++;
}
break;
}
case 'c':
buf[ptr++] = (char)va_arg(args, int);
break;
case 'x':
print_int((u32)va_arg(args, u32), arg_width, buf, &ptr, 16);
break;
case 'd':
print_int((u32)va_arg(args, u32), arg_width, buf, &ptr, 10);
break;
case '%':
buf[ptr++] = '%';
break;
default:
printf("FMT '%c' is not supported\n", fmt[i]);
k_panic();
break;
}
}
buf[ptr] = 0;
return ptr;
}
void printf(const char *fmt, ...) {
char buf[1024] = {-1};
va_list args;
va_start(args, fmt);
vasprintf(buf, fmt, args);
va_end(args);
kprint(buf);
}

10
kernel/libc/kprintf.h Normal file
View File

@@ -0,0 +1,10 @@
//
// Created by rick on 06-02-21.
//
#ifndef NEW_KERNEL_KPRINTF_H
#define NEW_KERNEL_KPRINTF_H
void printf(const char *fmt, ...);
#endif //NEW_KERNEL_KPRINTF_H

14
kernel/libc/va_list.h Normal file
View File

@@ -0,0 +1,14 @@
//
// Created by rick on 06-02-21.
//
#ifndef NEW_KERNEL_VA_LIST_H
#define NEW_KERNEL_VA_LIST_H
typedef __builtin_va_list va_list;
#define va_start(ap,last) __builtin_va_start(ap, last)
#define va_end(ap) __builtin_va_end(ap)
#define va_arg(ap,type) __builtin_va_arg(ap,type)
#define va_copy(dest, src) __builtin_va_copy(dest,src)
#endif //NEW_KERNEL_VA_LIST_H