shithub: scc

Download patch

ref: 54374eb1baef2600d9fd2aabd08f71a16d50a392
parent: 7599d1a808bd0b604b7e5cde5a84342cf868509e
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat Mar 4 02:19:52 EST 2017

[libc] Add skeleton of vfprintf()

This is a first version of a minimal vfprintf. This version only
supports %d, %c, %o, %x and %s that is good enough to help us
to debug other routines.

--- a/libc/src/Makefile
+++ b/libc/src/Makefile
@@ -10,7 +10,8 @@
           isalnum.o isalpha.o isascii.o isblank.o iscntrl.o isdigit.o \
           isgraph.o islower.o isprint.o ispunct.o isspace.o isupper.o \
           isxdigit.o toupper.o tolower.o ctype.o setlocale.o \
-          localeconv.o atoi.o atexit.o exit.o
+          localeconv.o atoi.o atexit.o exit.o \
+          printf.o fprintf.o vfprintf.o
 
 all: libc.a
 
--- /dev/null
+++ b/libc/src/fprintf.c
@@ -1,0 +1,17 @@
+/* See LICENSE file for copyright and license details. */
+
+#include <stdarg.h>
+#include <stdio.h>
+#undef fprintf
+
+int
+fprintf(FILE * restrict fp, const char * restrict fmt, ...)
+{
+	va_list va;
+	int cnt;
+
+	va_start(va, fmt);
+	cnt = vfprintf(fp, fmt, va);
+	va_end(va);
+	return cnt;
+}
--- /dev/null
+++ b/libc/src/printf.c
@@ -1,0 +1,17 @@
+/* See LICENSE file for copyright and license details. */
+
+#include <stdarg.h>
+#include <stdio.h>
+#undef printf
+
+int
+printf(const char * restrict fmt, ...)
+{
+	int cnt;
+	va_list va;
+
+	va_start(va, fmt);
+	cnt = vfprintf(stdin, fmt, va);
+	va_end(va);
+	return cnt;
+}
--- /dev/null
+++ b/libc/src/vfprintf.c
@@ -1,0 +1,76 @@
+/* See LICENSE file for copyright and license details. */
+
+#include <stdarg.h>
+#include <stdio.h>
+#undef vfprintf
+
+static int
+printn2(FILE * restrict fp, unsigned n, int  base)
+{
+	unsigned t;
+	int cnt = 0;
+	static char digits[] = "0123456789ABCDEF";
+
+	if ((t = n / base) != 0)
+		cnt += printn2(fp, t, base);
+	putc(digits[n % base], fp);
+	return cnt + 1;
+}
+
+static int
+printn(FILE * restrict fp, int n, int b, int sign)
+{
+	int cnt = 0;
+
+	if (sign && n < 0) {
+		n = -n;
+		putc('-', fp);
+		++cnt;
+	}
+	cnt += printn2(fp, n, b);
+	return cnt;
+}
+
+int
+vfprintf(FILE * restrict fp, const char *fmt, va_list va)
+{
+	int c, base, sign, cnt;
+	char *s;
+
+	while (( c = *fmt++) != '\0') {
+		if (c == '%') {
+			sign = 0;
+			switch (*fmt++) {
+			case '%':
+				c = '%';
+				break;
+			case 'c':
+				c = va_arg(va, int);
+				break;
+			case 'o':
+				base = 8;
+				goto numeric;
+			case 'd':
+				sign = 1;
+				base = 10;
+				goto numeric;
+			case 'x':
+				base = 16;
+			numeric:
+				c = va_arg(va, int);
+				cnt += printn(fp, c, base, sign);
+				continue;
+			case 's':
+				s = va_arg(va, char *);
+				while ((c = *s++) != '\0')
+					putc(c, fp);
+				/* passthrou */
+			default:
+				continue;
+			}
+		}
+		putc(c, fp);
+		++cnt;
+	}
+	return cnt;
+}