shithub: scc

Download patch

ref: b01e011f8f367e93c716a202abfb31a1497ad06a
parent: 0fc1735500cec3c113a2ae30cb98e6de81fc2c51
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Dec 11 10:10:17 EST 2017

[lib/c] Rethink the build process

The build process was broken since long time ago because the multiarch
support was wrong. This change it is a first step to make it right.

--- a/lib/c/Makefile
+++ b/lib/c/Makefile
@@ -1,6 +1,4 @@
 .POSIX:
 
-include ../../config.mk
-
 all dep clean distclean:
-	cd src && CC=scc $(MAKE) -e $@
+	cd target && $(MAKE) $@
--- /dev/null
+++ b/lib/c/__abs.c
@@ -1,0 +1,5 @@
+
+#define __USE_MACROS
+#include <stdlib.h>
+
+int __abs;
--- /dev/null
+++ b/lib/c/__getc.c
@@ -1,0 +1,36 @@
+
+#include <errno.h>
+#include <stdio.h>
+#include "syscall.h"
+#undef getc
+
+int
+__getc(FILE *fp)
+{
+	int cnt;
+
+	if (fp->flags & (_IOEOF | _IOERR))
+		return EOF;
+
+	if ((fp->flags & (_IOREAD | _IORW)) == 0) {
+		fp->flags |= _IOERR;
+		errno = EBADF;
+		return EOF;
+	}
+
+	if (fp->flags & _IOSTRG) {
+		fp->flags |= _IOEOF;
+		return EOF;
+	}
+
+	if ((cnt = _read(fp->fd, fp->buf, fp->len)) <= 0) {
+		fp->flags |= (cnt == 0) ? _IOEOF : _IOERR;
+		return EOF;
+	}
+
+	fp->flags |= _IOREAD;
+	fp->rp = fp->buf;
+	fp->wp = fp->buf + cnt;
+
+	return *fp->rp++;
+}
--- /dev/null
+++ b/lib/c/__labs.c
@@ -1,0 +1,5 @@
+
+#define __USE_MACROS
+#include <stdlib.h>
+
+long __labs;
--- /dev/null
+++ b/lib/c/__llabs.c
@@ -1,0 +1,5 @@
+
+#define __USE_MACROS
+#include <stdlib.h>
+
+long long __llabs;
--- /dev/null
+++ b/lib/c/__putc.c
@@ -1,0 +1,88 @@
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "syscall.h"
+
+int
+_fflush(FILE *fp)
+{
+	int lnbuf = fp->flags & _IOLBF;
+	size_t cnt;
+
+	cnt = ((lnbuf) ? fp->lp : fp->wp) - fp->buf;
+
+	if (_write(fp->fd, fp->buf, cnt) != cnt) {
+		fp->flags |= _IOERR;
+		return EOF;
+	}
+	fp->rp = fp->wp = fp->buf;
+
+	return 0;
+}
+
+int
+fflush(FILE *fp)
+{
+	int err = 0;
+
+	if (fp)
+		return _flsbuf(fp);
+
+	for (fp = __iob; fp < &__iob[FOPEN_MAX]; ++fp) {
+		if ((fp->flags & _IOWRITE) == 0 && _flush(fp))
+			err = EOF;
+	}
+	return err;
+}
+
+static void
+cleanup(void)
+{
+	fflush(NULL);
+}
+
+int
+__putc(int ch, FILE *fp)
+{
+	static int first = 1;
+
+	if (fp->flags & _IOERR)
+		return EOF;
+
+	if (fp->flags & _IOREAD) {
+		fp->flags |= _IOERR;
+		errno = EBADF;
+		return EOF;
+	}
+
+	if (fp->flags & _IOSTRG) {
+		fp->flags |= _IOERR;
+		return EOF;
+	}
+
+	if (first) {
+		if (atexit(cleanup)) {
+			fp->flags |= _IOERR;
+			errno = ENOMEM;
+			return EOF;
+		}
+		first = 0;
+	}
+
+	if (fp->flags & _IOLBF) {
+		if (fp->lp == fp->rp && _flush(fp))
+			return EOF;
+		*fp->lp++ = ch;
+		if (ch == '\n' && flsbuf(fp))
+			return EOF;
+	} else {
+		if (fp->wp == fp->rp && _flsbuf(fp))
+			return EOF;
+		*fp->wp++ = ch;
+	}
+
+done:
+	fp->flags |= _IOWRITE;
+	return ch & 0xFF;
+}
--- /dev/null
+++ b/lib/c/_fpopen.c
@@ -1,0 +1,70 @@
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "syscall.h"
+#undef fopen
+
+FILE *
+_fpopen(const char * restrict fname,
+         const char * restrict mode,
+         FILE * restrict fp)
+{
+	int i, flags, fd, rw, bin;
+
+	flags = rw = bin = 0;
+
+	if (mode[0] == '\0)
+		goto einval;
+	if (mode[i = 1] == '+')
+		i++, rw = 1;
+	if (mode[i] == 'b')
+		i++, bin = 1;
+	if (mode[i] != '\0')
+		goto einval;
+
+	switch (mode[0]) {
+	case 'a':
+		flags |= O_APPEND | O_CREAT;
+		goto wrflags;
+	case 'w':
+		flags |= O_TRUNC | O_CREAT;
+	wrflags:
+		flags |= (rw) ? O_RDWR : O_WRONLY;
+		break;
+	case 'r':
+		flags = (rw) ? O_RDWR : O_RDONLY;
+		break;
+	default:
+	einval:
+		errno = EINVAL;
+		return NULL;
+	}
+
+	if ((fd = _open(name, flags)) < 0)
+		return NULL;
+
+	if (fp->buf == NULL) {
+		if ((fp->buf = malloc(BUFSIZ)) == NULL) {
+			close(fd);
+			errno = ENOMEM;
+			return NULL;
+		}
+		fp->flags |= _IOALLOC;
+	}
+	fp->fd = fd;
+
+	if (!bin)
+		fp->flags |= _IOTEXT;
+
+	if (flags & O_RDWR)
+		fp->flags |= _IORW;
+	else if (flags & O_RDONLY)
+		fp->flags |= _IOREAD;
+	else
+		fp->flags |= _IOWRITE;
+
+	fp->lp = fp->rp = fp->wp = NULL;
+
+	return fp;
+}
--- /dev/null
+++ b/lib/c/abort.c
@@ -1,0 +1,12 @@
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#undef abort
+
+void
+abort(void)
+{
+	raise(SIGABRT);
+	_Exit(127);
+}
--- /dev/null
+++ b/lib/c/abs.c
@@ -1,0 +1,9 @@
+
+#include <stdlib.h>
+#undef abs
+
+int
+abs(int n)
+{
+	return (n < 0) ? -n : n;
+}
--- a/lib/c/amd64-sysv-linux/Makefile
+++ /dev/null
@@ -1,5 +1,0 @@
-.POSIX:
-
-include ../../../config.mk
-include ../common.mk
-
--- /dev/null
+++ b/lib/c/assert.c
@@ -1,0 +1,9 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+void __assert(char *exp, char *file, long line)
+{
+	fprintf(stderr, "%s:%ld: assertion failed '%s'\n", file, line, exp);
+	abort();
+}
--- /dev/null
+++ b/lib/c/atexit.c
@@ -1,0 +1,17 @@
+#include <stdlib.h>
+#include <errno.h>
+#undef atexit
+
+extern void (*_exitf[_ATEXIT_MAX])(void);
+extern unsigned _exitn;
+
+int
+atexit(void (*fun)(void))
+{
+	if (_exitn == _ATEXIT_MAX) {
+		errno = ENOMEM;
+		return -1;
+	}
+	_exitf[_exitn++] = fun;
+	return 0;
+}
--- /dev/null
+++ b/lib/c/atoi.c
@@ -1,0 +1,26 @@
+#include <ctype.h>
+#include <stdlib.h>
+#undef atoi
+
+int
+atoi(const char *s)
+{
+	int n, sign = -1;
+
+	while (isspace(*s))
+		++s;
+
+	switch (*s) {
+	case '-':
+		sign = 1;
+	case '+':
+		++s;
+	}
+
+	/* Compute n as a negative number to avoid overflow on INT_MIN */
+	for (n = 0; isdigit(*s); ++s)
+		n = 10*n - (*s - '0');
+
+	return sign * n;
+}
+
--- /dev/null
+++ b/lib/c/atol.c
@@ -1,0 +1,27 @@
+#include <ctype.h>
+#include <stdlib.h>
+#undef atol
+
+long
+atol(const char *s)
+{
+	int sign = -1;
+	long n;
+
+	while (isspace(*s))
+		++s;
+
+	switch (*s) {
+	case '-':
+		sign = 1;
+	case '+':
+		++s;
+	}
+
+	/* Compute n as a negative number to avoid overflow on LONG_MIN */
+	for (n = 0; isdigit(*s); ++s)
+		n = 10*n - (*s - '0');
+
+	return sign * n;
+}
+
--- /dev/null
+++ b/lib/c/atoll.c
@@ -1,0 +1,27 @@
+#include <ctype.h>
+#include <stdlib.h>
+#undef atoll
+
+long long
+atoll(const char *s)
+{
+	int sign = -1;
+	long long n;
+
+	while (isspace(*s))
+		++s;
+
+	switch (*s) {
+	case '-':
+		sign = 1;
+	case '+':
+		++s;
+	}
+
+	/* Compute n as a negative number to avoid overflow on LLONG_MIN */
+	for (n = 0; isdigit(*s); ++s)
+		n = 10*n - (*s - '0');
+
+	return sign * n;
+}
+
--- /dev/null
+++ b/lib/c/bsearch.c
@@ -1,0 +1,27 @@
+
+#include <stdlib.h>
+
+void *
+bsearch(const void *key, const void *ary, size_t n, size_t size,
+        int (*cmp)(const void *, const void *))
+{
+	int t;
+	size_t mid, low, high;
+	const char *cur, *base = ary;
+
+	low = 0;
+	high = n - 1;
+	while (low <= high) {
+		mid = low + (high - low) / 2;
+		cur = base + mid*size;
+
+		if ((t == (*cmp)(key, cur)) == 0)
+			return (void *) cur;
+		else if (t > 0)
+			low = mid + 1;
+		else
+			high = mid - 1;
+	}
+
+	return NULL;
+}
--- /dev/null
+++ b/lib/c/calloc.c
@@ -1,0 +1,17 @@
+#include <stdlib.h>
+#include <string.h>
+
+void *
+calloc(size_t nmemb, size_t size)
+{
+	size_t nbytes;
+	void *mem;
+
+	if (!nmemb || !size || nmemb > (size_t)-1/size)
+                return NULL;
+
+	nbytes = nmemb * size;
+	if ((mem = malloc(nbytes)) == NULL)
+		return NULL;
+	return memset(mem, 0, nbytes);
+}
--- /dev/null
+++ b/lib/c/clearerr.c
@@ -1,0 +1,9 @@
+
+#include <stdio.h>
+#undef clearerr
+
+void
+clearerr(FILE *fp)
+{
+	fp->flags &= ~(_IOERR | _IOEOF);
+}
--- a/lib/c/common.mk
+++ /dev/null
@@ -1,17 +1,0 @@
-SRC=$(OBJ:.o=.c)
-
-all: libc.a
-
-libc.a: $(OBJ)
-	$(AR) $(ARFLAGS) $@ $?
-	ranlib $@
-
-dep:
-	../gendep.sh
-
-clean:
-	rm -f $(OBJ)
-
-distclean: clean
-	rm -f $(SRC)
-	rm -f makefile
--- /dev/null
+++ b/lib/c/ctype.c
@@ -1,0 +1,26 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef ctype
+
+int __ctmp;
+
+/* __ctype is shifted by one to match EOF */
+unsigned char __ctype[257] = {
+	0,                                              /* EOF */
+	_C,_C,_C,_C,_C,_C,_C,_C,                        /* 0-7 */
+	_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,         /* 8-15 */
+	_C,_C,_C,_C,_C,_C,_C,_C,                        /* 16-23 */
+	_C,_C,_C,_C,_C,_C,_C,_C,                        /* 24-31 */
+	_S|_SP,_P,_P,_P,_P,_P,_P,_P,                    /* 32-39 */
+	_P,_P,_P,_P,_P,_P,_P,_P,                        /* 40-47 */
+	_D,_D,_D,_D,_D,_D,_D,_D,                        /* 48-55 */
+	_D,_D,_P,_P,_P,_P,_P,_P,                        /* 56-63 */
+	_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,      /* 64-71 */
+	_U,_U,_U,_U,_U,_U,_U,_U,                        /* 72-79 */
+	_U,_U,_U,_U,_U,_U,_U,_U,                        /* 80-87 */
+	_U,_U,_U,_P,_P,_P,_P,_P,                        /* 88-95 */
+	_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,      /* 96-103 */
+	_L,_L,_L,_L,_L,_L,_L,_L,                        /* 104-111 */
+	_L,_L,_L,_L,_L,_L,_L,_L,                        /* 112-119 */
+	_L,_L,_L,_P,_P,_P,_P,_C,                        /* 120-127 */
+};
--- /dev/null
+++ b/lib/c/exit.c
@@ -1,0 +1,13 @@
+#include <stdlib.h>
+#undef exit
+
+void (*_exitf[_ATEXIT_MAX])(void);
+unsigned _exitn;
+
+void
+exit(int status)
+{
+	while (_exitn > 0)
+		(*_exitf[--_exitn])();
+	_Exit(status);
+}
--- /dev/null
+++ b/lib/c/fclose.c
@@ -1,0 +1,31 @@
+
+#include <stdio.h>
+#undef fclose
+
+int
+fclose(FILE *fp)
+{
+	int r = EOF;
+
+	if ((fp->flags & _IOSTRG) == 0 &&
+	    fp->flags & (_IOWRITE | _IOREAD | _IOWR)) {
+		r = 0;
+		if (fflush(fp) == EOF)
+			r = EOF;
+		if (close(fp->fd) < 0)
+			r = EOF;
+	}
+
+	if (fp->flags & _IOALLOC) {
+		free(fp->buf);
+		fp->buf = NULL;
+	}
+
+	fp->flags &= ~(_IOWRITE | _IOREAD | _IOWR |
+	               _IOERR | _IOEOF |
+	               _IOALLOC |
+	               _IOTXT |
+	               _IOSTRG);
+
+	return r;
+}
--- /dev/null
+++ b/lib/c/feof.c
@@ -1,0 +1,9 @@
+
+#include <stdio.h>
+#undef feof
+
+int
+feof(FILE *fp)
+{
+	return fp->flags & _IOEOF;
+}
--- /dev/null
+++ b/lib/c/ferror.c
@@ -1,0 +1,9 @@
+
+#include <stdio.h>
+#undef ferror
+
+int
+ferror(FILE *fp)
+{
+	return fp->flags & _IOERR;
+}
--- /dev/null
+++ b/lib/c/fgetc.c
@@ -1,0 +1,9 @@
+
+#include <stdio.h>
+#undef fgetc
+
+int
+fgetc(FILE *fp)
+{
+	return getc(fp);
+}
--- /dev/null
+++ b/lib/c/fgets.c
@@ -1,0 +1,19 @@
+#include <stdio.h>
+#undef fgets
+
+char *
+fgets(char *s, int n, FILE *fp)
+{
+	int ch;
+	char *t = s;
+
+	while (--n > 0 && (ch = getc(fp)) != EOF) {
+		if ((*t++ = ch) == '\n')
+			break;
+	}
+	if (ch == EOF && s == t)
+		return NULL;
+	*t = '\0';
+
+	return s;
+}
--- /dev/null
+++ b/lib/c/fopen.c
@@ -1,0 +1,20 @@
+
+#include <errno.h>
+#include <stdio.h>
+#undef fopen
+
+FILE *
+fopen(const char * restrict name, const char * restrict mode)
+{
+	FILE *fp;
+
+	for (fp = __iob; fp < &__iob[FILE_MAX]; ++fp) {
+		if (fp->flags & (_IOREAD | _IOWRITE | _IORW) == 0)
+			break;
+	}
+	if (fp == &__iob[FILE_MAX]) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	return _fpopen(name, mode, fp);
+}
--- /dev/null
+++ b/lib/c/fprintf.c
@@ -1,0 +1,15 @@
+#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/lib/c/fputc.c
@@ -1,0 +1,9 @@
+
+#include <stdio.h>
+#undef fputc
+
+int
+fputc(int c, FILE *fp)
+{
+	return putc(c, fp);
+}
--- /dev/null
+++ b/lib/c/fputs.c
@@ -1,0 +1,12 @@
+
+#include <stdio.h>
+
+int
+fputs(const char * restrict bp, FILE * restrict fp)
+{
+	int r, ch;
+
+	while (ch = *bp++)
+		r = putc(ch, fp);
+	return r;
+}
--- /dev/null
+++ b/lib/c/fread.c
@@ -1,0 +1,24 @@
+
+#include <stdio.h>
+#undef fread
+
+size_t
+fread(void * restrict ptr, size_t size, size_t nmemb,
+      FILE * restrict fp)
+{
+	unsigned char *bp = ptr;
+	size_t n, i;
+
+	if (size == 0)
+		return 0;
+
+	for (n = 0; n < nmemb; n++) {
+		i = size;
+		do {
+			if ((*bp++ = getc(fp)) == EOF)
+				return n;
+		} while (--i);
+	}
+
+	return n;
+}
--- /dev/null
+++ b/lib/c/freopen.c
@@ -1,0 +1,12 @@
+
+#include <stdio.h>
+#undef freopen
+
+FILE *
+freopen(const char * restrict name, const char * restrict mode,
+        FILE * restrict fp)
+{
+	if (fclose(fp) == EOF)
+		return NULL;
+	return _fpopen(name, mode, fp);
+}
--- /dev/null
+++ b/lib/c/fseek.c
@@ -1,0 +1,27 @@
+
+#include <stdio.h>
+#include "syscall.h"
+#undef fseek
+
+int
+fseek(FILE *fp, long off, int whence)
+{
+	if (fp->flags & _IOERR)
+		return EOF;
+
+	if ((fp->flags & _IOWRITE) && fflush(fp))
+		return -1;
+	else if (whence == SEEK_CUR && (fp->flags & _IOREAD))
+		off -= fp->wp - fp->rd;
+
+	if (_seek(fp->fd, off, type) < 0) {
+		fp->flags |= _IOERR;
+		return EOF;
+	}
+
+	if (fp->flags & _IORW)
+		fp->flags &= ~(_IOREAD | _IOWRITE);
+	fp->flags &= ~_IOEOF;
+
+	return 0;
+}
--- /dev/null
+++ b/lib/c/fwrite.c
@@ -1,0 +1,25 @@
+
+#include <stdio.h>
+#undef fwrite
+
+size_t
+fwrite(const void * restrict ptr, size_t size, size_t nmemb,
+       FILE * restrict fp)
+{
+	const unsigned char *bp = ptr;
+	size_t n, i;
+
+	if (size == 0)
+		return 0;
+
+	for (n = 0; n < nmemb; n++) {
+		i = size;
+		do
+			putc(*bp++, fp);
+		while (--i);
+		if (ferror(fp))
+			break;
+	}
+
+	return n;
+}
--- a/lib/c/gendep.sh
+++ /dev/null
@@ -1,17 +1,0 @@
-#!/bin/sh
-
-sed 's/\.o/.c/' ../obj.lst |
-while read src
-do
-	echo '#include "../src/'$src'"' > $src
-done
-
-(cat Makefile
-echo
-printf "OBJ ="
-while read i
-do
-	printf " %s" $i
-done < ../obj.lst
-echo) > makefile
-
--- /dev/null
+++ b/lib/c/getc.c
@@ -1,0 +1,9 @@
+
+#include <stdio.h>
+#undef getc
+
+int
+getc(FILE *fp)
+{
+	return (fp->rp >= fp->wp) ?  __getc(fp) : *fp->rp++;
+}
--- /dev/null
+++ b/lib/c/getchar.c
@@ -1,0 +1,9 @@
+
+#include <stdio.h>
+#undef getchar
+
+int
+getchar(void)
+{
+	return getc(stdin);
+}
--- /dev/null
+++ b/lib/c/gets.c
@@ -1,0 +1,17 @@
+#include <stdio.h>
+#undef gets
+
+char *
+gets(char *s)
+{
+	int ch;
+	char *t = s;
+
+	while ((ch = getc(stdin)) != EOF && ch != '\n')
+		*t++ = ch;
+	if (ch == EOF && s == t)
+		return NULL;
+	*t = '\0';
+
+	return s;
+}
--- /dev/null
+++ b/lib/c/isalnum.c
@@ -1,0 +1,9 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef isalnum
+
+int
+isalnum(int c)
+{
+	return (__ctype+1)[c] & (_U|_L|_D);
+}
--- /dev/null
+++ b/lib/c/isalpha.c
@@ -1,0 +1,9 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef isalpha
+
+int
+isalpha(int c)
+{
+	return (__ctype+1)[c] & (_U|_L);
+}
--- /dev/null
+++ b/lib/c/isascii.c
@@ -1,0 +1,9 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef isascii
+
+int
+isascii(int c)
+{
+	return c <= 0x7f;
+}
--- /dev/null
+++ b/lib/c/isblank.c
@@ -1,0 +1,5 @@
+int
+isblank(int c)
+{
+	return (c == ' ') || (c == '\t');
+}
--- /dev/null
+++ b/lib/c/iscntrl.c
@@ -1,0 +1,9 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef iscntrl
+
+int
+iscntrl(int c)
+{
+	return (__ctype+1)[c] & (_C);
+}
--- /dev/null
+++ b/lib/c/isdigit.c
@@ -1,0 +1,9 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef isdigit
+
+int
+isdigit(int c)
+{
+	return (__ctype+1)[c] & (_D);
+}
--- /dev/null
+++ b/lib/c/isgraph.c
@@ -1,0 +1,9 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef isgraph
+
+int
+isgraph(int c)
+{
+	return (__ctype+1)[c] & (_P|_U|_L|_D);
+}
--- /dev/null
+++ b/lib/c/islower.c
@@ -1,0 +1,9 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef islower
+
+int
+islower(int c)
+{
+	return (__ctype+1)[c] & _L;
+}
--- /dev/null
+++ b/lib/c/isprint.c
@@ -1,0 +1,9 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef isprint
+
+int
+isprint(int c)
+{
+	return (__ctype+1)[c] & (_P|_U|_L|_D|_SP);
+}
--- /dev/null
+++ b/lib/c/ispunct.c
@@ -1,0 +1,9 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef ispunct
+
+int
+ispunct(int c)
+{
+	return (__ctype+1)[c] & (_P);
+}
--- /dev/null
+++ b/lib/c/isspace.c
@@ -1,0 +1,9 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef isspace
+
+int
+isspace(int c)
+{
+	return (__ctype+1)[c] & _S;
+}
--- /dev/null
+++ b/lib/c/isupper.c
@@ -1,0 +1,9 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef isupper
+
+int
+isupper(int c)
+{
+	return (__ctype+1)[c] & _U;
+}
--- /dev/null
+++ b/lib/c/isxdigit.c
@@ -1,0 +1,9 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef isxdigit
+
+int
+isxdigit(int c)
+{
+	return (__ctype+1)[c] & (_D|_X);
+}
--- /dev/null
+++ b/lib/c/labs.c
@@ -1,0 +1,9 @@
+
+#include <stdlib.h>
+#undef labs
+
+long
+labs(long n)
+{
+	return (n < 0) ? -n : n;
+}
--- /dev/null
+++ b/lib/c/llabs.c
@@ -1,0 +1,9 @@
+
+#include <stdlib.h>
+#undef llabs
+
+long long
+llabs(long long n)
+{
+	return (n < 0) ? -n : n;
+}
--- /dev/null
+++ b/lib/c/localeconv.c
@@ -1,0 +1,14 @@
+#include <locale.h>
+#include <limits.h>
+#undef localeconv
+
+struct lconv *
+localeconv(void)
+{
+	static struct lconv lc = { ".", "", "", "", "", "", "", "", "", "",
+	                           CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
+	                           CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
+	                           CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
+	                           CHAR_MAX, CHAR_MAX };
+	return &lc;
+}
--- /dev/null
+++ b/lib/c/malloc.c
@@ -1,0 +1,152 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "malloc.h"
+#include "syscall.h"
+
+#define MAXADDR ((char *)-1)
+#define ERRADDR ((char *)-1)
+
+extern char end[];
+static Header base = { .h.next = &base };
+static Header *freep = &base;
+static char *heap = end;
+
+/*
+ * Run over the free list looking for the nearest previous
+ * block. There are two possible results: end of the list
+ * or an intermediary block.
+ */
+void *
+_prevchunk(Header *hp)
+{
+	Header *p;
+
+	for (p = freep; ;p = p->h.next) {
+		/* hp between p and p->h.next? */
+		if (p < hp && hp < p->h.next)
+			break;
+		/* p before hp and hp at the end of list? */
+		if (p->h.next <= p && (hp < p->h.next || hp > p))
+			break;
+	}
+	return p;
+}
+
+/*
+ * Get the previous block and try to merge
+ * with next and previous blocks
+ */
+void
+free(void *mem)
+{
+	Header *hp, *prev;
+
+	if (!mem)
+		return;
+
+	hp = (Header *) mem - 1;
+	prev = _prevchunk(hp);
+
+	/* join to next */
+	if (hp + hp->h.size == prev->h.next) {
+		hp->h.size += prev->h.next->h.size;
+		hp->h.next = prev->h.next->h.next;
+	} else {
+		hp->h.next = prev->h.next;
+	}
+
+	/* join to previous */
+	if (prev + prev->h.size == hp) {
+		prev->h.size += hp->h.size;
+		prev->h.next = hp->h.next;
+	} else {
+		prev->h.next = hp;
+	}
+
+	freep = prev;
+}
+
+static void *
+sbrk(uintptr_t inc)
+{
+	char *new, *old = heap;
+
+	if (old >= MAXADDR - inc)
+		return ERRADDR;
+
+	new = old + inc;
+	if (_brk(new) < 0)
+		return ERRADDR;
+	heap = new;
+
+	return old;
+}
+
+static Header *
+morecore(size_t nunits)
+{
+	char *rawmem;
+	Header *hp;
+
+	if (nunits < NALLOC)
+		nunits = NALLOC;
+
+	rawmem = sbrk(nunits * sizeof(Header));
+	if (rawmem == ERRADDR)
+		return NULL;
+
+	hp = (Header*)rawmem;
+	hp->h.size = nunits;
+
+	/* integrate new memory into the list */
+	free(hp + 1);
+
+	return freep;
+}
+
+/*
+ * Run over the list of free blocks trying to find a block
+ * big enough for nbytes. If the block fit perfectly with
+ * the required size then we only have to unlink
+ * the block. Otherwise we have to split the block and
+ * return the right part. If we run over the full list
+ * without a fit then we have to require more memory
+ *
+ *              ______________________________________
+ * ___________./______________________________________\_____
+ * ...| in   |   |     | in  |  |.....| in   |  |    | |....
+ * ...| use  |   |     | use |  |.....| use  |  |    | |....
+ * ___|______|___|.____|_____|._|_____|______|._|.___|.|____
+ *            \__/ \_________/ \_____________/ \/ \__/
+ */
+void *
+malloc(size_t nbytes)
+{
+	Header *cur, *prev;
+	size_t nunits;
+
+	/* 1 unit for header plus enough units to fit nbytes */
+	nunits = (nbytes+sizeof(Header)-1) / sizeof(Header) + 1;
+
+	for (prev = freep; ; prev = cur) {
+		cur = prev->h.next;
+		if (cur->h.size >= nunits) {
+			if (cur->h.size == nunits) {
+				prev->h.next = cur->h.next;
+			} else {
+				cur->h.size -= nunits;
+				cur += cur->h.size;
+				cur->h.size = nunits;
+			}
+			freep = prev;
+			return cur + 1;
+		}
+
+		if (cur == freep) {
+			if ((cur = morecore(nunits)) == NULL)
+				return NULL;
+		}
+	}
+}
--- /dev/null
+++ b/lib/c/malloc.h
@@ -1,0 +1,16 @@
+#include <stdlib.h>
+
+/* minimum amount of required units */
+#define NALLOC 10000
+
+typedef union header Header;
+union header {
+	struct hdr {
+		Header *next;
+		size_t size;
+	} h;
+	/* most restrictive type fixes the union size for alignment */
+	_ALIGNTYPE most;
+};
+
+extern void *_prevchunk(Header *hp);
--- /dev/null
+++ b/lib/c/memchr.c
@@ -1,0 +1,12 @@
+#include <string.h>
+#undef memchr
+
+void *
+memchr(const void *s, int c, size_t n)
+{
+	unsigned char *bp = (char *) s;
+
+	while (n > 0 && *bp++ != c)
+		--n;
+	return (n == 0) ? NULL : bp-1;
+}
--- /dev/null
+++ b/lib/c/memcmp.c
@@ -1,0 +1,12 @@
+#include <string.h>
+#undef memcmp
+
+int
+memcmp(const void *s1, const void *s2, size_t n)
+{
+	char *s = (char *) s1, *t = (char *) s2;
+
+	while (n > 0 && *s == *t)
+		--n, ++s, ++t;
+	return n ? (*s - *t) : 0;
+}
--- /dev/null
+++ b/lib/c/memcpy.c
@@ -1,0 +1,13 @@
+#include <string.h>
+#undef memcpy
+
+void *
+memcpy(void * restrict dst, const void * restrict src, size_t n)
+{
+	char *s1 = dst;
+	const char *s2 = src;
+
+	while (n-- > 0)
+		*s1++ = *s2++;
+	return dst;
+}
--- /dev/null
+++ b/lib/c/memmove.c
@@ -1,0 +1,18 @@
+#include <string.h>
+#undef memmove
+
+void *
+memmove(void *dst, const void *src, size_t n)
+{
+	char *d = dst, *s = (char *) src;
+
+	if (d < s) {
+		while (n-- > 0)
+			*d++ = *s++;
+	} else {
+		s += n-1, d += n-1;
+		while (n-- > 0)
+			*d-- = *s--;
+	}
+	return dst;
+}
--- /dev/null
+++ b/lib/c/memset.c
@@ -1,0 +1,12 @@
+#include <string.h>
+#undef memset
+
+void *
+memset(void *s, int c, size_t n)
+{
+	char *m = s;
+
+	while (n-- > 0)
+		*m++ = c;
+	return s;
+}
--- a/lib/c/obj.lst
+++ /dev/null
@@ -1,49 +1,0 @@
-assert.o
-strcpy.o
-strcmp.o
-strlen.o
-strchr.o
-strrchr.o
-strcat.o
-strncmp.o
-strncpy.o
-strncat.o
-strcoll.o
-strxfrm.o
-strstr.o
-strspn.o
-strcspn.o
-strpbrk.o
-strtok.o
-memset.o
-memcpy.o
-memmove.o
-memcmp.o
-memchr.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
-printf.o
-fprintf.o
-vfprintf.o
-realloc.o
-calloc.o
-malloc.o
--- /dev/null
+++ b/lib/c/perror.c
@@ -1,0 +1,17 @@
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#undef perror
+
+void
+perror(const char *msg)
+{
+	if (msg && *msg) {
+		fputs(msg, stderr);
+		putc(':', stderr);
+		putc(' ', stderr);
+	}
+	fputs(strerror(errno), stderr);
+	putc('\n', stderr);
+}
--- /dev/null
+++ b/lib/c/printf.c
@@ -1,0 +1,15 @@
+#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(stdout, fmt, va);
+	va_end(va);
+	return cnt;
+}
--- /dev/null
+++ b/lib/c/putc.c
@@ -1,0 +1,9 @@
+
+#include <stdio.h>
+#undef putc
+
+int
+putc(int ch, FILE *fp)
+{
+	return (fp->wp >= fp->rp) ? __putc(c,fp) : *fp->wp++ = c;
+}
--- /dev/null
+++ b/lib/c/putchar.c
@@ -1,0 +1,9 @@
+
+#include <stdio.h>
+#undef putchar
+
+int
+putchar(int ch)
+{
+	return putc(ch, stdin);
+}
--- /dev/null
+++ b/lib/c/puts.c
@@ -1,0 +1,12 @@
+
+#include <stdio.h>
+
+int
+puts(const char *str)
+{
+	int ch;
+
+	while (ch = *str)
+		putchar(ch);
+	return putchar('\n');
+}
--- /dev/null
+++ b/lib/c/qsort.c
@@ -1,0 +1,69 @@
+
+#include <stdlib.h>
+#include <string.h>
+#undef qsort
+
+/*
+ * This implementation of qsort is based in the paper
+ * "Engineering a Sort Function", by Jon L.Bentley and M. Douglas McIlroy.
+ * A lot of different optimizations were removed to make the code simpler.
+ */
+
+struct qsort {
+	size_t es;
+	int (*cmp)(const void *, const void *);
+};
+
+static void
+swap(char *i, char *j, size_t n)
+{
+	do {
+		char c = *i;
+		*i++ = *j;
+		*j++ = c;
+	} while (--n > 0);
+}
+
+static void
+xqsort(char *a, size_t n, struct qsort *qs)
+{
+	size_t j, es = qs->es;
+	char *pi, *pj, *pn;
+
+	if (n <= 1)
+		return;
+
+	pi = a;
+	pn = pj = a + n*es;
+
+	swap(a, a + n/2 * es,  es);
+	for (;;) {
+		do {
+			pi += es;
+		} while  (pi < pn && qs->cmp(pi, a) < 0);
+
+		do {
+			pj -= es;
+		} while (pj > a && qs->cmp(pj, a) > 0);
+
+		if (pj < pi)
+			break;
+		swap(pi, pj, es);
+	}
+	swap(a, pj, es);
+
+	j = (pj - a) / es;
+	xqsort(a, j, qs);
+	xqsort(a + (j+1)*es, n-j-1, qs);
+}
+
+void
+qsort(void *base, size_t nmemb, size_t size,
+      int (*f)(const void *, const void *))
+{
+	struct qsort qs;
+
+	qs.cmp = f;
+	qs.es = size;
+	xqsort(base, nmemb, &qs);
+}
--- /dev/null
+++ b/lib/c/rand.c
@@ -1,0 +1,18 @@
+#include <stdlib.h>
+#undef rand
+#undef srand
+
+static int next;
+
+void
+srand(unsigned seed)
+{
+	next = seed;
+}
+
+int
+rand(void)  /* RAND_MAX assumed to be 32767. */
+{
+	next = next * 1103515245 + 12345;
+	return (unsigned)(next/65536) % 32768;
+}
--- /dev/null
+++ b/lib/c/realloc.c
@@ -1,0 +1,67 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "malloc.h"
+
+void *
+realloc(void *ptr, size_t nbytes)
+{
+	Header *oh, *prev, *next, *new;
+	size_t nunits, avail, onbytes, n;
+
+	if (!nbytes)
+		return NULL;
+
+	if (!ptr)
+		return malloc(nbytes);
+
+	nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1;
+	oh = (Header*)ptr - 1;
+
+	if (oh->h.size == nunits)
+		return ptr;
+
+	new = oh + nunits;
+
+	if (nunits < oh->h.size - 1) {
+		new->h.size = oh->h.size - nunits;
+		oh->h.size = nunits;
+		free(new + 1);
+		return oh;
+	}
+
+	prev = _prevchunk(oh);
+
+	if (oh + oh->h.size == prev->h.next) {
+		/*
+		 * if there is free space adjacent
+		 * to the current memory
+		 */
+		next = prev->h.next;
+		avail = oh->h.size + next->h.size;
+
+		if (avail == nunits) {
+			oh->h.size = nunits;
+			prev->h.next = next->h.next;
+			return oh;
+		}
+
+		if (avail > nunits) {
+			oh->h.size = nunits;
+			prev->h.next = new;
+			new->h.next = next;
+			new->h.size = avail - nunits;
+			return oh;
+		}
+	}
+
+	onbytes = (oh->h.size - 1) * sizeof(Header);
+	if ((new = malloc(nbytes)) == NULL)
+		return NULL;
+
+	n = (onbytes > nbytes) ? nbytes : onbytes;
+	memcpy(new, ptr, n);
+	free(ptr);
+
+	return new;
+}
--- /dev/null
+++ b/lib/c/rewind.c
@@ -1,0 +1,11 @@
+
+#include <stdio.h>
+#undef rewind
+
+void
+rewind(FILE *fp)
+{
+	fp->flags &= ~_IOERR;
+	fseek(fp, 0, SEEK_SET);
+	clearerr(fp);
+}
--- /dev/null
+++ b/lib/c/setbuf.c
@@ -1,0 +1,9 @@
+
+#include <stdio.h>
+#undef setbuf
+
+void
+setbuf(FILE * restrict fp, char * restrict buf)
+{
+	setvbuf(fp, buf, (buf) ? _IOFBF : _IONBF, BUFSIZ);
+}
--- /dev/null
+++ b/lib/c/setlocale.c
@@ -1,0 +1,16 @@
+#include <locale.h>
+#include <stddef.h>
+#undef setlocale
+
+char *
+setlocale(int category, const char *locale)
+{
+	if (category > LC_TIME || category < LC_ALL)
+		return NULL;
+	if (!locale ||
+	    locale[0] == '\0' ||
+	    locale[0] == 'C' && locale[1] == '\0') {
+		return "C";
+	}
+	return NULL;
+}
--- /dev/null
+++ b/lib/c/setvbuf.c
@@ -1,0 +1,44 @@
+
+#include <errno.h>
+#include <stdio.h>
+#undef setvbuf
+
+int
+setvbuf(FILE * restrict fp, char * restrict buf, int mode, size_t size)
+{
+	int flags, r;
+
+	if (fflush(fp) == EOF)
+		return EOF;
+
+	switch (mode) {
+	case _IONBF:
+		size = sizeof(fp->unbuf);
+		buf = fp->unbuf;
+		break;
+	case _IOLBF:
+	case _IOFBF:
+		if (size == 0) {
+			if ((buf = malloc(BUFSIZ)) == NULL) {
+				errno = ENOMEM;
+				return EOF;
+			}
+			size = BUFSIZ;
+		}
+		break;
+	default:
+		errno = EIVAL;
+		return EOF;
+	}
+
+	flags = fp->flags;
+	if (flags & _IOALLOC)
+		free(fp->buf);
+	flag &= ~(_IONBF | _IOLBF | _IOFBF | _IOALLOC | _IOALLOC);
+	flags |= mode;
+	fp->flags = flags;
+	fp->buf = buf;
+	fp->size = size;
+
+	return 0;
+}
--- /dev/null
+++ b/lib/c/snprintf.c
@@ -1,0 +1,18 @@
+
+#include <stdarg.h>
+#include <stdio.h>
+#undef snprintf
+
+int
+snprintf(char * restrict s, size_t siz, const char * restrict fmt, ...)
+{
+	int r;
+	va_list va;
+
+	va_list va_arg;
+	va_start(va, fmt);
+	r = vsnprintf(s, siz, fmt, va);
+	va_end(va);
+
+	return r;
+}
--- /dev/null
+++ b/lib/c/sprintf.c
@@ -1,0 +1,17 @@
+
+#include <stdarg.h>
+#include <stdio.h>
+#undef sprintf
+
+int
+sprintf(char * restrict s, const char * restrict fmt, ...)
+{
+	int r;
+
+	va_list va;
+	va_start(va, fmt);
+	r = vsprintf(s, fmt, va);
+	va_end(va);
+
+	return r;
+}
--- a/lib/c/src/Makefile
+++ /dev/null
@@ -1,34 +1,0 @@
-.POSIX:
-
-include ../../../config.mk
-
-OBJ = bsearch.o qsort.o \
-      abs.o __abs.o labs.o __labs.o llabs.o __llabs.o \
-      perror.o strerror.o \
-      tmpnam.o \
-      sprintf.o snprintf.o vsprintf.o vsnprintf.o \
-      printf.o fprintf.o vfprintf.o \
-      fgets.o gets.of fgetc.o fputc.o getchar.o putchar.o \
-      fputs.o puts.o fread.o fwrite.o \
-      getc.o putc.o __putc.o __getc.o \
-      rewind.o fseek.o ferror.o feof.o clearerr.o \
-      setbuf.o setvbuf.o \
-      fclose.o fopen.c freopen.c _fpopen.o stdio.o \
-      realloc.o calloc.o malloc.o \
-      assert.o strcpy.o strcmp.o strlen.o strchr.o \
-      strrchr.o strcat.o strncmp.o strncpy.o strncat.o strcoll.o \
-      strxfrm.o strstr.o strspn.o strcspn.o strpbrk.o strtok.o \
-      memset.o memcpy.o memmove.o memcmp.o memchr.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 atol.o atoll.o atexit.o abort.o exit.o
-
-all: $(ARCH)-libc.a
-
-clean distclean:
-	rm -f *.o *-libc.a
-
-$(ARCH)-libc.a: $(OBJ)
-	$(AR) $(ARFLAGS) $@ $?
-	ranlib $@
--- a/lib/c/src/__abs.c
+++ /dev/null
@@ -1,5 +1,0 @@
-
-#define __USE_MACROS
-#include <stdlib.h>
-
-int __abs;
--- a/lib/c/src/__getc.c
+++ /dev/null
@@ -1,36 +1,0 @@
-
-#include <errno.h>
-#include <stdio.h>
-#include "syscall.h"
-#undef getc
-
-int
-__getc(FILE *fp)
-{
-	int cnt;
-
-	if (fp->flags & (_IOEOF | _IOERR))
-		return EOF;
-
-	if ((fp->flags & (_IOREAD | _IORW)) == 0) {
-		fp->flags |= _IOERR;
-		errno = EBADF;
-		return EOF;
-	}
-
-	if (fp->flags & _IOSTRG) {
-		fp->flags |= _IOEOF;
-		return EOF;
-	}
-
-	if ((cnt = _read(fp->fd, fp->buf, fp->len)) <= 0) {
-		fp->flags |= (cnt == 0) ? _IOEOF : _IOERR;
-		return EOF;
-	}
-
-	fp->flags |= _IOREAD;
-	fp->rp = fp->buf;
-	fp->wp = fp->buf + cnt;
-
-	return *fp->rp++;
-}
--- a/lib/c/src/__labs.c
+++ /dev/null
@@ -1,5 +1,0 @@
-
-#define __USE_MACROS
-#include <stdlib.h>
-
-long __labs;
--- a/lib/c/src/__llabs.c
+++ /dev/null
@@ -1,5 +1,0 @@
-
-#define __USE_MACROS
-#include <stdlib.h>
-
-long long __llabs;
--- a/lib/c/src/__putc.c
+++ /dev/null
@@ -1,88 +1,0 @@
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "syscall.h"
-
-int
-_fflush(FILE *fp)
-{
-	int lnbuf = fp->flags & _IOLBF;
-	size_t cnt;
-
-	cnt = ((lnbuf) ? fp->lp : fp->wp) - fp->buf;
-
-	if (_write(fp->fd, fp->buf, cnt) != cnt) {
-		fp->flags |= _IOERR;
-		return EOF;
-	}
-	fp->rp = fp->wp = fp->buf;
-
-	return 0;
-}
-
-int
-fflush(FILE *fp)
-{
-	int err = 0;
-
-	if (fp)
-		return _flsbuf(fp);
-
-	for (fp = __iob; fp < &__iob[FOPEN_MAX]; ++fp) {
-		if ((fp->flags & _IOWRITE) == 0 && _flush(fp))
-			err = EOF;
-	}
-	return err;
-}
-
-static void
-cleanup(void)
-{
-	fflush(NULL);
-}
-
-int
-__putc(int ch, FILE *fp)
-{
-	static int first = 1;
-
-	if (fp->flags & _IOERR)
-		return EOF;
-
-	if (fp->flags & _IOREAD) {
-		fp->flags |= _IOERR;
-		errno = EBADF;
-		return EOF;
-	}
-
-	if (fp->flags & _IOSTRG) {
-		fp->flags |= _IOERR;
-		return EOF;
-	}
-
-	if (first) {
-		if (atexit(cleanup)) {
-			fp->flags |= _IOERR;
-			errno = ENOMEM;
-			return EOF;
-		}
-		first = 0;
-	}
-
-	if (fp->flags & _IOLBF) {
-		if (fp->lp == fp->rp && _flush(fp))
-			return EOF;
-		*fp->lp++ = ch;
-		if (ch == '\n' && flsbuf(fp))
-			return EOF;
-	} else {
-		if (fp->wp == fp->rp && _flsbuf(fp))
-			return EOF;
-		*fp->wp++ = ch;
-	}
-
-done:
-	fp->flags |= _IOWRITE;
-	return ch & 0xFF;
-}
--- a/lib/c/src/_fpopen.c
+++ /dev/null
@@ -1,70 +1,0 @@
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "syscall.h"
-#undef fopen
-
-FILE *
-_fpopen(const char * restrict fname,
-         const char * restrict mode,
-         FILE * restrict fp)
-{
-	int i, flags, fd, rw, bin;
-
-	flags = rw = bin = 0;
-
-	if (mode[0] == '\0)
-		goto einval;
-	if (mode[i = 1] == '+')
-		i++, rw = 1;
-	if (mode[i] == 'b')
-		i++, bin = 1;
-	if (mode[i] != '\0')
-		goto einval;
-
-	switch (mode[0]) {
-	case 'a':
-		flags |= O_APPEND | O_CREAT;
-		goto wrflags;
-	case 'w':
-		flags |= O_TRUNC | O_CREAT;
-	wrflags:
-		flags |= (rw) ? O_RDWR : O_WRONLY;
-		break;
-	case 'r':
-		flags = (rw) ? O_RDWR : O_RDONLY;
-		break;
-	default:
-	einval:
-		errno = EINVAL;
-		return NULL;
-	}
-
-	if ((fd = _open(name, flags)) < 0)
-		return NULL;
-
-	if (fp->buf == NULL) {
-		if ((fp->buf = malloc(BUFSIZ)) == NULL) {
-			close(fd);
-			errno = ENOMEM;
-			return NULL;
-		}
-		fp->flags |= _IOALLOC;
-	}
-	fp->fd = fd;
-
-	if (!bin)
-		fp->flags |= _IOTEXT;
-
-	if (flags & O_RDWR)
-		fp->flags |= _IORW;
-	else if (flags & O_RDONLY)
-		fp->flags |= _IOREAD;
-	else
-		fp->flags |= _IOWRITE;
-
-	fp->lp = fp->rp = fp->wp = NULL;
-
-	return fp;
-}
--- a/lib/c/src/abort.c
+++ /dev/null
@@ -1,12 +1,0 @@
-
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#undef abort
-
-void
-abort(void)
-{
-	raise(SIGABRT);
-	_Exit(127);
-}
--- a/lib/c/src/abs.c
+++ /dev/null
@@ -1,9 +1,0 @@
-
-#include <stdlib.h>
-#undef abs
-
-int
-abs(int n)
-{
-	return (n < 0) ? -n : n;
-}
--- a/lib/c/src/assert.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-void __assert(char *exp, char *file, long line)
-{
-	fprintf(stderr, "%s:%ld: assertion failed '%s'\n", file, line, exp);
-	abort();
-}
--- a/lib/c/src/atexit.c
+++ /dev/null
@@ -1,17 +1,0 @@
-#include <stdlib.h>
-#include <errno.h>
-#undef atexit
-
-extern void (*_exitf[_ATEXIT_MAX])(void);
-extern unsigned _exitn;
-
-int
-atexit(void (*fun)(void))
-{
-	if (_exitn == _ATEXIT_MAX) {
-		errno = ENOMEM;
-		return -1;
-	}
-	_exitf[_exitn++] = fun;
-	return 0;
-}
--- a/lib/c/src/atoi.c
+++ /dev/null
@@ -1,26 +1,0 @@
-#include <ctype.h>
-#include <stdlib.h>
-#undef atoi
-
-int
-atoi(const char *s)
-{
-	int n, sign = -1;
-
-	while (isspace(*s))
-		++s;
-
-	switch (*s) {
-	case '-':
-		sign = 1;
-	case '+':
-		++s;
-	}
-
-	/* Compute n as a negative number to avoid overflow on INT_MIN */
-	for (n = 0; isdigit(*s); ++s)
-		n = 10*n - (*s - '0');
-
-	return sign * n;
-}
-
--- a/lib/c/src/atol.c
+++ /dev/null
@@ -1,27 +1,0 @@
-#include <ctype.h>
-#include <stdlib.h>
-#undef atol
-
-long
-atol(const char *s)
-{
-	int sign = -1;
-	long n;
-
-	while (isspace(*s))
-		++s;
-
-	switch (*s) {
-	case '-':
-		sign = 1;
-	case '+':
-		++s;
-	}
-
-	/* Compute n as a negative number to avoid overflow on LONG_MIN */
-	for (n = 0; isdigit(*s); ++s)
-		n = 10*n - (*s - '0');
-
-	return sign * n;
-}
-
--- a/lib/c/src/atoll.c
+++ /dev/null
@@ -1,27 +1,0 @@
-#include <ctype.h>
-#include <stdlib.h>
-#undef atoll
-
-long long
-atoll(const char *s)
-{
-	int sign = -1;
-	long long n;
-
-	while (isspace(*s))
-		++s;
-
-	switch (*s) {
-	case '-':
-		sign = 1;
-	case '+':
-		++s;
-	}
-
-	/* Compute n as a negative number to avoid overflow on LLONG_MIN */
-	for (n = 0; isdigit(*s); ++s)
-		n = 10*n - (*s - '0');
-
-	return sign * n;
-}
-
--- a/lib/c/src/bsearch.c
+++ /dev/null
@@ -1,27 +1,0 @@
-
-#include <stdlib.h>
-
-void *
-bsearch(const void *key, const void *ary, size_t n, size_t size,
-        int (*cmp)(const void *, const void *))
-{
-	int t;
-	size_t mid, low, high;
-	const char *cur, *base = ary;
-
-	low = 0;
-	high = n - 1;
-	while (low <= high) {
-		mid = low + (high - low) / 2;
-		cur = base + mid*size;
-
-		if ((t == (*cmp)(key, cur)) == 0)
-			return (void *) cur;
-		else if (t > 0)
-			low = mid + 1;
-		else
-			high = mid - 1;
-	}
-
-	return NULL;
-}
--- a/lib/c/src/calloc.c
+++ /dev/null
@@ -1,17 +1,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-void *
-calloc(size_t nmemb, size_t size)
-{
-	size_t nbytes;
-	void *mem;
-
-	if (!nmemb || !size || nmemb > (size_t)-1/size)
-                return NULL;
-
-	nbytes = nmemb * size;
-	if ((mem = malloc(nbytes)) == NULL)
-		return NULL;
-	return memset(mem, 0, nbytes);
-}
--- a/lib/c/src/clearerr.c
+++ /dev/null
@@ -1,9 +1,0 @@
-
-#include <stdio.h>
-#undef clearerr
-
-void
-clearerr(FILE *fp)
-{
-	fp->flags &= ~(_IOERR | _IOEOF);
-}
--- a/lib/c/src/ctype.c
+++ /dev/null
@@ -1,26 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef ctype
-
-int __ctmp;
-
-/* __ctype is shifted by one to match EOF */
-unsigned char __ctype[257] = {
-	0,                                              /* EOF */
-	_C,_C,_C,_C,_C,_C,_C,_C,                        /* 0-7 */
-	_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,         /* 8-15 */
-	_C,_C,_C,_C,_C,_C,_C,_C,                        /* 16-23 */
-	_C,_C,_C,_C,_C,_C,_C,_C,                        /* 24-31 */
-	_S|_SP,_P,_P,_P,_P,_P,_P,_P,                    /* 32-39 */
-	_P,_P,_P,_P,_P,_P,_P,_P,                        /* 40-47 */
-	_D,_D,_D,_D,_D,_D,_D,_D,                        /* 48-55 */
-	_D,_D,_P,_P,_P,_P,_P,_P,                        /* 56-63 */
-	_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,      /* 64-71 */
-	_U,_U,_U,_U,_U,_U,_U,_U,                        /* 72-79 */
-	_U,_U,_U,_U,_U,_U,_U,_U,                        /* 80-87 */
-	_U,_U,_U,_P,_P,_P,_P,_P,                        /* 88-95 */
-	_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,      /* 96-103 */
-	_L,_L,_L,_L,_L,_L,_L,_L,                        /* 104-111 */
-	_L,_L,_L,_L,_L,_L,_L,_L,                        /* 112-119 */
-	_L,_L,_L,_P,_P,_P,_P,_C,                        /* 120-127 */
-};
--- a/lib/c/src/exit.c
+++ /dev/null
@@ -1,13 +1,0 @@
-#include <stdlib.h>
-#undef exit
-
-void (*_exitf[_ATEXIT_MAX])(void);
-unsigned _exitn;
-
-void
-exit(int status)
-{
-	while (_exitn > 0)
-		(*_exitf[--_exitn])();
-	_Exit(status);
-}
--- a/lib/c/src/fclose.c
+++ /dev/null
@@ -1,31 +1,0 @@
-
-#include <stdio.h>
-#undef fclose
-
-int
-fclose(FILE *fp)
-{
-	int r = EOF;
-
-	if ((fp->flags & _IOSTRG) == 0 &&
-	    fp->flags & (_IOWRITE | _IOREAD | _IOWR)) {
-		r = 0;
-		if (fflush(fp) == EOF)
-			r = EOF;
-		if (close(fp->fd) < 0)
-			r = EOF;
-	}
-
-	if (fp->flags & _IOALLOC) {
-		free(fp->buf);
-		fp->buf = NULL;
-	}
-
-	fp->flags &= ~(_IOWRITE | _IOREAD | _IOWR |
-	               _IOERR | _IOEOF |
-	               _IOALLOC |
-	               _IOTXT |
-	               _IOSTRG);
-
-	return r;
-}
--- a/lib/c/src/feof.c
+++ /dev/null
@@ -1,9 +1,0 @@
-
-#include <stdio.h>
-#undef feof
-
-int
-feof(FILE *fp)
-{
-	return fp->flags & _IOEOF;
-}
--- a/lib/c/src/ferror.c
+++ /dev/null
@@ -1,9 +1,0 @@
-
-#include <stdio.h>
-#undef ferror
-
-int
-ferror(FILE *fp)
-{
-	return fp->flags & _IOERR;
-}
--- a/lib/c/src/fgetc.c
+++ /dev/null
@@ -1,9 +1,0 @@
-
-#include <stdio.h>
-#undef fgetc
-
-int
-fgetc(FILE *fp)
-{
-	return getc(fp);
-}
--- a/lib/c/src/fgets.c
+++ /dev/null
@@ -1,19 +1,0 @@
-#include <stdio.h>
-#undef fgets
-
-char *
-fgets(char *s, int n, FILE *fp)
-{
-	int ch;
-	char *t = s;
-
-	while (--n > 0 && (ch = getc(fp)) != EOF) {
-		if ((*t++ = ch) == '\n')
-			break;
-	}
-	if (ch == EOF && s == t)
-		return NULL;
-	*t = '\0';
-
-	return s;
-}
--- a/lib/c/src/fopen.c
+++ /dev/null
@@ -1,20 +1,0 @@
-
-#include <errno.h>
-#include <stdio.h>
-#undef fopen
-
-FILE *
-fopen(const char * restrict name, const char * restrict mode)
-{
-	FILE *fp;
-
-	for (fp = __iob; fp < &__iob[FILE_MAX]; ++fp) {
-		if (fp->flags & (_IOREAD | _IOWRITE | _IORW) == 0)
-			break;
-	}
-	if (fp == &__iob[FILE_MAX]) {
-		errno = ENOMEM;
-		return NULL;
-	}
-	return _fpopen(name, mode, fp);
-}
--- a/lib/c/src/fprintf.c
+++ /dev/null
@@ -1,15 +1,0 @@
-#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;
-}
--- a/lib/c/src/fputc.c
+++ /dev/null
@@ -1,9 +1,0 @@
-
-#include <stdio.h>
-#undef fputc
-
-int
-fputc(int c, FILE *fp)
-{
-	return putc(c, fp);
-}
--- a/lib/c/src/fputs.c
+++ /dev/null
@@ -1,12 +1,0 @@
-
-#include <stdio.h>
-
-int
-fputs(const char * restrict bp, FILE * restrict fp)
-{
-	int r, ch;
-
-	while (ch = *bp++)
-		r = putc(ch, fp);
-	return r;
-}
--- a/lib/c/src/fread.c
+++ /dev/null
@@ -1,24 +1,0 @@
-
-#include <stdio.h>
-#undef fread
-
-size_t
-fread(void * restrict ptr, size_t size, size_t nmemb,
-      FILE * restrict fp)
-{
-	unsigned char *bp = ptr;
-	size_t n, i;
-
-	if (size == 0)
-		return 0;
-
-	for (n = 0; n < nmemb; n++) {
-		i = size;
-		do {
-			if ((*bp++ = getc(fp)) == EOF)
-				return n;
-		} while (--i);
-	}
-
-	return n;
-}
--- a/lib/c/src/freopen.c
+++ /dev/null
@@ -1,12 +1,0 @@
-
-#include <stdio.h>
-#undef freopen
-
-FILE *
-freopen(const char * restrict name, const char * restrict mode,
-        FILE * restrict fp)
-{
-	if (fclose(fp) == EOF)
-		return NULL;
-	return _fpopen(name, mode, fp);
-}
--- a/lib/c/src/fseek.c
+++ /dev/null
@@ -1,27 +1,0 @@
-
-#include <stdio.h>
-#include "syscall.h"
-#undef fseek
-
-int
-fseek(FILE *fp, long off, int whence)
-{
-	if (fp->flags & _IOERR)
-		return EOF;
-
-	if ((fp->flags & _IOWRITE) && fflush(fp))
-		return -1;
-	else if (whence == SEEK_CUR && (fp->flags & _IOREAD))
-		off -= fp->wp - fp->rd;
-
-	if (_seek(fp->fd, off, type) < 0) {
-		fp->flags |= _IOERR;
-		return EOF;
-	}
-
-	if (fp->flags & _IORW)
-		fp->flags &= ~(_IOREAD | _IOWRITE);
-	fp->flags &= ~_IOEOF;
-
-	return 0;
-}
--- a/lib/c/src/fwrite.c
+++ /dev/null
@@ -1,25 +1,0 @@
-
-#include <stdio.h>
-#undef fwrite
-
-size_t
-fwrite(const void * restrict ptr, size_t size, size_t nmemb,
-       FILE * restrict fp)
-{
-	const unsigned char *bp = ptr;
-	size_t n, i;
-
-	if (size == 0)
-		return 0;
-
-	for (n = 0; n < nmemb; n++) {
-		i = size;
-		do
-			putc(*bp++, fp);
-		while (--i);
-		if (ferror(fp))
-			break;
-	}
-
-	return n;
-}
--- a/lib/c/src/getc.c
+++ /dev/null
@@ -1,9 +1,0 @@
-
-#include <stdio.h>
-#undef getc
-
-int
-getc(FILE *fp)
-{
-	return (fp->rp >= fp->wp) ?  __getc(fp) : *fp->rp++;
-}
--- a/lib/c/src/getchar.c
+++ /dev/null
@@ -1,9 +1,0 @@
-
-#include <stdio.h>
-#undef getchar
-
-int
-getchar(void)
-{
-	return getc(stdin);
-}
--- a/lib/c/src/gets.c
+++ /dev/null
@@ -1,17 +1,0 @@
-#include <stdio.h>
-#undef gets
-
-char *
-gets(char *s)
-{
-	int ch;
-	char *t = s;
-
-	while ((ch = getc(stdin)) != EOF && ch != '\n')
-		*t++ = ch;
-	if (ch == EOF && s == t)
-		return NULL;
-	*t = '\0';
-
-	return s;
-}
--- a/lib/c/src/isalnum.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef isalnum
-
-int
-isalnum(int c)
-{
-	return (__ctype+1)[c] & (_U|_L|_D);
-}
--- a/lib/c/src/isalpha.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef isalpha
-
-int
-isalpha(int c)
-{
-	return (__ctype+1)[c] & (_U|_L);
-}
--- a/lib/c/src/isascii.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef isascii
-
-int
-isascii(int c)
-{
-	return c <= 0x7f;
-}
--- a/lib/c/src/isblank.c
+++ /dev/null
@@ -1,5 +1,0 @@
-int
-isblank(int c)
-{
-	return (c == ' ') || (c == '\t');
-}
--- a/lib/c/src/iscntrl.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef iscntrl
-
-int
-iscntrl(int c)
-{
-	return (__ctype+1)[c] & (_C);
-}
--- a/lib/c/src/isdigit.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef isdigit
-
-int
-isdigit(int c)
-{
-	return (__ctype+1)[c] & (_D);
-}
--- a/lib/c/src/isgraph.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef isgraph
-
-int
-isgraph(int c)
-{
-	return (__ctype+1)[c] & (_P|_U|_L|_D);
-}
--- a/lib/c/src/islower.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef islower
-
-int
-islower(int c)
-{
-	return (__ctype+1)[c] & _L;
-}
--- a/lib/c/src/isprint.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef isprint
-
-int
-isprint(int c)
-{
-	return (__ctype+1)[c] & (_P|_U|_L|_D|_SP);
-}
--- a/lib/c/src/ispunct.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef ispunct
-
-int
-ispunct(int c)
-{
-	return (__ctype+1)[c] & (_P);
-}
--- a/lib/c/src/isspace.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef isspace
-
-int
-isspace(int c)
-{
-	return (__ctype+1)[c] & _S;
-}
--- a/lib/c/src/isupper.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef isupper
-
-int
-isupper(int c)
-{
-	return (__ctype+1)[c] & _U;
-}
--- a/lib/c/src/isxdigit.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef isxdigit
-
-int
-isxdigit(int c)
-{
-	return (__ctype+1)[c] & (_D|_X);
-}
--- a/lib/c/src/labs.c
+++ /dev/null
@@ -1,9 +1,0 @@
-
-#include <stdlib.h>
-#undef labs
-
-long
-labs(long n)
-{
-	return (n < 0) ? -n : n;
-}
--- a/lib/c/src/llabs.c
+++ /dev/null
@@ -1,9 +1,0 @@
-
-#include <stdlib.h>
-#undef llabs
-
-long long
-llabs(long long n)
-{
-	return (n < 0) ? -n : n;
-}
--- a/lib/c/src/localeconv.c
+++ /dev/null
@@ -1,14 +1,0 @@
-#include <locale.h>
-#include <limits.h>
-#undef localeconv
-
-struct lconv *
-localeconv(void)
-{
-	static struct lconv lc = { ".", "", "", "", "", "", "", "", "", "",
-	                           CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
-	                           CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
-	                           CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
-	                           CHAR_MAX, CHAR_MAX };
-	return &lc;
-}
--- a/lib/c/src/malloc.c
+++ /dev/null
@@ -1,152 +1,0 @@
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "malloc.h"
-#include "syscall.h"
-
-#define MAXADDR ((char *)-1)
-#define ERRADDR ((char *)-1)
-
-extern char end[];
-static Header base = { .h.next = &base };
-static Header *freep = &base;
-static char *heap = end;
-
-/*
- * Run over the free list looking for the nearest previous
- * block. There are two possible results: end of the list
- * or an intermediary block.
- */
-void *
-_prevchunk(Header *hp)
-{
-	Header *p;
-
-	for (p = freep; ;p = p->h.next) {
-		/* hp between p and p->h.next? */
-		if (p < hp && hp < p->h.next)
-			break;
-		/* p before hp and hp at the end of list? */
-		if (p->h.next <= p && (hp < p->h.next || hp > p))
-			break;
-	}
-	return p;
-}
-
-/*
- * Get the previous block and try to merge
- * with next and previous blocks
- */
-void
-free(void *mem)
-{
-	Header *hp, *prev;
-
-	if (!mem)
-		return;
-
-	hp = (Header *) mem - 1;
-	prev = _prevchunk(hp);
-
-	/* join to next */
-	if (hp + hp->h.size == prev->h.next) {
-		hp->h.size += prev->h.next->h.size;
-		hp->h.next = prev->h.next->h.next;
-	} else {
-		hp->h.next = prev->h.next;
-	}
-
-	/* join to previous */
-	if (prev + prev->h.size == hp) {
-		prev->h.size += hp->h.size;
-		prev->h.next = hp->h.next;
-	} else {
-		prev->h.next = hp;
-	}
-
-	freep = prev;
-}
-
-static void *
-sbrk(uintptr_t inc)
-{
-	char *new, *old = heap;
-
-	if (old >= MAXADDR - inc)
-		return ERRADDR;
-
-	new = old + inc;
-	if (_brk(new) < 0)
-		return ERRADDR;
-	heap = new;
-
-	return old;
-}
-
-static Header *
-morecore(size_t nunits)
-{
-	char *rawmem;
-	Header *hp;
-
-	if (nunits < NALLOC)
-		nunits = NALLOC;
-
-	rawmem = sbrk(nunits * sizeof(Header));
-	if (rawmem == ERRADDR)
-		return NULL;
-
-	hp = (Header*)rawmem;
-	hp->h.size = nunits;
-
-	/* integrate new memory into the list */
-	free(hp + 1);
-
-	return freep;
-}
-
-/*
- * Run over the list of free blocks trying to find a block
- * big enough for nbytes. If the block fit perfectly with
- * the required size then we only have to unlink
- * the block. Otherwise we have to split the block and
- * return the right part. If we run over the full list
- * without a fit then we have to require more memory
- *
- *              ______________________________________
- * ___________./______________________________________\_____
- * ...| in   |   |     | in  |  |.....| in   |  |    | |....
- * ...| use  |   |     | use |  |.....| use  |  |    | |....
- * ___|______|___|.____|_____|._|_____|______|._|.___|.|____
- *            \__/ \_________/ \_____________/ \/ \__/
- */
-void *
-malloc(size_t nbytes)
-{
-	Header *cur, *prev;
-	size_t nunits;
-
-	/* 1 unit for header plus enough units to fit nbytes */
-	nunits = (nbytes+sizeof(Header)-1) / sizeof(Header) + 1;
-
-	for (prev = freep; ; prev = cur) {
-		cur = prev->h.next;
-		if (cur->h.size >= nunits) {
-			if (cur->h.size == nunits) {
-				prev->h.next = cur->h.next;
-			} else {
-				cur->h.size -= nunits;
-				cur += cur->h.size;
-				cur->h.size = nunits;
-			}
-			freep = prev;
-			return cur + 1;
-		}
-
-		if (cur == freep) {
-			if ((cur = morecore(nunits)) == NULL)
-				return NULL;
-		}
-	}
-}
--- a/lib/c/src/malloc.h
+++ /dev/null
@@ -1,16 +1,0 @@
-#include <stdlib.h>
-
-/* minimum amount of required units */
-#define NALLOC 10000
-
-typedef union header Header;
-union header {
-	struct hdr {
-		Header *next;
-		size_t size;
-	} h;
-	/* most restrictive type fixes the union size for alignment */
-	_ALIGNTYPE most;
-};
-
-extern void *_prevchunk(Header *hp);
--- a/lib/c/src/memchr.c
+++ /dev/null
@@ -1,12 +1,0 @@
-#include <string.h>
-#undef memchr
-
-void *
-memchr(const void *s, int c, size_t n)
-{
-	unsigned char *bp = (char *) s;
-
-	while (n > 0 && *bp++ != c)
-		--n;
-	return (n == 0) ? NULL : bp-1;
-}
--- a/lib/c/src/memcmp.c
+++ /dev/null
@@ -1,12 +1,0 @@
-#include <string.h>
-#undef memcmp
-
-int
-memcmp(const void *s1, const void *s2, size_t n)
-{
-	char *s = (char *) s1, *t = (char *) s2;
-
-	while (n > 0 && *s == *t)
-		--n, ++s, ++t;
-	return n ? (*s - *t) : 0;
-}
--- a/lib/c/src/memcpy.c
+++ /dev/null
@@ -1,13 +1,0 @@
-#include <string.h>
-#undef memcpy
-
-void *
-memcpy(void * restrict dst, const void * restrict src, size_t n)
-{
-	char *s1 = dst;
-	const char *s2 = src;
-
-	while (n-- > 0)
-		*s1++ = *s2++;
-	return dst;
-}
--- a/lib/c/src/memmove.c
+++ /dev/null
@@ -1,18 +1,0 @@
-#include <string.h>
-#undef memmove
-
-void *
-memmove(void *dst, const void *src, size_t n)
-{
-	char *d = dst, *s = (char *) src;
-
-	if (d < s) {
-		while (n-- > 0)
-			*d++ = *s++;
-	} else {
-		s += n-1, d += n-1;
-		while (n-- > 0)
-			*d-- = *s--;
-	}
-	return dst;
-}
--- a/lib/c/src/memset.c
+++ /dev/null
@@ -1,12 +1,0 @@
-#include <string.h>
-#undef memset
-
-void *
-memset(void *s, int c, size_t n)
-{
-	char *m = s;
-
-	while (n-- > 0)
-		*m++ = c;
-	return s;
-}
--- a/lib/c/src/perror.c
+++ /dev/null
@@ -1,17 +1,0 @@
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#undef perror
-
-void
-perror(const char *msg)
-{
-	if (msg && *msg) {
-		fputs(msg, stderr);
-		putc(':', stderr);
-		putc(' ', stderr);
-	}
-	fputs(strerror(errno), stderr);
-	putc('\n', stderr);
-}
--- a/lib/c/src/printf.c
+++ /dev/null
@@ -1,15 +1,0 @@
-#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(stdout, fmt, va);
-	va_end(va);
-	return cnt;
-}
--- a/lib/c/src/putc.c
+++ /dev/null
@@ -1,9 +1,0 @@
-
-#include <stdio.h>
-#undef putc
-
-int
-putc(int ch, FILE *fp)
-{
-	return (fp->wp >= fp->rp) ? __putc(c,fp) : *fp->wp++ = c;
-}
--- a/lib/c/src/putchar.c
+++ /dev/null
@@ -1,9 +1,0 @@
-
-#include <stdio.h>
-#undef putchar
-
-int
-putchar(int ch)
-{
-	return putc(ch, stdin);
-}
--- a/lib/c/src/puts.c
+++ /dev/null
@@ -1,12 +1,0 @@
-
-#include <stdio.h>
-
-int
-puts(const char *str)
-{
-	int ch;
-
-	while (ch = *str)
-		putchar(ch);
-	return putchar('\n');
-}
--- a/lib/c/src/qsort.c
+++ /dev/null
@@ -1,69 +1,0 @@
-
-#include <stdlib.h>
-#include <string.h>
-#undef qsort
-
-/*
- * This implementation of qsort is based in the paper
- * "Engineering a Sort Function", by Jon L.Bentley and M. Douglas McIlroy.
- * A lot of different optimizations were removed to make the code simpler.
- */
-
-struct qsort {
-	size_t es;
-	int (*cmp)(const void *, const void *);
-};
-
-static void
-swap(char *i, char *j, size_t n)
-{
-	do {
-		char c = *i;
-		*i++ = *j;
-		*j++ = c;
-	} while (--n > 0);
-}
-
-static void
-xqsort(char *a, size_t n, struct qsort *qs)
-{
-	size_t j, es = qs->es;
-	char *pi, *pj, *pn;
-
-	if (n <= 1)
-		return;
-
-	pi = a;
-	pn = pj = a + n*es;
-
-	swap(a, a + n/2 * es,  es);
-	for (;;) {
-		do {
-			pi += es;
-		} while  (pi < pn && qs->cmp(pi, a) < 0);
-
-		do {
-			pj -= es;
-		} while (pj > a && qs->cmp(pj, a) > 0);
-
-		if (pj < pi)
-			break;
-		swap(pi, pj, es);
-	}
-	swap(a, pj, es);
-
-	j = (pj - a) / es;
-	xqsort(a, j, qs);
-	xqsort(a + (j+1)*es, n-j-1, qs);
-}
-
-void
-qsort(void *base, size_t nmemb, size_t size,
-      int (*f)(const void *, const void *))
-{
-	struct qsort qs;
-
-	qs.cmp = f;
-	qs.es = size;
-	xqsort(base, nmemb, &qs);
-}
--- a/lib/c/src/rand.c
+++ /dev/null
@@ -1,18 +1,0 @@
-#include <stdlib.h>
-#undef rand
-#undef srand
-
-static int next;
-
-void
-srand(unsigned seed)
-{
-	next = seed;
-}
-
-int
-rand(void)  /* RAND_MAX assumed to be 32767. */
-{
-	next = next * 1103515245 + 12345;
-	return (unsigned)(next/65536) % 32768;
-}
--- a/lib/c/src/realloc.c
+++ /dev/null
@@ -1,67 +1,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-#include "malloc.h"
-
-void *
-realloc(void *ptr, size_t nbytes)
-{
-	Header *oh, *prev, *next, *new;
-	size_t nunits, avail, onbytes, n;
-
-	if (!nbytes)
-		return NULL;
-
-	if (!ptr)
-		return malloc(nbytes);
-
-	nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1;
-	oh = (Header*)ptr - 1;
-
-	if (oh->h.size == nunits)
-		return ptr;
-
-	new = oh + nunits;
-
-	if (nunits < oh->h.size - 1) {
-		new->h.size = oh->h.size - nunits;
-		oh->h.size = nunits;
-		free(new + 1);
-		return oh;
-	}
-
-	prev = _prevchunk(oh);
-
-	if (oh + oh->h.size == prev->h.next) {
-		/*
-		 * if there is free space adjacent
-		 * to the current memory
-		 */
-		next = prev->h.next;
-		avail = oh->h.size + next->h.size;
-
-		if (avail == nunits) {
-			oh->h.size = nunits;
-			prev->h.next = next->h.next;
-			return oh;
-		}
-
-		if (avail > nunits) {
-			oh->h.size = nunits;
-			prev->h.next = new;
-			new->h.next = next;
-			new->h.size = avail - nunits;
-			return oh;
-		}
-	}
-
-	onbytes = (oh->h.size - 1) * sizeof(Header);
-	if ((new = malloc(nbytes)) == NULL)
-		return NULL;
-
-	n = (onbytes > nbytes) ? nbytes : onbytes;
-	memcpy(new, ptr, n);
-	free(ptr);
-
-	return new;
-}
--- a/lib/c/src/rewind.c
+++ /dev/null
@@ -1,11 +1,0 @@
-
-#include <stdio.h>
-#undef rewind
-
-void
-rewind(FILE *fp)
-{
-	fp->flags &= ~_IOERR;
-	fseek(fp, 0, SEEK_SET);
-	clearerr(fp);
-}
--- a/lib/c/src/setbuf.c
+++ /dev/null
@@ -1,9 +1,0 @@
-
-#include <stdio.h>
-#undef setbuf
-
-void
-setbuf(FILE * restrict fp, char * restrict buf)
-{
-	setvbuf(fp, buf, (buf) ? _IOFBF : _IONBF, BUFSIZ);
-}
--- a/lib/c/src/setlocale.c
+++ /dev/null
@@ -1,16 +1,0 @@
-#include <locale.h>
-#include <stddef.h>
-#undef setlocale
-
-char *
-setlocale(int category, const char *locale)
-{
-	if (category > LC_TIME || category < LC_ALL)
-		return NULL;
-	if (!locale ||
-	    locale[0] == '\0' ||
-	    locale[0] == 'C' && locale[1] == '\0') {
-		return "C";
-	}
-	return NULL;
-}
--- a/lib/c/src/setvbuf.c
+++ /dev/null
@@ -1,44 +1,0 @@
-
-#include <errno.h>
-#include <stdio.h>
-#undef setvbuf
-
-int
-setvbuf(FILE * restrict fp, char * restrict buf, int mode, size_t size)
-{
-	int flags, r;
-
-	if (fflush(fp) == EOF)
-		return EOF;
-
-	switch (mode) {
-	case _IONBF:
-		size = sizeof(fp->unbuf);
-		buf = fp->unbuf;
-		break;
-	case _IOLBF:
-	case _IOFBF:
-		if (size == 0) {
-			if ((buf = malloc(BUFSIZ)) == NULL) {
-				errno = ENOMEM;
-				return EOF;
-			}
-			size = BUFSIZ;
-		}
-		break;
-	default:
-		errno = EIVAL;
-		return EOF;
-	}
-
-	flags = fp->flags;
-	if (flags & _IOALLOC)
-		free(fp->buf);
-	flag &= ~(_IONBF | _IOLBF | _IOFBF | _IOALLOC | _IOALLOC);
-	flags |= mode;
-	fp->flags = flags;
-	fp->buf = buf;
-	fp->size = size;
-
-	return 0;
-}
--- a/lib/c/src/snprintf.c
+++ /dev/null
@@ -1,18 +1,0 @@
-
-#include <stdarg.h>
-#include <stdio.h>
-#undef snprintf
-
-int
-snprintf(char * restrict s, size_t siz, const char * restrict fmt, ...)
-{
-	int r;
-	va_list va;
-
-	va_list va_arg;
-	va_start(va, fmt);
-	r = vsnprintf(s, siz, fmt, va);
-	va_end(va);
-
-	return r;
-}
--- a/lib/c/src/sprintf.c
+++ /dev/null
@@ -1,17 +1,0 @@
-
-#include <stdarg.h>
-#include <stdio.h>
-#undef sprintf
-
-int
-sprintf(char * restrict s, const char * restrict fmt, ...)
-{
-	int r;
-
-	va_list va;
-	va_start(va, fmt);
-	r = vsprintf(s, fmt, va);
-	va_end(va);
-
-	return r;
-}
--- a/lib/c/src/stdio.c
+++ /dev/null
@@ -1,26 +1,0 @@
-
-#include <stdio.h>
-
-static unsigned char inbuf[BUFSIZ];
-static unsigned char outbuf[BUFSIZ];
-
-FILE __iob[FOPEN_MAX] = {
-	{
-		.fd = 0,
-		.buf = inbuf,
-		.len = BUFSIZ,
-		.flags = _IOREAD
-	},
-	{
-		.fd = 1,
-		.buf = outbuf,
-		.len = BUFSIZ,
-		.flags = _IOWRITE | _IOLBF
-	},
-	{
-		.fd = 2,
-		.buf = stderr->unbuf,
-		.len = sizeof(stderr->unbuf),
-		.flags = _IOWRITE
-	},
-};
--- a/lib/c/src/strcat.c
+++ /dev/null
@@ -1,14 +1,0 @@
-#include <string.h>
-#undef strcat
-
-char *
-strcat(char * restrict dst, const char * restrict src)
-{
-	char *ret = dst;
-
-	while (*dst)
-		++dst;
-	while (*dst++ = *src++)
-		;
-	return ret;
-}
--- a/lib/c/src/strchr.c
+++ /dev/null
@@ -1,10 +1,0 @@
-#include <string.h>
-#undef strchr
-
-char *
-strchr(const char *s, int c)
-{
-	while (*s && *s != c)
-		++s;
-	return (*s == c) ? (char *)s : NULL;
-}
--- a/lib/c/src/strcmp.c
+++ /dev/null
@@ -1,10 +1,0 @@
-#include <string.h>
-#undef strcmp
-
-int
-strcmp(const char *s1, const char *s2)
-{
-	while (*s1 && *s2 && *s1 == *s2)
-		++s1, ++s2;
-	return *(unsigned char *)s1 - *(unsigned char *)s2;
-}
--- a/lib/c/src/strcoll.c
+++ /dev/null
@@ -1,10 +1,0 @@
-#include <string.h>
-#undef strcoll
-
-int
-strcoll(const char *s1, const char *s2)
-{
-	while (*s1 && *s2 && *s1 == *s2)
-		++s1, ++s2;
-	return *(unsigned char *) s1 - *(unsigned char *) s2;
-}
--- a/lib/c/src/strcpy.c
+++ /dev/null
@@ -1,12 +1,0 @@
-#include <string.h>
-#undef strcpy
-
-char *
-strcpy(char * restrict dst, const char * restrict src)
-{
-	char *ret = dst;
-
-	while (*dst++ = *src++)
-		;
-	return ret;
-}
--- a/lib/c/src/strcspn.c
+++ /dev/null
@@ -1,18 +1,0 @@
-#include <string.h>
-#undef strcspn
-
-size_t
-strcspn(const char *s1, const char *s2)
-{
-	size_t n;
-	int c;
-	const char *p;
-
-	for (n = 0; c = *s1++; ++n) {
-		for (p = s2; *p && *p != c; ++p)
-			;
-		if (*p == c)
-			break;
-	}
-	return n;
-}
--- a/lib/c/src/strerror.c
+++ /dev/null
@@ -1,13 +1,0 @@
-
-#include <errno.h>
-#include <string.h>
-#undef strerror
-
-char *
-strerror(int errnum)
-{
-	if (errnum < _sys_nerr)
-		return _sys_errlist[errnum];
-	else
-		return "Unknown error";
-}
--- a/lib/c/src/strlen.c
+++ /dev/null
@@ -1,12 +1,0 @@
-#include <string.h>
-#undef strlen
-
-size_t
-strlen(const char *s)
-{
-	const char *t;
-
-	for (t = s; *t; ++t)
-		;
-	return t - s;
-}
--- a/lib/c/src/strncat.c
+++ /dev/null
@@ -1,15 +1,0 @@
-#include <string.h>
-#undef strncat
-
-char *
-strncat(char * restrict dst, const char * restrict src, size_t n)
-{
-	char *ret = dst;
-
-	while (*dst)
-		++dst;
-	while (n-- > 0 && *src)
-		*dst++ = *src++;
-	*dst = '\0';
-	return ret;
-}
--- a/lib/c/src/strncmp.c
+++ /dev/null
@@ -1,17 +1,0 @@
-#include <string.h>
-#undef strncmp
-
-int
-strncmp(const char *s1, const char *s2, size_t n)
-{
-	int c;
-
-	if (n == 0)
-		return 0;
-	while ((c = *s1) != '\0' && c == *s2) {
-		if (--n == 0)
-			return 0;
-		++s1, ++s2;
-	}
-	return (*(unsigned char *) s1 - *(unsigned char *) s2);
-}
--- a/lib/c/src/strncpy.c
+++ /dev/null
@@ -1,14 +1,0 @@
-#include <string.h>
-#undef strncpy
-
-char *
-strncpy(char * restrict dst, const char * restrict src, size_t n)
-{
-	char *ret = dst;
-
-	for (; n > 0 && *src; --n)
-		*dst++ = *src++;
-	while (n-- > 0)
-		*dst++ = '\0';
-	return ret;
-}
--- a/lib/c/src/strpbrk.c
+++ /dev/null
@@ -1,17 +1,0 @@
-#include <string.h>
-#undef strpbrk
-
-char *
-strpbrk(const char *s1, const char *s2)
-{
-	int c;
-	const char *p;
-
-	for (; c = *s1; ++s1) {
-		for (p = s2; *p && *p != c; ++p)
-			;
-		if (*p == c)
-			return s1;
-	}
-	return NULL;
-}
--- a/lib/c/src/strrchr.c
+++ /dev/null
@@ -1,14 +1,0 @@
-#include <string.h>
-#undef strrchr
-
-char *
-strrchr(const char *s, int c)
-{
-	const char *t = s;
-
-	while (*t)
-		++t;
-	while (t > s && *t != c)
-		--t;
-	return (*t == c) ? (char *)t : NULL;
-}
--- a/lib/c/src/strspn.c
+++ /dev/null
@@ -1,18 +1,0 @@
-#include <string.h>
-#undef strspn
-
-size_t
-strspn(const char *s1, const char *s2)
-{
-	size_t n;
-	int c;
-	const char *p;
-
-	for (n = 0; c = *s1++; ++n) {
-		for (p = s2; *p && *p != c; ++p)
-			;
-		if (*p == '\0')
-			break;
-	}
-	return n;
-}
--- a/lib/c/src/strstr.c
+++ /dev/null
@@ -1,26 +1,0 @@
-#include <string.h>
-#undef strstr
-
-char *
-strstr(const char *s1, const char *s2)
-{
-	const char *p, *q;
-	int c0, c;
-
-	c0 = *s2;
-	if (c0 == '\0')
-		return (char *) s1;
-	--s1;
-	while ((s1 = strchr(s1 + 1, c0)) != NULL) {
-		p = s1;
-		q = s2;
-		for (;;) {
-			if ((c = *++p) == '\0')
-				return (char *) s1;
-			if (c != *++q)
-				break;
-		}
-	}
-
-	return NULL;
-}
--- a/lib/c/src/strtok.c
+++ /dev/null
@@ -1,25 +1,0 @@
-#include <string.h>
-#undef strtok
-
-char *
-strtok(char * restrict s, const char * restrict delim)
-{
-	static char *line;
-
-	if (s)
-		line = s;
-	if (!s && !line)
-		return NULL;
-
-	s = line + strspn(line, delim);
-	if (*s == '\0')
-		return line = NULL;
-
-	line = s + strcspn(s, delim);
-	if (*line != '\0')
-		*line++ = '\0';
-	else
-		line = NULL;
-
-	return s;
-}
--- a/lib/c/src/strxfrm.c
+++ /dev/null
@@ -1,12 +1,0 @@
-#include <string.h>
-#undef strxfrm
-
-size_t
-strxfrm(char * restrict dst, const char * restrict src, size_t n)
-{
-	size_t len = strlen(src);
-
-	if (len < n)
-		strcpy(dst, src);
-	return len;
-}
--- a/lib/c/src/syscall.h
+++ /dev/null
@@ -1,14 +1,0 @@
-extern void *_brk(void *addr);
-extern int _open(char *path, int flags, int perm);
-extern int _close(int fd);
-extern int _read(int fd, void *buf, size_t n);
-extern int _write(int fd, void *buf, size_t n);
-extern int _lseek(int fd, long off, int whence);
-extern void _Exit(int status);
-extern void _access(char *path, int mode);
-
-extern int raise(int sig);
-extern void (*signal(int sig, void (*func)(int)))(int);
-extern getenv(const char *var);
-extern int rename(const char *from, const char *to);
-extern int remove(const char *path);
--- a/lib/c/src/tmpnam.c
+++ /dev/null
@@ -1,32 +1,0 @@
-
-#include <stdio.h>
-#include <string.h>
-#include "syscall.h"
-#undef tmpnam
-
-char *
-tmpnam(char *s)
-{
-	static char *tmpl, buf[L_tmpnam];
-	char *p;
-
-	if (*buf == '\0') {
-		for (tmpl = buf, p = _TMPNAME; *tmpl++ = *p++; )
-			;
-		for (p = tmpl; p < &buf[L_tmpnam-1]; ++p)
-			*p = '0';
-		*p = '\0';
-	}
-	for (;;) {
-		for (p = tmpl; *p && *p != '9'; ++p)
-			;
-		if (*p == '\0')
-			return NULL;
-		++*p;
-		if (_access(buf, 0) != 0)
-			break;
-	}
-	if (s)
-		strcpy(s, buf);
-	return buf;
-}
--- a/lib/c/src/tolower.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef tolower
-
-int
-tolower(int c)
-{
-	return (isupper(c)) ? c | 0x20 : c;
-}
--- a/lib/c/src/toupper.c
+++ /dev/null
@@ -1,9 +1,0 @@
-#define __USE_MACROS
-#include <ctype.h>
-#undef toupper
-
-int
-toupper(int c)
-{
-	return (islower(c)) ? c & ~0x20 : c;
-}
--- a/lib/c/src/vfprintf.c
+++ /dev/null
@@ -1,369 +1,0 @@
-/*
- * This file is covered by the license that you can find in the file
- * LICENSE, but for this file, vfprintf.c, an additional clause is
- * added:
- *     - Christopher M. Graff (<cm0graff@gmail.com>) is forbidden to
- *       use, copy, modify and/or distribute this file. He is forbidden
- *       even to read this file.
- */ 
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <wchar.h>
-#undef vfprintf
-
-enum {
-	LONG     = 1 << 0,
-	LLONG    = 1 << 1,
-	SHORT    = 1 << 2,
-	CHAR     = 1 << 3,
-	SIZET    = 1 << 4,
-	PTRDIFF  = 1 << 5,
-	INTMAX   = 1 << 6,
-	VOIDPTR  = 1 << 7,
-	UNSIGNED = 1 << 8,
-	ALTFORM  = 1 << 9,
-};
-
-#define MAXPREC    50
-
-struct conv {
-	int sign;
-	int prec;
-	char *digs;
-	int base;
-};
-
-static uintmax_t
-getnum(va_list va, int flags, int *sign)
-{
-	uintmax_t uval;
-	intmax_t val;
-
-	if (flags & CHAR) {
-		val = uval = va_arg(va, int);
-		uval = (unsigned char) uval;
-	} else if (flags & SHORT) {
-		val = uval = va_arg(va, int);
-		uval = (unsigned short) uval;
-	} else if (flags & LONG) {
-		val = uval = va_arg(va, long);
-		uval = (unsigned long) uval;
-	} else if (flags & LLONG) {
-		val = uval = va_arg(va, long long);
-		uval = (unsigned long long) uval;
-	} else if (flags & SIZET) {
-		val = uval = va_arg(va, size_t);
-		uval = (size_t) uval;
-	} else if (flags & INTMAX) {
-		val = uval = va_arg(va, uintmax_t);
-	} else if (flags & VOIDPTR) {
-		val = uval = (uintmax_t) va_arg(va, void *);
-	} else {
-		val = uval = va_arg(va, int);
-		uval = (unsigned) uval;
-	}
-
-	if ((flags & UNSIGNED) == 0 && val < 0) {
-		*sign = '-';
-		uval = -uval;
-	}
-	return uval;
-}
-
-static char *
-numtostr(uintmax_t val, int flags, struct conv *conv, char *buf)
-{
-	char *buf0 = buf;
-	int len, base = conv->base, prec = conv->prec;
-	uintmax_t oval = val;
-
-	if (prec == -1)
-		prec = 1;
-
-	for (*buf = '\0'; val > 0; val /= base)
-		*--buf = conv->digs[val % base];
-	while (buf0 - buf < prec)
-		*--buf = '0';
-
-	if (flags & ALTFORM) {
-		if (base == 8 && *buf != '0') {
-			*--buf = '0';
-		} else if (base == 16 && oval != 0) {
-			*--buf = conv->digs[16];
-			*--buf = '0';
-		}
-	}
-	if (conv->sign)
-		*--buf = conv->sign;
-
-	return buf;
-}
-
-static void
-savecnt(va_list va, int flags, int cnt)
-{
-	if (flags & CHAR)
-		*va_arg(va, char*) = cnt;
-	else if (flags & SHORT)
-		*va_arg(va, short*) = cnt;
-	else if (flags & LONG)
-		*va_arg(va, long*) = cnt;
-	else if (flags & LLONG)
-		*va_arg(va, long long*) = cnt;
-	else if (flags & SIZET)
-		*va_arg(va, size_t*) = cnt;
-	else if (flags & INTMAX)
-		*va_arg(va, intmax_t*) = cnt;
-	else
-		*va_arg(va, int*) = cnt;
-}
-
-static size_t
-wstrout(wchar_t *ws, size_t len, int width, int fill, FILE * restrict fp)
-{
-	int left = 0, adjust;
-	size_t cnt = 0;
-	wchar_t wc;
-
-	if (width < 0) {
-		left = 1;
-		width = -width;
-	}
-
-	len *= sizeof(wchar_t);
-	adjust = (len < width) ? width - len : 0;
-	cnt = adjust + len;
-	if (left)
-		adjust = -adjust;
-
-	for ( ; adjust > 0; adjust++)
-		putc(fill, fp);
-
-	while (wc = *ws++)
-		putwc(wc, fp);
-
-	for ( ; adjust < 0; adjust--)
-		putc(' ', fp);
-
-	return cnt;
-}
-
-static size_t
-strout(char *s, size_t len, int width, int fill, FILE * restrict fp)
-{
-	int left = 0, adjust, ch, prefix;
-	size_t cnt = 0;
-
-	if (width < 0) {
-		left = 1;
-		width = -width;
-	}
-
-	adjust = (len < width) ? width - len : 0;
-	cnt = adjust + len;
-	if (left)
-		adjust = -adjust;
-
-	if (fill == '0') {
-		if (*s == '-' || *s == '+')
-			prefix = 1;
-		else if (*s == '0' && toupper(s[1]) == 'X')
-			prefix = 2;
-		else
-			prefix = 0;
-		while (prefix--) {
-			putc(*s++, fp);
-			--len;
-		}
-	}
-
-	for ( ; adjust > 0; adjust--)
-		putc(fill, fp);
-
-	while (ch = *s++)
-		putc(ch, fp);
-
-	for ( ; adjust < 0; adjust++)
-		putc(' ', fp);
-
-	return cnt;
-}
-
-int
-vfprintf(FILE * restrict fp, const char *fmt, va_list va)
-{
-	int *p, ch, n, flags, width, left, fill, cnt = 0;
-	size_t inc, len;
-	char *s;
-	wchar_t *ws;
-	struct conv conv;
-	char buf[MAXPREC+1];
-	wchar_t wbuf[2];
-
-	for (cnt = 0; ch = *fmt++; cnt += inc) {
-		if (ch != '%') {
-			putc(ch, fp);
-			inc = 1;
-			continue;
-		}
-
-		fill = ' ';
-		left = flags = width =  0;
-		conv.prec = -1;
-		conv.base = 10;
-		conv.sign = '\0';
-		conv.digs = "0123456789ABCDEFX";
-
-flags:
-		switch (*fmt++) {
-		case ' ':
-			if (conv.sign == '\0')
-				conv.sign = ' ';
-			goto flags;
-		case '+':
-			conv.sign = '+';
-			goto flags;
-		case '#':
-			flags |= ALTFORM;
-			goto flags;
-		case '.':
-			if (*fmt == '*') {
-				fmt++;
-				n = va_arg(va, int);
-			} else {
-				for (n = 0; isdigit(ch = *fmt); fmt++)
-					n = n * 10 + ch - '0';
-			}
-			if (n > MAXPREC)
-				n = MAXPREC;
-			if (n > 0)
-				conv.prec = n;
-			goto flags;
-		case '*':
-			width = va_arg(va, int);
-			goto flags;
-		case '-':
-			left = 1;
-			++fmt;
-		case '1':
-		case '2':
-		case '3':
-		case '4':
-		case '5':
-		case '6':
-		case '7':
-		case '8':
-		case '9':
-			--fmt;
-			for (n = 0; isdigit(ch = *fmt); ++fmt)
-				n = n * 10 + ch - '0';
-			if (left)
-				n = -n;
-			width = n;
-			goto flags;
-		case '0':
-			fill = '0';
-			goto flags;
-		case 'l':
-			flags += LONG;
-			goto flags;
-		case 'h':
-			flags += SHORT;
-			goto flags;
-		case '%':
-			ch = '%';
-			goto cout;
-		case 'c':
-			if (flags & LONG) {
-				wbuf[0] = va_arg(va, wint_t);
-				wbuf[1] = L'\0';
-				ws = wbuf;
-				len = 1;
-				goto wstrout;
-			}
-			ch = va_arg(va, int);
-		cout:
-			buf[0] = ch;
-			buf[1] = '\0';
-			s = buf;
-			len = 1;
-			goto strout;
-		case 'j':
-			flags |= INTMAX;
-			goto flags;
-		case 't':
-			flags |= PTRDIFF;
-			goto flags;
-		case 'z':
-			flags |= SIZET;
-			goto flags;
-		case 'u':
-			flags |= UNSIGNED;
-		case 'i':
-		case 'd':
-		numeric10:
-			conv.base = 10;
-			goto numeric;
-		case 'p':
-			flags |= VOIDPTR | ALTFORM;
-			goto numeric16;
-		case 'x':
-			conv.digs = "0123456789abcdefx";
-		case 'X':
-		numeric16:
-			conv.base = 16;
-			flags |= UNSIGNED;
-			goto numeric;
-		case 'o':
-			conv.base = 8;
-			flags |= UNSIGNED;
-		numeric:
-			if (conv.prec != -1)
-				fill = ' ';
-			s = numtostr(getnum(va, flags, &conv.sign),
-			             flags,
-			             &conv,
-			             &buf[MAXPREC]);
-			len = &buf[MAXPREC] - s;
-			goto strout;
-		case 'L':
-		case 'a':
-		case 'A':
-		case 'e':
-		case 'E':
-		case 'f':
-		case 'g':
-		case 'G':
-			/* TODO */
-		case 's':
-			if (flags & LONG) {
-				ws = va_arg(va, wchar_t *);
-				len = wcsnlen(ws, conv.prec);
-				goto wstrout;
-			} else {
-				s = va_arg(va, char *);
-				len = strnlen(s, conv.prec);
-				goto strout;
-			}
-		wstrout:
-			inc = wstrout(ws, len, width, fill, fp);
-			break;
-		strout:
-			inc = strout(s, len, width, fill, fp);
-			break;
-		case 'n':
-			savecnt(va, flags, cnt);
-			break;
-		case '\0':
-			goto out_loop;
-		}
-	}
-
-out_loop:
-	return (ferror(fp)) ? EOF : cnt;
-}
--- a/lib/c/src/vsnprintf.c
+++ /dev/null
@@ -1,26 +1,0 @@
-
-#include <stdarg.h>
-#include <stdio.h>
-#undef vsnprintf
-
-int
-vsnprintf(char * restrict s, size_t siz, const char * restrict fmt, va_list ap)
-{
-	FILE f;
-	int r;
-
-	f.flag = _IOWRT | _IOSTRG;
-	f.size = siz;
-	f.buf = s;
-	f.wp = s;
-	f.rp = s + siz;
-
-	r = vfprintf(&f, fmt, va);
-	if (s) {
-		if (f.wp == f.rp)
-			--f.wp;
-		*f.wp = '\0';
-	}
-
-	return r;
-}
--- a/lib/c/src/vsprintf.c
+++ /dev/null
@@ -1,12 +1,0 @@
-
-#include <limits.h>
-#include <stdarg.h>
-#include <stdio.h>
-#undef vsprintf
-
-
-int
-vsprintf(char * restrict s, const char * restrict fmt, va_list va)
-{
-	return vsnprintf(s, SIZE_MAX, fmt, va);
-}
--- /dev/null
+++ b/lib/c/stdio.c
@@ -1,0 +1,26 @@
+
+#include <stdio.h>
+
+static unsigned char inbuf[BUFSIZ];
+static unsigned char outbuf[BUFSIZ];
+
+FILE __iob[FOPEN_MAX] = {
+	{
+		.fd = 0,
+		.buf = inbuf,
+		.len = BUFSIZ,
+		.flags = _IOREAD
+	},
+	{
+		.fd = 1,
+		.buf = outbuf,
+		.len = BUFSIZ,
+		.flags = _IOWRITE | _IOLBF
+	},
+	{
+		.fd = 2,
+		.buf = stderr->unbuf,
+		.len = sizeof(stderr->unbuf),
+		.flags = _IOWRITE
+	},
+};
--- /dev/null
+++ b/lib/c/strcat.c
@@ -1,0 +1,14 @@
+#include <string.h>
+#undef strcat
+
+char *
+strcat(char * restrict dst, const char * restrict src)
+{
+	char *ret = dst;
+
+	while (*dst)
+		++dst;
+	while (*dst++ = *src++)
+		;
+	return ret;
+}
--- /dev/null
+++ b/lib/c/strchr.c
@@ -1,0 +1,10 @@
+#include <string.h>
+#undef strchr
+
+char *
+strchr(const char *s, int c)
+{
+	while (*s && *s != c)
+		++s;
+	return (*s == c) ? (char *)s : NULL;
+}
--- /dev/null
+++ b/lib/c/strcmp.c
@@ -1,0 +1,10 @@
+#include <string.h>
+#undef strcmp
+
+int
+strcmp(const char *s1, const char *s2)
+{
+	while (*s1 && *s2 && *s1 == *s2)
+		++s1, ++s2;
+	return *(unsigned char *)s1 - *(unsigned char *)s2;
+}
--- /dev/null
+++ b/lib/c/strcoll.c
@@ -1,0 +1,10 @@
+#include <string.h>
+#undef strcoll
+
+int
+strcoll(const char *s1, const char *s2)
+{
+	while (*s1 && *s2 && *s1 == *s2)
+		++s1, ++s2;
+	return *(unsigned char *) s1 - *(unsigned char *) s2;
+}
--- /dev/null
+++ b/lib/c/strcpy.c
@@ -1,0 +1,12 @@
+#include <string.h>
+#undef strcpy
+
+char *
+strcpy(char * restrict dst, const char * restrict src)
+{
+	char *ret = dst;
+
+	while (*dst++ = *src++)
+		;
+	return ret;
+}
--- /dev/null
+++ b/lib/c/strcspn.c
@@ -1,0 +1,18 @@
+#include <string.h>
+#undef strcspn
+
+size_t
+strcspn(const char *s1, const char *s2)
+{
+	size_t n;
+	int c;
+	const char *p;
+
+	for (n = 0; c = *s1++; ++n) {
+		for (p = s2; *p && *p != c; ++p)
+			;
+		if (*p == c)
+			break;
+	}
+	return n;
+}
--- /dev/null
+++ b/lib/c/strerror.c
@@ -1,0 +1,13 @@
+
+#include <errno.h>
+#include <string.h>
+#undef strerror
+
+char *
+strerror(int errnum)
+{
+	if (errnum < _sys_nerr)
+		return _sys_errlist[errnum];
+	else
+		return "Unknown error";
+}
--- /dev/null
+++ b/lib/c/strlen.c
@@ -1,0 +1,12 @@
+#include <string.h>
+#undef strlen
+
+size_t
+strlen(const char *s)
+{
+	const char *t;
+
+	for (t = s; *t; ++t)
+		;
+	return t - s;
+}
--- /dev/null
+++ b/lib/c/strncat.c
@@ -1,0 +1,15 @@
+#include <string.h>
+#undef strncat
+
+char *
+strncat(char * restrict dst, const char * restrict src, size_t n)
+{
+	char *ret = dst;
+
+	while (*dst)
+		++dst;
+	while (n-- > 0 && *src)
+		*dst++ = *src++;
+	*dst = '\0';
+	return ret;
+}
--- /dev/null
+++ b/lib/c/strncmp.c
@@ -1,0 +1,17 @@
+#include <string.h>
+#undef strncmp
+
+int
+strncmp(const char *s1, const char *s2, size_t n)
+{
+	int c;
+
+	if (n == 0)
+		return 0;
+	while ((c = *s1) != '\0' && c == *s2) {
+		if (--n == 0)
+			return 0;
+		++s1, ++s2;
+	}
+	return (*(unsigned char *) s1 - *(unsigned char *) s2);
+}
--- /dev/null
+++ b/lib/c/strncpy.c
@@ -1,0 +1,14 @@
+#include <string.h>
+#undef strncpy
+
+char *
+strncpy(char * restrict dst, const char * restrict src, size_t n)
+{
+	char *ret = dst;
+
+	for (; n > 0 && *src; --n)
+		*dst++ = *src++;
+	while (n-- > 0)
+		*dst++ = '\0';
+	return ret;
+}
--- /dev/null
+++ b/lib/c/strpbrk.c
@@ -1,0 +1,17 @@
+#include <string.h>
+#undef strpbrk
+
+char *
+strpbrk(const char *s1, const char *s2)
+{
+	int c;
+	const char *p;
+
+	for (; c = *s1; ++s1) {
+		for (p = s2; *p && *p != c; ++p)
+			;
+		if (*p == c)
+			return s1;
+	}
+	return NULL;
+}
--- /dev/null
+++ b/lib/c/strrchr.c
@@ -1,0 +1,14 @@
+#include <string.h>
+#undef strrchr
+
+char *
+strrchr(const char *s, int c)
+{
+	const char *t = s;
+
+	while (*t)
+		++t;
+	while (t > s && *t != c)
+		--t;
+	return (*t == c) ? (char *)t : NULL;
+}
--- /dev/null
+++ b/lib/c/strspn.c
@@ -1,0 +1,18 @@
+#include <string.h>
+#undef strspn
+
+size_t
+strspn(const char *s1, const char *s2)
+{
+	size_t n;
+	int c;
+	const char *p;
+
+	for (n = 0; c = *s1++; ++n) {
+		for (p = s2; *p && *p != c; ++p)
+			;
+		if (*p == '\0')
+			break;
+	}
+	return n;
+}
--- /dev/null
+++ b/lib/c/strstr.c
@@ -1,0 +1,26 @@
+#include <string.h>
+#undef strstr
+
+char *
+strstr(const char *s1, const char *s2)
+{
+	const char *p, *q;
+	int c0, c;
+
+	c0 = *s2;
+	if (c0 == '\0')
+		return (char *) s1;
+	--s1;
+	while ((s1 = strchr(s1 + 1, c0)) != NULL) {
+		p = s1;
+		q = s2;
+		for (;;) {
+			if ((c = *++p) == '\0')
+				return (char *) s1;
+			if (c != *++q)
+				break;
+		}
+	}
+
+	return NULL;
+}
--- /dev/null
+++ b/lib/c/strtok.c
@@ -1,0 +1,25 @@
+#include <string.h>
+#undef strtok
+
+char *
+strtok(char * restrict s, const char * restrict delim)
+{
+	static char *line;
+
+	if (s)
+		line = s;
+	if (!s && !line)
+		return NULL;
+
+	s = line + strspn(line, delim);
+	if (*s == '\0')
+		return line = NULL;
+
+	line = s + strcspn(s, delim);
+	if (*line != '\0')
+		*line++ = '\0';
+	else
+		line = NULL;
+
+	return s;
+}
--- /dev/null
+++ b/lib/c/strxfrm.c
@@ -1,0 +1,12 @@
+#include <string.h>
+#undef strxfrm
+
+size_t
+strxfrm(char * restrict dst, const char * restrict src, size_t n)
+{
+	size_t len = strlen(src);
+
+	if (len < n)
+		strcpy(dst, src);
+	return len;
+}
--- /dev/null
+++ b/lib/c/syscall.h
@@ -1,0 +1,14 @@
+extern void *_brk(void *addr);
+extern int _open(char *path, int flags, int perm);
+extern int _close(int fd);
+extern int _read(int fd, void *buf, size_t n);
+extern int _write(int fd, void *buf, size_t n);
+extern int _lseek(int fd, long off, int whence);
+extern void _Exit(int status);
+extern void _access(char *path, int mode);
+
+extern int raise(int sig);
+extern void (*signal(int sig, void (*func)(int)))(int);
+extern getenv(const char *var);
+extern int rename(const char *from, const char *to);
+extern int remove(const char *path);
--- /dev/null
+++ b/lib/c/target/Makefile
@@ -1,0 +1,7 @@
+
+include ../../../config.mk
+
+DIRS = $(TARGETS)
+
+all dep clean distclean:
+	$(FORALL)
--- /dev/null
+++ b/lib/c/target/amd64-sysv-linux-elf/Makefile
@@ -1,0 +1,5 @@
+.POSIX:
+
+include ../../../../config.mk
+include ../objlst.mk
+include ../common.mk
--- /dev/null
+++ b/lib/c/target/amd64-sysv-linux-elf/gendep.sh
@@ -1,0 +1,16 @@
+#!/bin/sh
+
+set -e
+
+rm -f makefile
+trap "rm -f $$.mk" 0 2 3
+
+(cat Makefile
+for i
+do
+	cat <<EOF
+$i: ../${i%.o}.c
+	\$(CC) \$(TF_CFLAGS) ../${i%.o}.c -c
+
+EOF
+done) > $$.mk && mv $$.mk makefile
--- /dev/null
+++ b/lib/c/target/amd64-sysv-openbsd-elf/Makefile
@@ -1,0 +1,5 @@
+.POSIX:
+
+include ../../../../config.mk
+include ../objlst.mk
+include ../common.mk
--- /dev/null
+++ b/lib/c/target/amd64-sysv-openbsd-elf/gendep.sh
@@ -1,0 +1,16 @@
+#!/bin/sh
+
+set -e
+
+rm -f makefile
+trap "rm -f $$.mk" 0 2 3
+
+(cat Makefile
+for i
+do
+	cat <<EOF
+$i: ../${i%.o}.c
+	\$(CC) \$(TF_CFLAGS) ../${i%.o}.c -c
+
+EOF
+done) > $$.mk && mv $$.mk makefile
--- /dev/null
+++ b/lib/c/target/common.mk
@@ -1,0 +1,15 @@
+
+all: libc.a
+
+libc.a: $(OBJ)
+	$(AR) $(ARFLAGS) $@ $?
+	ranlib $@
+
+dep:
+	gendep.sh
+
+clean:
+	rm -f *.o
+
+distclean: clean
+	rm -f makefile
--- /dev/null
+++ b/lib/c/target/i386-sysv-linux-elf/Makefile
@@ -1,0 +1,5 @@
+.POSIX:
+
+include ../../../../config.mk
+include ../objlst.mk
+include ../common.mk
--- /dev/null
+++ b/lib/c/target/i386-sysv-linux-elf/gendep.sh
@@ -1,0 +1,16 @@
+#!/bin/sh
+
+set -e
+
+rm -f makefile
+trap "rm -f $$.mk" 0 2 3
+
+(cat Makefile
+for i
+do
+	cat <<EOF
+$i: ../${i%.o}.c
+	\$(CC) \$(TF_CFLAGS) ../${i%.o}.c -c
+
+EOF
+done) > $$.mk && mv $$.mk makefile
--- /dev/null
+++ b/lib/c/target/objlst.mk
@@ -1,0 +1,22 @@
+
+OBJ = bsearch.o qsort.o \
+      abs.o __abs.o labs.o __labs.o llabs.o __llabs.o \
+      perror.o strerror.o \
+      tmpnam.o \
+      sprintf.o snprintf.o vsprintf.o vsnprintf.o \
+      printf.o fprintf.o vfprintf.o \
+      fgets.o gets.of fgetc.o fputc.o getchar.o putchar.o \
+      fputs.o puts.o fread.o fwrite.o \
+      getc.o putc.o __putc.o __getc.o \
+      rewind.o fseek.o ferror.o feof.o clearerr.o \
+      setbuf.o setvbuf.o \
+      fclose.o fopen.c freopen.c _fpopen.o stdio.o \
+      realloc.o calloc.o malloc.o \
+      assert.o strcpy.o strcmp.o strlen.o strchr.o \
+      strrchr.o strcat.o strncmp.o strncpy.o strncat.o strcoll.o \
+      strxfrm.o strstr.o strspn.o strcspn.o strpbrk.o strtok.o \
+      memset.o memcpy.o memmove.o memcmp.o memchr.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 atol.o atoll.o atexit.o abort.o exit.o
--- /dev/null
+++ b/lib/c/target/z80-scc-none-none/Makefile
@@ -1,0 +1,5 @@
+.POSIX:
+
+include ../../../../config.mk
+include ../objlst.mk
+include ../common.mk
--- /dev/null
+++ b/lib/c/target/z80-scc-none-none/gendep.sh
@@ -1,0 +1,16 @@
+#!/bin/sh
+
+set -e
+
+rm -f makefile
+trap "rm -f $$.mk" 0 2 3
+
+(cat Makefile
+for i
+do
+	cat <<EOF
+$i: ../${i%.o}.c
+	\$(CC) \$(TF_CFLAGS) ../${i%.o}.c -c
+
+EOF
+done) > $$.mk && mv $$.mk makefile
--- /dev/null
+++ b/lib/c/tmpnam.c
@@ -1,0 +1,32 @@
+
+#include <stdio.h>
+#include <string.h>
+#include "syscall.h"
+#undef tmpnam
+
+char *
+tmpnam(char *s)
+{
+	static char *tmpl, buf[L_tmpnam];
+	char *p;
+
+	if (*buf == '\0') {
+		for (tmpl = buf, p = _TMPNAME; *tmpl++ = *p++; )
+			;
+		for (p = tmpl; p < &buf[L_tmpnam-1]; ++p)
+			*p = '0';
+		*p = '\0';
+	}
+	for (;;) {
+		for (p = tmpl; *p && *p != '9'; ++p)
+			;
+		if (*p == '\0')
+			return NULL;
+		++*p;
+		if (_access(buf, 0) != 0)
+			break;
+	}
+	if (s)
+		strcpy(s, buf);
+	return buf;
+}
--- /dev/null
+++ b/lib/c/tolower.c
@@ -1,0 +1,9 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef tolower
+
+int
+tolower(int c)
+{
+	return (isupper(c)) ? c | 0x20 : c;
+}
--- /dev/null
+++ b/lib/c/toupper.c
@@ -1,0 +1,9 @@
+#define __USE_MACROS
+#include <ctype.h>
+#undef toupper
+
+int
+toupper(int c)
+{
+	return (islower(c)) ? c & ~0x20 : c;
+}
--- /dev/null
+++ b/lib/c/vfprintf.c
@@ -1,0 +1,369 @@
+/*
+ * This file is covered by the license that you can find in the file
+ * LICENSE, but for this file, vfprintf.c, an additional clause is
+ * added:
+ *     - Christopher M. Graff (<cm0graff@gmail.com>) is forbidden to
+ *       use, copy, modify and/or distribute this file. He is forbidden
+ *       even to read this file.
+ */ 
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+#undef vfprintf
+
+enum {
+	LONG     = 1 << 0,
+	LLONG    = 1 << 1,
+	SHORT    = 1 << 2,
+	CHAR     = 1 << 3,
+	SIZET    = 1 << 4,
+	PTRDIFF  = 1 << 5,
+	INTMAX   = 1 << 6,
+	VOIDPTR  = 1 << 7,
+	UNSIGNED = 1 << 8,
+	ALTFORM  = 1 << 9,
+};
+
+#define MAXPREC    50
+
+struct conv {
+	int sign;
+	int prec;
+	char *digs;
+	int base;
+};
+
+static uintmax_t
+getnum(va_list va, int flags, int *sign)
+{
+	uintmax_t uval;
+	intmax_t val;
+
+	if (flags & CHAR) {
+		val = uval = va_arg(va, int);
+		uval = (unsigned char) uval;
+	} else if (flags & SHORT) {
+		val = uval = va_arg(va, int);
+		uval = (unsigned short) uval;
+	} else if (flags & LONG) {
+		val = uval = va_arg(va, long);
+		uval = (unsigned long) uval;
+	} else if (flags & LLONG) {
+		val = uval = va_arg(va, long long);
+		uval = (unsigned long long) uval;
+	} else if (flags & SIZET) {
+		val = uval = va_arg(va, size_t);
+		uval = (size_t) uval;
+	} else if (flags & INTMAX) {
+		val = uval = va_arg(va, uintmax_t);
+	} else if (flags & VOIDPTR) {
+		val = uval = (uintmax_t) va_arg(va, void *);
+	} else {
+		val = uval = va_arg(va, int);
+		uval = (unsigned) uval;
+	}
+
+	if ((flags & UNSIGNED) == 0 && val < 0) {
+		*sign = '-';
+		uval = -uval;
+	}
+	return uval;
+}
+
+static char *
+numtostr(uintmax_t val, int flags, struct conv *conv, char *buf)
+{
+	char *buf0 = buf;
+	int len, base = conv->base, prec = conv->prec;
+	uintmax_t oval = val;
+
+	if (prec == -1)
+		prec = 1;
+
+	for (*buf = '\0'; val > 0; val /= base)
+		*--buf = conv->digs[val % base];
+	while (buf0 - buf < prec)
+		*--buf = '0';
+
+	if (flags & ALTFORM) {
+		if (base == 8 && *buf != '0') {
+			*--buf = '0';
+		} else if (base == 16 && oval != 0) {
+			*--buf = conv->digs[16];
+			*--buf = '0';
+		}
+	}
+	if (conv->sign)
+		*--buf = conv->sign;
+
+	return buf;
+}
+
+static void
+savecnt(va_list va, int flags, int cnt)
+{
+	if (flags & CHAR)
+		*va_arg(va, char*) = cnt;
+	else if (flags & SHORT)
+		*va_arg(va, short*) = cnt;
+	else if (flags & LONG)
+		*va_arg(va, long*) = cnt;
+	else if (flags & LLONG)
+		*va_arg(va, long long*) = cnt;
+	else if (flags & SIZET)
+		*va_arg(va, size_t*) = cnt;
+	else if (flags & INTMAX)
+		*va_arg(va, intmax_t*) = cnt;
+	else
+		*va_arg(va, int*) = cnt;
+}
+
+static size_t
+wstrout(wchar_t *ws, size_t len, int width, int fill, FILE * restrict fp)
+{
+	int left = 0, adjust;
+	size_t cnt = 0;
+	wchar_t wc;
+
+	if (width < 0) {
+		left = 1;
+		width = -width;
+	}
+
+	len *= sizeof(wchar_t);
+	adjust = (len < width) ? width - len : 0;
+	cnt = adjust + len;
+	if (left)
+		adjust = -adjust;
+
+	for ( ; adjust > 0; adjust++)
+		putc(fill, fp);
+
+	while (wc = *ws++)
+		putwc(wc, fp);
+
+	for ( ; adjust < 0; adjust--)
+		putc(' ', fp);
+
+	return cnt;
+}
+
+static size_t
+strout(char *s, size_t len, int width, int fill, FILE * restrict fp)
+{
+	int left = 0, adjust, ch, prefix;
+	size_t cnt = 0;
+
+	if (width < 0) {
+		left = 1;
+		width = -width;
+	}
+
+	adjust = (len < width) ? width - len : 0;
+	cnt = adjust + len;
+	if (left)
+		adjust = -adjust;
+
+	if (fill == '0') {
+		if (*s == '-' || *s == '+')
+			prefix = 1;
+		else if (*s == '0' && toupper(s[1]) == 'X')
+			prefix = 2;
+		else
+			prefix = 0;
+		while (prefix--) {
+			putc(*s++, fp);
+			--len;
+		}
+	}
+
+	for ( ; adjust > 0; adjust--)
+		putc(fill, fp);
+
+	while (ch = *s++)
+		putc(ch, fp);
+
+	for ( ; adjust < 0; adjust++)
+		putc(' ', fp);
+
+	return cnt;
+}
+
+int
+vfprintf(FILE * restrict fp, const char *fmt, va_list va)
+{
+	int *p, ch, n, flags, width, left, fill, cnt = 0;
+	size_t inc, len;
+	char *s;
+	wchar_t *ws;
+	struct conv conv;
+	char buf[MAXPREC+1];
+	wchar_t wbuf[2];
+
+	for (cnt = 0; ch = *fmt++; cnt += inc) {
+		if (ch != '%') {
+			putc(ch, fp);
+			inc = 1;
+			continue;
+		}
+
+		fill = ' ';
+		left = flags = width =  0;
+		conv.prec = -1;
+		conv.base = 10;
+		conv.sign = '\0';
+		conv.digs = "0123456789ABCDEFX";
+
+flags:
+		switch (*fmt++) {
+		case ' ':
+			if (conv.sign == '\0')
+				conv.sign = ' ';
+			goto flags;
+		case '+':
+			conv.sign = '+';
+			goto flags;
+		case '#':
+			flags |= ALTFORM;
+			goto flags;
+		case '.':
+			if (*fmt == '*') {
+				fmt++;
+				n = va_arg(va, int);
+			} else {
+				for (n = 0; isdigit(ch = *fmt); fmt++)
+					n = n * 10 + ch - '0';
+			}
+			if (n > MAXPREC)
+				n = MAXPREC;
+			if (n > 0)
+				conv.prec = n;
+			goto flags;
+		case '*':
+			width = va_arg(va, int);
+			goto flags;
+		case '-':
+			left = 1;
+			++fmt;
+		case '1':
+		case '2':
+		case '3':
+		case '4':
+		case '5':
+		case '6':
+		case '7':
+		case '8':
+		case '9':
+			--fmt;
+			for (n = 0; isdigit(ch = *fmt); ++fmt)
+				n = n * 10 + ch - '0';
+			if (left)
+				n = -n;
+			width = n;
+			goto flags;
+		case '0':
+			fill = '0';
+			goto flags;
+		case 'l':
+			flags += LONG;
+			goto flags;
+		case 'h':
+			flags += SHORT;
+			goto flags;
+		case '%':
+			ch = '%';
+			goto cout;
+		case 'c':
+			if (flags & LONG) {
+				wbuf[0] = va_arg(va, wint_t);
+				wbuf[1] = L'\0';
+				ws = wbuf;
+				len = 1;
+				goto wstrout;
+			}
+			ch = va_arg(va, int);
+		cout:
+			buf[0] = ch;
+			buf[1] = '\0';
+			s = buf;
+			len = 1;
+			goto strout;
+		case 'j':
+			flags |= INTMAX;
+			goto flags;
+		case 't':
+			flags |= PTRDIFF;
+			goto flags;
+		case 'z':
+			flags |= SIZET;
+			goto flags;
+		case 'u':
+			flags |= UNSIGNED;
+		case 'i':
+		case 'd':
+		numeric10:
+			conv.base = 10;
+			goto numeric;
+		case 'p':
+			flags |= VOIDPTR | ALTFORM;
+			goto numeric16;
+		case 'x':
+			conv.digs = "0123456789abcdefx";
+		case 'X':
+		numeric16:
+			conv.base = 16;
+			flags |= UNSIGNED;
+			goto numeric;
+		case 'o':
+			conv.base = 8;
+			flags |= UNSIGNED;
+		numeric:
+			if (conv.prec != -1)
+				fill = ' ';
+			s = numtostr(getnum(va, flags, &conv.sign),
+			             flags,
+			             &conv,
+			             &buf[MAXPREC]);
+			len = &buf[MAXPREC] - s;
+			goto strout;
+		case 'L':
+		case 'a':
+		case 'A':
+		case 'e':
+		case 'E':
+		case 'f':
+		case 'g':
+		case 'G':
+			/* TODO */
+		case 's':
+			if (flags & LONG) {
+				ws = va_arg(va, wchar_t *);
+				len = wcsnlen(ws, conv.prec);
+				goto wstrout;
+			} else {
+				s = va_arg(va, char *);
+				len = strnlen(s, conv.prec);
+				goto strout;
+			}
+		wstrout:
+			inc = wstrout(ws, len, width, fill, fp);
+			break;
+		strout:
+			inc = strout(s, len, width, fill, fp);
+			break;
+		case 'n':
+			savecnt(va, flags, cnt);
+			break;
+		case '\0':
+			goto out_loop;
+		}
+	}
+
+out_loop:
+	return (ferror(fp)) ? EOF : cnt;
+}
--- /dev/null
+++ b/lib/c/vsnprintf.c
@@ -1,0 +1,26 @@
+
+#include <stdarg.h>
+#include <stdio.h>
+#undef vsnprintf
+
+int
+vsnprintf(char * restrict s, size_t siz, const char * restrict fmt, va_list ap)
+{
+	FILE f;
+	int r;
+
+	f.flag = _IOWRT | _IOSTRG;
+	f.size = siz;
+	f.buf = s;
+	f.wp = s;
+	f.rp = s + siz;
+
+	r = vfprintf(&f, fmt, va);
+	if (s) {
+		if (f.wp == f.rp)
+			--f.wp;
+		*f.wp = '\0';
+	}
+
+	return r;
+}
--- /dev/null
+++ b/lib/c/vsprintf.c
@@ -1,0 +1,12 @@
+
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#undef vsprintf
+
+
+int
+vsprintf(char * restrict s, const char * restrict fmt, va_list va)
+{
+	return vsnprintf(s, SIZE_MAX, fmt, va);
+}