Add basic printing/formatting infrastructure for debugging
This commit is contained in:
		
							
								
								
									
										106
									
								
								kernel/print.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								kernel/print.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| #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; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user