diff options
Diffstat (limited to 'src/user/lib/std/stdio.c')
-rw-r--r-- | src/user/lib/std/stdio.c | 124 |
1 files changed, 58 insertions, 66 deletions
diff --git a/src/user/lib/std/stdio.c b/src/user/lib/std/stdio.c index 1628a78..b1778d6 100644 --- a/src/user/lib/std/stdio.c +++ b/src/user/lib/std/stdio.c @@ -7,7 +7,7 @@ void print(char *s) { fprint(term, s); } void printf(char *format, ...) { va_list ap; va_start(ap, format); - vsfprintf(term, format, ap); + vfprintf(term, format, ap); va_end(ap); } char* readln() { return freadln(term); } @@ -15,25 +15,22 @@ char* readln() { return freadln(term); } void fprintf(FILE f, char* format, ...) { va_list ap; va_start(ap, format); - vsfprintf(f, format, ap); + vfprintf(f, format, ap); va_end(ap); } +// INTERNAL, FOR FORMATTING -void fprint(FILE f, char *s) { - write(f, 0, strlen(s), s); -} - -void fprint_int(FILE f, int number) { +static char* format_int(char* buf, int number) { if (number == 0) { - fprint(f, "0"); - return; + *(buf++) = '0'; + return buf; } - int negative = 0; if (number < 0) { - negative = 1; + *(buf++) = '-'; number = 0 - number; } + int order = 0, temp = number, i; char numbers[] = "0123456789"; while (temp > 0) { @@ -41,86 +38,81 @@ void fprint_int(FILE f, int number) { temp /= 10; } - char s[32], *r; - if (negative) { - s[0] = '-'; - r = s + 1; - } else { - r = s; - } - for (i = order; i > 0; i--) { - r[i - 1] = numbers[number % 10]; + buf[i - 1] = numbers[number % 10]; number /= 10; } - r[order] = 0; - fprint(f, s); + return buf + order; } -void fprint_hex(FILE f, unsigned v) { - char s[11] = {'0', 'x', 0}; +static char* format_hex(char *buf, unsigned v) { + *(buf++) = '0'; + *(buf++) = 'x'; int i; - char hexdigits[] = "0123456789ABCDEF"; - for (i = 0; i < 8; i++) { - s[i + 2] = (hexdigits[v >> 28]); + *(buf++) = hexdigits[v >> 28]; v = v << 4; } - s[11] = 0; + return buf; +} + + +// FUNCTIONS + +void fprint(FILE f, char *s) { + write(f, 0, strlen(s), s); +} + +void fprint_int(FILE f, int number) { + char s[32]; + char *v = format_int(s, number); + *v = 0; + fprint(f, s); +} + +void fprint_hex(FILE f, unsigned v) { + char s[11]; + char *e = format_hex(s, v); + *e = 0; fprint(f, s); } -void vsfprintf(FILE f, char *format, va_list ap) { - char* start = format; +void vfprintf(FILE f, char *format, va_list ap) { + char bb[256]; + int bufl = 256; + + char *buf = bb; + char *end = buf; while (*format) { if (*format == '%') { - if (start != format) write(f, 0, format - start, start); + // ASSUMPTION : (TODO) WE HAVE ENOUGH SPACE - NOT THE CASE!!! format++; if (*format == 'd' || *format == 'i') { - fprint_int(f, va_arg(ap, int)); + end = format_int(end, va_arg(ap, int)); } else if (*format == 'p') { - fprint_hex(f, va_arg(ap, uint32_t)); + end = format_hex(end, va_arg(ap, uint32_t)); } else if (*format == 's') { - fprint(f, va_arg(ap, char*)); + char *s = va_arg(ap, char*); + strcpy(end, s); + end += strlen(s); } format++; - start = format; } else { - format++; + *(end++) = *(format++); } - } - if (start != format) write(f, 0, format - start, start); -} - -char* freadln(FILE f) { - int i; - - char *p = (char*)malloc(256); - char *b = p; - - while (1) { - int l = read(f, 0, 255, b); - if (l < 0) { - free(b); - return 0; + if (end - buf > bufl - 2) { + bufl *= 2; + char *nbuf = (char*)malloc(bufl); + memcpy(nbuf, buf, end - buf); + end = nbuf + (end - buf); + if (buf != bb) free(buf); + buf = nbuf; } - - for (i = 0; i < l; i++) { - if (b[i] == '\n') { - b[i+1] = 0; - return p; - } - } - - int d = b - p + l; - - char* newp = (char*)malloc(d + 256); - memcpy(newp, p, d); - free(p); - p = newp; - b = p + d; } + *end = 0; + fprint(f, buf); + if (buf != bb) free(buf); } |