cowos

custom OS from scratch in C
git clone git://git.daat.foo/cowos.git
Log | Files | Refs | README | LICENSE

stdio.c (1963B)


      1 #include <limits.h>
      2 #include <stdarg.h>
      3 /* #include <tty.h> */
      4 #include <klibc/stdio.h>
      5 #include <klibc/string.h>
      6 
      7 /* returns 1 for true, adhering to suckless */
      8 static int
      9 print(const char* data, size_t length)
     10 {
     11 	const unsigned char* bytes = (const unsigned char*) data;
     12 	for (size_t i = 0; i < length; i++) {
     13 		if (putchar(bytes[i]) == EOF) {
     14 			return 0;
     15                 }
     16         }
     17 	return 1;
     18 }
     19 
     20 /* todo: set errno to eoverflow for some cases in which errno should not be used */
     21 int
     22 printf(const char* restrict format, ...)
     23 {
     24 	va_list parameters;
     25 	va_start(parameters, format);
     26 
     27 	int written = 0;
     28 
     29 	while (*format != '\0') {
     30 		size_t maxrem = INT_MAX - written;
     31 
     32 		if (format[0] != '%' || format[1] == '%') {
     33 			if (format[0] == '%')
     34 				format++;
     35 			size_t amount = 1;
     36 			while (format[amount] && format[amount] != '%')
     37 				amount++;
     38 			if (maxrem < amount) {
     39 				return -1;
     40 			}
     41 			if (!print(format, amount))
     42 				return -1;
     43 			format += amount;
     44 			written += amount;
     45 			continue;
     46 		}
     47 
     48 		const char* format_begun_at = format++;
     49 
     50 		if (*format == 'c') {
     51 			format++;
     52 			char c = (char) va_arg(parameters, int /* char promotes to int */);
     53 			if (!maxrem) {
     54 				return -1;
     55 			}
     56 			if (!print(&c, sizeof(c))) {
     57 				return -1;
     58                         }
     59 			written++;
     60 		} else if (*format == 's') {
     61 			format++;
     62 			const char* str = va_arg(parameters, const char*);
     63 			size_t len = strlen(str);
     64 			if (maxrem < len) {
     65 				return -1;
     66 			}
     67 			if (!print(str, len)) {
     68 				return -1;
     69                         }
     70 			written += len;
     71 		} else {
     72 			format = format_begun_at;
     73 			size_t len = strlen(format);
     74 			if (maxrem < len) {
     75 				return -1;
     76 			}
     77 			if (!print(format, len)) {
     78 				return -1;
     79                         }
     80 			written += len;
     81 			format += len;
     82 		}
     83 	}
     84 
     85 	va_end(parameters);
     86 	return written;
     87 }
     88 
     89 /* todo: Implement stdio and the write system call. */
     90 int
     91 putchar(int ic)
     92 {
     93 	return ic;
     94 }
     95 
     96 int
     97 puts(const char* string)
     98 {
     99         return printf("%s\n", string);
    100 }