Kernel: Serial: Add serial_printf function
This function can output with decorators (like printf from stdio)
This commit is contained in:
parent
99888ea24d
commit
beaa4078f7
|
@ -7,12 +7,12 @@
|
|||
|
||||
void kernel_main(void) {
|
||||
terminal_initialize();
|
||||
init_serial();
|
||||
printf("Hello from OrionOS!\n");
|
||||
printf("Testing serial\n");
|
||||
init_serial();
|
||||
serial_print("Test is success!\n");
|
||||
serial_print("Newline test\n");
|
||||
serial_print("No newline test ");
|
||||
serial_print("No newline test");
|
||||
serial_printf("Test is success!\n");
|
||||
serial_printf("Newline test\n");
|
||||
char * test_string = "test";
|
||||
serial_printf("This is string from variable: %s", test_string);
|
||||
printf("Test finished success!\n");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define PORT 0x3f8 // COM1
|
||||
|
||||
|
@ -45,16 +48,84 @@ void write_serial(char a) {
|
|||
outb(PORT, a);
|
||||
}
|
||||
|
||||
void serial_print(const char* str, ...) {
|
||||
size_t len = strlen(str);
|
||||
for (size_t i=0; i < len; i++) {
|
||||
if (str[i] == '\n') {
|
||||
static bool print(const char* data, size_t length) {
|
||||
const unsigned char* bytes = (const unsigned char*) data;
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
if (bytes[i] == '\n') {
|
||||
write_serial('\r');
|
||||
write_serial('\n');
|
||||
} else {
|
||||
write_serial(str[i]);
|
||||
write_serial(bytes[i]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int serial_printf(const char* restrict format, ...) {
|
||||
va_list parameters;
|
||||
va_start(parameters, format);
|
||||
|
||||
int written = 0;
|
||||
|
||||
while (*format != '\0') {
|
||||
size_t maxrem = INT_MAX - written;
|
||||
|
||||
if (format[0] != '%' || format[1] == '%') {
|
||||
if (format[0] == '%')
|
||||
format++;
|
||||
size_t amount = 1;
|
||||
while (format[amount] && format[amount] != '%')
|
||||
amount++;
|
||||
if (maxrem < amount) {
|
||||
// TODO: Set errno to EOVERFLOW.
|
||||
return -1;
|
||||
}
|
||||
if (!print(format, amount))
|
||||
return -1;
|
||||
format += amount;
|
||||
written += amount;
|
||||
continue;
|
||||
}
|
||||
|
||||
const char* format_begun_at = format++;
|
||||
|
||||
if (*format == 'c') {
|
||||
format++;
|
||||
char c = (char) va_arg(parameters, int /* char promotes to int */);
|
||||
if (!maxrem) {
|
||||
// TODO: Set errno to EOVERFLOW.
|
||||
return -1;
|
||||
}
|
||||
if (!print(&c, sizeof(c)))
|
||||
return -1;
|
||||
written++;
|
||||
} else if (*format == 's') {
|
||||
format++;
|
||||
const char* str = va_arg(parameters, const char*);
|
||||
size_t len = strlen(str);
|
||||
if (maxrem < len) {
|
||||
// TODO: Set errno to EOVERFLOW.
|
||||
return -1;
|
||||
}
|
||||
if (!print(str, len))
|
||||
return -1;
|
||||
written += len;
|
||||
} else {
|
||||
format = format_begun_at;
|
||||
size_t len = strlen(format);
|
||||
if (maxrem < len) {
|
||||
// TODO: Set errno to EOVERFLOW.
|
||||
return -1;
|
||||
}
|
||||
if (!print(format, len))
|
||||
return -1;
|
||||
written += len;
|
||||
format += len;
|
||||
}
|
||||
}
|
||||
|
||||
va_end(parameters);
|
||||
return written;
|
||||
}
|
||||
|
||||
inline void outb(uint16_t port, uint8_t val)
|
||||
|
|
Loading…
Reference in New Issue