--- /dev/null
+ROOTDIR=.
+include Makefile.inc
+
+
+# build binary in each test dir
+DIRS = $(sort $(wildcard src/*))
+
+local:
+ for i in $(DIRS); do make -C $$i; done
+localrun: local
+ for i in $(DIRS); do $$i/t; done
+localclean:
+ for i in $(DIRS); do make -C $$i clean; done
+cleanall: clean localclean
--- /dev/null
+# copy to Makefile.conf and edit
+usemusl=yes
+prefix = /usr/local/musl
+includedir = $(prefix)/include
+libdir = $(prefix)/lib
--- /dev/null
+# gnu makefile
+# when included in src/*/Makefile then it builds a binary locally
+# when included in ./Makefile then all tests are linked into one binary
+
+ROOTDIR ?= ../..
+ifeq ($(ROOTDIR), .)
+SRCS = $(sort $(wildcard src/*/*.c))
+else
+SRCS = $(sort $(wildcard *.c))
+endif
+OBJS = $(SRCS:.c=.o)
+
+usemusl = yes
+prefix = /usr/local/musl
+includedir = $(prefix)/include
+libdir = $(prefix)/lib
+-include $(ROOTDIR)/Makefile.conf
+
+
+CFLAGS += -g -std=c99 -pipe -Wall
+LDFLAGS += -g
+INC += -I$(ROOTDIR)/common
+
+ifeq ($(usemusl), yes)
+CC=gcc
+LIBCC=$(shell gcc -print-file-name=libgcc.a |sed 's,/libgcc.a,,')
+#LIBCC=$(shell pcc -v /dev/null 2>&1 |sed -n 's,/crtbegin.o.*,,;s,.* /,/,p')
+CFLAGS += -nostdinc -ffreestanding -fno-stack-protector
+LDFLAGS += -nostdlib -Wl,-e,_start,-Bstatic $(libdir)/crti.o $(libdir)/crt1.o $(libdir)/crtn.o -L $(libdir) -lc -L $(LIBCC) -l$(CC)
+INC += -isystem $(includedir)
+endif
+
+all: t
+
+clean:
+ rm -f $(OBJS) t main.o main.h
+
+.c.o:
+ $(CC) $(CFLAGS) $(INC) -c -o $@ $<
+
+$(OBJS): $(ROOTDIR)/common/test.h
+
+main.h: $(OBJS)
+ nm -f posix $+ |awk '/^test/ && $$2=="T"{print "T(" $$1 ")"}' >main.h
+
+main.o: $(ROOTDIR)/common/main.c $(ROOTDIR)/common/test.h main.h
+ $(CC) $(CFLAGS) $(INC) -I. -c -o $@ $<
+
+t: $(OBJS) main.o
+ $(CC) $+ $(LDFLAGS) -o $@
+
+.PHONY: all clean
--- /dev/null
+simple libc tests based on the libc-testsuit of dalias
+see http://git.etalabs.net/cgi-bin/gitweb.cgi
+
+build tests:
+ cp Makefile.conf.def Makefile.conf
+ # edit Makefile.conf
+ make
+run tests:
+ ./t
+
+about the framework:
+
+the only hook in the test framework is error(...) which
+prints a formatted message and sets the test to failed
+see common/test.h
+
+in the root dir make builds an executable with all tests
+in a src/* dir make builds only local tests
+see Makefile.inc
+
+a test function looks like
+ void test_foo() {
+ if (foo != 42)
+ error("foo=%d expected 42\n", foo);
+ }
+extern functions with name ~ /^test/ are recognized to be
+test functions
+see Makefile.inc
+
+edit the generated main.h to exclude certain tests
+see common/main.c
--- /dev/null
+#include "test.h"
+
+#define T(t) void t();
+#include "main.h"
+#undef T
+
+struct test test__ = {0};
+
+static int verbose;
+static int count;
+static int nfailed;
+
+static void run(const char *n, void (*f)()) {
+ count++;
+ test__.failed = 0;
+ test__.name = n;
+ if (verbose)
+ fprintf(stderr, "running %s:\n", test__.name);
+ f();
+ if (test__.failed) {
+ nfailed++;
+ fprintf(stderr, "FAILED %s\n", test__.name);
+ } else if (verbose)
+ fprintf(stderr, "PASSED %s\n", test__.name);
+}
+
+static int summary() {
+ fprintf(stderr, "PASS:%d FAIL:%d\n", count-nfailed, nfailed);
+ return !!nfailed;
+}
+
+int main() {
+#define T(t) run(#t, t);
+#include "main.h"
+ return summary();
+}
--- /dev/null
+#include <stdio.h>
+#include <stdarg.h>
+
+extern struct test {
+ int failed;
+ const char *name;
+} test__;
+
+#define error(...) error__(__FILE__, __LINE__, __VA_ARGS__)
+
+static void error__(const char *n, int l, const char *s, ...) {
+ va_list ap;
+
+ test__.failed = 1;
+ fprintf(stderr, "- ERROR %s at %s:%d: ", test__.name, n, l);
+ va_start(ap, s);
+ vfprintf(stderr, s, ap);
+ va_end(ap);
+}
--- /dev/null
+include ../../Makefile.inc
--- /dev/null
+#define _XOPEN_SOURCE 700
+#include "test.h"
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+extern char **environ;
+int clearenv(void);
+
+void test_env() {
+ char *s;
+ int r;
+
+ if (clearenv() || (environ && *environ))
+ error("clrearenv: %s\n", strerror(errno));
+ if (putenv("TEST=1"))
+ error("putenv: %s\n", strerror(errno));
+ if ((s=environ[1]))
+ error("environ[1]: %p, wanted 0\n", s);
+ if (!(s=getenv("TEST")))
+ error("getenv(\"TEST\"): 0, wanted \"1\"\n");
+ if (strcmp(s,"1") != 0)
+ error("getenv(\"TEST\"): \"%s\", wanted \"1\"\n", s);
+ if (unsetenv("TEST"))
+ error("unsetenv: %s\n", strerror(errno));
+ if ((s=*environ))
+ error("*environ: %p != 0\n", s);
+ if ((s=getenv("TEST")))
+ error("getenv(\"TEST\"): %p, wanted 0\n", s);
+ if (setenv("TEST", "2", 0))
+ error("setenv: %s\n", strerror(errno));
+ if (strcmp(s=getenv("TEST"),"2") != 0)
+ error("getenv(\"TEST\"): \"%s\", wanted \"2\"\n", s);
+ if (setenv("TEST", "3", 0))
+ error("setenv: %s\n", strerror(errno));
+ if (strcmp(s=getenv("TEST"),"2") != 0)
+ error("getenv(\"TEST\"): \"%s\", wanted \"2\"\n", s);
+ if (setenv("TEST", "3", 1))
+ error("setenv: %s\n", strerror(errno));
+ if (strcmp(s=getenv("TEST"),"3") != 0)
+ error("getenv(\"TEST\"): \"%s\", wanted \"3\"\n", s);
+ if ((r=setenv("","",0)) != -1 || errno != EINVAL)
+ error("setenv(\"\",\"\"): %d, errno: %d (%s), wanted -1, %d (EINVAL)\n", r, errno, strerror(errno), EINVAL);
+}
--- /dev/null
+include ../../Makefile.inc
--- /dev/null
+#define _GNU_SOURCE
+#include "test.h"
+#include <stdlib.h>
+#include <string.h>
+#include <libgen.h>
+
+static void t(char *p, char *b) {
+ char *tmp = strdup(p);
+ char *s = basename(tmp);
+
+ if (strcmp(b,s) != 0)
+ error("basename(\"%s\") returned \"%s\"; expected \"%s\"\n", p, s, b);
+ free(tmp);
+}
+
+void test_basename() {
+ if (strcmp(".", basename(0)) != 0)
+ error("basename(0) returned \"%s\"; expected \".\"\n", basename(0));
+ t("", ".");
+ t("/usr/lib", "lib");
+ t("/usr/", "usr");
+ t("/", "/");
+ t("///", "/");
+ t("//usr//lib//", "lib");
+}
--- /dev/null
+#define _GNU_SOURCE
+#include "test.h"
+#include <stdlib.h>
+#include <string.h>
+#include <libgen.h>
+
+static void t(char *p, char *b) {
+ char *tmp = strdup(p);
+ char *s = dirname(tmp);
+
+ if (strcmp(b,s) != 0)
+ error("dirname(\"%s\") returned \"%s\"; expected \"%s\"\n", p, s, b);
+ free(tmp);
+}
+
+void test_dirname() {
+ if (strcmp(dirname(0), ".") != 0)
+ error("dirname(0) returned \"%s\"; expected \".\"\n", dirname(0));
+ t("", ".");
+ t("/usr/lib", "/usr");
+ t("/usr/", "/");
+ t("usr", ".");
+ t("/", "/");
+ t("///", "/");
+ t(".", ".");
+ t("..", ".");
+}
--- /dev/null
+include ../../Makefile.inc
--- /dev/null
+#define _XOPEN_SOURCE 700
+#include "test.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#define TEST(c) do { \
+ errno = 0; \
+ if (!(c)) \
+ error("%s failed (errno = %d)\n", #c, errno); \
+} while(0)
+
+void test_fdopen(void)
+{
+ char tmp[] = "/tmp/testsuite-XXXXXX";
+ char foo[6];
+ int fd;
+ FILE *f;
+
+ TEST((fd = mkstemp(tmp)) > 2);
+ TEST(write(fd, "hello", 6)==6);
+ TEST(f = fdopen(fd, "rb"));
+ if (f) {
+ TEST(ftello(f)==6);
+ TEST(fseeko(f, 0, SEEK_SET)==0);
+ TEST(fgets(foo, sizeof foo, f));
+ if (strcmp(foo,"hello") != 0)
+ error("fgets read back wrong message: \"%s\" wanted: \"hello\"\n", foo);
+ fclose(f);
+ }
+ if (fd > 2)
+ TEST(unlink(tmp) != -1);
+}