feature (kernel): implemented basic format strings
This commit is contained in:
parent
3787701642
commit
58124b6cdb
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue