feature (kernel): implemented basic format strings

This commit is contained in:
antifallobst 2023-02-12 01:26:41 +01:00
parent 3787701642
commit 58124b6cdb
3 changed files with 272 additions and 4 deletions

View File

@ -17,11 +17,18 @@
#define NOX_STRING_H #define NOX_STRING_H
#include "stdtypes.h" #include "stdtypes.h"
#include <stdarg.h>
typedef const char* string_t; typedef const char* string_t;
uint32_t string_length (string_t string); uint32_t string_length (string_t string);
bool string_compare (string_t a, string_t b); bool string_compare (string_t a, string_t b);
uint64_t variadic_format_size (string_t string, va_list args);
uint64_t format_size (string_t string, ...);
void variadic_format (string_t output, string_t string, va_list args);
void format (string_t output, string_t string, ...);
void string_unsigned_dec_to_alpha (string_t string, uint64_t value); void string_unsigned_dec_to_alpha (string_t string, uint64_t value);
void string_dec_to_alpha (string_t string, int64_t value); void string_dec_to_alpha (string_t string, int64_t value);
void string_hex_8bit_to_alpha (string_t string, uint8_t value); void string_hex_8bit_to_alpha (string_t string, uint8_t value);

View File

@ -41,12 +41,16 @@ void kmain(boot_info_T boot_info) {
kernel_init(&boot_info); kernel_init(&boot_info);
// this should cause a kernel panic uint64_t size = format_size("Test: %d", 1312);
// int x = 1312 / 0;
char string[size];
format(string, "Test: %d", 1312);
char buf[16];
format(buf, "size: %d", size);
char string[17];
string_hex_64bit_to_alpha(string, &kmain);
log(LOG_DEBUG, string); log(LOG_DEBUG, string);
log(LOG_DEBUG, buf);
CORE_HALT_FOREVER CORE_HALT_FOREVER

View File

@ -40,6 +40,263 @@ bool string_compare(string_t a, string_t b) {
return memory_compare(a, b, a_len); return memory_compare(a, b, a_len);
} }
uint64_t variadic_format_size(string_t string, va_list args) {
const char* buffer_in = (const char*)string;
uint64_t length = 0;
while(*buffer_in != '\0') {
if (*buffer_in == '%') {
uint8_t numeric_specifier = 0;
buffer_in++;
if (*buffer_in == '.') {
buffer_in++;
while (*buffer_in > '0' && *buffer_in < '9') {
numeric_specifier *= 10;
numeric_specifier += *buffer_in - '0';
buffer_in++;
}
}
switch(*buffer_in) {
case '%': {
length++;
break;
}
case 's': {
// string
length += string_length(va_arg(args, string_t));
break;
}
case 'c': {
// char
char tmp = (char)va_arg(args, int);
length++;
break;
}
case 'u': {
// decimal unsigned int
char str[32];
string_unsigned_dec_to_alpha(str, va_arg(args, uint64_t));
length += string_length(str);
break;
}
case 'd': {
// decimal signed int
char str[32];
string_dec_to_alpha(str, va_arg(args, int64_t));
length += string_length(str);
break;
}
case 'x': {
// Hexadecimal int
char str[32];
buffer_in++;
switch(*buffer_in) {
case 'b': {
// byte
string_hex_8bit_to_alpha(str, va_arg(args, int));
break;
}
case 'w': {
// word
string_hex_16bit_to_alpha(str, va_arg(args, int));
break;
}
case 'd': {
// dword
string_hex_32bit_to_alpha(str, va_arg(args, uint32_t));
break;
}
case 'q': {
// qword
string_hex_64bit_to_alpha(str, va_arg(args, uint64_t));
break;
}
default: {
string_hex_64bit_to_alpha(str, va_arg(args, uint64_t));
buffer_in--;
break;
}
}
length += string_length(str);
break;
}
case '?': {
char str[7];
string_bool_to_alpha(str, (bool)va_arg(args, int));
length += string_length(str);
break;
}
case 'b': {
if (numeric_specifier == 0) {
numeric_specifier = 64;
}
char str[65];
string_bin_to_alpha(str, numeric_specifier, va_arg(args, uint64_t));
length += string_length(str);
break;
}
}
} else {
length++;
}
buffer_in++;
}
length++;
return length;
}
uint64_t format_size(string_t string, ...) {
va_list args;
va_start(args, string);
uint64_t size = variadic_format_size(string, args);
va_end(args);
return size;
}
void variadic_format(string_t output, string_t string, va_list args) {
char* buffer_out = (char*)output;
const char* buffer_in = (const char*)string;
while(*buffer_in != '\0') {
if (*buffer_in == '%') {
uint8_t numeric_specifier = 0;
buffer_in++;
if (*buffer_in == '.') {
buffer_in++;
while (*buffer_in > '0' && *buffer_in < '9') {
numeric_specifier *= 10;
numeric_specifier += *buffer_in - '0';
buffer_in++;
}
}
switch(*buffer_in) {
case '%': {
*buffer_out = '%';
buffer_out++;
break;
}
case 's': {
// string
string_t str = va_arg(args, string_t);
uint64_t strlen = string_length(str);
memory_copy((void*)str, buffer_out, strlen);
buffer_out += strlen;
break;
}
case 'c': {
// char
*buffer_out = (char)va_arg(args, int);
buffer_out++;
break;
}
case 'u': {
// decimal unsigned int
char str[32];
string_unsigned_dec_to_alpha(str, va_arg(args, uint64_t));
uint64_t strlen = string_length(str);
memory_copy((void*)str, buffer_out, strlen);
buffer_out += strlen;
break;
}
case 'd': {
// decimal signed int
char str[32];
string_dec_to_alpha(str, va_arg(args, int64_t));
uint64_t strlen = string_length(str);
memory_copy((void*)str, buffer_out, strlen);
buffer_out += strlen;
break;
}
case 'x': {
// Hexadecimal int
char str[32];
buffer_in++;
switch(*buffer_in) {
case 'b': {
// byte
string_hex_8bit_to_alpha(str, va_arg(args, int));
break;
}
case 'w': {
// word
string_hex_16bit_to_alpha(str, va_arg(args, int));
break;
}
case 'd': {
// dword
string_hex_32bit_to_alpha(str, va_arg(args, uint32_t));
break;
}
case 'q': {
// qword
string_hex_64bit_to_alpha(str, va_arg(args, uint64_t));
break;
}
default: {
string_hex_64bit_to_alpha(str, va_arg(args, uint64_t));
buffer_in--;
break;
}
}
uint64_t strlen = string_length(str);
memory_copy((void*)str, buffer_out, strlen);
buffer_out += strlen;
break;
}
case '?': {
char str[7];
string_bool_to_alpha(str, (bool)va_arg(args, int));
uint64_t strlen = string_length(str);
memory_copy((void*)str, buffer_out, strlen);
buffer_out += strlen;
break;
}
case 'b': {
if (numeric_specifier == 0) {
numeric_specifier = 64;
}
char str[65];
string_bin_to_alpha(str, numeric_specifier, va_arg(args, uint64_t));
uint64_t strlen = string_length(str);
memory_copy((void*)str, buffer_out, strlen);
buffer_out += strlen;
break;
}
}
} else {
*buffer_out = *buffer_in;
buffer_out++;
}
buffer_in++;
}
*buffer_out = '\0';
}
void format(string_t output, string_t string, ...) {
va_list args;
va_start(args, string);
variadic_format(output, string, args);
va_end(args);
}
void string_unsigned_dec_to_alpha(string_t string, uint64_t value) { void string_unsigned_dec_to_alpha(string_t string, uint64_t value) {
char* buffer = (char*)string; char* buffer = (char*)string;
uint8_t length = 0; uint8_t length = 0;