82 lines
1.5 KiB
C
82 lines
1.5 KiB
C
#include "common.h"
|
|
|
|
void putchar(char ch);
|
|
|
|
void *memset(void *buf, int c, size_t n) {
|
|
uint8_t *p = (uint8_t*)buf;
|
|
while (n--) *p++ = (uint8_t)c;
|
|
return buf;
|
|
}
|
|
|
|
static void print_uint_hex(uint32_t v) {
|
|
for (int i = 7; i >= 0; i--) {
|
|
uint32_t nib = (v >> (i * 4)) & 0xF;
|
|
putchar("0123456789abcdef"[nib]);
|
|
}
|
|
}
|
|
|
|
static void print_int_dec(int v) {
|
|
if (v == 0) { putchar('0'); return; }
|
|
if (v < 0) { putchar('-'); v = -v; }
|
|
|
|
int div = 1;
|
|
while (v / div > 9) div *= 10;
|
|
|
|
while (div > 0) {
|
|
putchar('0' + (v / div));
|
|
v %= div;
|
|
div /= 10;
|
|
}
|
|
}
|
|
|
|
void printf(const char *fmt, ...) {
|
|
va_list ap;
|
|
va_start(ap, fmt);
|
|
|
|
while (*fmt) {
|
|
if (*fmt != '%') {
|
|
putchar(*fmt++);
|
|
continue;
|
|
}
|
|
|
|
fmt++;
|
|
char spec = *fmt ? *fmt : '\0';
|
|
|
|
if (spec == '\0') { putchar('%'); break; }
|
|
|
|
switch (spec) {
|
|
case '%':
|
|
putchar('%');
|
|
break;
|
|
case 'c': {
|
|
int ch = va_arg(ap, int);
|
|
putchar((char)ch);
|
|
break;
|
|
}
|
|
case 's': {
|
|
const char *s = va_arg(ap, const char*);
|
|
if (!s) s = "(null)";
|
|
while (*s) putchar(*s++);
|
|
break;
|
|
}
|
|
case 'd': {
|
|
int v = va_arg(ap, int);
|
|
print_int_dec(v);
|
|
break;
|
|
}
|
|
case 'x': {
|
|
uint32_t v = va_arg(ap, uint32_t);
|
|
print_uint_hex(v);
|
|
break;
|
|
}
|
|
default:
|
|
putchar('%');
|
|
putchar(spec);
|
|
break;
|
|
}
|
|
|
|
fmt++;
|
|
}
|
|
|
|
va_end(ap);
|
|
} |