scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit ed368eb12822027ed7c15bcfdf4eae457373ca33
parent e664ff944c0a8fd8fdafe37b48828397a49d045f
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat,  4 Mar 2017 07:19:52 +0100

[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.

Diffstat:
Mlibc/src/Makefile | 3++-
Alibc/src/fprintf.c | 17+++++++++++++++++
Alibc/src/printf.c | 17+++++++++++++++++
Alibc/src/vfprintf.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/libc/src/Makefile b/libc/src/Makefile @@ -10,7 +10,8 @@ LIBCOBJ = assert.o strcpy.o strcmp.o strlen.o strchr.o \ 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 diff --git a/libc/src/fprintf.c b/libc/src/fprintf.c @@ -0,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; +} diff --git a/libc/src/printf.c b/libc/src/printf.c @@ -0,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; +} diff --git a/libc/src/vfprintf.c b/libc/src/vfprintf.c @@ -0,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; +}