add format string padding
This commit is contained in:
parent
58e8632fb0
commit
e4c652f475
|
@ -30,8 +30,8 @@ void print_havarie_msg() {
|
|||
[esi]"=m" (esi), [edi]"=m" (edi), [esp]"=m" (esp), [ebp]"=m" (ebp)
|
||||
);
|
||||
|
||||
tsprintf("eax=0x%x\t\tesi=0x%x\n", eax, esi);
|
||||
tsprintf("ebx=0x%x\t\tedi=0x%x\n", ebx, edi);
|
||||
tsprintf("ecx=0x%x\t\tesp=0x%x\n", ecx, esp);
|
||||
tsprintf("edx=0x%x\t\tebp=0x%x\n", edx, ebp);
|
||||
tsprintf("eax=0x%08x\t\tesi=0x%08x\n", eax, esi);
|
||||
tsprintf("ebx=0x%08x\t\tedi=0x%08x\n", ebx, edi);
|
||||
tsprintf("ecx=0x%08x\t\tesp=0x%08x\n", ecx, esp);
|
||||
tsprintf("edx=0x%08x\t\tebp=0x%08x\n", edx, ebp);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdarg.h>
|
||||
#include "internal/io.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
|
||||
struct text_screen_char {
|
||||
char character;
|
||||
|
@ -16,13 +17,20 @@ static uint8_t cursor_y = 0;
|
|||
#define SCREEN_WIDTH 80
|
||||
#define SCREEN_HEIGHT 25
|
||||
|
||||
enum printf_format_specifier {
|
||||
enum printf_format_specifier_type {
|
||||
FORMAT_SPECIFIER_INT,
|
||||
FORMAT_SPECIFIER_UNSIGNED,
|
||||
FORMAT_SPECIFIER_HEXADECIMAL,
|
||||
FORMAT_SPEFICIER_UNKNOWN
|
||||
};
|
||||
|
||||
struct printf_format_specifier {
|
||||
enum printf_format_specifier_type type;
|
||||
|
||||
int field_size;
|
||||
char padding_char;
|
||||
};
|
||||
|
||||
void tsinit(void) {
|
||||
outb(0x3D4, 0x0A);
|
||||
outb(0x3D5, 0x20);
|
||||
|
@ -90,50 +98,101 @@ void tsputs(const char* ch, uint8_t color) {
|
|||
}
|
||||
|
||||
static
|
||||
const char* decode_format_spefifier(const char* str, enum printf_format_specifier* data) {
|
||||
const char* decode_format_specifier_flag(const char* str, struct printf_format_specifier* data) {
|
||||
switch (*str) {
|
||||
case '0':
|
||||
data->padding_char = '0';
|
||||
return str+1;
|
||||
}
|
||||
|
||||
data->padding_char = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
static
|
||||
const char* decode_format_specifier_field_width(const char* str, struct printf_format_specifier* data) {
|
||||
char tmp[16];
|
||||
|
||||
int i;
|
||||
for(i = 0; i < 15; i++) {
|
||||
if (*str < '0' || *str > '9') {
|
||||
break;
|
||||
}
|
||||
|
||||
tmp[i] = *str++;
|
||||
}
|
||||
tmp[0] = '8';
|
||||
tmp[1] = 0;
|
||||
tmp[i] = '\0';
|
||||
|
||||
data->field_size = atoi(tmp);
|
||||
return str;
|
||||
}
|
||||
|
||||
static
|
||||
const char* decode_format_spefifier(const char* str, struct printf_format_specifier* data) {
|
||||
switch (*str) {
|
||||
case 'd':
|
||||
case 'i':
|
||||
*data = FORMAT_SPECIFIER_INT;
|
||||
data->type = FORMAT_SPECIFIER_INT;
|
||||
return str+1;
|
||||
|
||||
case 'o':
|
||||
case 'u':
|
||||
*data = FORMAT_SPECIFIER_UNSIGNED;
|
||||
data->type = FORMAT_SPECIFIER_UNSIGNED;
|
||||
return str+1;
|
||||
|
||||
case 'x':
|
||||
case 'X':
|
||||
*data = FORMAT_SPECIFIER_HEXADECIMAL;
|
||||
data->type = FORMAT_SPECIFIER_HEXADECIMAL;
|
||||
return str+1;
|
||||
}
|
||||
|
||||
*data = FORMAT_SPEFICIER_UNKNOWN;
|
||||
data->type = FORMAT_SPEFICIER_UNKNOWN;
|
||||
return str;
|
||||
}
|
||||
|
||||
static
|
||||
void put_formated_string(const char* str, const struct printf_format_specifier* specifier) {
|
||||
// Padding
|
||||
if (specifier->padding_char != '\0') {
|
||||
size_t length = strlen(str);
|
||||
|
||||
while ((int)length < specifier->field_size) {
|
||||
tsputch(specifier->padding_char, TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_WHITE);
|
||||
length++;
|
||||
}
|
||||
}
|
||||
|
||||
tsputs(str, TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_WHITE);
|
||||
}
|
||||
|
||||
static
|
||||
const char* handle_format_specifier(const char* str, va_list* args) {
|
||||
str++;
|
||||
char tmp[16];
|
||||
|
||||
enum printf_format_specifier specifier;
|
||||
struct printf_format_specifier specifier;
|
||||
|
||||
str = decode_format_specifier_flag(str, &specifier);
|
||||
str = decode_format_specifier_field_width(str, &specifier);
|
||||
|
||||
str = decode_format_spefifier(str, &specifier);
|
||||
switch (specifier) {
|
||||
switch (specifier.type) {
|
||||
case FORMAT_SPECIFIER_INT: {
|
||||
int value = va_arg(*args, int);
|
||||
tsputs(itoa(value, tmp, 10), TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_WHITE);
|
||||
put_formated_string(itoa(value, tmp, 10), &specifier);
|
||||
} break;
|
||||
|
||||
case FORMAT_SPECIFIER_UNSIGNED: {
|
||||
unsigned int value = va_arg(*args, unsigned int);
|
||||
tsputs(utoa(value, tmp, 10), TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_WHITE);
|
||||
put_formated_string(utoa(value, tmp, 10), &specifier);
|
||||
} break;
|
||||
|
||||
|
||||
case FORMAT_SPECIFIER_HEXADECIMAL: {
|
||||
unsigned int value = va_arg(*args, unsigned int);
|
||||
tsputs(utoa(value, tmp, 16), TEXT_SCREEN_BG_BLACK | TEXT_SCREEN_FG_WHITE);
|
||||
put_formated_string(utoa(value, tmp, 16), &specifier);
|
||||
} break;
|
||||
default: return str;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue