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 }