Debug printing functions

This commit is contained in:
Thomas Lovén 2017-12-01 22:16:26 +01:00
parent a766726065
commit d05ddfeab4
3 changed files with 242 additions and 0 deletions

116
src/kernel/boot/debug.c Normal file
View File

@ -0,0 +1,116 @@
#include <stddef.h>
#include <stdarg.h>
#include <stdint.h>
// TODO: Temporary declarations
void vga_write(char c);
void serial_write(int port, char c);
#define PORT_COM1 0
void num2str(char *buf, uint64_t num, uint64_t base)
{
if(num == 0)
{
buf[0] = '0';
buf[1] = '\0';
return;
}
uint64_t i=0, j=0;
char chars[] = "0123456789ABCDEF";
while(num > 0)
{
buf[i++] = chars[num%base];
num /= base;
}
i--;
while(j<i)
{
char t = buf[i];
buf[i--] = buf[j];
buf[j++] = t;
}
buf[i+j+1] = '\0';
}
void debug_putch(char c)
{
vga_write(c);
serial_write(PORT_COM1, c);
}
void debug_putsn(char *s, size_t n)
{
while(n--)
debug_putch(*s++);
}
void debug_puts(char *s)
{
size_t len = 0;
while(s[len]) len++;
debug_putsn(s, len);
}
void debug_vprintf(char *fmt, va_list args)
{
if(!(*fmt))
return;
if(*fmt != '%')
{
size_t len = 0;
while(fmt[len] && fmt[len] != '%')
len++;
debug_putsn(fmt, len);
debug_vprintf(&fmt[len], args);
return;
}
fmt++;
uint64_t base = 0;
switch(*fmt)
{
case 'b':
base = 2;
break;
case 'o':
base = 8;
break;
case 'd':
base = 10;
break;
case 'x':
base = 16;
break;
case 'c':
debug_putch((char)va_arg(args, uint64_t));
break;
case 's':
debug_puts(va_arg(args, char*));
break;
default:
debug_putch('%');
fmt--;
}
if(base)
{
uintmax_t number = va_arg(args, uintmax_t);
char buf[128];
num2str(buf, number, base);
debug_puts(buf);
}
fmt++;
debug_vprintf(fmt, args);
}
void debug_printf(char *fmt, ...)
{
va_list args;
va_start(args, fmt);
debug_vprintf(fmt, args);
va_end(args);
}

117
src/kernel/boot/debug.tt Normal file
View File

@ -0,0 +1,117 @@
// vim: ft=c
#include <ttest.h>
#include "debug.c"
#define BUFFER_SIZE 16
char vga_recv[BUFFER_SIZE];
char serial_recv[BUFFER_SIZE];
BEFORE()
{
for(int i = 0; i < BUFFER_SIZE; i++)
{
vga_recv[i] = '\0';
serial_recv[i] = '\0';
}
}
void vga_write(char c)
{
static int i = 0;
vga_recv[i++] = c;
}
void serial_write(int port, char c)
{
(void)port;
static int i = 0;
serial_recv[i++] = c;
}
TEST(putch_sends_character_to_vga)
{
char input = 'a';
debug_putch(input);
ASSERT_EQ_CHR(vga_recv[0], input);
}
TEST(putch_sends_character_to_serial)
{
char input = 'a';
debug_putch(input);
ASSERT_EQ_CHR(serial_recv[0], input);
}
TEST(putsn_writes_string)
{
char *str = "hello";
debug_putsn(str, 5);
ASSERT_EQ_STR(vga_recv, str, BUFFER_SIZE);
}
TEST(putsn_writes_correct_number_of_characters)
{
char *str = "1234567890";
debug_putsn(str, 5);
ASSERT_EQ_STR(vga_recv, "12345", BUFFER_SIZE);
}
TEST(puts_writes_string)
{
char *str = "world";
debug_puts(str);
ASSERT_EQ_STR(vga_recv, str, BUFFER_SIZE);
}
TEST(printf_prints_string)
{
char *str = "Hello, world!";
debug_printf(str);
ASSERT_EQ_STR(vga_recv, str, BUFFER_SIZE);
}
TEST(printf_does_not_print_percent)
{
debug_printf("123%d", 45);
ASSERT_NEQ_CHR(vga_recv[3], '%');
}
TEST(printf_prints_binary_number)
{
debug_printf("%b", 0x55aa);
ASSERT_EQ_STR(vga_recv, "101010110101010", BUFFER_SIZE);
}
TEST(printf_prints_ocal_number)
{
debug_printf("%o", 8);
ASSERT_EQ_STR(vga_recv, "10", BUFFER_SIZE);
}
TEST(printf_prints_decimal_number)
{
debug_printf("%d", 123);
ASSERT_EQ_STR(vga_recv, "123", BUFFER_SIZE);
}
TEST(printf_prints_hexadecimal_number)
{
debug_printf("%x", 42);
ASSERT_EQ_STR(vga_recv, "2A", BUFFER_SIZE);
}
TEST(printf_prints_char)
{
debug_printf("%c", 'X');
ASSERT_EQ_STR(vga_recv, "X", BUFFER_SIZE);
}
TEST(printf_prints_passed_string)
{
debug_printf("%s", "asdf");
ASSERT_EQ_STR(vga_recv, "asdf", BUFFER_SIZE);
}
TEST(printf_keeps_printing_after_number)
{
debug_printf("%x123", 0);
ASSERT_EQ_STR(vga_recv, "0123", BUFFER_SIZE);
}
TEST(printf_prints_text_around_number)
{
debug_printf("ABC%dDEF", 0);
ASSERT_EQ_STR(vga_recv, "ABC0DEF", BUFFER_SIZE);
}
TEST(printf_keeps_going_for_unknown_format_specifier)
{
debug_printf("%y");
ASSERT_EQ_STR(vga_recv, "%y", BUFFER_SIZE);
}

View File

@ -0,0 +1,9 @@
#pragma once
#include <stddef.h>
#include <stdarg.h>
void debug_putch(char c);
void debug_putsn(char *s, size_t n);
void debug_puts(char *s);
void debug_vprintf(char *fmt, va_list args);
void debug_printf(char *fmt, ...);