summaryrefslogtreecommitdiff
path: root/410user/libstdio/printf.c
diff options
context:
space:
mode:
Diffstat (limited to '410user/libstdio/printf.c')
-rw-r--r--410user/libstdio/printf.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/410user/libstdio/printf.c b/410user/libstdio/printf.c
new file mode 100644
index 0000000..0a4a4db
--- /dev/null
+++ b/410user/libstdio/printf.c
@@ -0,0 +1,97 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1989 Carnegie Mellon University.
+ * Copyright (c) 1994 The University of Utah and
+ * the Computer Systems Laboratory (CSL).
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF
+ * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY
+ * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
+ * THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <syscall.h>
+#include "doprnt.h"
+
+/* This version of printf is implemented in terms of putchar and puts. */
+
+#define PRINTF_BUFMAX 128
+
+struct printf_state {
+ char buf[PRINTF_BUFMAX];
+ unsigned int index;
+};
+
+static void
+flush(struct printf_state *state)
+{
+ print(state->index, state->buf);
+ state->index = 0;
+}
+
+static void
+printf_char(char *arg, int c)
+{
+ struct printf_state *state = (struct printf_state *) arg;
+
+ if (state->index >= PRINTF_BUFMAX) {
+ flush(state);
+ }
+
+ state->buf[state->index] = c;
+ state->index++;
+ if (c == '\n') {
+ flush(state);
+ }
+}
+
+/*
+ * Printing (to console)
+ */
+int vprintf(const char *fmt, va_list args)
+{
+ struct printf_state state;
+
+ state.index = 0;
+ _doprnt(fmt, args, 0, (void (*)())printf_char, (char *) &state);
+
+ if (state.index != 0)
+ flush(&state);
+
+ /* _doprnt currently doesn't pass back error codes,
+ so just assume nothing bad happened. */
+ return 0;
+}
+
+int
+printf(const char *fmt, ...)
+{
+ va_list args;
+ int err;
+
+ va_start(args, fmt);
+ err = vprintf(fmt, args);
+ va_end(args);
+
+ return err;
+}
+