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)
|
[esi]"=m" (esi), [edi]"=m" (edi), [esp]"=m" (esp), [ebp]"=m" (ebp)
|
||||||
);
|
);
|
||||||
|
|
||||||
tsprintf("eax=0x%x\t\tesi=0x%x\n", eax, esi);
|
tsprintf("eax=0x%08x\t\tesi=0x%08x\n", eax, esi);
|
||||||
tsprintf("ebx=0x%x\t\tedi=0x%x\n", ebx, edi);
|
tsprintf("ebx=0x%08x\t\tedi=0x%08x\n", ebx, edi);
|
||||||
tsprintf("ecx=0x%x\t\tesp=0x%x\n", ecx, esp);
|
tsprintf("ecx=0x%08x\t\tesp=0x%08x\n", ecx, esp);
|
||||||
tsprintf("edx=0x%x\t\tebp=0x%x\n", edx, ebp);
|
tsprintf("edx=0x%08x\t\tebp=0x%08x\n", edx, ebp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "internal/io.h"
|
#include "internal/io.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
struct text_screen_char {
|
struct text_screen_char {
|
||||||
char character;
|
char character;
|
||||||
|
@ -16,13 +17,20 @@ static uint8_t cursor_y = 0;
|
||||||
#define SCREEN_WIDTH 80
|
#define SCREEN_WIDTH 80
|
||||||
#define SCREEN_HEIGHT 25
|
#define SCREEN_HEIGHT 25
|
||||||
|
|
||||||
enum printf_format_specifier {
|
enum printf_format_specifier_type {
|
||||||
FORMAT_SPECIFIER_INT,
|
FORMAT_SPECIFIER_INT,
|
||||||
FORMAT_SPECIFIER_UNSIGNED,
|
FORMAT_SPECIFIER_UNSIGNED,
|
||||||
FORMAT_SPECIFIER_HEXADECIMAL,
|
FORMAT_SPECIFIER_HEXADECIMAL,
|
||||||
FORMAT_SPEFICIER_UNKNOWN
|
FORMAT_SPEFICIER_UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct printf_format_specifier {
|
||||||
|
enum printf_format_specifier_type type;
|
||||||
|
|
||||||
|
int field_size;
|
||||||
|
char padding_char;
|
||||||
|
};
|
||||||
|
|
||||||
void tsinit(void) {
|
void tsinit(void) {
|
||||||
outb(0x3D4, 0x0A);
|
outb(0x3D4, 0x0A);
|
||||||
outb(0x3D5, 0x20);
|
outb(0x3D5, 0x20);
|
||||||
|
@ -90,50 +98,101 @@ void tsputs(const char* ch, uint8_t color) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
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) {
|
switch (*str) {
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'i':
|
case 'i':
|
||||||
*data = FORMAT_SPECIFIER_INT;
|
data->type = FORMAT_SPECIFIER_INT;
|
||||||
return str+1;
|
return str+1;
|
||||||
|
|
||||||
case 'o':
|
case 'o':
|
||||||
case 'u':
|
case 'u':
|
||||||
*data = FORMAT_SPECIFIER_UNSIGNED;
|
data->type = FORMAT_SPECIFIER_UNSIGNED;
|
||||||
return str+1;
|
return str+1;
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'X':
|
case 'X':
|
||||||
*data = FORMAT_SPECIFIER_HEXADECIMAL;
|
data->type = FORMAT_SPECIFIER_HEXADECIMAL;
|
||||||
return str+1;
|
return str+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*data = FORMAT_SPEFICIER_UNKNOWN;
|
data->type = FORMAT_SPEFICIER_UNKNOWN;
|
||||||
return str;
|
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
|
static
|
||||||
const char* handle_format_specifier(const char* str, va_list* args) {
|
const char* handle_format_specifier(const char* str, va_list* args) {
|
||||||
str++;
|
str++;
|
||||||
char tmp[16];
|
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);
|
str = decode_format_spefifier(str, &specifier);
|
||||||
switch (specifier) {
|
switch (specifier.type) {
|
||||||
case FORMAT_SPECIFIER_INT: {
|
case FORMAT_SPECIFIER_INT: {
|
||||||
int value = va_arg(*args, 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;
|
} break;
|
||||||
|
|
||||||
case FORMAT_SPECIFIER_UNSIGNED: {
|
case FORMAT_SPECIFIER_UNSIGNED: {
|
||||||
unsigned int value = va_arg(*args, unsigned int);
|
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;
|
} break;
|
||||||
|
|
||||||
|
|
||||||
case FORMAT_SPECIFIER_HEXADECIMAL: {
|
case FORMAT_SPECIFIER_HEXADECIMAL: {
|
||||||
unsigned int value = va_arg(*args, unsigned int);
|
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;
|
} break;
|
||||||
default: return str;
|
default: return str;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue