kprint
This commit is contained in:
parent
dc0487648a
commit
74a39e1822
1 changed files with 103 additions and 0 deletions
103
kern/kprint.c
Normal file
103
kern/kprint.c
Normal file
|
@ -0,0 +1,103 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
static void append_char(char **buf, size_t *remaining, char c) {
|
||||
if (*remaining > 1) { // Leave space for null terminator
|
||||
**buf = c;
|
||||
(*buf)++;
|
||||
(*remaining)--;
|
||||
}
|
||||
}
|
||||
|
||||
static void append_str(char **buf, size_t *remaining, const char *str) {
|
||||
while (*str) {
|
||||
append_char(buf, remaining, *str++);
|
||||
}
|
||||
}
|
||||
|
||||
static void append_int(char **buf, size_t *remaining, int value, int base) {
|
||||
char tmp[32];
|
||||
const char *digits = "0123456789abcdef";
|
||||
bool neg = false;
|
||||
int i = 0;
|
||||
|
||||
if (base == 10 && value < 0) {
|
||||
neg = true;
|
||||
value = -value;
|
||||
}
|
||||
|
||||
do {
|
||||
tmp[i++] = digits[value % base];
|
||||
value /= base;
|
||||
} while (value && i < (int)sizeof(tmp));
|
||||
|
||||
if (neg) {
|
||||
tmp[i++] = '-';
|
||||
}
|
||||
|
||||
while (i--) {
|
||||
append_char(buf, remaining, tmp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int kvsnprintf(char *buf, size_t size, const char *fmt, va_list args) {
|
||||
char *p = buf;
|
||||
size_t remaining = size;
|
||||
|
||||
while (*fmt) {
|
||||
if (*fmt != '%') {
|
||||
append_char(&p, &remaining, *fmt++);
|
||||
continue;
|
||||
}
|
||||
fmt++; // skip '%'
|
||||
|
||||
switch (*fmt) {
|
||||
case 's':
|
||||
append_str(&p, &remaining, va_arg(args, const char *));
|
||||
break;
|
||||
case 'd':
|
||||
append_int(&p, &remaining, va_arg(args, int), 10);
|
||||
break;
|
||||
case 'x':
|
||||
append_int(&p, &remaining, va_arg(args, unsigned int), 16);
|
||||
break;
|
||||
case 'c':
|
||||
append_char(&p, &remaining, (char)va_arg(args, int));
|
||||
break;
|
||||
case '%':
|
||||
append_char(&p, &remaining, '%');
|
||||
break;
|
||||
default:
|
||||
append_char(&p, &remaining, '?');
|
||||
break;
|
||||
}
|
||||
fmt++;
|
||||
}
|
||||
|
||||
if (remaining > 0) {
|
||||
*p = '\0';
|
||||
} else {
|
||||
buf[size - 1] = '\0';
|
||||
}
|
||||
|
||||
return (int)(p - buf);
|
||||
}
|
||||
|
||||
int ksnprintf(char *buf, size_t size, const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int ret = kvsnprintf(buf, size, fmt, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void kprintf(const char *fmt, ...) {
|
||||
char buffer[256];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
kvsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
// Now send buffer to your console/serial output
|
||||
console_write(buffer);
|
||||
}
|
Loading…
Add table
Reference in a new issue