107 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <print.h>
 | |
| #include <vargs.h>
 | |
| 
 | |
| /* 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;
 | |
| }
 |