summaryrefslogtreecommitdiff
path: root/src/user/lib/libc/std/stdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/lib/libc/std/stdio.c')
-rw-r--r--src/user/lib/libc/std/stdio.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/user/lib/libc/std/stdio.c b/src/user/lib/libc/std/stdio.c
new file mode 100644
index 0000000..3595622
--- /dev/null
+++ b/src/user/lib/libc/std/stdio.c
@@ -0,0 +1,119 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <tce/syscall.h>
+#include <readline.h>
+
+FILE term = 0;
+void print(char *s) { fprint(term, s); }
+void printf(char *format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ vfprintf(term, format, ap);
+ va_end(ap);
+}
+char* readln() { return freadln(term); }
+
+void fprintf(FILE f, char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ vfprintf(f, format, ap);
+ va_end(ap);
+}
+
+// INTERNAL, FOR FORMATTING
+
+static char* format_int(char* buf, int number) {
+ if (number == 0) {
+ *(buf++) = '0';
+ return buf;
+ }
+ if (number < 0) {
+ *(buf++) = '-';
+ number = 0 - number;
+ }
+
+ int order = 0, temp = number, i;
+ char numbers[] = "0123456789";
+ while (temp > 0) {
+ order++;
+ temp /= 10;
+ }
+
+ for (i = order; i > 0; i--) {
+ buf[i - 1] = numbers[number % 10];
+ number /= 10;
+ }
+ return buf + order;
+}
+
+static char* format_hex(char *buf, unsigned v) {
+ *(buf++) = '0';
+ *(buf++) = 'x';
+
+ int i;
+ char hexdigits[] = "0123456789ABCDEF";
+ for (i = 0; i < 8; i++) {
+ *(buf++) = hexdigits[v >> 28];
+ v = v << 4;
+ }
+ 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 vfprintf(FILE f, char *format, va_list ap) {
+ char bb[256];
+ int bufl = 256;
+
+ char *buf = bb;
+ char *end = buf;
+
+ while (*format) {
+ if (*format == '%') {
+ // ASSUMPTION : (TODO) WE HAVE ENOUGH SPACE - NOT THE CASE!!!
+ format++;
+ if (*format == 'd' || *format == 'i') {
+ end = format_int(end, va_arg(ap, int));
+ } else if (*format == 'p') {
+ end = format_hex(end, va_arg(ap, uint32_t));
+ } else if (*format == 's') {
+ char *s = va_arg(ap, char*);
+ strcpy(end, s);
+ end += strlen(s);
+ }
+ format++;
+ } else {
+ *(end++) = *(format++);
+ }
+ 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;
+ }
+ }
+ *end = 0;
+ fprint(f, buf);
+ if (buf != bb) free(buf);
+}