#include "kio.h" #include "string.h" #include #include /* va_*() */ static void fmt_d2a(char * buf, int val); static void fmt_u2a(char * buf, unsigned int val); static void fmt_ll2a(char * buf, long long val); static void fmt_ull2a(char * buf, unsigned long long val); static void fmt_x2a(char * buf, unsigned int val); static void fmt_o2a(char * buf, unsigned int val); extern "C" { void kprintf(char * fmt, ...) { va_list args; va_start(args, fmt); kvprintf(fmt, args); va_end(args); } void kvprintf(char * fmt, va_list args) { char tmpbuf[25]; for ( ; *fmt; fmt++) { if (*fmt == '%') { fmt++; if (*fmt) { switch (*fmt) { case 'c': kputc(va_arg(args, int)); break; case 'd': fmt_d2a(tmpbuf, va_arg(args, int)); kputs(tmpbuf); break; case 'l': fmt_ll2a(tmpbuf, va_arg(args, long long)); kputs(tmpbuf); break; case 'L': fmt_ull2a(tmpbuf, va_arg(args, unsigned long long)); kputs(tmpbuf); break; case 'o': fmt_o2a(tmpbuf, va_arg(args, unsigned int)); kputs(tmpbuf); break; case 's': kputs(va_arg(args, char *)); break; case 'u': fmt_u2a(tmpbuf, va_arg(args, unsigned int)); kputs(tmpbuf); break; case 'x': fmt_x2a(tmpbuf, va_arg(args, unsigned int)); kputs(tmpbuf); break; case '%': kputc('%'); break; } } } else { kputc(*fmt); } } } void kputc(char c) { } void kputs(char * s) { while (*s) { kputc(*s); s++; } } } /* extern "C" */ static void fmt_d2a(char * buf, int val) { if (val == INT_MIN) { strcpy(buf, "-2147483648"); } else { if (val < 0) { *buf++ = '-'; val = -val; } fmt_u2a(buf, (unsigned int) val); } } static void fmt_u2a(char * buf, unsigned int val) { bool printing = false; for (unsigned int div = 1000000000; div >= 1; div /= 10) { unsigned int n = val / div; if (n) { printing = true; } if (printing) { *buf++ = '0' + (val % div); } val -= n * div; } } static void fmt_ll2a(char * buf, long long val) { if (val == LONG_LONG_MIN) { strcpy(buf, "-9223372036854775808"); } else { if (val < 0) { *buf++ = '-'; val = -val; } fmt_ull2a(buf, (unsigned long long) val); } } static void fmt_ull2a(char * buf, unsigned long long val) { bool printing = false; for (unsigned long long div = 10000000000000000000ull; div >= 1; div /= 10) { unsigned long long n = val / div; if (n) { printing = true; } if (printing) { *buf++ = '0' + (val % div); } val -= n * div; } } static void fmt_x2a(char * buf, unsigned int val) { bool printing = false; for (int s = 28; s >= 0; s -= 4) { unsigned int n = (val >> s) & 0xF; if (n) { printing = true; } if (printing) { *buf++ = "0123456789ABCDEF"[n]; } } } static void fmt_o2a(char * buf, unsigned int val) { bool printing = false; for (int s = 30; s >= 0; s -= 3) { unsigned int n = (val >> s) & 0x7; if (n) { printing = true; } if (printing) { *buf++ = "01234567"[n]; } } }