#include #include /* This function exists solely so crashes don't happen if putc() gets * called before it is initialized. */ void putc_initial(char c) { (void)c; } void (*putc)(char) = &putc_initial; void print_init(void (*putcfn)(char)) { if (putcfn) putc = putcfn; } void puts(const char *s) { while (*s) putc (*s++); } void puti(int i) { unsigned int left; char buf[1 << (sizeof(int)*8) / 10]; char *p = buf; unsigned char negative = i < 0; if (!i) putc('0'); left = negative ? -1*i : i; while (left) { unsigned int remainder = left % 10; left /= 10; *p = ('0'-0) + remainder; p++; } if (negative) putc('-'); while (p-- != buf) putc(*p); } void putx(unsigned int i) { unsigned int left = i; char buf[1 << (sizeof(int)*8) / 16]; char *p = buf; puts("0x"); if (!i) putc('0'); while (left) { unsigned int remainder = left % 16; left /= 16; if (remainder < 10) *p = ('0'-0) + remainder; else *p = ('a'-10) + remainder; p++; } while (p-- != buf) putc(*p); } int print(char *fmt, ...) { char *c; va_list arg; va_start(arg, fmt); for (c = fmt; *c; c++) { if (*c == '%') { switch (*++c) { case '%': putc('%'); break; case 's': puts(va_arg(arg, char *)); break; case 'c': putc(va_arg(arg, unsigned int)); break; case 'd': puti(va_arg(arg, int)); break; case 'x': putx(va_arg(arg, unsigned int)); break; default: puts("\nError: print(): Invalid formatting character: '"); putc(*c); puts("'\n"); return -1; } } else { putc(*c); } } va_end(arg); return 0; }