From: Szabolcs Nagy Date: Fri, 5 Jul 2013 07:39:28 +0000 (+0000) Subject: rename X-Git-Url: http://nsz.repo.hu/git/?p=libc-test;a=commitdiff_plain;h=2cf89517c5b25c2524fe0c0c01ed277d7307a852 rename --- diff --git a/src/functional/Makefile b/src/functional/Makefile new file mode 100644 index 0000000..642a485 --- /dev/null +++ b/src/functional/Makefile @@ -0,0 +1,34 @@ +CFLAGS+=-pipe -std=c99 -D_POSIX_C_SOURCE=200809L -Wall -Wno-unused-function -Wno-missing-braces +LDFLAGS+= + +SRC=$(sort $(wildcard *.c)) +OBJ=$(SRC:.c=.o) +DSOOBJ=$(filter %_dso.o,$(OBJ)) +BINOBJ=$(filter-out %_dso.o,$(OBJ)) +DSO=$(DSOOBJ:.o=.so) +BIN=$(BINOBJ:.o=) + +-include ../../config.mak + +all: $(BIN) $(DSO) +run: all + @N=0; for i in $(BIN);do ./$$i || N=$$((N+1)); done; [ "$$N" = 0 ] && echo PASS || echo FAILS: $$N +clean: + rm -f $(OBJ) $(DSO) $(BIN) + +$(OBJ): test.h +$(DSOOBJ): CFLAGS += -fPIC +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< || true +%.so: %.o + $(CC) $(LDFLAGS) -shared -o $@ $< || true +%: %.o + $(CC) $(LDFLAGS) -o $@ $(patsubst %.so,./%.so,$+) || true + +dlopen: LDFLAGS+=-ldl -rdynamic +pthread: LDFLAGS+=-lpthread +sem: LDFLAGS+=-lpthread -lrt +strtod_simple: LDFLAGS+=-lm +tls_align: tls_align_dso.so +tls_align_dlopen: LDFLAGS+=-ldl +tls_init: LDFLAGS+=-lpthread diff --git a/src/functional/basename.c b/src/functional/basename.c new file mode 100644 index 0000000..a993587 --- /dev/null +++ b/src/functional/basename.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include "test.h" + +#define T(path, want) \ +{ \ + char tmp[100]; \ + char *got = basename(strcpy(tmp, path)); \ + if (strcmp(want, got) != 0) \ + error("basename(\"%s\") got \"%s\" want \"%s\"\n", path, got, want); \ +} + +int main() +{ + if (strcmp(basename(0), ".") != 0) + error("basename(0) returned \"%s\"; expected \".\"\n", basename(0)); + T("", "."); + T("/usr/lib", "lib"); + T("/usr/", "usr"); + T("usr/", "usr"); + T("/", "/"); + T("///", "/"); + T("//usr//lib//", "lib"); + T(".", "."); + T("..", ".."); + return test_status; +} diff --git a/src/functional/dirname.c b/src/functional/dirname.c new file mode 100644 index 0000000..7a15a0a --- /dev/null +++ b/src/functional/dirname.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include "test.h" + +#define T(path, want) \ +{ \ + char tmp[100]; \ + char *got = dirname(strcpy(tmp, path)); \ + if (strcmp(want, got) != 0) \ + error("dirname(\"%s\") got \"%s\" want \"%s\"\n", path, got, want); \ +} + +int main() +{ + if (strcmp(dirname(0), ".") != 0) + error("dirname(0) returned \"%s\"; expected \".\"\n", dirname(0)); + T("", "."); + T("/usr/lib", "/usr"); + T("/usr/", "/"); + T("usr", "."); + T("usr/", "."); + T("/", "/"); + T("///", "/"); + T(".", "."); + T("..", "."); + return test_status; +} diff --git a/src/functional/dlopen.c b/src/functional/dlopen.c new file mode 100644 index 0000000..3150f6f --- /dev/null +++ b/src/functional/dlopen.c @@ -0,0 +1,47 @@ +#include +#include "test.h" + +int main() +{ + void *h, *g; + int *i, *i2; + char *s; + void (*f)(void); + + h = dlopen("./dlopen_dso.so", RTLD_LAZY|RTLD_LOCAL); + if (!h) + error("dlopen ./dlopen_dso.so failed: %s\n", dlerror()); + i = dlsym(h, "i"); + if (!i) + error("dlsym i failed: %s\n", dlerror()); + if (*i != 1) + error("initialization failed: want i=1 got i=%d\n", *i); + f = (void (*)(void))dlsym(h, "f"); + if (!f) + error("dlsym f failed: %s\n", dlerror()); + f(); + if (*i != 2) + error("f call failed: want i=2 got i=%d\n", *i); + if (dlclose(h)) + error("dlclose failed: %s\n", dlerror()); + + g = dlopen(0, RTLD_LAZY|RTLD_LOCAL); + if (!g) + error("dlopen 0 failed: %s\n", dlerror()); + i2 = dlsym(g, "i"); + s = dlerror(); + if (i2 || s == 0) + error("dlsym i should have failed\n"); + if (dlsym(g, "main") == 0) + error("dlsym main failed: %s\n", dlerror()); + + h = dlopen("./dlopen_dso.so", RTLD_LAZY|RTLD_GLOBAL); + i2 = dlsym(g, "i"); + if (!i2) + error("dlsym i failed: %s\n", dlerror()); + if (*i2 != 2) + error("want i2=2, got i2=%d\n", *i2); + if (dlclose(g)) + error("dlclose failed: %s\n", dlerror()); + return test_status; +} diff --git a/src/functional/dlopen_dso.c b/src/functional/dlopen_dso.c new file mode 100644 index 0000000..cb3220a --- /dev/null +++ b/src/functional/dlopen_dso.c @@ -0,0 +1,6 @@ +int i = 1; + +void f(void) +{ + i++; +} diff --git a/src/functional/env.c b/src/functional/env.c new file mode 100644 index 0000000..7962bf5 --- /dev/null +++ b/src/functional/env.c @@ -0,0 +1,51 @@ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif +#include +#include +#include +#include +#include "test.h" + +extern char **environ; + +int main() +{ + 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); + /* test failures */ + if ((r=setenv("","",0)) != -1 || errno != EINVAL) + error("setenv(\"\",\"\",0): %d, errno: %d (%s), wanted -1, %d (EINVAL)\n", r, errno, strerror(errno), EINVAL); + if ((r=setenv(0,"",0)) != -1 || errno != EINVAL) + error("setenv(0,\"\",0): %d, errno: %d (%s), wanted -1, %d (EINVAL)\n", r, errno, strerror(errno), EINVAL); + return test_status; +} diff --git a/src/functional/fdopen.c b/src/functional/fdopen.c new file mode 100644 index 0000000..1f4da03 --- /dev/null +++ b/src/functional/fdopen.c @@ -0,0 +1,38 @@ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif +#include +#include +#include +#include +#include +#include "test.h" + +#define TEST(c) do { \ + errno = 0; \ + if (!(c)) \ + error("%s failed (errno = %d)\n", #c, errno); \ +} while(0) + +int main(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: \"%s\"; wanted: \"hello\"\n", foo); + fclose(f); + } + if (fd > 2) + TEST(unlink(tmp) != -1); + return test_status; +} diff --git a/src/functional/fnmatch.c b/src/functional/fnmatch.c new file mode 100644 index 0000000..33f508f --- /dev/null +++ b/src/functional/fnmatch.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include +#include "test.h" + +/* adapted from dietlibc's test-newfnmatch.c */ + +/* xlat / printflags adapted from http://www.liacs.nl/~wichert/strace/ */ +#define FLAG(f) { f, #f } + +struct xlat { + int val; + char *str; +} fnmatch_flags[] = { + FLAG(FNM_NOESCAPE), + FLAG(FNM_PATHNAME), + FLAG(FNM_PERIOD), + {0, NULL}, +}; + +static char *flagstr(const struct xlat *map, int flags) +{ + static char buf[1000]; + char *sep; + + if (!flags) { + sprintf(buf, "0"); + return buf; + } + sep = ""; + for (; map->str; map++) { + if (map->val && (flags & map->val) == map->val) { + sprintf(buf, "%s%s", sep, map->str); + sep = "|"; + flags &= ~(map->val); + } + } + if (flags) + sprintf(buf, "%sunknown=%#x", sep, flags); + return buf; +} + +/* tests harness adapted from glibc testfnm.c */ +struct { + const char *pattern; + const char *string; + int flags; + int expected; +} tests[] = { + /* begin dietlibc tests */ + { "*.c", "foo.c", 0, 0 }, + { "*.c", ".c", 0, 0 }, + { "*.a", "foo.c", 0, FNM_NOMATCH }, + { "*.c", ".foo.c", 0, 0 }, + { "*.c", ".foo.c", FNM_PERIOD, FNM_NOMATCH }, + { "*.c", "foo.c", FNM_PERIOD, 0 }, + { "a\\*.c", "a*.c", FNM_NOESCAPE, FNM_NOMATCH }, + { "a\\*.c", "ax.c", 0, FNM_NOMATCH }, + { "a[xy].c", "ax.c", 0, 0 }, + { "a[!y].c", "ax.c", 0, 0 }, + { "a[a/z]*.c", "a/x.c", FNM_PATHNAME, FNM_NOMATCH }, + { "a/*.c", "a/x.c", FNM_PATHNAME, 0 }, + { "a*.c", "a/x.c", FNM_PATHNAME, FNM_NOMATCH }, + { "*/foo", "/foo", FNM_PATHNAME, 0 }, + { "-O[01]", "-O1", 0, 0 }, + { "[[?*\\]", "\\", 0, 0 }, + { "[]?*\\]", "]", 0, 0 }, + /* initial right-bracket tests */ + { "[!]a-]", "b", 0, 0 }, + { "[]-_]", "^", 0, 0 }, /* range: ']', '^', '_' */ + { "[!]-_]", "X", 0, 0 }, + { "??", "-", 0, FNM_NOMATCH }, + /* begin glibc tests */ + { "*LIB*", "lib", FNM_PERIOD, FNM_NOMATCH }, + { "a[/]b", "a/b", 0, 0 }, + { "a[/]b", "a/b", FNM_PATHNAME, FNM_NOMATCH }, + { "[a-z]/[a-z]", "a/b", 0, 0 }, + { "*", "a/b", FNM_PATHNAME, FNM_NOMATCH }, + { "*[/]b", "a/b", FNM_PATHNAME, FNM_NOMATCH }, + { "*[b]", "a/b", FNM_PATHNAME, FNM_NOMATCH }, + { "[*]/b", "a/b", 0, FNM_NOMATCH }, + { "[*]/b", "*/b", 0, 0 }, + { "[?]/b", "a/b", 0, FNM_NOMATCH }, + { "[?]/b", "?/b", 0, 0 }, + { "[[a]/b", "a/b", 0, 0 }, + { "[[a]/b", "[/b", 0, 0 }, + { "\\*/b", "a/b", 0, FNM_NOMATCH }, + { "\\*/b", "*/b", 0, 0 }, + { "\\?/b", "a/b", 0, FNM_NOMATCH }, + { "\\?/b", "?/b", 0, 0 }, + { "[/b", "[/b", 0, 0 }, + { "\\[/b", "[/b", 0, 0 }, + { "??""/b", "aa/b", 0, 0 }, + { "???b", "aa/b", 0, 0 }, + { "???b", "aa/b", FNM_PATHNAME, FNM_NOMATCH }, + { "?a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, + { "a/?b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, + { "*a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, + { "a/*b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, + { "[.]a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, + { "a/[.]b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, + { "*/?", "a/b", FNM_PATHNAME|FNM_PERIOD, 0 }, + { "?/*", "a/b", FNM_PATHNAME|FNM_PERIOD, 0 }, + { ".*/?", ".a/b", FNM_PATHNAME|FNM_PERIOD, 0 }, + { "*/.?", "a/.b", FNM_PATHNAME|FNM_PERIOD, 0 }, + { "*/*", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, + { "*?*/*", "a/.b", FNM_PERIOD, 0 }, + { "*[.]/b", "a./b", FNM_PATHNAME|FNM_PERIOD, 0 }, + { "*[[:alpha:]]/*[[:alnum:]]", "a/b", FNM_PATHNAME, 0 }, + /* These three tests should result in error according to SUSv3. + * See XCU 2.13.1, XBD 9.3.5, & fnmatch() */ + { "*[![:digit:]]*/[![:d-d]", "a/b", FNM_PATHNAME, -FNM_NOMATCH }, + { "*[![:digit:]]*/[[:d-d]", "a/[", FNM_PATHNAME, -FNM_NOMATCH }, + { "*[![:digit:]]*/[![:d-d]", "a/[", FNM_PATHNAME, -FNM_NOMATCH }, + { "a?b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 }, + { "a*b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 }, + { "a[.]b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 }, +}; + +int main(void) +{ + int i; + + for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { + int r, x; + + r = fnmatch(tests[i].pattern, tests[i].string, tests[i].flags); + x = tests[i].expected; + if (r != x && (r != FNM_NOMATCH || x != -FNM_NOMATCH)) { + error("fnmatch(\"%s\", \"%s\", %s) failed, got %d want %d\n", + tests[i].pattern, tests[i].string, + flagstr(fnmatch_flags, tests[i].flags), + r, x); + } + } + return test_status; +} diff --git a/src/functional/fscanf.c b/src/functional/fscanf.c new file mode 100644 index 0000000..62627b7 --- /dev/null +++ b/src/functional/fscanf.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include "test.h" + +#define T(f, x, m) do { \ + r = (f); \ + if (r != (x)) \ + error("%s failed (got %d, expected %d, errno \"%s\") (%s)\n", \ + #f, r, x, errno ? strerror(errno) : "", m); \ + errno = 0; \ +} while (0) + +#define S(s, x, m) do { \ + if (strcmp(s, x) != 0) \ + error("got [%s] want [%s] (%s)\n", s, x, m); \ +} while(0) + +int main(void) +{ + int r, x, y; + char a[100], b[100]; + int p[2]; + FILE *f; + + T(pipe(p), 0, "open pipe"); + T(!(f = fdopen(p[0], "rb")), 0, "fdopen pipe"); + if (!f) { + close(p[0]); + close(p[1]); + return test_status; + } + + T(write(p[1], "hello, world\n", 13), 13, "write to pipe"); + T(fscanf(f, "%s %[own]", a, b), 2, ""); + S(a, "hello,", "wrong result for %s"); + S(b, "wo", "wrong result for %[own]"); + T(fgetc(f), 'r', "fgetc 'r'"); + + T(write(p[1], " 0x12 0x34", 10), 10, ""); + T(fscanf(f, "ld %5i%2i", &x, &y), 1, ""); + T(x, 0x12, ""); + T(fgetc(f), '3', "fgetc '3'"); + + fclose(f); + close(p[1]); + return test_status; +} diff --git a/src/functional/ipc_msg.c b/src/functional/ipc_msg.c new file mode 100644 index 0000000..3b91aeb --- /dev/null +++ b/src/functional/ipc_msg.c @@ -0,0 +1,127 @@ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include "test.h" + +static const char path[] = "."; +static const int id = 'x'; + +#define T(f) do{ \ + if ((f)+1 == 0) \ + error("%s failed: %s\n", #f, strerror(errno)); \ +}while(0) + +#define EQ(a,b,fmt) do{ \ + if ((a) != (b)) \ + error("%s == %s failed: " fmt "\n", #a, #b, a, b); \ +}while(0) + +static void snd() +{ + time_t t; + key_t k; + int qid; + struct msqid_ds qid_ds; + struct { + long type; + char data[20]; + } msg = {1, "test message"}; + + T(t = time(0)); + T(k = ftok(path, id)); + + /* make sure we get a clean message queue id */ + T(qid = msgget(k, IPC_CREAT|0666)); + T(msgctl(qid, IPC_RMID, 0)); + T(qid = msgget(k, IPC_CREAT|IPC_EXCL|0666)); + + if (test_status) + exit(test_status); + + /* check IPC_EXCL */ + errno = 0; + if (msgget(k, IPC_CREAT|IPC_EXCL|0666) != -1 || errno != EEXIST) + error("msgget(IPC_CREAT|IPC_EXCL) should have failed with EEXIST, got %s\n", strerror(errno)); + + /* check if msgget initilaized the msqid_ds structure correctly */ + T(msgctl(qid, IPC_STAT, &qid_ds)); + EQ(qid_ds.msg_perm.cuid, geteuid(), "got %d, want %d"); + EQ(qid_ds.msg_perm.uid, geteuid(), "got %d, want %d"); + EQ(qid_ds.msg_perm.cgid, getegid(), "got %d, want %d"); + EQ(qid_ds.msg_perm.gid, getegid(), "got %d, want %d"); + EQ(qid_ds.msg_perm.mode & 0x1ff, 0666, "got %o, want %o"); + EQ(qid_ds.msg_qnum, 0, "got %d, want %d"); + EQ(qid_ds.msg_lspid, 0, "got %d, want %d"); + EQ(qid_ds.msg_lrpid, 0, "got %d, want %d"); + EQ((long)qid_ds.msg_stime, 0, "got %ld, want %d"); + EQ((long)qid_ds.msg_rtime, 0, "got %ld, want %d"); + if (qid_ds.msg_ctime < t) + error("qid_ds.msg_ctime >= t failed: got %ld, want %ld\n", (long)qid_ds.msg_ctime, (long)t); + if (qid_ds.msg_qbytes <= 0) + error("qid_ds.msg_qbytes > 0 failed: got %d, want 0\n", qid_ds.msg_qbytes, t); + + /* test send */ + T(msgsnd(qid, &msg, sizeof msg.data, IPC_NOWAIT)); + T(msgctl(qid, IPC_STAT, &qid_ds)); + EQ(qid_ds.msg_qnum, 1, "got %d, want %d"); + EQ(qid_ds.msg_lspid, getpid(), "got %d, want %d"); + if (qid_ds.msg_stime < t) + error("msg_stime is %ld want >= %ld\n", (long)qid_ds.msg_stime, (long)t); +} + +static void rcv() +{ + key_t k; + int qid; + struct { + long type; + char data[20]; + } msg; + long msgtyp = 0; + + T(k = ftok(path, id)); + T(qid = msgget(k, 0)); + + errno = 0; + if (msgrcv(qid, &msg, 0, msgtyp, 0) != -1 || errno != E2BIG) + error("msgrcv should have failed when msgsize==0 with E2BIG, got %s\n", strerror(errno)); + + /* test receive */ + T(msgrcv(qid, &msg, sizeof msg.data, msgtyp, IPC_NOWAIT)); + if (strcmp(msg.data,"test message") != 0) + error("received \"%s\" instead of \"%s\"\n", msg.data, "test message"); + + errno = 0; + if (msgrcv(qid, &msg, sizeof msg.data, msgtyp, MSG_NOERROR|IPC_NOWAIT) != -1 || errno != ENOMSG) + error("msgrcv should have failed when ther is no msg with ENOMSG, got %s\n", strerror(errno)); + + /* cleanup */ + T(msgctl(qid, IPC_RMID, 0)); +} + +int main(void) +{ + int p; + int status; + + snd(); + p = fork(); + if (p == -1) + error("fork failed: %s\n", strerror(errno)); + else if (p == 0) + rcv(); + else { + T(waitpid(p, &status, 0)); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + error("child exit status: %d\n", status); + } + return test_status; +} diff --git a/src/functional/ipc_sem.c b/src/functional/ipc_sem.c new file mode 100644 index 0000000..8f69586 --- /dev/null +++ b/src/functional/ipc_sem.c @@ -0,0 +1,123 @@ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include "test.h" + +static const char path[] = "."; +static const int id = 'x'; + +#define T(f) do{ \ + if ((f)+1 == 0) \ + error("%s failed: %s\n", #f, strerror(errno)); \ +}while(0) + +#define EQ(a,b,fmt) do{ \ + if ((a) != (b)) \ + error("%s == %s failed: " fmt "\n", #a, #b, a, b); \ +}while(0) + +static void inc() +{ + time_t t; + key_t k; + int semid, semval, sempid, semncnt, semzcnt; + struct semid_ds semid_ds; + union semun { + int val; + struct semid_ds *buf; + unsigned short *array; + } arg; + struct sembuf sops; + + T(t = time(0)); + T(k = ftok(path, id)); + + /* make sure we get a clean semaphore id */ + T(semid = semget(k, 1, IPC_CREAT|0666)); + T(semctl(semid, 0, IPC_RMID)); + T(semid = semget(k, 1, IPC_CREAT|IPC_EXCL|0666)); + + if (test_status) + exit(test_status); + + /* check IPC_EXCL */ + errno = 0; + if (semget(k, 1, IPC_CREAT|IPC_EXCL|0666) != -1 || errno != EEXIST) + error("semget(IPC_CREAT|IPC_EXCL) should have failed with EEXIST, got %s\n", strerror(errno)); + + /* check if msgget initilaized the msqid_ds structure correctly */ + arg.buf = &semid_ds; + T(semctl(semid, 0, IPC_STAT, arg)); + EQ(semid_ds.sem_perm.cuid, geteuid(), "got %d, want %d"); + EQ(semid_ds.sem_perm.uid, geteuid(), "got %d, want %d"); + EQ(semid_ds.sem_perm.cgid, getegid(), "got %d, want %d"); + EQ(semid_ds.sem_perm.gid, getegid(), "got %d, want %d"); + EQ(semid_ds.sem_perm.mode & 0x1ff, 0666, "got %o, want %o"); + EQ(semid_ds.sem_nsems, 1, "got %d, want %d"); + EQ((long)semid_ds.sem_otime, 0, "got %ld, want %d"); + if (semid_ds.sem_ctime < t) + error("semid_ds.sem_ctime >= t failed: got %ld, want %ld\n", (long)semid_ds.sem_ctime, (long)t); + + /* test sem_op > 0 */ + sops.sem_num = 0; + sops.sem_op = 1; + sops.sem_flg = 0; + T(semop(semid, &sops, 1)); + T(semval = semctl(semid, 0, GETVAL)); + EQ(semval, 1, "got %d, want %d"); + T(sempid = semctl(semid, 0, GETPID)); + EQ(sempid, getpid(), "got %d, want %d"); + T(semncnt = semctl(semid, 0, GETNCNT)); + EQ(semncnt, 0, "got %d, want %d"); + T(semzcnt = semctl(semid, 0, GETZCNT)); + EQ(semzcnt, 0, "got %d, want %d"); +} + +static void dec() +{ + key_t k; + int semid, semval; + struct sembuf sops; + + T(k = ftok(path, id)); + T(semid = semget(k, 0, 0)); + + /* test sem_op < 0 */ + sops.sem_num = 0; + sops.sem_op = -1; + sops.sem_flg = 0; + T(semop(semid, &sops, 1)); + T(semval = semctl(semid, 0, GETVAL)); + EQ(semval, 0, "got %d, want %d"); + + /* cleanup */ + T(semctl(semid, 0, IPC_RMID)); +} + +int main(void) +{ + int p; + int status; + + inc(); + p = fork(); + if (p == -1) + error("fork failed: %s\n", strerror(errno)); + else if (p == 0) + dec(); + else { + T(waitpid(p, &status, 0)); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + error("child exit status: %d\n", status); + } + return test_status; +} + diff --git a/src/functional/ipc_shm.c b/src/functional/ipc_shm.c new file mode 100644 index 0000000..7d0086b --- /dev/null +++ b/src/functional/ipc_shm.c @@ -0,0 +1,117 @@ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include "test.h" + +static const char path[] = "."; +static const int id = 'x'; + +#define T(f) do{ \ + if ((f)+1 == 0) \ + error("%s failed: %s\n", #f, strerror(errno)); \ +}while(0) + +#define EQ(a,b,fmt) do{ \ + if ((a) != (b)) \ + error("%s == %s failed: " fmt "\n", #a, #b, a, b); \ +}while(0) + +static void set() +{ + time_t t; + key_t k; + int shmid; + struct shmid_ds shmid_ds; + void *p; + + T(t = time(0)); + T(k = ftok(path, id)); + + /* make sure we get a clean shared memory id */ + T(shmid = shmget(k, 100, IPC_CREAT|0666)); + T(shmctl(shmid, IPC_RMID, 0)); + T(shmid = shmget(k, 100, IPC_CREAT|IPC_EXCL|0666)); + + if (test_status) + exit(test_status); + + /* check IPC_EXCL */ + errno = 0; + if (shmget(k, 100, IPC_CREAT|IPC_EXCL|0666) != -1 || errno != EEXIST) + error("shmget(IPC_CREAT|IPC_EXCL) should have failed with EEXIST, got %s\n", strerror(errno)); + + /* check if shmget initilaized the msshmid_ds structure correctly */ + T(shmctl(shmid, IPC_STAT, &shmid_ds)); + EQ(shmid_ds.shm_perm.cuid, geteuid(), "got %d, want %d"); + EQ(shmid_ds.shm_perm.uid, geteuid(), "got %d, want %d"); + EQ(shmid_ds.shm_perm.cgid, getegid(), "got %d, want %d"); + EQ(shmid_ds.shm_perm.gid, getegid(), "got %d, want %d"); + EQ(shmid_ds.shm_perm.mode & 0x1ff, 0666, "got %o, want %o"); + EQ(shmid_ds.shm_segsz, 100, "got %d, want %d"); + EQ(shmid_ds.shm_lpid, 0, "got %d, want %d"); + EQ(shmid_ds.shm_cpid, getpid(), "got %d, want %d"); + EQ((int)shmid_ds.shm_nattch, 0, "got %d, want %d"); + EQ((long)shmid_ds.shm_atime, 0, "got %ld, want %d"); + EQ((long)shmid_ds.shm_dtime, 0, "got %ld, want %d"); + if (shmid_ds.shm_ctime < t) + error("shmid_ds.shm_ctime >= t failed: got %ld, want %ld\n", (long)shmid_ds.shm_ctime, (long)t); + + /* test attach */ + if ((p=shmat(shmid, 0, 0)) == 0) + error("shmat failed: %s\n", strerror(errno)); + T(shmctl(shmid, IPC_STAT, &shmid_ds)); + EQ((int)shmid_ds.shm_nattch, 1, "got %d, want %d"); + EQ(shmid_ds.shm_lpid, getpid(), "got %d, want %d"); + if (shmid_ds.shm_atime < t) + error("shm_atime is %ld want >= %ld\n", (long)shmid_ds.shm_atime, (long)t); + strcpy(p, "test data"); + T(shmdt(p)); +} + +static void get() +{ + key_t k; + int shmid; + void *p; + + T(k = ftok(path, id)); + T(shmid = shmget(k, 0, 0)); + + errno = 0; + if ((p=shmat(shmid, 0, SHM_RDONLY)) == 0) + error("shmat failed: %s\n", strerror(errno)); + + if (strcmp(p, "test data") != 0) + error("reading shared mem failed: got \"%.100s\" want \"test data\"\n", p); + + /* cleanup */ + T(shmdt(p)); + T(shmctl(shmid, IPC_RMID, 0)); +} + +int main(void) +{ + int p; + int status; + + set(); + p = fork(); + if (p == -1) + error("fork failed: %s\n", strerror(errno)); + else if (p == 0) + get(); + else { + T(waitpid(p, &status, 0)); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + error("child exit status: %d\n", status); + } + return test_status; +} diff --git a/src/functional/mbc.c b/src/functional/mbc.c new file mode 100644 index 0000000..56c546b --- /dev/null +++ b/src/functional/mbc.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include +#include +#include "test.h" + +/* + * f = function call to test (or any expression) + * x = expected result + * m = message to print on failure + */ +#define T(f, x, m) (void)( \ + memset(&st, 0, sizeof st), \ + (i = (f)) == (x) || \ + error("%s failed (%s) got %d want %d\n", #f, m, i, x) ) +#define TCHAR(f, x, m) (void)( \ + memset(&st, 0, sizeof st), \ + (i = (f)) == (x) || \ + error("%s failed (%s) got 0x%04x want 0x%04x\n", #f, m, i, x) ) + +int main(void) +{ + const char *cs; + int i; + mbstate_t st, st2; + wchar_t wc, wcs[32]; + + (void)( + setlocale(LC_CTYPE, "en_US.UTF-8") || + setlocale(LC_CTYPE, "en_GB.UTF-8") || + setlocale(LC_CTYPE, "en.UTF-8") || + setlocale(LC_CTYPE, "POSIX.UTF-8") || + setlocale(LC_CTYPE, "C.UTF-8") || + setlocale(LC_CTYPE, "UTF-8") || + setlocale(LC_CTYPE, "") ); + + T(mbsrtowcs(wcs, (cs="abcdef",&cs), 3, &st), 3, "wrong semantics for wcs buf len"); + T(mbsrtowcs(wcs, (cs="abcdef",&cs), 8, &st), 6, "wrong semantics for wcs buf len"); + T(mbsrtowcs(NULL, (cs="abcdef",&cs), 2, &st), 6, "wrong semantics for NULL wcs"); + + if (strcmp(nl_langinfo(CODESET), "UTF-8")) + return error("cannot set UTF-8 locale for test (codeset=%s)\n", nl_langinfo(CODESET)); + + T(mbrtowc(&wc, "\x80", 1, &st), -1, "failed to catch error"); + T(mbrtowc(&wc, "\xc0", 1, &st), -1, "failed to catch illegal initial"); + + T(mbrtowc(&wc, "\xc0\x80", 2, &st), -1, "aliasing nul"); + T(mbrtowc(&wc, "\xc0\xaf", 2, &st), -1, "aliasing slash"); + T(mbrtowc(&wc, "\xe0\x80\xaf", 3, &st), -1, "aliasing slash"); + T(mbrtowc(&wc, "\xf0\x80\x80\xaf", 4, &st), -1, "aliasing slash"); + T(mbrtowc(&wc, "\xf8\x80\x80\x80\xaf", 5, &st), -1, "aliasing slash"); + T(mbrtowc(&wc, "\xfc\x80\x80\x80\x80\xaf", 6, &st), -1, "aliasing slash"); + T(mbrtowc(&wc, "\xe0\x82\x80", 3, &st), -1, "aliasing U+0080"); + T(mbrtowc(&wc, "\xe0\x9f\xbf", 3, &st), -1, "aliasing U+07FF"); + T(mbrtowc(&wc, "\xf0\x80\xa0\x80", 4, &st), -1, "aliasing U+0800"); + T(mbrtowc(&wc, "\xf0\x8f\xbf\xbd", 4, &st), -1, "aliasing U+FFFD"); + + T(mbrtowc(&wc, "\xed\xa0\x80", 3, &st), -1, "failed to catch surrogate"); + T(mbrtowc(&wc, "\xef\xbf\xbe", 3, &st), 3, "failed to accept U+FFFE"); + T(mbrtowc(&wc, "\xef\xbf\xbf", 3, &st), 3, "failed to accept U+FFFF"); + T(mbrtowc(&wc, "\xf4\x8f\xbf\xbe", 4, &st), 4, "failed to accept U+10FFFE"); + T(mbrtowc(&wc, "\xf4\x8f\xbf\xbf", 4, &st), 4, "failed to accept U+10FFFF"); + + T(mbrtowc(&wc, "\xc2\x80", 2, &st), 2, "wrong length"); + TCHAR((mbrtowc(&wc, "\xc2\x80", 2, &st),wc), 0x80, "wrong char"); + T(mbrtowc(&wc, "\xe0\xa0\x80", 3, &st), 3, "wrong length"); + TCHAR((mbrtowc(&wc, "\xe0\xa0\x80", 3, &st),wc), 0x800, "wrong char"); + T(mbrtowc(&wc, "\xf0\x90\x80\x80", 4, &st), 4, "wrong length"); + TCHAR((mbrtowc(&wc, "\xf0\x90\x80\x80", 4, &st),wc), 0x10000, "wrong char"); + + memset(&st2, 0, sizeof st2); + T(mbrtowc(&wc, "\xc2", 1, &st2), -2, "failed to accept initial byte"); + T(mbrtowc(&wc, "\x80", 1, &st2), 1, "failed to resume"); + TCHAR(wc, 0x80, "wrong char"); + + memset(&st2, 0, sizeof st2); + T(mbrtowc(&wc, "\xc2", 1, &st2), -2, "failed to accept initial byte"); + T(mbsrtowcs(wcs, (cs="\xa0""abc",&cs), 32, &st2), 4, "failed to resume"); + TCHAR(wcs[0], 0xa0, "wrong char"); + TCHAR(wcs[1], 'a', "wrong char"); + T(!cs, 1, "wrong final position"); + return test_status; +} diff --git a/src/functional/memstream.c b/src/functional/memstream.c new file mode 100644 index 0000000..749c664 --- /dev/null +++ b/src/functional/memstream.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include "test.h" + +#define TEST(r, f, x, m) ( \ +((r) = (f)) == (x) || \ +(error("%s failed (" m ")\n", #f, r, x), 0) ) + +#define TEST_E(f) ( (errno = 0), (f) || \ +(error("%s failed (errno = %d)\n", #f, errno), 0) ) + +#define TEST_S(s, x, m) ( \ +!strcmp((s),(x)) || \ +(error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +#define TEST_M(s, x, n, m) ( \ +!memcmp((s),(x),(n)) || \ +(error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +int main(void) +{ + FILE *f; + char *s; + size_t l; + char buf[100]; + int i; + + s = 0; + TEST_E(f = open_memstream(&s, &l)); + TEST_E(putc('a', f) == 'a'); + TEST_E(putc('b', f) == 'b'); + TEST_E(putc('c', f) == 'c'); + TEST_E(!fflush(f)); + fclose(f); + if (s) TEST_S(s, "abc", "wrong output"); + free(s); + + s = 0; + TEST_E(f = open_memstream(&s, &l)); + TEST_E(fseek(f,1,SEEK_CUR)>=0); + TEST_E(putc('q', f) == 'q'); + TEST_E(!fflush(f)); + if (s) TEST_M(s, "\0q", 3, "wrong output"); + TEST(i, fseek(f,-3,SEEK_CUR), -1, "invalid seek allowed"); + TEST(i, errno, EINVAL, "%d != %d"); + TEST(i, ftell(f), 2, "%d != %d"); + TEST_E(fseek(f,-2,SEEK_CUR)>=0); + TEST_E(putc('e', f) == 'e'); + TEST_E(!fflush(f)); + if (s) TEST_S(s, "eq", "wrong output"); + fclose(f); + free(s); + + TEST_E(f = fmemopen(buf, 10, "r+")); + TEST_E(fputs("hello", f) >= 0); + TEST_E(fputc(0, f)==0); + TEST_E(fseek(f, 0, SEEK_SET)>=0); + i=0; + TEST_E(fscanf(f, "hello%n", &i)==0); + TEST(i, i, 5, "%d != %d"); + TEST(i, ftell(f), 5, "%d != %d"); + errno = 0; + TEST(i, fseek(f, 6, SEEK_CUR)<0, 1, ""); + TEST(i, errno!=0, 1, ""); + TEST(i, ftell(f), 5, "%d != %d"); + TEST_S(buf, "hello", ""); + fclose(f); + + TEST_E(f = fmemopen(buf, 10, "a+")); + TEST(i, ftell(f), 5, "%d != %d"); + TEST_E(fseek(f, 0, SEEK_SET)>=0); + TEST(i, getc(f), 'h', "%d != %d"); + TEST(i, getc(f), 'e', "%d != %d"); + TEST(i, getc(f), 'l', "%d != %d"); + TEST(i, getc(f), 'l', "%d != %d"); + TEST(i, getc(f), 'o', "%d != %d"); + TEST(i, getc(f), EOF, "%d != %d"); + TEST_E(fseek(f, 6, SEEK_SET)>=0); + TEST(i, ftell(f), 6, "%d != %d"); + TEST(i, getc(f), EOF, "%d != %d"); + TEST(i, ftell(f), 6, "%d != %d"); + TEST_E(fseek(f, 0, SEEK_SET)>=0); + TEST(i, getc(f), 'h', "%d != %d"); + TEST_E(fseek(f, 0, SEEK_CUR)>=0); + buf[7] = 'x'; + TEST_E(fprintf(f, "%d", i)==3); + TEST_E(fflush(f)==0); + TEST(i, ftell(f), 8, "%d != %d"); + TEST_S(buf, "hello104", ""); + fclose(f); + return test_status; +} diff --git a/src/functional/popen.c b/src/functional/popen.c new file mode 100644 index 0000000..f5cf05a --- /dev/null +++ b/src/functional/popen.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include "test.h" + +#define TEST(r, f, x, m) ( \ + ((r) = (f)) == (x) || (error("%s failed (" m ")\n", #f, r, x), 0) ) + +#define TEST_E(f) ( \ + (errno = 0), \ + (f) || (error("%s failed (errno = %d)\n", #f, errno), 0) ) + +#define TEST_S(s, x, m) ( \ + !strcmp((s),(x)) || \ + (error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +static sig_atomic_t got_sig; + +static void handler(int sig) { + got_sig = 1; +} + +int main(void) +{ + int i; + char foo[6]; + char cmd[64]; + FILE *f; + + TEST_E(f = popen("echo hello", "r")); + if (f) { + TEST_E(fgets(foo, sizeof foo, f)); + TEST_S(foo, "hello", "child process did not say hello"); + TEST(i, pclose(f), 0, "exit status %04x != %04x"); + } + + signal(SIGUSR1, handler); + snprintf(cmd, sizeof cmd, "read a ; test \"x$a\" = xhello && kill -USR1 %d", getpid()); + TEST_E(f = popen(cmd, "w")); + if (f) { + TEST_E(fputs("hello", f) >= 0); + TEST(i, pclose(f), 0, "exit status %04x != %04x"); + TEST(i, got_sig, 1, "child process did not send signal"); + } + signal(SIGUSR1, SIG_DFL); + return test_status; +} diff --git a/src/functional/pthread.c b/src/functional/pthread.c new file mode 100644 index 0000000..3c25c57 --- /dev/null +++ b/src/functional/pthread.c @@ -0,0 +1,294 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "test.h" + +#define TEST(r, f, x, m) ( \ + msg = #f, ((r) = (f)) == (x) || \ + (error("%s failed (" m ")\n", #f, r, x), 0) ) + +#define TEST_S(s, x, m) ( \ + !strcmp((s),(x)) || \ + (error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +static volatile char *msg = ""; + +static void alarmhandler(int sig) { + error("timeout in %s\n", msg); + _Exit(1); +} + +static pthread_key_t k1, k2; + +static void dtor(void *p) +{ + *(int *)p = 1; +} + +static void *start1(void *arg) +{ + return arg; +} + +static void *start2(void *arg) +{ + int *p = arg; + if (pthread_setspecific(k1, p) || pthread_setspecific(k2, p+1)) + return arg; + return 0; +} + +static void *start3(void *arg) +{ + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0); + sem_post(arg); + for (;;); + return 0; +} + +static void cleanup4(void *arg) +{ + *(int *)arg = 1; +} + +static void *start4(void *arg) +{ + pthread_cleanup_push(cleanup4, arg); + sleep(3); + pthread_cleanup_pop(0); + return 0; +} + +static void cleanup4a2(void *arg) +{ + *(int *)arg += 2; +} + +static void cleanup4a3(void *arg) +{ + *(int *)arg += 3; +} + +static void cleanup4a4(void *arg) +{ + *(int *)arg += 4; +} + +static void *start4a(void *arg) +{ + int *foo = arg; + pthread_cleanup_push(cleanup4, foo); + pthread_cleanup_push(cleanup4a2, foo+1); + pthread_cleanup_push(cleanup4a3, foo+2); + pthread_cleanup_push(cleanup4a4, foo+3); + sleep(3); + pthread_cleanup_pop(0); + pthread_cleanup_pop(0); + pthread_cleanup_pop(0); + pthread_cleanup_pop(0); + return 0; +} + +static void *start5(void *arg) +{ + pthread_mutex_lock(arg); + return 0; +} + +static void *start6(void *arg) +{ + void **args = arg; + pthread_mutex_lock(args[1]); + pthread_barrier_wait(args[0]); + nanosleep(&(struct timespec){ .tv_nsec = 10000000 }, 0); + return 0; +} + +static void *start7(void *arg) +{ + void **args = arg; + pthread_mutex_lock(args[1]); + pthread_cond_signal(args[0]); + pthread_mutex_unlock(args[1]); + return 0; +} + +static void *start8(void *arg) +{ + void **args = arg; + pthread_mutex_t *m = args[1]; + pthread_cond_t *c = args[0]; + int *x = args[2]; + + pthread_mutex_lock(m); + while (*x) pthread_cond_wait(c, m); + pthread_mutex_unlock(m); + + return 0; +} + +int main(void) +{ + pthread_t td, td1, td2, td3; + int r; + void *res; + int foo[4], bar[2]; + pthread_barrier_t barrier2; + pthread_mutexattr_t mtx_a; + sem_t sem1; + pthread_mutex_t mtx; + pthread_cond_t cond; + + signal(SIGALRM, alarmhandler); + alarm(10); + + TEST(r, pthread_barrier_init(&barrier2, 0, 2), 0, "creating barrier"); + TEST(r, sem_init(&sem1, 0, 0), 0, "creating semaphore"); + + /* Test basic thread creation and joining */ + TEST(r, pthread_create(&td, 0, start1, &res), 0, "failed to create thread"); + res = 0; + TEST(r, pthread_join(td, &res), 0, "failed to join"); + TEST(r, (res==&res), 1, "wrong result from join"); + + /* Test POSIX thread-specific data */ + TEST(r, pthread_key_create(&k1, dtor), 0, "failed to create key"); + TEST(r, pthread_key_create(&k2, dtor), 0, "failed to create key"); + foo[0] = foo[1] = 0; + TEST(r, pthread_setspecific(k1, bar), 0, "failed to set tsd"); + TEST(r, pthread_setspecific(k2, bar+1), 0, "failed to set tsd"); + TEST(r, pthread_create(&td, 0, start2, foo), 0, "failed to create thread"); + TEST(r, pthread_join(td, &res), 0, "failed to join"); + TEST(res, res, 0, "pthread_setspecific failed in thread"); + TEST(r, foo[0], 1, "dtor failed to run"); + TEST(r, foo[1], 1, "dtor failed to run"); + TEST(res, pthread_getspecific(k1), bar, "tsd corrupted"); + TEST(res, pthread_getspecific(k2), bar+1, "tsd corrupted"); + TEST(r, pthread_setspecific(k1, 0), 0, "failed to clear tsd"); + TEST(r, pthread_setspecific(k2, 0), 0, "failed to clear tsd"); + TEST(r, pthread_key_delete(k1), 0, "failed to destroy key"); + TEST(r, pthread_key_delete(k2), 0, "failed to destroy key"); + + /* Asynchronous cancellation */ + TEST(r, pthread_create(&td, 0, start3, &sem1), 0, "failed to create thread"); + while (sem_wait(&sem1)); + TEST(r, pthread_cancel(td), 0, "canceling"); + TEST(r, pthread_join(td, &res), 0, "joining canceled thread"); + TEST(res, res, PTHREAD_CANCELED, "canceled thread exit status"); + + /* Cancellation cleanup handlers */ + foo[0] = 0; + TEST(r, pthread_create(&td, 0, start4, foo), 0, "failed to create thread"); + TEST(r, pthread_cancel(td), 0, "cancelling"); + TEST(r, pthread_join(td, &res), 0, "joining canceled thread"); + TEST(res, res, PTHREAD_CANCELED, "canceled thread exit status"); + TEST(r, foo[0], 1, "cleanup handler failed to run"); + + /* Nested cleanup handlers */ + memset(foo, 0, sizeof foo); + TEST(r, pthread_create(&td, 0, start4a, foo), 0, "failed to create thread"); + TEST(r, pthread_cancel(td), 0, "cancelling"); + TEST(r, pthread_join(td, &res), 0, "joining canceled thread"); + TEST(res, res, PTHREAD_CANCELED, "canceled thread exit status"); + TEST(r, foo[0], 1, "cleanup handler failed to run"); + TEST(r, foo[1], 2, "cleanup handler failed to run"); + TEST(r, foo[2], 3, "cleanup handler failed to run"); + TEST(r, foo[3], 4, "cleanup handler failed to run"); + + /* Robust mutexes */ + TEST(r, pthread_mutexattr_init(&mtx_a), 0, "initializing mutex attr"); + TEST(r, pthread_mutexattr_setrobust(&mtx_a, PTHREAD_MUTEX_ROBUST), 0, "setting robust attribute"); + TEST(r, pthread_mutex_init(&mtx, &mtx_a), 0, "initializing robust mutex"); + TEST(r, pthread_mutex_lock(&mtx), 0, "locking robust mutex"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "unlocking robust mutex"); + TEST(r, pthread_create(&td, 0, start5, &mtx), 0, "failed to create thread"); + TEST(r, pthread_join(td, &res), 0, "joining thread"); + TEST(r, pthread_mutex_lock(&mtx), EOWNERDEAD, "locking orphaned robust mutex %d!=%d"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "unlocking orphaned robust mutex %d!=%d"); + TEST(r, pthread_mutex_lock(&mtx), ENOTRECOVERABLE, "re-locking orphaned robust mutex %d!=%d"); + TEST(r, pthread_mutex_destroy(&mtx), 0, "destroying unrecoverable mutex %d!=%d"); + + TEST(r, pthread_mutex_init(&mtx, &mtx_a), 0, "initializing robust mutex"); + TEST(r, pthread_create(&td, 0, start5, &mtx), 0, "failed to create thread"); + TEST(r, pthread_join(td, &res), 0, "joining thread"); + TEST(r, pthread_mutex_lock(&mtx), EOWNERDEAD, "locking orphaned robust mutex %d!=%d"); + TEST(r, pthread_mutex_consistent(&mtx), 0, "%d!=%d"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "unlocking orphaned robust mutex %d!=%d"); + TEST(r, pthread_mutex_lock(&mtx), 0, "re-locking orphaned robust mutex %d!=%d"); + TEST(r, pthread_mutex_destroy(&mtx), 0, "destroying mutex %d!=%d"); + + TEST(r, pthread_mutex_init(&mtx, &mtx_a), 0, "%d != %d"); + TEST(r, pthread_create(&td, 0, start6, (void *[]){ &barrier2, &mtx }), 0, "%d != %d"); + pthread_barrier_wait(&barrier2); + TEST(r, pthread_mutex_lock(&mtx), EOWNERDEAD, "%d != %d"); + TEST(r, pthread_join(td, &res), 0, "%d != %d"); + TEST(r, pthread_mutex_consistent(&mtx), 0, "%d != %d"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); + TEST(r, pthread_mutex_destroy(&mtx), 0, "%d != %d"); + + //TEST(r, (fd=open("/dev/zero", O_RDWR))>=0, 1, "opening zero page file"); + //TEST(r, + + /* Condition variables */ + TEST(r, pthread_mutex_init(&mtx, 0), 0, "%d != %d"); + TEST(r, pthread_cond_init(&cond, 0), 0, "%d != %d"); + TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); + TEST(r, pthread_create(&td, 0, start7, (void *[]){ &cond, &mtx }), 0, "%d != %d"); + TEST(r, pthread_cond_wait(&cond, &mtx), 0, "%d != %d"); + TEST(r, pthread_join(td, &res), 0, "%d != %d"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); + TEST(r, pthread_mutex_destroy(&mtx), 0, "%d != %d"); + TEST(r, pthread_cond_destroy(&cond), 0, "%d != %d"); + + /* Condition variables with multiple waiters */ + TEST(r, pthread_mutex_init(&mtx, 0), 0, "%d != %d"); + TEST(r, pthread_cond_init(&cond, 0), 0, "%d != %d"); + TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); + foo[0] = 1; + TEST(r, pthread_create(&td1, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); + TEST(r, pthread_create(&td2, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); + TEST(r, pthread_create(&td3, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); + nanosleep(&(struct timespec){.tv_nsec=1000000}, 0); + foo[0] = 0; + TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); + TEST(r, pthread_cond_signal(&cond), 0, "%d != %d"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); + TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); + TEST(r, pthread_cond_signal(&cond), 0, "%d != %d"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); + TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); + TEST(r, pthread_cond_signal(&cond), 0, "%d != %d"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); + TEST(r, pthread_join(td1, 0), 0, "%d != %d"); + TEST(r, pthread_join(td2, 0), 0, "%d != %d"); + TEST(r, pthread_join(td3, 0), 0, "%d != %d"); + TEST(r, pthread_mutex_destroy(&mtx), 0, "%d != %d"); + TEST(r, pthread_cond_destroy(&cond), 0, "%d != %d"); + + /* Condition variables with broadcast signals */ + TEST(r, pthread_mutex_init(&mtx, 0), 0, "%d != %d"); + TEST(r, pthread_cond_init(&cond, 0), 0, "%d != %d"); + TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); + foo[0] = 1; + TEST(r, pthread_create(&td1, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); + TEST(r, pthread_create(&td2, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); + TEST(r, pthread_create(&td3, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); + TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); + nanosleep(&(struct timespec){.tv_nsec=1000000}, 0); + TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); + foo[0] = 0; + TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); + TEST(r, pthread_cond_broadcast(&cond), 0, "%d != %d"); + TEST(r, pthread_join(td1, 0), 0, "%d != %d"); + TEST(r, pthread_join(td2, 0), 0, "%d != %d"); + TEST(r, pthread_join(td3, 0), 0, "%d != %d"); + TEST(r, pthread_mutex_destroy(&mtx), 0, "%d != %d"); + TEST(r, pthread_cond_destroy(&cond), 0, "%d != %d"); + return test_status; +} diff --git a/src/functional/qsort.c b/src/functional/qsort.c new file mode 100644 index 0000000..b45c080 --- /dev/null +++ b/src/functional/qsort.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include "test.h" + +static int scmp(const void *a, const void *b) +{ + return strcmp(*(char **)a, *(char **)b); +} + +static int icmp(const void *a, const void *b) +{ + return *(int*)a - *(int*)b; +} + +/* 26 items -- even */ +static char *s[] = { + "Bob", "Alice", "John", "Ceres", + "Helga", "Drepper", "Emeralda", "Zoran", + "Momo", "Frank", "Pema", "Xavier", + "Yeva", "Gedun", "Irina", "Nono", + "Wiener", "Vincent", "Tsering", "Karnica", + "Lulu", "Quincy", "Osama", "Riley", + "Ursula", "Sam" +}; +/* 23 items -- odd, prime */ +static int n[] = { + 879045, 394, 99405644, 33434, 232323, 4334, 5454, + 343, 45545, 454, 324, 22, 34344, 233, 45345, 343, + 848405, 3434, 3434344, 3535, 93994, 2230404, 4334 +}; + +int main(void) +{ + int i; + + qsort(s, sizeof(s)/sizeof(char *), sizeof(char *), scmp); + for (i=0; i 0) { + error("string sort failed at index %d\n", i); + for (i=0; i n[i+1]) { + error("integer sort failed at index %d\n", i); + for (i=0; i +#include +#include +#include +#include +#include +#include +#include "test.h" + +#define TEST(c, ...) \ + ( (c) || (error(#c " failed: " __VA_ARGS__),0) ) + +int main(void) +{ + char buf[100]; + struct timespec ts; + sem_t *sem, *sem2; + int val; + + clock_gettime(CLOCK_REALTIME, &ts); + snprintf(buf, sizeof buf, "/testsuite-%d-%d", (int)getpid(), (int)ts.tv_nsec); + + TEST((sem=sem_open(buf, O_CREAT|O_EXCL, 0700, 1)) != SEM_FAILED, + "could not open sem: %s\n", strerror(errno)); + errno = 0; + TEST(sem_open(buf, O_CREAT|O_EXCL, 0700, 1) == SEM_FAILED, + "reopening should fail with O_EXCL\n"); + TEST(errno == EEXIST, + "after reopen failure errno is \"%s\" (%d); want EEXIST (%d)\n", strerror(errno), errno, EEXIST); + + TEST(sem_getvalue(sem, &val) == 0, "failed to get sem value\n"); + TEST(val == 1, "wrong initial semaphore value: %d\n", val); + + TEST((sem2=sem_open(buf, 0)) == sem, + "could not reopen sem: got %p, want %p\n", sem2, sem); + + errno = 0; + TEST(sem_wait(sem) == 0, "%s\n", strerror(errno)); + TEST(sem_getvalue(sem2, &val) == 0, "%s\n", strerror(errno)); + TEST(val == 0, "wrong semaphore value on second handle: %d\n", val); + + errno = 0; + TEST(sem_trywait(sem) == -1 && errno == EAGAIN, + "trywait on locked sem: got errno \"%s\" (%d), want EAGAIN (%d)\n", strerror(errno), errno, EAGAIN); + + TEST(sem_post(sem) == 0, "%s\n", strerror(errno)); + TEST(sem_getvalue(sem2, &val) == 0, "%s\n", strerror(errno)); + TEST(val == 1, "wrong semaphore value on second handle: %d\n", val); + + TEST(sem_close(sem) == 0, "%s\n", strerror(errno)); + TEST(sem_close(sem) == 0, "%s\n", strerror(errno)); + TEST(sem_unlink(buf) == 0, "%s\n", strerror(errno)); + return test_status; +} diff --git a/src/functional/snprintf.c b/src/functional/snprintf.c new file mode 100644 index 0000000..fefe814 --- /dev/null +++ b/src/functional/snprintf.c @@ -0,0 +1,184 @@ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif +#include +#include +#include +#include +#include +#include "test.h" + +#define DISABLE_SLOW_TESTS + +#define TEST(r, f, x, m) ( \ + ((r) = (f)) == (x) || \ + (error("%s failed (" m ")\n", #f, r, x), 0) ) + +#define TEST_S(s, x, m) ( \ + !strcmp((s),(x)) || \ + (error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +static const struct { + const char *fmt; + int i; + const char *expect; +} int_tests[] = { + /* width, precision, alignment */ + { "%04d", 12, "0012" }, + { "%.3d", 12, "012" }, + { "%3d", 12, " 12" }, + { "%-3d", 12, "12 " }, + { "%+3d", 12, "+12" }, + { "%+-5d", 12, "+12 " }, + { "%+- 5d", 12, "+12 " }, + { "%- 5d", 12, " 12 " }, + { "% d", 12, " 12" }, + { "%0-5d", 12, "12 " }, + { "%-05d", 12, "12 " }, + + /* ...explicit precision of 0 shall be no characters. */ + { "%.0d", 0, "" }, + { "%.0o", 0, "" }, + { "%#.0d", 0, "" }, + { "%#.0o", 0, "" }, + { "%#.0x", 0, "" }, + + /* ...but it still has to honor width and flags. */ + { "%2.0u", 0, " " }, + { "%02.0u", 0, " " }, + { "%2.0d", 0, " " }, + { "%02.0d", 0, " " }, + { "% .0d", 0, " " }, + { "%+.0d", 0, "+" }, + + /* hex: test alt form and case */ + { "%x", 63, "3f" }, + { "%#x", 63, "0x3f" }, + { "%X", 63, "3F" }, + + /* octal: test alt form */ + { "%o", 15, "17" }, + { "%#o", 15, "017" }, + + { NULL, 0.0, NULL } +}; + +static const struct { + const char *fmt; + double f; + const char *expect; +} fp_tests[] = { + /* basic form, handling of exponent/precision for 0 */ + { "%a", 0.0, "0x0p+0" }, + { "%e", 0.0, "0.000000e+00" }, + { "%f", 0.0, "0.000000" }, + { "%g", 0.0, "0" }, + { "%#g", 0.0, "0.00000" }, + { "%la", 0.0, "0x0p+0" }, + { "%le", 0.0, "0.000000e+00" }, + { "%lf", 0.0, "0.000000" }, + { "%lg", 0.0, "0" }, + { "%#lg", 0.0, "0.00000" }, + + /* rounding */ + { "%f", 1.1, "1.100000" }, + { "%f", 1.2, "1.200000" }, + { "%f", 1.3, "1.300000" }, + { "%f", 1.4, "1.400000" }, + { "%f", 1.5, "1.500000" }, + { "%.4f", 1.06125, "1.0612" }, + { "%.2f", 1.375, "1.38" }, + { "%.1f", 1.375, "1.4" }, + { "%.1lf", 1.375, "1.4" }, + { "%.15f", 1.1, "1.100000000000000" }, + { "%.16f", 1.1, "1.1000000000000001" }, + { "%.17f", 1.1, "1.10000000000000009" }, + { "%.2e", 1500001.0, "1.50e+06" }, + { "%.2e", 1505000.0, "1.50e+06" }, + { "%.2e", 1505000.00000095367431640625, "1.51e+06" }, + { "%.2e", 1505001.0, "1.51e+06" }, + { "%.2e", 1506000.0, "1.51e+06" }, + + /* correctness in DBL_DIG places */ + { "%.15g", 1.23456789012345, "1.23456789012345" }, + + /* correct choice of notation for %g */ + { "%g", 0.0001, "0.0001" }, + { "%g", 0.00001, "1e-05" }, + { "%g", 123456, "123456" }, + { "%g", 1234567, "1.23457e+06" }, + { "%.7g", 1234567, "1234567" }, + { "%.7g", 12345678, "1.234568e+07" }, + { "%.8g", 0.1, "0.1" }, + { "%.9g", 0.1, "0.1" }, + { "%.10g", 0.1, "0.1" }, + { "%.11g", 0.1, "0.1" }, + + /* pi in double precision, printed to a few extra places */ + { "%.15f", M_PI, "3.141592653589793" }, + { "%.18f", M_PI, "3.141592653589793116" }, + + /* exact conversion of large integers */ + { "%.0f", 340282366920938463463374607431768211456.0, + "340282366920938463463374607431768211456" }, + + { NULL, 0.0, NULL } +}; + +int main(void) +{ + int i, j, k; + char b[2000]; + + TEST(i, snprintf(0, 0, "%d", 123456), 6, "length returned %d != %d"); + TEST(i, snprintf(0, 0, "%.4s", "hello"), 4, "length returned %d != %d"); + TEST(i, snprintf(b, 0, "%.0s", "goodbye"), 0, "length returned %d != %d"); + + strcpy(b, "xxxxxxxx"); + TEST(i, snprintf(b, 4, "%d", 123456), 6, "length returned %d != %d"); + TEST_S(b, "123", "incorrect output"); + TEST(i, b[5], 'x', "buffer overrun"); + + /* Perform ascii arithmetic to test printing tiny doubles */ + TEST(i, snprintf(b, sizeof b, "%.1022f", 0x1p-1021), 1024, "%d != %d"); + b[1] = '0'; + for (i=0; i<1021; i++) { + for (k=0, j=1023; j>0; j--) { + if (b[j]<'5') b[j]+=b[j]-'0'+k, k=0; + else b[j]+=b[j]-'0'-10+k, k=1; + } + } + TEST(i, b[1], '1', "'%c' != '%c'"); + for (j=2; b[j]=='0'; j++); + TEST(i, j, 1024, "%d != %d"); + + +#ifndef DISABLE_SLOW_TESTS + errno = 0; + TEST(i, snprintf(NULL, 0, "%.*u", 2147483647, 0), 2147483647, "cannot print max length %d"); + TEST(i, snprintf(NULL, 0, "%.*u ", 2147483647, 0), -1, "integer overflow %d"); + TEST(i, errno, EOVERFLOW, "after overflow: %d != %d"); +#endif + for (j=0; int_tests[j].fmt; j++) { + i = snprintf(b, sizeof b, int_tests[j].fmt, int_tests[j].i); + if (i != strlen(int_tests[j].expect)) { + error("snprintf(b, sizeof b, \"%s\", %d) returned %d wanted %d\n", + int_tests[j].fmt, int_tests[j].i, i, strlen(int_tests[j].expect)); + } + if (strcmp(b, int_tests[j].expect) != 0) + error("bad integer conversion: got \"%s\", want \"%s\"\n", b, int_tests[j].expect); + } + + for (j=0; fp_tests[j].fmt; j++) { + i = snprintf(b, sizeof b, fp_tests[j].fmt, fp_tests[j].f); + if (i != strlen(fp_tests[j].expect)) { + error("snprintf(b, sizeof b, \"%s\", %f) returned %d wanted %d\n", + fp_tests[j].fmt, fp_tests[j].f, i, strlen(fp_tests[j].expect)); + } + if (strcmp(b, fp_tests[j].expect) != 0) + error("bad floating-point conversion: got \"%s\", want \"%s\"\n", b, fp_tests[j].expect); + } + + TEST(i, snprintf(0, 0, "%.4a", 1.0), 11, "%d != %d"); + return test_status; +} diff --git a/src/functional/spawn.c b/src/functional/spawn.c new file mode 100644 index 0000000..707b1a5 --- /dev/null +++ b/src/functional/spawn.c @@ -0,0 +1,42 @@ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif +#include +#include +#include +#include +#include +#include +#include +#include "test.h" + +#define TEST(f, x) (void)( \ + (r = (f)) == (x) || \ + error("%s failed, got %d want %d\n", #f, r, x) ) + +#define TEST_E(f) (void)( \ + (errno = 0), (f) || \ + error("%s failed (errno = %d \"%s\")\n", #f, errno, strerror(errno)) ) + +int main(void) +{ + int r; + char foo[10]; + int p[2]; + pid_t pid; + int status; + posix_spawn_file_actions_t fa; + + TEST_E(!pipe(p)); + TEST(posix_spawn_file_actions_init(&fa), 0); + TEST(posix_spawn_file_actions_addclose(&fa, p[0]), 0); + TEST(posix_spawn_file_actions_adddup2(&fa, p[1], 1), 0); + TEST(posix_spawn_file_actions_addclose(&fa, p[1]), 0); + TEST(posix_spawnp(&pid, "echo", &fa, 0, (char *[]){"echo","hello",0}, 0), 0); + close(p[1]); + TEST(waitpid(pid, &status, 0), pid); + TEST(read(p[0], foo, sizeof foo), 6); + close(p[0]); + TEST(posix_spawn_file_actions_destroy(&fa), 0); + return test_status; +} diff --git a/src/functional/sscanf.c b/src/functional/sscanf.c new file mode 100644 index 0000000..a087c21 --- /dev/null +++ b/src/functional/sscanf.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include "test.h" + +#define TEST(r, f, x, m) ( \ + ((r) = (f)) == (x) || \ + (error("%s failed (" m ")\n", #f, r, x), 0) ) + +#define TEST_S(s, x, m) ( \ + !strcmp((s),(x)) || \ + (error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +#define TEST_F(x) ( \ + TEST(i, sscanf(# x, "%lf", &d), 1, "got %d fields, expected %d"), \ + TEST(t, d, (double)x, "%g != %g") ) + +int main(void) +{ + int i; + char a[100], b[100]; + int x, y, z, u, v; + double d, t; + + TEST(i, sscanf("hello, world\n", "%s %s", a, b), 2, "only %d fields, expected %d"); + TEST_S(a, "hello,", ""); + TEST_S(b, "world", ""); + + TEST(i, sscanf("hello, world\n", "%[hel]%s", a, b), 2, "only %d fields, expected %d"); + TEST_S(a, "hell", ""); + TEST_S(b, "o,", ""); + + TEST(i, sscanf("hello, world\n", "%[hel] %s", a, b), 2, "only %d fields, expected %d"); + TEST_S(a, "hell", ""); + TEST_S(b, "o,", ""); + + a[8] = 'X'; + a[9] = 0; + TEST(i, sscanf("hello, world\n", "%8c%8c", a, b), 1, "%d fields, expected %d"); + TEST_S(a, "hello, wX", ""); + + TEST(i, sscanf("56789 0123 56a72", "%2d%d%*d %[0123456789]\n", &x, &y, a), 3, "only %d fields, expected %d"); + TEST(i, x, 56, "%d != %d"); + TEST(i, y, 789, "%d != %d"); + TEST_S(a, "56", ""); + + TEST(i, sscanf("011 0x100 11 0x100 100", "%i %i %o %x %x\n", &x, &y, &z, &u, &v), 5, "only %d fields, expected %d"); + TEST(i, x, 9, "%d != %d"); + TEST(i, y, 256, "%d != %d"); + TEST(i, z, 9, "%d != %d"); + TEST(i, u, 256, "%d != %d"); + TEST(i, v, 256, "%d != %d"); + + TEST(i, sscanf("20 xyz", "%d %d\n", &x, &y), 1, "only %d fields, expected %d"); + TEST(i, x, 20, "%d != %d"); + + TEST(i, sscanf("xyz", "%d\n", &x, &y), 0, "got %d fields, expected no match (%d)"); + + TEST(i, sscanf("", "%d\n", &x, &y), -1, "got %d fields, expected input failure (%d)"); + + TEST(i, sscanf(" 12345 6", "%2d%d%d", &x, &y, &z), 3, "only %d fields, expected %d"); + TEST(i, x, 12, "%d != %d"); + TEST(i, y, 345, "%d != %d"); + TEST(i, z, 6, "%d != %d"); + + TEST(i, sscanf(" 0x12 0x34", "%5i%2i", &x, &y), 1, "got %d fields, expected %d"); + TEST(i, x, 0x12, "%d != %d"); + + TEST_F(123); + TEST_F(123.0); + TEST_F(123.0e+0); + TEST_F(123.0e+4); + TEST_F(1.234e1234); + TEST_F(1.234e-1234); + TEST_F(1.234e56789); + TEST_F(1.234e-56789); + TEST_F(-0.5); + TEST_F(0.1); + TEST_F(0.2); + TEST_F(0.1e-10); + TEST_F(0x1234p56); + + TEST(i, sscanf("10e", "%lf", &d), 0, "got %d fields, expected no match (%d)"); + TEST(i, sscanf("", "%lf\n", &d), -1, "got %d fields, expected input failure (%d)"); + return test_status; +} diff --git a/src/functional/sscanf_long.c b/src/functional/sscanf_long.c new file mode 100644 index 0000000..a26999d --- /dev/null +++ b/src/functional/sscanf_long.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include "test.h" + +static void setrl(int r, long lim) +{ + struct rlimit rl; + + if (getrlimit(r, &rl)) + error("getrlimit %d: %s\n", r, strerror(errno)); + rl.rlim_cur = lim; + if (setrlimit(r, &rl)) + error("setrlimit %d: %s\n", r, strerror(errno)); +} + +int main(void) +{ + enum {n = 8*1024*1024}; + char *s = malloc(n); + int i; + float f; + char c; + + if (!s) + return error("out of memory"); + setrl(RLIMIT_STACK, 128*1024); + + for (i = 0; i < n; i++) s[i] = '1'; + s[n-3] = ' '; + s[n-1] = 0; + + /* + * stack overflow if scanf copies s on the stack (glibc) + * same issue with %d except then storing the conversion + * result is undefined behaviour + */ + i = sscanf(s, "%f %c", &f, &c); + + if (i != 2) + error("sscanf returned %d, want 2\n", i); + if (f != INFINITY) + error("sscanf(longnum, \"%%f\") read %f, want inf\n", f); + if (c != '1') + error("sscanf(\"1\", %%c) read '%c', want '1'\n", c); + free(s); + return test_status; +} diff --git a/src/functional/string.c b/src/functional/string.c new file mode 100644 index 0000000..2e06eb9 --- /dev/null +++ b/src/functional/string.c @@ -0,0 +1,116 @@ +#define _BSD_SOURCE +#include +#include +#include "test.h" + +/* r = place to store result + * f = function call to test (or any expression) + * x = expected result + * m = message to print on failure (with formats for r & x) +**/ + +#define TEST(r, f, x, m) ( \ + ((r) = (f)) == (x) || \ + (error("%s failed (" m ")\n", #f, r, x), 0) ) + +#define TEST_S(s, x, m) ( \ + !strcmp((s),(x)) || \ + (error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +int main(void) +{ + char b[32]; + char *s; + int i; + + b[16]='a'; b[17]='b'; b[18]='c'; b[19]=0; + TEST(s, strcpy(b, b+16), b, "wrong return %p != %p"); + TEST_S(s, "abc", "strcpy gave incorrect string"); + TEST(s, strcpy(b+1, b+16), b+1, "wrong return %p != %p"); + TEST_S(s, "abc", "strcpy gave incorrect string"); + TEST(s, strcpy(b+2, b+16), b+2, "wrong return %p != %p"); + TEST_S(s, "abc", "strcpy gave incorrect string"); + TEST(s, strcpy(b+3, b+16), b+3, "wrong return %p != %p"); + TEST_S(s, "abc", "strcpy gave incorrect string"); + + TEST(s, strcpy(b+1, b+17), b+1, "wrong return %p != %p"); + TEST_S(s, "bc", "strcpy gave incorrect string"); + TEST(s, strcpy(b+2, b+18), b+2, "wrong return %p != %p"); + TEST_S(s, "c", "strcpy gave incorrect string"); + TEST(s, strcpy(b+3, b+19), b+3, "wrong return %p != %p"); + TEST_S(s, "", "strcpy gave incorrect string"); + + TEST(s, memset(b, 'x', sizeof b), b, "wrong return %p != %p"); + TEST(s, strncpy(b, "abc", sizeof b - 1), b, "wrong return %p != %p"); + TEST(i, memcmp(b, "abc\0\0\0\0", 8), 0, "strncpy fails to zero-pad dest"); + TEST(i, b[sizeof b - 1], 'x', "strncpy overruns buffer when n > strlen(src)"); + + b[3] = 'x'; b[4] = 0; + strncpy(b, "abc", 3); + TEST(i, b[2], 'c', "strncpy fails to copy last byte: %hhu != %hhu"); + TEST(i, b[3], 'x', "strncpy overruns buffer to null-terminate: %hhu != %hhu"); + + TEST(i, !strncmp("abcd", "abce", 3), 1, "strncmp compares past n"); + TEST(i, !!strncmp("abc", "abd", 3), 1, "strncmp fails to compare n-1st byte"); + + strcpy(b, "abc"); + TEST(s, strncat(b, "123456", 3), b, "%p != %p"); + TEST(i, b[6], 0, "strncat failed to null-terminate (%d)"); + TEST_S(s, "abc123", "strncat gave incorrect string"); + + strcpy(b, "aaababccdd0001122223"); + TEST(s, strchr(b, 'b'), b+3, "%p != %p"); + TEST(s, strrchr(b, 'b'), b+5, "%p != %p"); + TEST(i, strspn(b, "abcd"), 10, "%d != %d"); + TEST(i, strcspn(b, "0123"), 10, "%d != %d"); + TEST(s, strpbrk(b, "0123"), b+10, "%d != %d"); + + strcpy(b, "abc 123; xyz; foo"); + TEST(s, strtok(b, " "), b, "%p != %p"); + TEST_S(s, "abc", "strtok result"); + + TEST(s, strtok(NULL, ";"), b+4, "%p != %p"); + TEST_S(s, " 123", "strtok result"); + + TEST(s, strtok(NULL, " ;"), b+11, "%p != %p"); + TEST_S(s, "xyz", "strtok result"); + + TEST(s, strtok(NULL, " ;"), b+16, "%p != %p"); + TEST_S(s, "foo", "strtok result"); + +#ifdef HAVE_BSD_STRL + memset(b, 'x', sizeof b); + TEST(i, strlcpy(b, "abc", sizeof b - 1), 3, "length %d != %d"); + TEST(i, b[3], 0, "strlcpy did not null-terminate short string (%d)"); + TEST(i, b[4], 'x', "strlcpy wrote extra bytes (%d)"); + + memset(b, 'x', sizeof b); + TEST(i, strlcpy(b, "abc", 2), 3, "length %d != %d"); + TEST(i, b[0], 'a', "strlcpy did not copy character %d"); + TEST(i, b[1], 0, "strlcpy did not null-terminate long string (%d)"); + + memset(b, 'x', sizeof b); + TEST(i, strlcpy(b, "abc", 3), 3, "length %d != %d"); + TEST(i, b[2], 0, "strlcpy did not null-terminate l-length string (%d)"); + + TEST(i, strlcpy(NULL, "abc", 0), 3, "length %d != %d"); + + memcpy(b, "abc\0\0\0x\0", 8); + TEST(i, strlcat(b, "123", sizeof b), 6, "length %d != %d"); + TEST_S(b, "abc123", "strlcat result"); + + memcpy(b, "abc\0\0\0x\0", 8); + TEST(i, strlcat(b, "123", 6), 6, "length %d != %d"); + TEST_S(b, "abc12", "strlcat result"); + TEST(i, b[6], 'x', "strlcat wrote past string %d != %d"); + + memcpy(b, "abc\0\0\0x\0", 8); + TEST(i, strlcat(b, "123", 4), 6, "length %d != %d"); + TEST_S(b, "abc", "strlcat result"); + + memcpy(b, "abc\0\0\0x\0", 8); + TEST(i, strlcat(b, "123", 3), 6, "length %d != %d"); + TEST_S(b, "abc", "strlcat result"); +#endif + return test_status; +} diff --git a/src/functional/string_memmem.c b/src/functional/string_memmem.c new file mode 100644 index 0000000..d21164a --- /dev/null +++ b/src/functional/string_memmem.c @@ -0,0 +1,58 @@ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif +#include +#include "test.h" + +#define N(s, sub) { \ + char *p = s; \ + char *q = memmem(p, strlen(p), sub, strlen(sub)); \ + if (q) \ + error("memmem(%s,%s) returned str+%d, wanted 0\n", #s, #sub, q-p); \ +} + +#define T(s, sub, n) { \ + char *p = s; \ + char *q = memmem(p, strlen(p), sub, strlen(sub)); \ + if (q == 0) \ + error("memmem(%s,%s) returned 0, wanted str+%d\n", #s, #sub, n); \ + else if (q - p != n) \ + error("memmem(%s,%s) returned str+%d, wanted str+%d\n", #s, #sub, q-p, n); \ +} + +int main(void) +{ + N("", "a") + N("a", "aa") + N("a", "b") + N("aa", "ab") + N("aa", "aaa") + N("abba", "aba") + N("abc abc", "abcd") + N("0-1-2-3-4-5-6-7-8-9", "-3-4-56-7-8-") + N("0-1-2-3-4-5-6-7-8-9", "-3-4-5+6-7-8-") + N("_ _ _\xff_ _ _", "_\x7f_") + N("_ _ _\x7f_ _ _", "_\xff_") + + T("", "", 0) + T("abcd", "", 0) + T("abcd", "a", 0) + T("abcd", "b", 1) + T("abcd", "c", 2) + T("abcd", "d", 3) + T("abcd", "ab", 0) + T("abcd", "bc", 1) + T("abcd", "cd", 2) + T("ababa", "baba", 1) + T("ababab", "babab", 1) + T("abababa", "bababa", 1) + T("abababab", "bababab", 1) + T("ababababa", "babababa", 1) + T("nanabanabanana", "aba", 3) + T("nanabanabanana", "ban", 4) + T("nanabanabanana", "anab", 1) + T("nanabanabanana", "banana", 8) + T("_ _\xff_ _", "_\xff_", 2) + + return test_status; +} diff --git a/src/functional/string_strchr.c b/src/functional/string_strchr.c new file mode 100644 index 0000000..c05d881 --- /dev/null +++ b/src/functional/string_strchr.c @@ -0,0 +1,58 @@ +#include +#include "test.h" + +#define N(s, c) { \ + char *p = s; \ + char *q = strchr(p, c); \ + if (q) \ + error("strchr(%s,%s) returned str+%d, wanted 0\n", #s, #c, q-p); \ +} + +#define T(s, c, n) { \ + char *p = s; \ + char *q = strchr(p, c); \ + if (q == 0) \ + error("strchr(%s,%s) returned 0, wanted str+%d\n", #s, #c, n); \ + else if (q - p != n) \ + error("strchr(%s,%s) returned str+%d, wanted str+%d\n", #s, #c, q-p, n); \ +} + +int main(void) +{ + int i; + char a[128]; + char s[256]; + + for (i = 0; i < 128; i++) + a[i] = (i+1) & 127; + for (i = 0; i < 256; i++) + *((unsigned char*)s+i) = i+1; + + N("", 'a') + N("a", 'b') + N("abc abc", 'x') + N(a, 128) + N(a, 255) + + T("", 0, 0) + T("a", 'a', 0) + T("a", 'a'+256, 0) + T("a", 0, 1) + T("ab", 'b', 1) + T("aab", 'b', 2) + T("aaab", 'b', 3) + T("aaaab", 'b', 4) + T("aaaaab", 'b', 5) + T("aaaaaab", 'b', 6) + T("abc abc", 'c', 2) + T(s, 1, 0) + T(s, 2, 1) + T(s, 10, 9) + T(s, 11, 10) + T(s, 127, 126) + T(s, 128, 127) + T(s, 255, 254) + T(s, 0, 255) + + return test_status; +} diff --git a/src/functional/string_strcspn.c b/src/functional/string_strcspn.c new file mode 100644 index 0000000..87fcd10 --- /dev/null +++ b/src/functional/string_strcspn.c @@ -0,0 +1,34 @@ +#include +#include +#include "test.h" + +#define T(s, c, n) { \ + char *p = s; \ + char *q = c; \ + size_t r = strcspn(p, q); \ + if (r != n) \ + error("strcspn(%s,%s) returned %lu, wanted %lu\n", #s, #c, (unsigned long)r, (unsigned long)(n)); \ +} + +int main(void) +{ + int i; + char a[128]; + char s[256]; + + for (i = 0; i < 128; i++) + a[i] = (i+1) & 127; + for (i = 0; i < 256; i++) + *((unsigned char*)s+i) = i+1; + + T("", "", 0) + T("a", "", 1) + T("", "a", 0) + T("abc", "cde", 2) + T("abc", "ccc", 2) + T("abc", a, 0) + T("\xff\x80 abc", a, 2) + T(s, "\xff", 254) + + return test_status; +} diff --git a/src/functional/string_strstr.c b/src/functional/string_strstr.c new file mode 100644 index 0000000..2e3b352 --- /dev/null +++ b/src/functional/string_strstr.c @@ -0,0 +1,55 @@ +#include +#include "test.h" + +#define N(s, sub) { \ + char *p = s; \ + char *q = strstr(p, sub); \ + if (q) \ + error("strstr(%s,%s) returned str+%d, wanted 0\n", #s, #sub, q-p); \ +} + +#define T(s, sub, n) { \ + char *p = s; \ + char *q = strstr(p, sub); \ + if (q == 0) \ + error("strstr(%s,%s) returned 0, wanted str+%d\n", #s, #sub, n); \ + else if (q - p != n) \ + error("strstr(%s,%s) returned str+%d, wanted str+%d\n", #s, #sub, q-p, n); \ +} + +int main(void) +{ + N("", "a") + N("a", "aa") + N("a", "b") + N("aa", "ab") + N("aa", "aaa") + N("abba", "aba") + N("abc abc", "abcd") + N("0-1-2-3-4-5-6-7-8-9", "-3-4-56-7-8-") + N("0-1-2-3-4-5-6-7-8-9", "-3-4-5+6-7-8-") + N("_ _ _\xff_ _ _", "_\x7f_") + N("_ _ _\x7f_ _ _", "_\xff_") + + T("", "", 0) + T("abcd", "", 0) + T("abcd", "a", 0) + T("abcd", "b", 1) + T("abcd", "c", 2) + T("abcd", "d", 3) + T("abcd", "ab", 0) + T("abcd", "bc", 1) + T("abcd", "cd", 2) + T("ababa", "baba", 1) + T("ababab", "babab", 1) + T("abababa", "bababa", 1) + T("abababab", "bababab", 1) + T("ababababa", "babababa", 1) + T("nanabanabanana", "aba", 3) + T("nanabanabanana", "ban", 4) + T("nanabanabanana", "anab", 1) + T("nanabanabanana", "banana", 8) + T("_ _\xff_ _", "_\xff_", 2) + + return test_status; +} diff --git a/src/functional/strtod.c b/src/functional/strtod.c new file mode 100644 index 0000000..c6967ac --- /dev/null +++ b/src/functional/strtod.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include "test.h" + +#define length(x) (sizeof(x) / sizeof *(x)) + +static struct { + char *s; + double f; +} t[] = { + {"0", 0.0}, + {"00.00", 0.0}, + {"-.00000", -0.0}, + {"1e+1000000", INFINITY}, + {"1e-1000000", 0}, + // 2^-1074 * 0.5 - eps + {".2470328229206232720882843964341106861825299013071623822127928412503377536351043e-323", 0}, + // 2^-1074 * 0.5 + eps + {".2470328229206232720882843964341106861825299013071623822127928412503377536351044e-323", 0x1p-1074}, + // 2^-1074 * 1.5 - eps + {".7410984687618698162648531893023320585475897039214871466383785237510132609053131e-323", 0x1p-1074}, + // 2^-1074 * 1.5 + eps + {".7410984687618698162648531893023320585475897039214871466383785237510132609053132e-323", 0x1p-1073}, + // 2^-1022 + 2^-1075 - eps + {".2225073858507201630123055637955676152503612414573018013083228724049586647606759e-307", 0x1p-1022}, + // 2^-1022 + 2^-1075 + eps + {".2225073858507201630123055637955676152503612414573018013083228724049586647606760e-307", 0x1.0000000000001p-1022}, + // 2^1024 - 2^970 - eps + {"17976931348623158079372897140530341507993413271003782693617377898044" + "49682927647509466490179775872070963302864166928879109465555478519404" + "02630657488671505820681908902000708383676273854845817711531764475730" + "27006985557136695962284291481986083493647529271907416844436551070434" + "2711559699508093042880177904174497791.999999999999999999999999999999", 0x1.fffffffffffffp1023}, + // 2^1024 - 2^970 + {"17976931348623158079372897140530341507993413271003782693617377898044" + "49682927647509466490179775872070963302864166928879109465555478519404" + "02630657488671505820681908902000708383676273854845817711531764475730" + "27006985557136695962284291481986083493647529271907416844436551070434" + "2711559699508093042880177904174497792", INFINITY}, + // some random numbers + {".5961860348131807091861002266453941950428e00", 0.59618603481318067}, // 0x1.313f4bc3b584cp-1 + {"1.815013169218038729887460898733526957442e-1", 0.18150131692180388}, // 0x1.73b6f662e1712p-3 + {"42.07082357534453600681618685682257590772e-2", 0.42070823575344535}, // 0x1.aece23c6e028dp-2 + {"665.4686306516261456328973225579833470816e-3", 0.66546863065162609}, // 0x1.54b84dea53453p-1 + {"6101.852922970868621786690495485449831753e-4", 0.61018529229708685}, // 0x1.386a34e5d516bp-1 + {"76966.95208236968077849464348875471158549e-5", 0.76966952082369677}, // 0x1.8a121f9954dfap-1 + {"250506.5322228682496132604807222923702304e-6", 0.25050653222286823}, // 0x1.0084c8cd538c2p-2 + {"2740037.230228005325852424697698331177377e-7", 0.27400372302280052}, // 0x1.18946e9575ef4p-2 + {"20723093.50049742645941529268715428324490e-8", 0.20723093500497428}, // 0x1.a868b14486e4dp-3 + {"0.7900280238081604956226011047460238748912e1", 7.9002802380816046}, // 0x1.f99e3100f2eaep+2 + {"0.9822860653737296848190558448760465863597e2", 98.228606537372968}, // 0x1.88ea17d506accp+6 + {"0.7468949723190370809405570560160405324869e3", 746.89497231903704}, // 0x1.75728e73f48b7p+9 + {"0.1630268320282728475980459844271031751665e4", 1630.2683202827284}, // 0x1.97912c28d5cbp+10 + {"0.4637168629719170695109918769645492022088e5", 46371.686297191707}, // 0x1.6a475f6258737p+15 + {"0.6537805944497711554209461686415872067523e6", 653780.59444977110}, // 0x1.3f3a9305bb86cp+19 + {"0.2346324356502437045212230713960457676531e6", 234632.43565024371}, // 0x1.ca4437c3631eap+17 + {"0.9709481716420048341897258980454298205278e8", 97094817.164200485}, // 0x1.7263284a8242cp+26 + {"0.4996908522051874110779982354932499499602e9", 499690852.20518744}, // 0x1.dc8ad6434872ap+28 +}; + +int main(void) +{ + int i; + double x; + char *p; + + for (i = 0; i < length(t); i++) { + x = strtod(t[i].s, &p); + if (x != t[i].f) + error("strtod(\"%s\") want %a got %a\n", t[i].s, t[i].f, x); + } + return test_status; +} + diff --git a/src/functional/strtod_long.c b/src/functional/strtod_long.c new file mode 100644 index 0000000..d2db2e8 --- /dev/null +++ b/src/functional/strtod_long.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include "test.h" + +int main(void) +{ + double x, want = .1111111111111111111111; + char buf[40000]; + + memset(buf, '1', sizeof buf); + buf[0] = '.'; + buf[sizeof buf - 1] = 0; + + if ((x=strtod(buf, 0)) != want) + error("strtod(.11[...]1) got %a want %a\n", x, want); + return test_status; +} + diff --git a/src/functional/strtod_simple.c b/src/functional/strtod_simple.c new file mode 100644 index 0000000..c95dc9e --- /dev/null +++ b/src/functional/strtod_simple.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include "test.h" + +/* r = place to store result + * f = function call to test (or any expression) + * x = expected result + * m = message to print on failure (with formats for r & x) +**/ + +#define TEST(r, f, x, m) ( \ + ((r) = (f)) == (x) || \ + (error("%s failed (" m ")\n", #f, r, x, r-x), 0) ) + +int main(void) +{ + int i; + double d, d2; + char buf[1000]; + + for (i=0; i<100; i++) { + d = sin(i); + snprintf(buf, sizeof buf, "%.300f", d); + TEST(d2, strtod(buf, 0), d, "round trip fail %a != %a (%a)"); + } + + TEST(d, strtod("0x1p4", 0), 16.0, "hex float %a != %a"); + TEST(d, strtod("0x1.1p4", 0), 17.0, "hex float %a != %a"); + return test_status; +} + diff --git a/src/functional/strtof.c b/src/functional/strtof.c new file mode 100644 index 0000000..29876bc --- /dev/null +++ b/src/functional/strtof.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include "test.h" + +#define length(x) (sizeof(x) / sizeof *(x)) + +static struct { + char *s; + float f; +} t[] = { + // 2^-149 * 0.5 - eps + {".7006492321624085354618647916449580656401309709382578858785341419448955413429303e-45", 0}, + // 2^-149 * 0.5 + eps + {".7006492321624085354618647916449580656401309709382578858785341419448955413429304e-45", 0x1p-149}, + // 2^-149 * 0.5 - eps + {".2101947696487225606385594374934874196920392912814773657635602425834686624028790e-44", 0x1p-149}, + // 2^-149 * 0.5 + eps + {".2101947696487225606385594374934874196920392912814773657635602425834686624028791e-44", 0x1p-148}, + // 2^-126 + 2^-150 - eps + {".1175494420887210724209590083408724842314472120785184615334540294131831453944281e-37", 0x1p-126}, + // 2^-126 + 2^-150 + eps + {".1175494420887210724209590083408724842314472120785184615334540294131831453944282e-37", 0x1.000002p-126}, + // 2^128 - 2^103 - eps + {"340282356779733661637539395458142568447.9999999999999999999", 0x1.fffffep127}, + // 2^128 - 2^103 + {"340282356779733661637539395458142568448", INFINITY}, +}; + +int main(void) +{ + int i; + float x; + char *p; + + for (i = 0; i < length(t); i++) { + x = strtof(t[i].s, &p); + if (x != t[i].f) + error("strtof(\"%s\") want %a got %a\n", t[i].s, t[i].f, x); + } + return test_status; +} diff --git a/src/functional/strtol.c b/src/functional/strtol.c new file mode 100644 index 0000000..81df887 --- /dev/null +++ b/src/functional/strtol.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include "test.h" + +/* r = place to store result + * f = function call to test (or any expression) + * x = expected result + * m = message to print on failure (with formats for r & x) +**/ + +#define TEST(r, f, x, m) ( \ + errno = 0, msg = #f, ((r) = (f)) == (x) || \ + (error("%s failed (" m ")\n", #f, r, x), 0) ) + +#define TEST2(r, f, x, m) ( \ + ((r) = (f)) == (x) || \ + (error("%s failed (" m ")\n", msg, r, x), 0) ) + +int main(void) +{ + int i; + long l; + unsigned long ul; + char *msg=""; + char *s, *c; + + TEST(l, atol("2147483647"), 2147483647L, "max 32bit signed %ld != %ld"); + TEST(l, strtol("2147483647", 0, 0), 2147483647L, "max 32bit signed %ld != %ld"); + TEST(ul, strtoul("4294967295", 0, 0), 4294967295UL, "max 32bit unsigned %lu != %lu"); + + if (sizeof(long) == 4) { + TEST(l, strtol(s="2147483648", &c, 0), 2147483647L, "uncaught overflow %ld != %ld"); + TEST2(i, c-s, 10, "wrong final position %d != %d"); + TEST2(i, errno, ERANGE, "missing errno %d != %d"); + TEST(l, strtol(s="-2147483649", &c, 0), -2147483647L-1, "uncaught overflow %ld != %ld"); + TEST2(i, c-s, 11, "wrong final position %d != %d"); + TEST2(i, errno, ERANGE, "missing errno %d != %d"); + TEST(ul, strtoul(s="4294967296", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu"); + TEST2(i, c-s, 10, "wrong final position %d != %d"); + TEST2(i, errno, ERANGE, "missing errno %d != %d"); + TEST(ul, strtoul(s="-1", &c, 0), -1UL, "rejected negative %lu != %lu"); + TEST2(i, c-s, 2, "wrong final position %d != %d"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, strtoul(s="-2", &c, 0), -2UL, "rejected negative %lu != %lu"); + TEST2(i, c-s, 2, "wrong final position %d != %d"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, strtoul(s="-2147483648", &c, 0), -2147483648UL, "rejected negative %lu != %lu"); + TEST2(i, c-s, 11, "wrong final position %d != %d"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, strtoul(s="-2147483649", &c, 0), -2147483649UL, "rejected negative %lu != %lu"); + TEST2(i, c-s, 11, "wrong final position %d != %d"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + } else { + TEST(i, 0, 1, "64bit tests not implemented"); + } + + TEST(l, strtol("z", 0, 36), 35, "%ld != %ld"); + TEST(l, strtol("00010010001101000101011001111000", 0, 2), 0x12345678, "%ld != %ld"); + TEST(l, strtol(s="0F5F", &c, 16), 0x0f5f, "%ld != %ld"); + + TEST(l, strtol(s="0xz", &c, 16), 0, "%ld != %ld"); + TEST2(i, c-s, 1, "wrong final position %ld != %ld"); + + TEST(l, strtol(s="0x1234", &c, 16), 0x1234, "%ld != %ld"); + TEST2(i, c-s, 6, "wrong final position %ld != %ld"); + + c = NULL; + TEST(l, strtol(s="123", &c, 37), 0, "%ld != %ld"); + TEST2(i, c-s, 0, "wrong final position %d != %d"); + TEST2(i, errno, EINVAL, "%d != %d"); + return test_status; +} diff --git a/src/functional/strtold.c b/src/functional/strtold.c new file mode 100644 index 0000000..e37f7f0 --- /dev/null +++ b/src/functional/strtold.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include "test.h" + +#define length(x) (sizeof(x) / sizeof *(x)) + +static struct { + char *s; + long double f; +} t[] = { + {"0", 0.0}, + {"12.345", 12.345L}, + {"1.2345e1", 12.345L}, + {"1e+1000000", INFINITY}, + {"1e-1000000", 0}, +#if LDBL_MANT_DIG == 53 + // 2^-1074 * 0.5 - eps + {".2470328229206232720882843964341106861825299013071623822127928412503377536351043e-323", 0}, + // 2^-1074 * 0.5 + eps + {".2470328229206232720882843964341106861825299013071623822127928412503377536351044e-323", 0x1p-1074}, + // 2^-1074 * 1.5 - eps + {".7410984687618698162648531893023320585475897039214871466383785237510132609053131e-323", 0x1p-1074}, + // 2^-1074 * 1.5 + eps + {".7410984687618698162648531893023320585475897039214871466383785237510132609053132e-323", 0x1p-1073}, + // 2^-1022 + 2^-1075 - eps + {".2225073858507201630123055637955676152503612414573018013083228724049586647606759e-307", 0x1p-1022}, + // 2^-1022 + 2^-1075 + eps + {".2225073858507201630123055637955676152503612414573018013083228724049586647606760e-307", 0x1.0000000000001p-1022}, + // 2^1024 - 2^970 - eps + {"17976931348623158079372897140530341507993413271003782693617377898044" + "49682927647509466490179775872070963302864166928879109465555478519404" + "02630657488671505820681908902000708383676273854845817711531764475730" + "27006985557136695962284291481986083493647529271907416844436551070434" + "2711559699508093042880177904174497791.999999999999999999999999999999", 0x1.fffffffffffffp1023}, + // 2^1024 - 2^970 + {"17976931348623158079372897140530341507993413271003782693617377898044" + "49682927647509466490179775872070963302864166928879109465555478519404" + "02630657488671505820681908902000708383676273854845817711531764475730" + "27006985557136695962284291481986083493647529271907416844436551070434" + "2711559699508093042880177904174497792", INFINITY}, + // some random numbers + {".5961860348131807091861002266453941950428e00", 0.59618603481318067}, // 0x1.313f4bc3b584cp-1 + {"1.815013169218038729887460898733526957442e-1", 0.18150131692180388}, // 0x1.73b6f662e1712p-3 + {"42.07082357534453600681618685682257590772e-2", 0.42070823575344535}, // 0x1.aece23c6e028dp-2 + {"665.4686306516261456328973225579833470816e-3", 0.66546863065162609}, // 0x1.54b84dea53453p-1 + {"6101.852922970868621786690495485449831753e-4", 0.61018529229708685}, // 0x1.386a34e5d516bp-1 + {"76966.95208236968077849464348875471158549e-5", 0.76966952082369677}, // 0x1.8a121f9954dfap-1 + {"250506.5322228682496132604807222923702304e-6", 0.25050653222286823}, // 0x1.0084c8cd538c2p-2 + {"2740037.230228005325852424697698331177377e-7", 0.27400372302280052}, // 0x1.18946e9575ef4p-2 + {"20723093.50049742645941529268715428324490e-8", 0.20723093500497428}, // 0x1.a868b14486e4dp-3 + {"0.7900280238081604956226011047460238748912e1", 7.9002802380816046}, // 0x1.f99e3100f2eaep+2 + {"0.9822860653737296848190558448760465863597e2", 98.228606537372968}, // 0x1.88ea17d506accp+6 + {"0.7468949723190370809405570560160405324869e3", 746.89497231903704}, // 0x1.75728e73f48b7p+9 + {"0.1630268320282728475980459844271031751665e4", 1630.2683202827284}, // 0x1.97912c28d5cbp+10 + {"0.4637168629719170695109918769645492022088e5", 46371.686297191707}, // 0x1.6a475f6258737p+15 + {"0.6537805944497711554209461686415872067523e6", 653780.59444977110}, // 0x1.3f3a9305bb86cp+19 + {"0.2346324356502437045212230713960457676531e6", 234632.43565024371}, // 0x1.ca4437c3631eap+17 + {"0.9709481716420048341897258980454298205278e8", 97094817.164200485}, // 0x1.7263284a8242cp+26 + {"0.4996908522051874110779982354932499499602e9", 499690852.20518744}, // 0x1.dc8ad6434872ap+28 +#elif LDBL_MANT_DIG == 64 + // 2^-16445 * 0.5 - eps + {".1822599765941237301264202966809709908199525407846781671860490243514185844316698e-4950", 0}, + // 2^-16445 * 0.5 + eps + {".1822599765941237301264202966809709908199525407846781671860490243514185844316699e-4950", 0x1p-16445L}, + // 2^-16445 * 1.5 - eps + {".5467799297823711903792608900429129724598576223540345015581470730542557532950096e-4950", 0x1p-16445L}, + // 2^-16445 * 1.5 + eps + {".5467799297823711903792608900429129724598576223540345015581470730542557532950097e-4950", 0x1p-16444L}, + // 2^-16382 + 2^-16446 - eps + {".3362103143112093506444937793915876332724499641527442230928779770593420866576777e-4931", 0x1p-16382L}, + // 2^-16382 + 2^-16446 + eps + {".3362103143112093506444937793915876332724499641527442230928779770593420866576778e-4931", 0x1.0000000000000002p-16382L}, + // 2^16384 - 2^16319 - eps + {"118973149535723176505351158982948.86679662540046955672e4900", 0x1.fffffffffffffffep16383L}, + // 2^16384 - 2^16319 + eps + {"118973149535723176505351158982948.86679662540046955673e4900", INFINITY}, +#endif +}; + +int main(void) +{ + int i; + long double x; + char *p; + + for (i = 0; i < length(t); i++) { + x = strtold(t[i].s, &p); + if (x != t[i].f) + error("strtold(\"%s\") want %La got %La\n", t[i].s, t[i].f, x); + } + return test_status; +} diff --git a/src/functional/swprintf.c b/src/functional/swprintf.c new file mode 100644 index 0000000..10a8380 --- /dev/null +++ b/src/functional/swprintf.c @@ -0,0 +1,151 @@ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include "test.h" + +#define TEST(r, f, x, m) ( \ + ((r) = (f)) == (x) || \ + (error("%s failed (" m ")\n", #f, r, x), 0) ) + +#define TEST_S(s, x, m) ( \ + !wcscmp((s),(x)) || \ + (error("[%ls] != [%ls] (%s)\n", s, x, m), 0) ) + +static const struct { + const wchar_t *fmt; + int i; + const wchar_t *expect; +} int_tests[] = { + /* width, precision, alignment */ + { L"%04d", 12, L"0012" }, + { L"%.3d", 12, L"012" }, + { L"%3d", 12, L" 12" }, + { L"%-3d", 12, L"12 " }, + { L"%+3d", 12, L"+12" }, + { L"%+-5d", 12, L"+12 " }, + { L"%+- 5d", 12, L"+12 " }, + { L"%- 5d", 12, L" 12 " }, + { L"% d", 12, L" 12" }, + { L"%0-5d", 12, L"12 " }, + { L"%-05d", 12, L"12 " }, + + /* ...explicit precision of 0 shall be no characters. */ + { L"%.0d", 0, L"" }, + { L"%.0o", 0, L"" }, + { L"%#.0d", 0, L"" }, + { L"%#.0o", 0, L"" }, + { L"%#.0x", 0, L"" }, + + /* hex: test alt form and case */ + { L"%x", 63, L"3f" }, + { L"%#x", 63, L"0x3f" }, + { L"%X", 63, L"3F" }, + + /* octal: test alt form */ + { L"%o", 15, L"17" }, + { L"%#o", 15, L"017" }, + + { NULL, 0.0, NULL } +}; + +static const struct { + const wchar_t *fmt; + double f; + const wchar_t *expect; +} fp_tests[] = { + /* basic form, handling of exponent/precision for 0 */ + { L"%e", 0.0, L"0.000000e+00" }, + { L"%f", 0.0, L"0.000000" }, + { L"%g", 0.0, L"0" }, + { L"%#g", 0.0, L"0.00000" }, + + /* rounding */ + { L"%f", 1.1, L"1.100000" }, + { L"%f", 1.2, L"1.200000" }, + { L"%f", 1.3, L"1.300000" }, + { L"%f", 1.4, L"1.400000" }, + { L"%f", 1.5, L"1.500000" }, + + /* correctness in DBL_DIG places */ + { L"%.15g", 1.23456789012345, L"1.23456789012345" }, + + /* correct choice of notation for %g */ + { L"%g", 0.0001, L"0.0001" }, + { L"%g", 0.00001, L"1e-05" }, + { L"%g", 123456, L"123456" }, + { L"%g", 1234567, L"1.23457e+06" }, + { L"%.7g", 1234567, L"1234567" }, + { L"%.7g", 12345678, L"1.234568e+07" }, + + /* pi in double precision, printed to a few extra places */ + { L"%.15f", M_PI, L"3.141592653589793" }, + { L"%.18f", M_PI, L"3.141592653589793116" }, + + /* exact conversion of large integers */ + { L"%.0f", 340282366920938463463374607431768211456.0, + L"340282366920938463463374607431768211456" }, + + { NULL, 0.0, NULL } +}; + +int main(void) +{ + int i, j; + wchar_t b[500]; + + (void)( + setlocale(LC_CTYPE, "en_US.UTF-8") || + setlocale(LC_CTYPE, "en_GB.UTF-8") || + setlocale(LC_CTYPE, "en.UTF-8") || + setlocale(LC_CTYPE, "POSIX.UTF-8") || + setlocale(LC_CTYPE, "C.UTF-8") || + setlocale(LC_CTYPE, "UTF-8") || + setlocale(LC_CTYPE, "") ); + + TEST(i, strcmp(nl_langinfo(CODESET), "UTF-8"), 0, "no UTF-8 locale; tests might fail"); + + TEST(i, swprintf(0, 0, L"%d", 123456)<0, 1, "%d != %d"); + + TEST(i, swprintf(b, 2, L"%lc", 0xc0), 1, "%d != %d"); + TEST(i, b[0], 0xc0, "wrong character %x != %x"); + TEST(i, swprintf(b, 2, L"%lc", 0x20ac), 1, "%d != %d"); + TEST(i, b[0], 0x20ac, "wrong character %x != %x"); + TEST(i, swprintf(b, 3, L"%s", "\xc3\x80!"), 2, "%d != %d"); + TEST(i, b[0], 0xc0, "wrong character %x != %x"); + TEST(i, swprintf(b, 2, L"%.1s", "\xc3\x80!"), 1, "%d != %d"); + TEST(i, b[0], 0xc0, "wrong character %x != %x"); + + wcscpy(b, L"xxxxxxxx"); + TEST(i, swprintf(b, 4, L"%d", 123456)<0, 1, "%d != %d"); + TEST_S(b, L"123", "incorrect output"); + TEST(i, b[5], 'x', "buffer overrun"); + + for (j=0; int_tests[j].fmt; j++) { + i = swprintf(b, sizeof b, int_tests[j].fmt, int_tests[j].i); + if (i != wcslen(int_tests[j].expect)) { + error("swprintf(b, sizeof b, \"%ls\", %d) returned %d wanted %d\n", + int_tests[j].fmt, int_tests[j].i, i, wcslen(int_tests[j].expect)); + } + if (wcscmp(b, int_tests[j].expect) != 0) + error("bad integer conversion: got \"%ls\", want \"%ls\"\n", b, int_tests[j].expect); + } + + for (j=0; fp_tests[j].fmt; j++) { + i = swprintf(b, sizeof b, fp_tests[j].fmt, fp_tests[j].f); + if (i != wcslen(fp_tests[j].expect)) { + error("swprintf(b, sizeof b, \"%ls\", %f) returned %d wanted %d\n", + fp_tests[j].fmt, fp_tests[j].f, i, wcslen(fp_tests[j].expect)); + } + if (wcscmp(b, fp_tests[j].expect) != 0) + error("bad floating-point conversion: got \"%ls\", want \"%ls\"\n", b, fp_tests[j].expect); + } + return test_status; +} diff --git a/src/functional/test.h b/src/functional/test.h new file mode 100644 index 0000000..a17c185 --- /dev/null +++ b/src/functional/test.h @@ -0,0 +1,21 @@ +#include +#include +#define error(...) test_error(__FILE__, __LINE__, __VA_ARGS__) + +/* TODO: not thread-safe nor fork-safe */ +static int test_status; + +static int test_error(const char *n, int l, const char *s, ...) +{ + va_list ap; + + if (test_status == 0) + printf("FAIL\n"); + test_status = 1; + printf(" ERROR %s:%d: ", n, l); + va_start(ap, s); + vprintf(s, ap); + va_end(ap); + return -1; +} + diff --git a/src/functional/tgmath.c b/src/functional/tgmath.c new file mode 100644 index 0000000..8cc2c3e --- /dev/null +++ b/src/functional/tgmath.c @@ -0,0 +1,39 @@ +#include +#include "test.h" + +int main(void) +{ + long i; + + i = lrint(123456789.1f) & 0x7fffffff; + if (i != 123456792) + error("lrint(123456789.1f)&0x7fffffff want 123456792 got %ld\n", i); + i = lrint(123456789.1) & 0x7fffffff; + if (i != 123456789) + error("lrint(123456789.1)&0x7fffffff want 123456789 got %ld\n", i); + + if (sqrt(2.0f) != 1.41421353816986083984375) + error("sqrt(2.0f) want 0x1.6a09e6p+0 got %a\n", sqrt(2.0f)); + if (sqrt(2.0) != 1.414213562373095145474621858738828450441360) + error("sqrt(2.0) want 0x1.6a09e667f3bcdp+0 got %a\n", sqrt(2.0)); + if (sqrt(2) != 1.414213562373095145474621858738828450441360) + error("sqrt(2) want 0x1.6a09e667f3bcdp+0 got %a\n", sqrt(2.0)); + + if (sizeof pow(sqrt(8),0.5f) != sizeof(double)) + error("sizeof pow(sqrt(8),0.5f) want %d got %d\n", (int)sizeof(double), (int)sizeof pow(sqrt(8),0.5f)); + if (sizeof pow(2.0,0.5) != sizeof(double)) + error("sizeof pow(2.0,0.5) want %d got %d\n", (int)sizeof(double), (int)sizeof pow(2.0,0.5)); + if (sizeof pow(2.0f,0.5f) != sizeof(float)) + error("sizeof pow(2.0f,0.5f) want %d got %d\n", (int)sizeof(float), (int)sizeof pow(2.0f,0.5f)); + if (sizeof pow(2.0,0.5+0*I) != sizeof(double complex)) + error("sizeof pow(2.0,0.5+0*I) want %d got %d\n", (int)sizeof(double complex), (int)sizeof pow(2.0,0.5+0*I)); + + if (pow(2.0,0.5) != 1.414213562373095145474621858738828450441360) + error("pow(2.0,0.5) want 0x1.6a09e667f3bcdp+0 got %a\n", pow(2.0,0.5)); + if (pow(2,0.5) != 1.414213562373095145474621858738828450441360) + error("pow(2,0.5) want 0x1.6a09e667f3bcdp+0 got %a\n", pow(2,0.5)); + if (pow(2,0.5f) != 1.414213562373095145474621858738828450441360) + error("pow(2,0.5f) want 0x1.6a09e667f3bcdp+0 got %a\n", pow(2,0.5f)); + + return test_status; +} diff --git a/src/functional/time.c b/src/functional/time.c new file mode 100644 index 0000000..27598b8 --- /dev/null +++ b/src/functional/time.c @@ -0,0 +1,76 @@ +#define _XOPEN_SOURCE 700 +#include +#include +#include +#include "test.h" + +/* We use this instead of memcmp because some broken C libraries + * add additional nonstandard fields to struct tm... */ + +int tm_cmp(struct tm tm1, struct tm tm2) +{ + return tm1.tm_sec != tm2.tm_sec || + tm1.tm_min != tm2.tm_min || + tm1.tm_hour != tm2.tm_hour || + tm1.tm_mday != tm2.tm_mday || + tm1.tm_mon != tm2.tm_mon || + tm1.tm_year != tm2.tm_year || + tm1.tm_wday != tm2.tm_wday || + tm1.tm_yday != tm2.tm_yday || + tm1.tm_isdst!= tm2.tm_isdst; +} + +char *tm_str(struct tm tm) +{ + static int i; + static char b[4][64]; + i = (i+1)%4; + snprintf(b[i], sizeof b[i], + "s=%02d m=%02d h=%02d mday=%02d mon=%02d year=%04d wday=%d yday=%d isdst=%d", + tm.tm_sec, tm.tm_min, tm.tm_hour, + tm.tm_mday, tm.tm_mon, tm.tm_year, + tm.tm_wday, tm.tm_yday, tm.tm_isdst); + return b[i]; +} + +#define TM(ss,mm,hh,md,mo,yr,wd,yd,dst) (struct tm){ \ + .tm_sec = ss, .tm_min = mm, .tm_hour = hh, \ + .tm_mday = md, .tm_mon = mo, .tm_year = yr, \ + .tm_wday = wd, .tm_yday = yd, .tm_isdst = dst } + +#define TM_EPOCH TM(0,0,0,1,0,70,4,0,0) +#define TM_Y2038_1S TM(7,14,3,19,0,138,2,18,0) +#define TM_Y2038 TM(8,14,3,19,0,138,2,18,0) + +#define TEST_TM(r,x,m) (!tm_cmp((r),(x)) || \ + (error("%s failed:\n\tresult: %s\n\texpect: %s\n", \ + m, tm_str(r), tm_str(x)), 0) ) + +#define TEST(r, f, x, m) ( \ + ((r) = (f)) == (x) || \ + (error("%s failed (" m ")\n", #f, r, x), 0) ) + +int main(void) +{ + struct tm tm, *tm_p; + time_t t; + + putenv("TZ=GMT"); + tzset(); + + t=0; tm_p = gmtime(&t); + TEST_TM(*tm_p, TM_EPOCH, "gmtime(0)"); + + tm = TM_Y2038_1S; + t = mktime(&tm); + tm = *(gmtime(&t)); + TEST_TM(*tm_p, TM_Y2038_1S, "mktime/gmtime(Y2038-1)"); + + tm = TM_Y2038; + t = mktime(&tm); + tm = *(gmtime(&t)); + TEST_TM(*tm_p, TM_Y2038, "mktime/gmtime(Y2038)"); + + /* FIXME: set a TZ var and check DST boundary conditions */ + return test_status; +} diff --git a/src/functional/tls_align.c b/src/functional/tls_align.c new file mode 100644 index 0000000..505abf2 --- /dev/null +++ b/src/functional/tls_align.c @@ -0,0 +1,22 @@ +#include "test.h" + +extern struct { + char *name; + unsigned size; + unsigned align; + unsigned long addr; +} t[4]; + +int main() +{ + int i; + + for (i = 0; i < sizeof t/sizeof *t; i++) { + if (!t[i].name) + error("name is not set for t[%d]\n", i); + if (t[i].addr & (t[i].align-1)) + error("bad alignment: %s, size: %u, align: %u, addr: 0x%lx\n", + t[i].name, t[i].size, t[i].align, t[i].addr); + } + return test_status; +} diff --git a/src/functional/tls_align_dlopen.c b/src/functional/tls_align_dlopen.c new file mode 100644 index 0000000..64517e1 --- /dev/null +++ b/src/functional/tls_align_dlopen.c @@ -0,0 +1,30 @@ +#include +#include "test.h" + +int main() +{ + int i; + void *h; + struct { + char *name; + unsigned size; + unsigned align; + unsigned long addr; + } *t; + + h = dlopen("./tls_align_dso.so", RTLD_LAZY); + if (!h) + error("dlopen failed\n"); + t = dlsym(h, "t"); + if (!t) + error("dlsym failed\n"); + + for (i = 0; i < 4; i++) { + if (!t[i].name) + error("name is not set for t[%d]\n", i); + if (t[i].addr & (t[i].align-1)) + error("bad alignment: %s, size: %u, align: %u, addr: 0x%lx\n", + t[i].name, t[i].size, t[i].align, t[i].addr); + } + return test_status; +} diff --git a/src/functional/tls_align_dso.c b/src/functional/tls_align_dso.c new file mode 100644 index 0000000..9ca759e --- /dev/null +++ b/src/functional/tls_align_dso.c @@ -0,0 +1,30 @@ +__thread char c1 = 1; +__thread char xchar = 2; +__thread char c2 = 3; +__thread short xshort = 4; +__thread char c3 = 5; +__thread int xint = 6; +__thread char c4 = 7; +__thread long long xllong = 8; + +struct { + char *name; + unsigned size; + unsigned align; + unsigned long addr; +} t[4]; + +#define entry(i,x) \ + t[i].name = #x; \ + t[i].size = sizeof x; \ + t[i].align = __alignof__(x); \ + t[i].addr = (unsigned long)&x; + +__attribute__((constructor)) static void init(void) +{ + entry(0, xchar) + entry(1, xshort) + entry(2, xint) + entry(3, xllong) +} + diff --git a/src/functional/tls_init.c b/src/functional/tls_init.c new file mode 100644 index 0000000..8a43829 --- /dev/null +++ b/src/functional/tls_init.c @@ -0,0 +1,42 @@ +#include +#include "test.h" + +__thread int tls_fix = 23; +__thread int tls_zero; + +static void *f(void *arg) +{ + if (tls_fix != 23) + error("fixed init failed: want 23 got %d\n", tls_fix); + if (tls_zero != 0) + error("zero init failed: want 0 got %d\n", tls_zero); + tls_fix++; + tls_zero++; + return 0; +} + +#define CHECK(f) do{ if(f) error("%s failed.\n", #f); }while(0) +#define length(a) (sizeof(a)/sizeof*(a)) + +int main() +{ + pthread_t t[5]; + int i, j; + + if (tls_fix != 23) + error("fixed init failed: want 23 got %d\n", tls_fix); + if (tls_zero != 0) + error("zero init failed: want 0 got %d\n", tls_zero); + + for (j = 0; j < 2; j++) { + for (i = 0; i < length(t); i++) { + CHECK(pthread_create(t+i, 0, f, 0)); + tls_fix++; + tls_zero++; + } + for (i = 0; i < length(t); i++) + CHECK(pthread_join(t[i], 0)); + } + + return test_status; +} diff --git a/src/functional/udiv.c b/src/functional/udiv.c new file mode 100644 index 0000000..e5b6d2c --- /dev/null +++ b/src/functional/udiv.c @@ -0,0 +1,168 @@ +#include "test.h" +#include + +/* +static uint64_t randstate = 0x123456789abcdef0ull; +static uint64_t rnd(void) { + randstate = 6364136223846793005ull*randstate + 1; + return randstate; +} +void test_maketest() +{ + int i; + uint64_t x,y; + for (i = 0; i < 128; i++) { + x = rnd(); + y = rnd()>>(i/2); + if (!y) + continue; + printf("0x%llxull, 0x%llxull, 0x%llxull, 0x%llxull,\n", x, y, x/y, x%y); + } +} +*/ + +static struct { + uint64_t x, y, div, mod; +} t[] = { +0x8ddb1a43e77c4031ull, 0x5950e8c33d34979eull, 0x1ull, 0x348a3180aa47a893ull, +0x723f4114006c08c7ull, 0x817de530db2b43fcull, 0x0ull, 0x723f4114006c08c7ull, +0x47811fa5f00f74dull, 0x3d98e7d3fcd5d5c5ull, 0x0ull, 0x47811fa5f00f74dull, +0x51ffcc7cdc989d43ull, 0x36be8bd6746b70e4ull, 0x1ull, 0x1b4140a6682d2c5full, +0x57bf9128512fe829ull, 0x197b3858155d498dull, 0x3ull, 0xb4de82011180b82ull, +0x89fc1c5968fa817full, 0xdcea797734c7115ull, 0x9ull, 0xdb838065b4a87c2ull, +0x4ed5264cf7092ec5ull, 0xde40d1e15ef3e74ull, 0x5ull, 0x960e4b6895cf681ull, +0xffd86b253d97317bull, 0x13f9ff2d24b6d6f4ull, 0xcull, 0x1020750785051e0bull, +0x8771fa2da656a721ull, 0x9210fe654c59bfcull, 0xeull, 0x7a31b9503881f59ull, +0xb5961d12bcd3e937ull, 0xbdb5a33662f547aull, 0xfull, 0x3bbd40fc00df611ull, +0x93c79eecdac7ed3dull, 0x6f267c57ea2b7b5ull, 0x15ull, 0x1e51bb9776edb64ull, +0x6b93ffce49f1a4b3ull, 0x3583d1f9702ee03ull, 0x20ull, 0x8c5bdb6993e453ull, +0x138aefcc98ce5d19ull, 0x117002fa7600b11ull, 0x11ull, 0x103eca27b6da0f8ull, +0xb3da641cef491fefull, 0x357615f638334b8ull, 0x35ull, 0x2c33b5d551f35d7ull, +0x71c4b06e463912b5ull, 0x1c286ad9e8f5229ull, 0x40ull, 0x1230506a2648875ull, +0x97d4cf7df046d6ebull, 0x1e9412f5c77b2b8ull, 0x4full, 0xd9b1e06756b023ull, +0x1428f04bd490ea11ull, 0x9d97f29a897c93ull, 0x20ull, 0x75f1f8836157b1ull, +0x35256c76832705a7ull, 0xa962f1a447dcd7ull, 0x50ull, 0x3680f32cb20277ull, +0x2969e82bd9347f2dull, 0x723d68574d4156ull, 0x5cull, 0x5bd6ac79710445ull, +0x9061a12aae71a823ull, 0x4186d8a1a66175ull, 0x234ull, 0x48be68be2f25full, +0x695b8d33ef342e09ull, 0x3ed1fe1a998fe3ull, 0x1adull, 0x15a6615bde0ea2ull, +0x46b4dd1e06367a5full, 0xa04e70622e4e8ull, 0x70eull, 0x64750bc0b9dafull, +0xd68b05ba7eee12a5ull, 0x72ab3fb682444ull, 0x1defull, 0x3c437fc988329ull, +0x1e59cc2ac508f85bull, 0xeb15ae6d4d7f9ull, 0x210ull, 0xc00aeae0b86cbull, +0x296f8d2c76a0901ull, 0xf65628b31b01ull, 0x2b0ull, 0xf14566117651ull, +0x7036f5ad7cbc5e17ull, 0xa09d3bfcf72cfull, 0xb2dull, 0x72236db564ab4ull, +0x915d6883c575ad1dull, 0x3a38d68d3a38eull, 0x27f2ull, 0x241de6f7a6ee1ull, +0x845ba74f5adfa793ull, 0x2f6950e58d00bull, 0x2caaull, 0x249dc90239c45ull, +0xb910d16c54805af9ull, 0x1fc2ca5c99a7aull, 0x5d3aull, 0x1771487b50955ull, +0x27a2e280bcf990cfull, 0x389aa0c0b0cc0ull, 0xb34ull, 0x9d71d12eb9cfull, +0x1e032f04a5372e95ull, 0x63c2a1d58710ull, 0x4d04ull, 0x154ce4414255ull, +0x3a1a5659908495cbull, 0x279dcd85418aull, 0x17775ull, 0x132c6f9c7bb9ull, +0xd769a376e5e103f1ull, 0xadacb670e0c7ull, 0x13d85ull, 0x8ad256e5d18eull, +0x269f4f4baaaf287ull, 0x1aed2ad9daf0ull, 0x16f3ull, 0x426550f80b7ull, +0x6700daeeb87a770dull, 0xeca7ab1aa93ull, 0x6f6c5ull, 0x70d9466f1eeull, +0xd0201f3783c2a303ull, 0x3a0c01aa3e6aull, 0x395e1ull, 0x18b33b9015d9ull, +0xca3f2e00d291e3e9ull, 0xbe0e048cd94ull, 0x1106c2ull, 0x37f7fc0a1c1ull, +0xec4d240dc289633full, 0x4f8aadb7483ull, 0x2f8855ull, 0x46e0db91bc0ull, +0xd7967b29e2e36685ull, 0xe61d902db27ull, 0xefd69ull, 0x36811fff886ull, +0xe3ecd4374320af3bull, 0x4edd0edd0a0ull, 0x2e3defull, 0x4ad0da4c9dbull, +0x7a08fe1d98b4dae1ull, 0x6bced9c0c15ull, 0x121c89ull, 0x40c856617a4ull, +0x34435992a5c9c2f7ull, 0x4f4a94c109full, 0xa8bc9ull, 0x94c5d46120ull, +0x6fd0027468f1dcfdull, 0x597186b0153ull, 0x140060ull, 0x16f26555dddull, +0x4fe37c1db1619a73ull, 0x47a0c30bd15ull, 0x11d861ull, 0x5964fb3d7eull, +0x77aa77f86d07c8d9ull, 0x3a39cf03d65ull, 0x20e21cull, 0x37f7fede7cdull, +0xc072e76ad59cf1afull, 0x3a786701dull, 0x34a98c59ull, 0x22b6b1b9aull, +0xfb8e8f1f7781ba75ull, 0xe8ca427d3eull, 0x114a34dull, 0xa344eb94cfull, +0x160e34cf590444abull, 0xe2388f12feull, 0x18f574ull, 0xc303329393ull, +0x2509ddea3a648dd1ull, 0xec762d81bcull, 0x281955ull, 0xc0463d1e65ull, +0xc9ba10cd6eafcf67ull, 0x96a51d06f7ull, 0x156ce72ull, 0x133e2df369ull, +0x1dd4fe261b4adeedull, 0x2736e25406ull, 0xc2bfefull, 0x1354c1f353ull, +0x480258f92fc38de3ull, 0x2599b52bb0ull, 0x1ea450cull, 0x2879f11a3ull, +0x5a3257b1114109c9ull, 0x2978f9f1aaull, 0x22cc30aull, 0x1317311b25ull, +0xf4eeda8f34ab3c1full, 0x1aa70450d9ull, 0x9309d64ull, 0x1187b6925bull, +0x3c2c319ca8612a65ull, 0x73fc01eceull, 0x84d0088ull, 0x3165accf5ull, +0x4f6034e74a16561bull, 0x1f29d53707ull, 0x28c0daaull, 0xd88e07075ull, +0x206665a7072f1cc1ull, 0xda87e7ceaull, 0x25f48c1ull, 0xd3ddb2057ull, +0x100c559d7db417d7ull, 0xb907ebbc2ull, 0x1634188ull, 0xa2eae16c7ull, +0x64c5f83691b47cddull, 0x5aced6ebbull, 0x11c17fb7ull, 0x344109030ull, +0x32a812777eaf7d53ull, 0x1cb63fe4full, 0x1c3a9675ull, 0xb113f938ull, +0x67478d96865ca6b9ull, 0x142fa03aull, 0x51dcb463dull, 0x11359ce7ull, +0x71024e740deb428full, 0x142d3885ull, 0x599d9edd5ull, 0x13b1ae6ull, +0x52c78160b090b655ull, 0xd02101c6ull, 0x65d1b205ull, 0x1c0a0177ull, +0x16917d5f9fde38bull, 0xfb1566c7ull, 0x17029e0ull, 0x1bbe166bull, +0xa6ee688a0d1387b1ull, 0x22c4d384ull, 0x4cd19afcfull, 0x77143f5ull, +0x74babc1be2ed9c47ull, 0x22eda9a6ull, 0x3578b1967ull, 0x189b247dull, +0x7c5cbf2dfc1db6cdull, 0x5f09c060ull, 0x14efd44d4ull, 0x5210e74dull, +0x7c046071c1ac68c3ull, 0x3696c8e6ull, 0x24596d86bull, 0x26060a1ull, +0x84728ab55d399fa9ull, 0x267d7771ull, 0x370ea7405ull, 0x255d1674ull, +0x99f57100ef5404ffull, 0x10c0df86ull, 0x9308fef0dull, 0x9009131ull, +0x3f4c0514b0df5e45ull, 0xf2c3810ull, 0x42bf84d39ull, 0x3aa12b5ull, +0xd01edb572821ecfbull, 0x2a443aeull, 0x4ec8b88639ull, 0x111c73dull, +0xeecb08561bd0cea1ull, 0xbeca231ull, 0x140692508bull, 0x9b36e06ull, +0x8c856facc6335cb7ull, 0x398eab4ull, 0x271008c7a5ull, 0x922ab3ull, +0x23fb9839e8358cbdull, 0x24deb54ull, 0xf9d714151ull, 0xb9c329ull, +0x2005d5de30015033ull, 0x47c06dbull, 0x7240bccbaull, 0x104d115ull, +0x67d59c29e076f499ull, 0x179f009ull, 0x465554ac22ull, 0x10b0767ull, +0x32d2dd34369c836full, 0x13d3fbfull, 0x2902f2fb54ull, 0x7553c3ull, +0x3960c3c99fdc2235ull, 0x1b808baull, 0x21618743cdull, 0x11e7743ull, +0x343bad5adfa9726bull, 0xeef444ull, 0x37f58c51a6ull, 0x3d8a53ull, +0x7a4aadd7b4e5f191ull, 0x129c9ull, 0x6921bb5a2a53ull, 0x6b66ull, +0x9eb7dae5d71c5927ull, 0x31d7f5ull, 0x32f2ff2c6d5ull, 0x22c4eull, +0x1b285999316afeadull, 0x115477ull, 0x1912cf6611eull, 0x801bbull, +0x917aee3d84b533a3ull, 0x71d26full, 0x1473408589aull, 0x6e74ddull, +0x18e6a86b0473a589ull, 0x50a12ull, 0x4f0fabc67d4ull, 0x210a1ull, +0xf22c9887813bbddfull, 0x5b17aull, 0x2a897505c07bull, 0x1f841ull, +0xef7a551239d60225ull, 0x7fb5aull, 0x1e00b98e188bull, 0x41847ull, +0xffd2ad0e77b73dbull, 0x146f14ull, 0xc8500600a3ull, 0xba1full, +0x76743abdfb91f081ull, 0xd5888ull, 0x8e0303c479cull, 0x245a1ull, +0xc2eeb030bcff9197ull, 0x7a4e8ull, 0x198034e02c37ull, 0x343bfull, +0x63cc9c23f0ed0c9dull, 0x6c1e5ull, 0xec4d5841041ull, 0x38178ull, +0x7ad70f846e8f1313ull, 0x7fdf5ull, 0xf5ecec69bc9ull, 0x756b6ull, +0x60de3d71574eb279ull, 0x6ea3ull, 0xe02421997a61ull, 0x18b6ull, +0xd27054901c68b44full, 0x2dd0full, 0x497d639c8f46ull, 0xe135ull, +0xbcf297b8f0dbfe15ull, 0xcf17ull, 0xe992af0ca1abull, 0x32b8ull, +0x96c3ae70323ef14bull, 0xbbdcull, 0xcd7329b68d81ull, 0x1b6full, +0xdc1a13cfa4d3cb71ull, 0xdb16ull, 0x1012fe5ed296full, 0x46e7ull, +0xa1d40a2986f40607ull, 0x8067ull, 0x142a473fdb7beull, 0x1895ull, +0x227f92ef6daab68dull, 0x15ecull, 0x192dda5d5ed25ull, 0xf71ull, +0xc0a4a7810015ee83ull, 0x6064ull, 0x1ffa220762fc8ull, 0x4463ull, +0xd38b6eb9f0e71b69ull, 0x1909ull, 0x8732ce2cc77f4ull, 0xfd5ull, +0x2e588bdb751a66bfull, 0x229cull, 0x156d025c70d97ull, 0x10bbull, +0xd90f7e11dcbd1605ull, 0x760ull, 0x1d6e934381ba2eull, 0x2c5ull, +0x60ab67a4e5aeabbull, 0x1bf7ull, 0x374f26f3e3edull, 0x210ull, +0x224f627be76a8261ull, 0x4f4ull, 0x6ed4d3882b567ull, 0x35ull, +0x300d1ab91bd0b677ull, 0xe9cull, 0x34a002fb76e63ull, 0x823ull, +0x2a63d80e0c52fc7dull, 0x32ull, 0xd90970ebc4383full, 0x2full, +0xb0e94bbc1f90c5f3ull, 0x3b3ull, 0x2fd2ef70381c52ull, 0x29dull, +0x2b5dc22562dbe059ull, 0x30aull, 0xe45055015fff5ull, 0x1c7ull, +0x4a7fd1078807d52full, 0x18dull, 0x300a32f60677d4ull, 0x16bull, +0x41a01ee8ab0849f5ull, 0x13cull, 0x352a3971f57e9dull, 0x29ull, +0x95a7287ad5f6602bull, 0x1d0ull, 0x529130d1034a23ull, 0xbbull, +0x723bacc76bd51551ull, 0x16ull, 0x53142091089af83ull, 0xfull, +0x81c49febaa2ca2e7ull, 0xcdull, 0xa20d44956f5bf4ull, 0x83ull, +0x11593d6b3f54de6dull, 0x63ull, 0x2cdc6b1a7f9078ull, 0x5ull, +0x756c82d6f7069963ull, 0x5cull, 0x146bea3ba565525ull, 0x17ull, +0xda882ab2a88c0149ull, 0x1bull, 0x8180194d6d5c728ull, 0x11ull, +0xbb03671751a7ff9full, 0x20ull, 0x5d81b38ba8d3ffcull, 0x1full, +0x6884fa0a8f0c99e5ull, 0x12ull, 0x5ce7fab40d6088cull, 0xdull, +0x5052a2953c528441ull, 0x7ull, 0xb7984f0bf79809bull, 0x4ull, +0x58dd1583185ecb57ull, 0x9ull, 0x9dfad0e90ee1697ull, 0x8ull, +0xaa6870c376df5c5dull, 0x3ull, 0x38cd7aebd24a741full, 0x0ull, +0x4b21d01617167e39ull, 0x2ull, 0x2590e80b0b8b3f1cull, 0x1ull, +}; + +int main(void) +{ + uint64_t x, y, div, mod; + int i; + + for (i = 0; i < sizeof t/sizeof *t; i++) { + x = t[i].x; + y = t[i].y; + div = x / y; + mod = x % y; + if (div != t[i].div) + error("udiv %llu/%llu want %llu got %llu\n", x, y, t[i].div, div); + if (mod != t[i].mod) + error("umod %llu%%%llu want %llu got %llu\n", x, y, t[i].mod, mod); + } + return test_status; +} diff --git a/src/functional/ungetc.c b/src/functional/ungetc.c new file mode 100644 index 0000000..9003a1c --- /dev/null +++ b/src/functional/ungetc.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include +#include "test.h" + +#define TEST(r, f, x, m) ( \ + errno = 0, ((r) = (f)) == (x) || \ + (error("%s failed (" m ")\n", #f, r, x, strerror(errno)), 0) ) + +#define TEST_S(s, x, m) ( \ + !strcmp((s),(x)) || \ + (error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +int main(void) +{ + int i; + char a[100]; + FILE *f; + + TEST(i, !(f = tmpfile()), 0, "failed to create temp file %d!=%d (%s)"); + + if (!f) return test_status; + + TEST(i, fprintf(f, "hello, world\n"), 13, "%d != %d (%m)"); + TEST(i, fseek(f, 0, SEEK_SET), 0, "%d != %d (%m)"); + + TEST(i, feof(f), 0, "%d != %d"); + TEST(i, fgetc(f), 'h', "'%c' != '%c'"); + TEST(i, ftell(f), 1, "%d != %d"); + TEST(i, ungetc('x', f), 'x', "%d != %d"); + TEST(i, ftell(f), 0, "%d != %d"); + TEST(i, fscanf(f, "%[h]", a), 0, "got %d fields, expected %d"); + TEST(i, ftell(f), 0, "%d != %d"); + TEST(i, fgetc(f), 'x', "'%c' != '%c'"); + TEST(i, ftell(f), 1, "%d != %d"); + + TEST(i, fseek(f, 0, SEEK_SET), 0, "%d != %d"); + TEST(i, ungetc('x', f), 'x', "%d != %d"); + TEST(i, fread(a, 1, sizeof a, f), 14, "read %d, expected %d"); + a[14] = 0; + TEST_S(a, "xhello, world\n", "mismatch reading ungot character"); + + TEST(i, fseek(f, 0, SEEK_SET), 0, "%d != %d"); + TEST(i, fscanf(f, "%[x]", a), 0, "got %d fields, expected %d"); + TEST(i, ungetc('x', f), 'x', "unget failed after fscanf: %d != %d"); + TEST(i, fgetc(f), 'x', "'%c' != '%c'"); + TEST(i, fgetc(f), 'h', "'%c' != '%c'"); + + fclose(f); + return test_status; +} diff --git a/src/functional/wcstol.c b/src/functional/wcstol.c new file mode 100644 index 0000000..abd76af --- /dev/null +++ b/src/functional/wcstol.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +#include "test.h" + +#define TEST(r, f, x, m) ( \ + errno = 0, msg = #f, ((r) = (f)) == (x) || \ + (error("%s failed (" m ")\n", #f, r, x), 0) ) + +#define TEST2(r, f, x, m) ( \ + ((r) = (f)) == (x) || \ + (error("%s failed (" m ")\n", msg, r, x), 0) ) + +int main(void) +{ + int i; + long l; + unsigned long ul; + char *msg=""; + wchar_t *s, *c; + + TEST(l, wcstol(L"2147483647", 0, 0), 2147483647L, "max 32bit signed %ld != %ld"); + TEST(ul, wcstoul(L"4294967295", 0, 0), 4294967295UL, "max 32bit unsigned %lu != %lu"); + + if (sizeof(long) == 4) { + TEST(l, wcstol(s=L"2147483648", &c, 0), 2147483647L, "uncaught overflow %ld != %ld"); + TEST2(i, c-s, 10, "wrong final position %d != %d"); + TEST2(i, errno, ERANGE, "missing errno %d != %d"); + TEST(l, wcstol(s=L"-2147483649", &c, 0), -2147483647L-1, "uncaught overflow %ld != %ld"); + TEST2(i, c-s, 11, "wrong final position %d != %d"); + TEST2(i, errno, ERANGE, "missing errno %d != %d"); + TEST(ul, wcstoul(s=L"4294967296", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu"); + TEST2(i, c-s, 10, "wrong final position %d != %d"); + TEST2(i, errno, ERANGE, "missing errno %d != %d"); + TEST(ul, wcstoul(s=L"-1", &c, 0), -1UL, "rejected negative %lu != %lu"); + TEST2(i, c-s, 2, "wrong final position %d != %d"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, wcstoul(s=L"-2", &c, 0), -2UL, "rejected negative %lu != %lu"); + TEST2(i, c-s, 2, "wrong final position %d != %d"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, wcstoul(s=L"-2147483648", &c, 0), -2147483648UL, "rejected negative %lu != %lu"); + TEST2(i, c-s, 11, "wrong final position %d != %d"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + TEST(ul, wcstoul(s=L"-2147483649", &c, 0), -2147483649UL, "rejected negative %lu != %lu"); + TEST2(i, c-s, 11, "wrong final position %d != %d"); + TEST2(i, errno, 0, "spurious errno %d != %d"); + } else { + TEST(i, 0, 1, "64bit tests not implemented"); + } + + TEST(l, wcstol(L"z", 0, 36), 35, "%ld != %ld"); + TEST(l, wcstol(L"00010010001101000101011001111000", 0, 2), 0x12345678, "%ld != %ld"); + + TEST(l, wcstol(s=L"0xz", &c, 16), 0, "%ld != %ld"); + TEST2(i, c-s, 1, "wrong final position %ld != %ld"); + + TEST(l, wcstol(s=L"0x1234", &c, 16), 0x1234, "%ld != %ld"); + TEST2(i, c-s, 6, "wrong final position %ld != %ld"); + + c = NULL; + TEST(l, wcstol(s=L"123", &c, 37), 0, "%ld != %ld"); + TEST2(i, c-s, 0, "wrong final position %d != %d"); + TEST2(i, errno, EINVAL, "%d != %d"); + return test_status; +} diff --git a/src/general/Makefile b/src/general/Makefile deleted file mode 100644 index 642a485..0000000 --- a/src/general/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -CFLAGS+=-pipe -std=c99 -D_POSIX_C_SOURCE=200809L -Wall -Wno-unused-function -Wno-missing-braces -LDFLAGS+= - -SRC=$(sort $(wildcard *.c)) -OBJ=$(SRC:.c=.o) -DSOOBJ=$(filter %_dso.o,$(OBJ)) -BINOBJ=$(filter-out %_dso.o,$(OBJ)) -DSO=$(DSOOBJ:.o=.so) -BIN=$(BINOBJ:.o=) - --include ../../config.mak - -all: $(BIN) $(DSO) -run: all - @N=0; for i in $(BIN);do ./$$i || N=$$((N+1)); done; [ "$$N" = 0 ] && echo PASS || echo FAILS: $$N -clean: - rm -f $(OBJ) $(DSO) $(BIN) - -$(OBJ): test.h -$(DSOOBJ): CFLAGS += -fPIC -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< || true -%.so: %.o - $(CC) $(LDFLAGS) -shared -o $@ $< || true -%: %.o - $(CC) $(LDFLAGS) -o $@ $(patsubst %.so,./%.so,$+) || true - -dlopen: LDFLAGS+=-ldl -rdynamic -pthread: LDFLAGS+=-lpthread -sem: LDFLAGS+=-lpthread -lrt -strtod_simple: LDFLAGS+=-lm -tls_align: tls_align_dso.so -tls_align_dlopen: LDFLAGS+=-ldl -tls_init: LDFLAGS+=-lpthread diff --git a/src/general/basename.c b/src/general/basename.c deleted file mode 100644 index a993587..0000000 --- a/src/general/basename.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include -#include "test.h" - -#define T(path, want) \ -{ \ - char tmp[100]; \ - char *got = basename(strcpy(tmp, path)); \ - if (strcmp(want, got) != 0) \ - error("basename(\"%s\") got \"%s\" want \"%s\"\n", path, got, want); \ -} - -int main() -{ - if (strcmp(basename(0), ".") != 0) - error("basename(0) returned \"%s\"; expected \".\"\n", basename(0)); - T("", "."); - T("/usr/lib", "lib"); - T("/usr/", "usr"); - T("usr/", "usr"); - T("/", "/"); - T("///", "/"); - T("//usr//lib//", "lib"); - T(".", "."); - T("..", ".."); - return test_status; -} diff --git a/src/general/dirname.c b/src/general/dirname.c deleted file mode 100644 index 7a15a0a..0000000 --- a/src/general/dirname.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include -#include "test.h" - -#define T(path, want) \ -{ \ - char tmp[100]; \ - char *got = dirname(strcpy(tmp, path)); \ - if (strcmp(want, got) != 0) \ - error("dirname(\"%s\") got \"%s\" want \"%s\"\n", path, got, want); \ -} - -int main() -{ - if (strcmp(dirname(0), ".") != 0) - error("dirname(0) returned \"%s\"; expected \".\"\n", dirname(0)); - T("", "."); - T("/usr/lib", "/usr"); - T("/usr/", "/"); - T("usr", "."); - T("usr/", "."); - T("/", "/"); - T("///", "/"); - T(".", "."); - T("..", "."); - return test_status; -} diff --git a/src/general/dlopen.c b/src/general/dlopen.c deleted file mode 100644 index 3150f6f..0000000 --- a/src/general/dlopen.c +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include "test.h" - -int main() -{ - void *h, *g; - int *i, *i2; - char *s; - void (*f)(void); - - h = dlopen("./dlopen_dso.so", RTLD_LAZY|RTLD_LOCAL); - if (!h) - error("dlopen ./dlopen_dso.so failed: %s\n", dlerror()); - i = dlsym(h, "i"); - if (!i) - error("dlsym i failed: %s\n", dlerror()); - if (*i != 1) - error("initialization failed: want i=1 got i=%d\n", *i); - f = (void (*)(void))dlsym(h, "f"); - if (!f) - error("dlsym f failed: %s\n", dlerror()); - f(); - if (*i != 2) - error("f call failed: want i=2 got i=%d\n", *i); - if (dlclose(h)) - error("dlclose failed: %s\n", dlerror()); - - g = dlopen(0, RTLD_LAZY|RTLD_LOCAL); - if (!g) - error("dlopen 0 failed: %s\n", dlerror()); - i2 = dlsym(g, "i"); - s = dlerror(); - if (i2 || s == 0) - error("dlsym i should have failed\n"); - if (dlsym(g, "main") == 0) - error("dlsym main failed: %s\n", dlerror()); - - h = dlopen("./dlopen_dso.so", RTLD_LAZY|RTLD_GLOBAL); - i2 = dlsym(g, "i"); - if (!i2) - error("dlsym i failed: %s\n", dlerror()); - if (*i2 != 2) - error("want i2=2, got i2=%d\n", *i2); - if (dlclose(g)) - error("dlclose failed: %s\n", dlerror()); - return test_status; -} diff --git a/src/general/dlopen_dso.c b/src/general/dlopen_dso.c deleted file mode 100644 index cb3220a..0000000 --- a/src/general/dlopen_dso.c +++ /dev/null @@ -1,6 +0,0 @@ -int i = 1; - -void f(void) -{ - i++; -} diff --git a/src/general/env.c b/src/general/env.c deleted file mode 100644 index 7962bf5..0000000 --- a/src/general/env.c +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE 1 -#endif -#include -#include -#include -#include -#include "test.h" - -extern char **environ; - -int main() -{ - 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); - /* test failures */ - if ((r=setenv("","",0)) != -1 || errno != EINVAL) - error("setenv(\"\",\"\",0): %d, errno: %d (%s), wanted -1, %d (EINVAL)\n", r, errno, strerror(errno), EINVAL); - if ((r=setenv(0,"",0)) != -1 || errno != EINVAL) - error("setenv(0,\"\",0): %d, errno: %d (%s), wanted -1, %d (EINVAL)\n", r, errno, strerror(errno), EINVAL); - return test_status; -} diff --git a/src/general/fdopen.c b/src/general/fdopen.c deleted file mode 100644 index 1f4da03..0000000 --- a/src/general/fdopen.c +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 700 -#endif -#include -#include -#include -#include -#include -#include "test.h" - -#define TEST(c) do { \ - errno = 0; \ - if (!(c)) \ - error("%s failed (errno = %d)\n", #c, errno); \ -} while(0) - -int main(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: \"%s\"; wanted: \"hello\"\n", foo); - fclose(f); - } - if (fd > 2) - TEST(unlink(tmp) != -1); - return test_status; -} diff --git a/src/general/fnmatch.c b/src/general/fnmatch.c deleted file mode 100644 index 33f508f..0000000 --- a/src/general/fnmatch.c +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include -#include "test.h" - -/* adapted from dietlibc's test-newfnmatch.c */ - -/* xlat / printflags adapted from http://www.liacs.nl/~wichert/strace/ */ -#define FLAG(f) { f, #f } - -struct xlat { - int val; - char *str; -} fnmatch_flags[] = { - FLAG(FNM_NOESCAPE), - FLAG(FNM_PATHNAME), - FLAG(FNM_PERIOD), - {0, NULL}, -}; - -static char *flagstr(const struct xlat *map, int flags) -{ - static char buf[1000]; - char *sep; - - if (!flags) { - sprintf(buf, "0"); - return buf; - } - sep = ""; - for (; map->str; map++) { - if (map->val && (flags & map->val) == map->val) { - sprintf(buf, "%s%s", sep, map->str); - sep = "|"; - flags &= ~(map->val); - } - } - if (flags) - sprintf(buf, "%sunknown=%#x", sep, flags); - return buf; -} - -/* tests harness adapted from glibc testfnm.c */ -struct { - const char *pattern; - const char *string; - int flags; - int expected; -} tests[] = { - /* begin dietlibc tests */ - { "*.c", "foo.c", 0, 0 }, - { "*.c", ".c", 0, 0 }, - { "*.a", "foo.c", 0, FNM_NOMATCH }, - { "*.c", ".foo.c", 0, 0 }, - { "*.c", ".foo.c", FNM_PERIOD, FNM_NOMATCH }, - { "*.c", "foo.c", FNM_PERIOD, 0 }, - { "a\\*.c", "a*.c", FNM_NOESCAPE, FNM_NOMATCH }, - { "a\\*.c", "ax.c", 0, FNM_NOMATCH }, - { "a[xy].c", "ax.c", 0, 0 }, - { "a[!y].c", "ax.c", 0, 0 }, - { "a[a/z]*.c", "a/x.c", FNM_PATHNAME, FNM_NOMATCH }, - { "a/*.c", "a/x.c", FNM_PATHNAME, 0 }, - { "a*.c", "a/x.c", FNM_PATHNAME, FNM_NOMATCH }, - { "*/foo", "/foo", FNM_PATHNAME, 0 }, - { "-O[01]", "-O1", 0, 0 }, - { "[[?*\\]", "\\", 0, 0 }, - { "[]?*\\]", "]", 0, 0 }, - /* initial right-bracket tests */ - { "[!]a-]", "b", 0, 0 }, - { "[]-_]", "^", 0, 0 }, /* range: ']', '^', '_' */ - { "[!]-_]", "X", 0, 0 }, - { "??", "-", 0, FNM_NOMATCH }, - /* begin glibc tests */ - { "*LIB*", "lib", FNM_PERIOD, FNM_NOMATCH }, - { "a[/]b", "a/b", 0, 0 }, - { "a[/]b", "a/b", FNM_PATHNAME, FNM_NOMATCH }, - { "[a-z]/[a-z]", "a/b", 0, 0 }, - { "*", "a/b", FNM_PATHNAME, FNM_NOMATCH }, - { "*[/]b", "a/b", FNM_PATHNAME, FNM_NOMATCH }, - { "*[b]", "a/b", FNM_PATHNAME, FNM_NOMATCH }, - { "[*]/b", "a/b", 0, FNM_NOMATCH }, - { "[*]/b", "*/b", 0, 0 }, - { "[?]/b", "a/b", 0, FNM_NOMATCH }, - { "[?]/b", "?/b", 0, 0 }, - { "[[a]/b", "a/b", 0, 0 }, - { "[[a]/b", "[/b", 0, 0 }, - { "\\*/b", "a/b", 0, FNM_NOMATCH }, - { "\\*/b", "*/b", 0, 0 }, - { "\\?/b", "a/b", 0, FNM_NOMATCH }, - { "\\?/b", "?/b", 0, 0 }, - { "[/b", "[/b", 0, 0 }, - { "\\[/b", "[/b", 0, 0 }, - { "??""/b", "aa/b", 0, 0 }, - { "???b", "aa/b", 0, 0 }, - { "???b", "aa/b", FNM_PATHNAME, FNM_NOMATCH }, - { "?a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, - { "a/?b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, - { "*a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, - { "a/*b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, - { "[.]a/b", ".a/b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, - { "a/[.]b", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, - { "*/?", "a/b", FNM_PATHNAME|FNM_PERIOD, 0 }, - { "?/*", "a/b", FNM_PATHNAME|FNM_PERIOD, 0 }, - { ".*/?", ".a/b", FNM_PATHNAME|FNM_PERIOD, 0 }, - { "*/.?", "a/.b", FNM_PATHNAME|FNM_PERIOD, 0 }, - { "*/*", "a/.b", FNM_PATHNAME|FNM_PERIOD, FNM_NOMATCH }, - { "*?*/*", "a/.b", FNM_PERIOD, 0 }, - { "*[.]/b", "a./b", FNM_PATHNAME|FNM_PERIOD, 0 }, - { "*[[:alpha:]]/*[[:alnum:]]", "a/b", FNM_PATHNAME, 0 }, - /* These three tests should result in error according to SUSv3. - * See XCU 2.13.1, XBD 9.3.5, & fnmatch() */ - { "*[![:digit:]]*/[![:d-d]", "a/b", FNM_PATHNAME, -FNM_NOMATCH }, - { "*[![:digit:]]*/[[:d-d]", "a/[", FNM_PATHNAME, -FNM_NOMATCH }, - { "*[![:digit:]]*/[![:d-d]", "a/[", FNM_PATHNAME, -FNM_NOMATCH }, - { "a?b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 }, - { "a*b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 }, - { "a[.]b", "a.b", FNM_PATHNAME|FNM_PERIOD, 0 }, -}; - -int main(void) -{ - int i; - - for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { - int r, x; - - r = fnmatch(tests[i].pattern, tests[i].string, tests[i].flags); - x = tests[i].expected; - if (r != x && (r != FNM_NOMATCH || x != -FNM_NOMATCH)) { - error("fnmatch(\"%s\", \"%s\", %s) failed, got %d want %d\n", - tests[i].pattern, tests[i].string, - flagstr(fnmatch_flags, tests[i].flags), - r, x); - } - } - return test_status; -} diff --git a/src/general/fscanf.c b/src/general/fscanf.c deleted file mode 100644 index 62627b7..0000000 --- a/src/general/fscanf.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "test.h" - -#define T(f, x, m) do { \ - r = (f); \ - if (r != (x)) \ - error("%s failed (got %d, expected %d, errno \"%s\") (%s)\n", \ - #f, r, x, errno ? strerror(errno) : "", m); \ - errno = 0; \ -} while (0) - -#define S(s, x, m) do { \ - if (strcmp(s, x) != 0) \ - error("got [%s] want [%s] (%s)\n", s, x, m); \ -} while(0) - -int main(void) -{ - int r, x, y; - char a[100], b[100]; - int p[2]; - FILE *f; - - T(pipe(p), 0, "open pipe"); - T(!(f = fdopen(p[0], "rb")), 0, "fdopen pipe"); - if (!f) { - close(p[0]); - close(p[1]); - return test_status; - } - - T(write(p[1], "hello, world\n", 13), 13, "write to pipe"); - T(fscanf(f, "%s %[own]", a, b), 2, ""); - S(a, "hello,", "wrong result for %s"); - S(b, "wo", "wrong result for %[own]"); - T(fgetc(f), 'r', "fgetc 'r'"); - - T(write(p[1], " 0x12 0x34", 10), 10, ""); - T(fscanf(f, "ld %5i%2i", &x, &y), 1, ""); - T(x, 0x12, ""); - T(fgetc(f), '3', "fgetc '3'"); - - fclose(f); - close(p[1]); - return test_status; -} diff --git a/src/general/ipc_msg.c b/src/general/ipc_msg.c deleted file mode 100644 index 3b91aeb..0000000 --- a/src/general/ipc_msg.c +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 700 -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include "test.h" - -static const char path[] = "."; -static const int id = 'x'; - -#define T(f) do{ \ - if ((f)+1 == 0) \ - error("%s failed: %s\n", #f, strerror(errno)); \ -}while(0) - -#define EQ(a,b,fmt) do{ \ - if ((a) != (b)) \ - error("%s == %s failed: " fmt "\n", #a, #b, a, b); \ -}while(0) - -static void snd() -{ - time_t t; - key_t k; - int qid; - struct msqid_ds qid_ds; - struct { - long type; - char data[20]; - } msg = {1, "test message"}; - - T(t = time(0)); - T(k = ftok(path, id)); - - /* make sure we get a clean message queue id */ - T(qid = msgget(k, IPC_CREAT|0666)); - T(msgctl(qid, IPC_RMID, 0)); - T(qid = msgget(k, IPC_CREAT|IPC_EXCL|0666)); - - if (test_status) - exit(test_status); - - /* check IPC_EXCL */ - errno = 0; - if (msgget(k, IPC_CREAT|IPC_EXCL|0666) != -1 || errno != EEXIST) - error("msgget(IPC_CREAT|IPC_EXCL) should have failed with EEXIST, got %s\n", strerror(errno)); - - /* check if msgget initilaized the msqid_ds structure correctly */ - T(msgctl(qid, IPC_STAT, &qid_ds)); - EQ(qid_ds.msg_perm.cuid, geteuid(), "got %d, want %d"); - EQ(qid_ds.msg_perm.uid, geteuid(), "got %d, want %d"); - EQ(qid_ds.msg_perm.cgid, getegid(), "got %d, want %d"); - EQ(qid_ds.msg_perm.gid, getegid(), "got %d, want %d"); - EQ(qid_ds.msg_perm.mode & 0x1ff, 0666, "got %o, want %o"); - EQ(qid_ds.msg_qnum, 0, "got %d, want %d"); - EQ(qid_ds.msg_lspid, 0, "got %d, want %d"); - EQ(qid_ds.msg_lrpid, 0, "got %d, want %d"); - EQ((long)qid_ds.msg_stime, 0, "got %ld, want %d"); - EQ((long)qid_ds.msg_rtime, 0, "got %ld, want %d"); - if (qid_ds.msg_ctime < t) - error("qid_ds.msg_ctime >= t failed: got %ld, want %ld\n", (long)qid_ds.msg_ctime, (long)t); - if (qid_ds.msg_qbytes <= 0) - error("qid_ds.msg_qbytes > 0 failed: got %d, want 0\n", qid_ds.msg_qbytes, t); - - /* test send */ - T(msgsnd(qid, &msg, sizeof msg.data, IPC_NOWAIT)); - T(msgctl(qid, IPC_STAT, &qid_ds)); - EQ(qid_ds.msg_qnum, 1, "got %d, want %d"); - EQ(qid_ds.msg_lspid, getpid(), "got %d, want %d"); - if (qid_ds.msg_stime < t) - error("msg_stime is %ld want >= %ld\n", (long)qid_ds.msg_stime, (long)t); -} - -static void rcv() -{ - key_t k; - int qid; - struct { - long type; - char data[20]; - } msg; - long msgtyp = 0; - - T(k = ftok(path, id)); - T(qid = msgget(k, 0)); - - errno = 0; - if (msgrcv(qid, &msg, 0, msgtyp, 0) != -1 || errno != E2BIG) - error("msgrcv should have failed when msgsize==0 with E2BIG, got %s\n", strerror(errno)); - - /* test receive */ - T(msgrcv(qid, &msg, sizeof msg.data, msgtyp, IPC_NOWAIT)); - if (strcmp(msg.data,"test message") != 0) - error("received \"%s\" instead of \"%s\"\n", msg.data, "test message"); - - errno = 0; - if (msgrcv(qid, &msg, sizeof msg.data, msgtyp, MSG_NOERROR|IPC_NOWAIT) != -1 || errno != ENOMSG) - error("msgrcv should have failed when ther is no msg with ENOMSG, got %s\n", strerror(errno)); - - /* cleanup */ - T(msgctl(qid, IPC_RMID, 0)); -} - -int main(void) -{ - int p; - int status; - - snd(); - p = fork(); - if (p == -1) - error("fork failed: %s\n", strerror(errno)); - else if (p == 0) - rcv(); - else { - T(waitpid(p, &status, 0)); - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) - error("child exit status: %d\n", status); - } - return test_status; -} diff --git a/src/general/ipc_sem.c b/src/general/ipc_sem.c deleted file mode 100644 index 8f69586..0000000 --- a/src/general/ipc_sem.c +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 700 -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include "test.h" - -static const char path[] = "."; -static const int id = 'x'; - -#define T(f) do{ \ - if ((f)+1 == 0) \ - error("%s failed: %s\n", #f, strerror(errno)); \ -}while(0) - -#define EQ(a,b,fmt) do{ \ - if ((a) != (b)) \ - error("%s == %s failed: " fmt "\n", #a, #b, a, b); \ -}while(0) - -static void inc() -{ - time_t t; - key_t k; - int semid, semval, sempid, semncnt, semzcnt; - struct semid_ds semid_ds; - union semun { - int val; - struct semid_ds *buf; - unsigned short *array; - } arg; - struct sembuf sops; - - T(t = time(0)); - T(k = ftok(path, id)); - - /* make sure we get a clean semaphore id */ - T(semid = semget(k, 1, IPC_CREAT|0666)); - T(semctl(semid, 0, IPC_RMID)); - T(semid = semget(k, 1, IPC_CREAT|IPC_EXCL|0666)); - - if (test_status) - exit(test_status); - - /* check IPC_EXCL */ - errno = 0; - if (semget(k, 1, IPC_CREAT|IPC_EXCL|0666) != -1 || errno != EEXIST) - error("semget(IPC_CREAT|IPC_EXCL) should have failed with EEXIST, got %s\n", strerror(errno)); - - /* check if msgget initilaized the msqid_ds structure correctly */ - arg.buf = &semid_ds; - T(semctl(semid, 0, IPC_STAT, arg)); - EQ(semid_ds.sem_perm.cuid, geteuid(), "got %d, want %d"); - EQ(semid_ds.sem_perm.uid, geteuid(), "got %d, want %d"); - EQ(semid_ds.sem_perm.cgid, getegid(), "got %d, want %d"); - EQ(semid_ds.sem_perm.gid, getegid(), "got %d, want %d"); - EQ(semid_ds.sem_perm.mode & 0x1ff, 0666, "got %o, want %o"); - EQ(semid_ds.sem_nsems, 1, "got %d, want %d"); - EQ((long)semid_ds.sem_otime, 0, "got %ld, want %d"); - if (semid_ds.sem_ctime < t) - error("semid_ds.sem_ctime >= t failed: got %ld, want %ld\n", (long)semid_ds.sem_ctime, (long)t); - - /* test sem_op > 0 */ - sops.sem_num = 0; - sops.sem_op = 1; - sops.sem_flg = 0; - T(semop(semid, &sops, 1)); - T(semval = semctl(semid, 0, GETVAL)); - EQ(semval, 1, "got %d, want %d"); - T(sempid = semctl(semid, 0, GETPID)); - EQ(sempid, getpid(), "got %d, want %d"); - T(semncnt = semctl(semid, 0, GETNCNT)); - EQ(semncnt, 0, "got %d, want %d"); - T(semzcnt = semctl(semid, 0, GETZCNT)); - EQ(semzcnt, 0, "got %d, want %d"); -} - -static void dec() -{ - key_t k; - int semid, semval; - struct sembuf sops; - - T(k = ftok(path, id)); - T(semid = semget(k, 0, 0)); - - /* test sem_op < 0 */ - sops.sem_num = 0; - sops.sem_op = -1; - sops.sem_flg = 0; - T(semop(semid, &sops, 1)); - T(semval = semctl(semid, 0, GETVAL)); - EQ(semval, 0, "got %d, want %d"); - - /* cleanup */ - T(semctl(semid, 0, IPC_RMID)); -} - -int main(void) -{ - int p; - int status; - - inc(); - p = fork(); - if (p == -1) - error("fork failed: %s\n", strerror(errno)); - else if (p == 0) - dec(); - else { - T(waitpid(p, &status, 0)); - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) - error("child exit status: %d\n", status); - } - return test_status; -} - diff --git a/src/general/ipc_shm.c b/src/general/ipc_shm.c deleted file mode 100644 index 7d0086b..0000000 --- a/src/general/ipc_shm.c +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 700 -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include "test.h" - -static const char path[] = "."; -static const int id = 'x'; - -#define T(f) do{ \ - if ((f)+1 == 0) \ - error("%s failed: %s\n", #f, strerror(errno)); \ -}while(0) - -#define EQ(a,b,fmt) do{ \ - if ((a) != (b)) \ - error("%s == %s failed: " fmt "\n", #a, #b, a, b); \ -}while(0) - -static void set() -{ - time_t t; - key_t k; - int shmid; - struct shmid_ds shmid_ds; - void *p; - - T(t = time(0)); - T(k = ftok(path, id)); - - /* make sure we get a clean shared memory id */ - T(shmid = shmget(k, 100, IPC_CREAT|0666)); - T(shmctl(shmid, IPC_RMID, 0)); - T(shmid = shmget(k, 100, IPC_CREAT|IPC_EXCL|0666)); - - if (test_status) - exit(test_status); - - /* check IPC_EXCL */ - errno = 0; - if (shmget(k, 100, IPC_CREAT|IPC_EXCL|0666) != -1 || errno != EEXIST) - error("shmget(IPC_CREAT|IPC_EXCL) should have failed with EEXIST, got %s\n", strerror(errno)); - - /* check if shmget initilaized the msshmid_ds structure correctly */ - T(shmctl(shmid, IPC_STAT, &shmid_ds)); - EQ(shmid_ds.shm_perm.cuid, geteuid(), "got %d, want %d"); - EQ(shmid_ds.shm_perm.uid, geteuid(), "got %d, want %d"); - EQ(shmid_ds.shm_perm.cgid, getegid(), "got %d, want %d"); - EQ(shmid_ds.shm_perm.gid, getegid(), "got %d, want %d"); - EQ(shmid_ds.shm_perm.mode & 0x1ff, 0666, "got %o, want %o"); - EQ(shmid_ds.shm_segsz, 100, "got %d, want %d"); - EQ(shmid_ds.shm_lpid, 0, "got %d, want %d"); - EQ(shmid_ds.shm_cpid, getpid(), "got %d, want %d"); - EQ((int)shmid_ds.shm_nattch, 0, "got %d, want %d"); - EQ((long)shmid_ds.shm_atime, 0, "got %ld, want %d"); - EQ((long)shmid_ds.shm_dtime, 0, "got %ld, want %d"); - if (shmid_ds.shm_ctime < t) - error("shmid_ds.shm_ctime >= t failed: got %ld, want %ld\n", (long)shmid_ds.shm_ctime, (long)t); - - /* test attach */ - if ((p=shmat(shmid, 0, 0)) == 0) - error("shmat failed: %s\n", strerror(errno)); - T(shmctl(shmid, IPC_STAT, &shmid_ds)); - EQ((int)shmid_ds.shm_nattch, 1, "got %d, want %d"); - EQ(shmid_ds.shm_lpid, getpid(), "got %d, want %d"); - if (shmid_ds.shm_atime < t) - error("shm_atime is %ld want >= %ld\n", (long)shmid_ds.shm_atime, (long)t); - strcpy(p, "test data"); - T(shmdt(p)); -} - -static void get() -{ - key_t k; - int shmid; - void *p; - - T(k = ftok(path, id)); - T(shmid = shmget(k, 0, 0)); - - errno = 0; - if ((p=shmat(shmid, 0, SHM_RDONLY)) == 0) - error("shmat failed: %s\n", strerror(errno)); - - if (strcmp(p, "test data") != 0) - error("reading shared mem failed: got \"%.100s\" want \"test data\"\n", p); - - /* cleanup */ - T(shmdt(p)); - T(shmctl(shmid, IPC_RMID, 0)); -} - -int main(void) -{ - int p; - int status; - - set(); - p = fork(); - if (p == -1) - error("fork failed: %s\n", strerror(errno)); - else if (p == 0) - get(); - else { - T(waitpid(p, &status, 0)); - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) - error("child exit status: %d\n", status); - } - return test_status; -} diff --git a/src/general/mbc.c b/src/general/mbc.c deleted file mode 100644 index 56c546b..0000000 --- a/src/general/mbc.c +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "test.h" - -/* - * f = function call to test (or any expression) - * x = expected result - * m = message to print on failure - */ -#define T(f, x, m) (void)( \ - memset(&st, 0, sizeof st), \ - (i = (f)) == (x) || \ - error("%s failed (%s) got %d want %d\n", #f, m, i, x) ) -#define TCHAR(f, x, m) (void)( \ - memset(&st, 0, sizeof st), \ - (i = (f)) == (x) || \ - error("%s failed (%s) got 0x%04x want 0x%04x\n", #f, m, i, x) ) - -int main(void) -{ - const char *cs; - int i; - mbstate_t st, st2; - wchar_t wc, wcs[32]; - - (void)( - setlocale(LC_CTYPE, "en_US.UTF-8") || - setlocale(LC_CTYPE, "en_GB.UTF-8") || - setlocale(LC_CTYPE, "en.UTF-8") || - setlocale(LC_CTYPE, "POSIX.UTF-8") || - setlocale(LC_CTYPE, "C.UTF-8") || - setlocale(LC_CTYPE, "UTF-8") || - setlocale(LC_CTYPE, "") ); - - T(mbsrtowcs(wcs, (cs="abcdef",&cs), 3, &st), 3, "wrong semantics for wcs buf len"); - T(mbsrtowcs(wcs, (cs="abcdef",&cs), 8, &st), 6, "wrong semantics for wcs buf len"); - T(mbsrtowcs(NULL, (cs="abcdef",&cs), 2, &st), 6, "wrong semantics for NULL wcs"); - - if (strcmp(nl_langinfo(CODESET), "UTF-8")) - return error("cannot set UTF-8 locale for test (codeset=%s)\n", nl_langinfo(CODESET)); - - T(mbrtowc(&wc, "\x80", 1, &st), -1, "failed to catch error"); - T(mbrtowc(&wc, "\xc0", 1, &st), -1, "failed to catch illegal initial"); - - T(mbrtowc(&wc, "\xc0\x80", 2, &st), -1, "aliasing nul"); - T(mbrtowc(&wc, "\xc0\xaf", 2, &st), -1, "aliasing slash"); - T(mbrtowc(&wc, "\xe0\x80\xaf", 3, &st), -1, "aliasing slash"); - T(mbrtowc(&wc, "\xf0\x80\x80\xaf", 4, &st), -1, "aliasing slash"); - T(mbrtowc(&wc, "\xf8\x80\x80\x80\xaf", 5, &st), -1, "aliasing slash"); - T(mbrtowc(&wc, "\xfc\x80\x80\x80\x80\xaf", 6, &st), -1, "aliasing slash"); - T(mbrtowc(&wc, "\xe0\x82\x80", 3, &st), -1, "aliasing U+0080"); - T(mbrtowc(&wc, "\xe0\x9f\xbf", 3, &st), -1, "aliasing U+07FF"); - T(mbrtowc(&wc, "\xf0\x80\xa0\x80", 4, &st), -1, "aliasing U+0800"); - T(mbrtowc(&wc, "\xf0\x8f\xbf\xbd", 4, &st), -1, "aliasing U+FFFD"); - - T(mbrtowc(&wc, "\xed\xa0\x80", 3, &st), -1, "failed to catch surrogate"); - T(mbrtowc(&wc, "\xef\xbf\xbe", 3, &st), 3, "failed to accept U+FFFE"); - T(mbrtowc(&wc, "\xef\xbf\xbf", 3, &st), 3, "failed to accept U+FFFF"); - T(mbrtowc(&wc, "\xf4\x8f\xbf\xbe", 4, &st), 4, "failed to accept U+10FFFE"); - T(mbrtowc(&wc, "\xf4\x8f\xbf\xbf", 4, &st), 4, "failed to accept U+10FFFF"); - - T(mbrtowc(&wc, "\xc2\x80", 2, &st), 2, "wrong length"); - TCHAR((mbrtowc(&wc, "\xc2\x80", 2, &st),wc), 0x80, "wrong char"); - T(mbrtowc(&wc, "\xe0\xa0\x80", 3, &st), 3, "wrong length"); - TCHAR((mbrtowc(&wc, "\xe0\xa0\x80", 3, &st),wc), 0x800, "wrong char"); - T(mbrtowc(&wc, "\xf0\x90\x80\x80", 4, &st), 4, "wrong length"); - TCHAR((mbrtowc(&wc, "\xf0\x90\x80\x80", 4, &st),wc), 0x10000, "wrong char"); - - memset(&st2, 0, sizeof st2); - T(mbrtowc(&wc, "\xc2", 1, &st2), -2, "failed to accept initial byte"); - T(mbrtowc(&wc, "\x80", 1, &st2), 1, "failed to resume"); - TCHAR(wc, 0x80, "wrong char"); - - memset(&st2, 0, sizeof st2); - T(mbrtowc(&wc, "\xc2", 1, &st2), -2, "failed to accept initial byte"); - T(mbsrtowcs(wcs, (cs="\xa0""abc",&cs), 32, &st2), 4, "failed to resume"); - TCHAR(wcs[0], 0xa0, "wrong char"); - TCHAR(wcs[1], 'a', "wrong char"); - T(!cs, 1, "wrong final position"); - return test_status; -} diff --git a/src/general/memstream.c b/src/general/memstream.c deleted file mode 100644 index 749c664..0000000 --- a/src/general/memstream.c +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include -#include -#include -#include -#include "test.h" - -#define TEST(r, f, x, m) ( \ -((r) = (f)) == (x) || \ -(error("%s failed (" m ")\n", #f, r, x), 0) ) - -#define TEST_E(f) ( (errno = 0), (f) || \ -(error("%s failed (errno = %d)\n", #f, errno), 0) ) - -#define TEST_S(s, x, m) ( \ -!strcmp((s),(x)) || \ -(error("[%s] != [%s] (%s)\n", s, x, m), 0) ) - -#define TEST_M(s, x, n, m) ( \ -!memcmp((s),(x),(n)) || \ -(error("[%s] != [%s] (%s)\n", s, x, m), 0) ) - -int main(void) -{ - FILE *f; - char *s; - size_t l; - char buf[100]; - int i; - - s = 0; - TEST_E(f = open_memstream(&s, &l)); - TEST_E(putc('a', f) == 'a'); - TEST_E(putc('b', f) == 'b'); - TEST_E(putc('c', f) == 'c'); - TEST_E(!fflush(f)); - fclose(f); - if (s) TEST_S(s, "abc", "wrong output"); - free(s); - - s = 0; - TEST_E(f = open_memstream(&s, &l)); - TEST_E(fseek(f,1,SEEK_CUR)>=0); - TEST_E(putc('q', f) == 'q'); - TEST_E(!fflush(f)); - if (s) TEST_M(s, "\0q", 3, "wrong output"); - TEST(i, fseek(f,-3,SEEK_CUR), -1, "invalid seek allowed"); - TEST(i, errno, EINVAL, "%d != %d"); - TEST(i, ftell(f), 2, "%d != %d"); - TEST_E(fseek(f,-2,SEEK_CUR)>=0); - TEST_E(putc('e', f) == 'e'); - TEST_E(!fflush(f)); - if (s) TEST_S(s, "eq", "wrong output"); - fclose(f); - free(s); - - TEST_E(f = fmemopen(buf, 10, "r+")); - TEST_E(fputs("hello", f) >= 0); - TEST_E(fputc(0, f)==0); - TEST_E(fseek(f, 0, SEEK_SET)>=0); - i=0; - TEST_E(fscanf(f, "hello%n", &i)==0); - TEST(i, i, 5, "%d != %d"); - TEST(i, ftell(f), 5, "%d != %d"); - errno = 0; - TEST(i, fseek(f, 6, SEEK_CUR)<0, 1, ""); - TEST(i, errno!=0, 1, ""); - TEST(i, ftell(f), 5, "%d != %d"); - TEST_S(buf, "hello", ""); - fclose(f); - - TEST_E(f = fmemopen(buf, 10, "a+")); - TEST(i, ftell(f), 5, "%d != %d"); - TEST_E(fseek(f, 0, SEEK_SET)>=0); - TEST(i, getc(f), 'h', "%d != %d"); - TEST(i, getc(f), 'e', "%d != %d"); - TEST(i, getc(f), 'l', "%d != %d"); - TEST(i, getc(f), 'l', "%d != %d"); - TEST(i, getc(f), 'o', "%d != %d"); - TEST(i, getc(f), EOF, "%d != %d"); - TEST_E(fseek(f, 6, SEEK_SET)>=0); - TEST(i, ftell(f), 6, "%d != %d"); - TEST(i, getc(f), EOF, "%d != %d"); - TEST(i, ftell(f), 6, "%d != %d"); - TEST_E(fseek(f, 0, SEEK_SET)>=0); - TEST(i, getc(f), 'h', "%d != %d"); - TEST_E(fseek(f, 0, SEEK_CUR)>=0); - buf[7] = 'x'; - TEST_E(fprintf(f, "%d", i)==3); - TEST_E(fflush(f)==0); - TEST(i, ftell(f), 8, "%d != %d"); - TEST_S(buf, "hello104", ""); - fclose(f); - return test_status; -} diff --git a/src/general/popen.c b/src/general/popen.c deleted file mode 100644 index f5cf05a..0000000 --- a/src/general/popen.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include -#include -#include -#include "test.h" - -#define TEST(r, f, x, m) ( \ - ((r) = (f)) == (x) || (error("%s failed (" m ")\n", #f, r, x), 0) ) - -#define TEST_E(f) ( \ - (errno = 0), \ - (f) || (error("%s failed (errno = %d)\n", #f, errno), 0) ) - -#define TEST_S(s, x, m) ( \ - !strcmp((s),(x)) || \ - (error("[%s] != [%s] (%s)\n", s, x, m), 0) ) - -static sig_atomic_t got_sig; - -static void handler(int sig) { - got_sig = 1; -} - -int main(void) -{ - int i; - char foo[6]; - char cmd[64]; - FILE *f; - - TEST_E(f = popen("echo hello", "r")); - if (f) { - TEST_E(fgets(foo, sizeof foo, f)); - TEST_S(foo, "hello", "child process did not say hello"); - TEST(i, pclose(f), 0, "exit status %04x != %04x"); - } - - signal(SIGUSR1, handler); - snprintf(cmd, sizeof cmd, "read a ; test \"x$a\" = xhello && kill -USR1 %d", getpid()); - TEST_E(f = popen(cmd, "w")); - if (f) { - TEST_E(fputs("hello", f) >= 0); - TEST(i, pclose(f), 0, "exit status %04x != %04x"); - TEST(i, got_sig, 1, "child process did not send signal"); - } - signal(SIGUSR1, SIG_DFL); - return test_status; -} diff --git a/src/general/pthread.c b/src/general/pthread.c deleted file mode 100644 index 3c25c57..0000000 --- a/src/general/pthread.c +++ /dev/null @@ -1,294 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "test.h" - -#define TEST(r, f, x, m) ( \ - msg = #f, ((r) = (f)) == (x) || \ - (error("%s failed (" m ")\n", #f, r, x), 0) ) - -#define TEST_S(s, x, m) ( \ - !strcmp((s),(x)) || \ - (error("[%s] != [%s] (%s)\n", s, x, m), 0) ) - -static volatile char *msg = ""; - -static void alarmhandler(int sig) { - error("timeout in %s\n", msg); - _Exit(1); -} - -static pthread_key_t k1, k2; - -static void dtor(void *p) -{ - *(int *)p = 1; -} - -static void *start1(void *arg) -{ - return arg; -} - -static void *start2(void *arg) -{ - int *p = arg; - if (pthread_setspecific(k1, p) || pthread_setspecific(k2, p+1)) - return arg; - return 0; -} - -static void *start3(void *arg) -{ - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0); - sem_post(arg); - for (;;); - return 0; -} - -static void cleanup4(void *arg) -{ - *(int *)arg = 1; -} - -static void *start4(void *arg) -{ - pthread_cleanup_push(cleanup4, arg); - sleep(3); - pthread_cleanup_pop(0); - return 0; -} - -static void cleanup4a2(void *arg) -{ - *(int *)arg += 2; -} - -static void cleanup4a3(void *arg) -{ - *(int *)arg += 3; -} - -static void cleanup4a4(void *arg) -{ - *(int *)arg += 4; -} - -static void *start4a(void *arg) -{ - int *foo = arg; - pthread_cleanup_push(cleanup4, foo); - pthread_cleanup_push(cleanup4a2, foo+1); - pthread_cleanup_push(cleanup4a3, foo+2); - pthread_cleanup_push(cleanup4a4, foo+3); - sleep(3); - pthread_cleanup_pop(0); - pthread_cleanup_pop(0); - pthread_cleanup_pop(0); - pthread_cleanup_pop(0); - return 0; -} - -static void *start5(void *arg) -{ - pthread_mutex_lock(arg); - return 0; -} - -static void *start6(void *arg) -{ - void **args = arg; - pthread_mutex_lock(args[1]); - pthread_barrier_wait(args[0]); - nanosleep(&(struct timespec){ .tv_nsec = 10000000 }, 0); - return 0; -} - -static void *start7(void *arg) -{ - void **args = arg; - pthread_mutex_lock(args[1]); - pthread_cond_signal(args[0]); - pthread_mutex_unlock(args[1]); - return 0; -} - -static void *start8(void *arg) -{ - void **args = arg; - pthread_mutex_t *m = args[1]; - pthread_cond_t *c = args[0]; - int *x = args[2]; - - pthread_mutex_lock(m); - while (*x) pthread_cond_wait(c, m); - pthread_mutex_unlock(m); - - return 0; -} - -int main(void) -{ - pthread_t td, td1, td2, td3; - int r; - void *res; - int foo[4], bar[2]; - pthread_barrier_t barrier2; - pthread_mutexattr_t mtx_a; - sem_t sem1; - pthread_mutex_t mtx; - pthread_cond_t cond; - - signal(SIGALRM, alarmhandler); - alarm(10); - - TEST(r, pthread_barrier_init(&barrier2, 0, 2), 0, "creating barrier"); - TEST(r, sem_init(&sem1, 0, 0), 0, "creating semaphore"); - - /* Test basic thread creation and joining */ - TEST(r, pthread_create(&td, 0, start1, &res), 0, "failed to create thread"); - res = 0; - TEST(r, pthread_join(td, &res), 0, "failed to join"); - TEST(r, (res==&res), 1, "wrong result from join"); - - /* Test POSIX thread-specific data */ - TEST(r, pthread_key_create(&k1, dtor), 0, "failed to create key"); - TEST(r, pthread_key_create(&k2, dtor), 0, "failed to create key"); - foo[0] = foo[1] = 0; - TEST(r, pthread_setspecific(k1, bar), 0, "failed to set tsd"); - TEST(r, pthread_setspecific(k2, bar+1), 0, "failed to set tsd"); - TEST(r, pthread_create(&td, 0, start2, foo), 0, "failed to create thread"); - TEST(r, pthread_join(td, &res), 0, "failed to join"); - TEST(res, res, 0, "pthread_setspecific failed in thread"); - TEST(r, foo[0], 1, "dtor failed to run"); - TEST(r, foo[1], 1, "dtor failed to run"); - TEST(res, pthread_getspecific(k1), bar, "tsd corrupted"); - TEST(res, pthread_getspecific(k2), bar+1, "tsd corrupted"); - TEST(r, pthread_setspecific(k1, 0), 0, "failed to clear tsd"); - TEST(r, pthread_setspecific(k2, 0), 0, "failed to clear tsd"); - TEST(r, pthread_key_delete(k1), 0, "failed to destroy key"); - TEST(r, pthread_key_delete(k2), 0, "failed to destroy key"); - - /* Asynchronous cancellation */ - TEST(r, pthread_create(&td, 0, start3, &sem1), 0, "failed to create thread"); - while (sem_wait(&sem1)); - TEST(r, pthread_cancel(td), 0, "canceling"); - TEST(r, pthread_join(td, &res), 0, "joining canceled thread"); - TEST(res, res, PTHREAD_CANCELED, "canceled thread exit status"); - - /* Cancellation cleanup handlers */ - foo[0] = 0; - TEST(r, pthread_create(&td, 0, start4, foo), 0, "failed to create thread"); - TEST(r, pthread_cancel(td), 0, "cancelling"); - TEST(r, pthread_join(td, &res), 0, "joining canceled thread"); - TEST(res, res, PTHREAD_CANCELED, "canceled thread exit status"); - TEST(r, foo[0], 1, "cleanup handler failed to run"); - - /* Nested cleanup handlers */ - memset(foo, 0, sizeof foo); - TEST(r, pthread_create(&td, 0, start4a, foo), 0, "failed to create thread"); - TEST(r, pthread_cancel(td), 0, "cancelling"); - TEST(r, pthread_join(td, &res), 0, "joining canceled thread"); - TEST(res, res, PTHREAD_CANCELED, "canceled thread exit status"); - TEST(r, foo[0], 1, "cleanup handler failed to run"); - TEST(r, foo[1], 2, "cleanup handler failed to run"); - TEST(r, foo[2], 3, "cleanup handler failed to run"); - TEST(r, foo[3], 4, "cleanup handler failed to run"); - - /* Robust mutexes */ - TEST(r, pthread_mutexattr_init(&mtx_a), 0, "initializing mutex attr"); - TEST(r, pthread_mutexattr_setrobust(&mtx_a, PTHREAD_MUTEX_ROBUST), 0, "setting robust attribute"); - TEST(r, pthread_mutex_init(&mtx, &mtx_a), 0, "initializing robust mutex"); - TEST(r, pthread_mutex_lock(&mtx), 0, "locking robust mutex"); - TEST(r, pthread_mutex_unlock(&mtx), 0, "unlocking robust mutex"); - TEST(r, pthread_create(&td, 0, start5, &mtx), 0, "failed to create thread"); - TEST(r, pthread_join(td, &res), 0, "joining thread"); - TEST(r, pthread_mutex_lock(&mtx), EOWNERDEAD, "locking orphaned robust mutex %d!=%d"); - TEST(r, pthread_mutex_unlock(&mtx), 0, "unlocking orphaned robust mutex %d!=%d"); - TEST(r, pthread_mutex_lock(&mtx), ENOTRECOVERABLE, "re-locking orphaned robust mutex %d!=%d"); - TEST(r, pthread_mutex_destroy(&mtx), 0, "destroying unrecoverable mutex %d!=%d"); - - TEST(r, pthread_mutex_init(&mtx, &mtx_a), 0, "initializing robust mutex"); - TEST(r, pthread_create(&td, 0, start5, &mtx), 0, "failed to create thread"); - TEST(r, pthread_join(td, &res), 0, "joining thread"); - TEST(r, pthread_mutex_lock(&mtx), EOWNERDEAD, "locking orphaned robust mutex %d!=%d"); - TEST(r, pthread_mutex_consistent(&mtx), 0, "%d!=%d"); - TEST(r, pthread_mutex_unlock(&mtx), 0, "unlocking orphaned robust mutex %d!=%d"); - TEST(r, pthread_mutex_lock(&mtx), 0, "re-locking orphaned robust mutex %d!=%d"); - TEST(r, pthread_mutex_destroy(&mtx), 0, "destroying mutex %d!=%d"); - - TEST(r, pthread_mutex_init(&mtx, &mtx_a), 0, "%d != %d"); - TEST(r, pthread_create(&td, 0, start6, (void *[]){ &barrier2, &mtx }), 0, "%d != %d"); - pthread_barrier_wait(&barrier2); - TEST(r, pthread_mutex_lock(&mtx), EOWNERDEAD, "%d != %d"); - TEST(r, pthread_join(td, &res), 0, "%d != %d"); - TEST(r, pthread_mutex_consistent(&mtx), 0, "%d != %d"); - TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); - TEST(r, pthread_mutex_destroy(&mtx), 0, "%d != %d"); - - //TEST(r, (fd=open("/dev/zero", O_RDWR))>=0, 1, "opening zero page file"); - //TEST(r, - - /* Condition variables */ - TEST(r, pthread_mutex_init(&mtx, 0), 0, "%d != %d"); - TEST(r, pthread_cond_init(&cond, 0), 0, "%d != %d"); - TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); - TEST(r, pthread_create(&td, 0, start7, (void *[]){ &cond, &mtx }), 0, "%d != %d"); - TEST(r, pthread_cond_wait(&cond, &mtx), 0, "%d != %d"); - TEST(r, pthread_join(td, &res), 0, "%d != %d"); - TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); - TEST(r, pthread_mutex_destroy(&mtx), 0, "%d != %d"); - TEST(r, pthread_cond_destroy(&cond), 0, "%d != %d"); - - /* Condition variables with multiple waiters */ - TEST(r, pthread_mutex_init(&mtx, 0), 0, "%d != %d"); - TEST(r, pthread_cond_init(&cond, 0), 0, "%d != %d"); - TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); - foo[0] = 1; - TEST(r, pthread_create(&td1, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); - TEST(r, pthread_create(&td2, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); - TEST(r, pthread_create(&td3, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); - TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); - nanosleep(&(struct timespec){.tv_nsec=1000000}, 0); - foo[0] = 0; - TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); - TEST(r, pthread_cond_signal(&cond), 0, "%d != %d"); - TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); - TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); - TEST(r, pthread_cond_signal(&cond), 0, "%d != %d"); - TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); - TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); - TEST(r, pthread_cond_signal(&cond), 0, "%d != %d"); - TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); - TEST(r, pthread_join(td1, 0), 0, "%d != %d"); - TEST(r, pthread_join(td2, 0), 0, "%d != %d"); - TEST(r, pthread_join(td3, 0), 0, "%d != %d"); - TEST(r, pthread_mutex_destroy(&mtx), 0, "%d != %d"); - TEST(r, pthread_cond_destroy(&cond), 0, "%d != %d"); - - /* Condition variables with broadcast signals */ - TEST(r, pthread_mutex_init(&mtx, 0), 0, "%d != %d"); - TEST(r, pthread_cond_init(&cond, 0), 0, "%d != %d"); - TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); - foo[0] = 1; - TEST(r, pthread_create(&td1, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); - TEST(r, pthread_create(&td2, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); - TEST(r, pthread_create(&td3, 0, start8, (void *[]){ &cond, &mtx, foo }), 0, "%d != %d"); - TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); - nanosleep(&(struct timespec){.tv_nsec=1000000}, 0); - TEST(r, pthread_mutex_lock(&mtx), 0, "%d != %d"); - foo[0] = 0; - TEST(r, pthread_mutex_unlock(&mtx), 0, "%d != %d"); - TEST(r, pthread_cond_broadcast(&cond), 0, "%d != %d"); - TEST(r, pthread_join(td1, 0), 0, "%d != %d"); - TEST(r, pthread_join(td2, 0), 0, "%d != %d"); - TEST(r, pthread_join(td3, 0), 0, "%d != %d"); - TEST(r, pthread_mutex_destroy(&mtx), 0, "%d != %d"); - TEST(r, pthread_cond_destroy(&cond), 0, "%d != %d"); - return test_status; -} diff --git a/src/general/qsort.c b/src/general/qsort.c deleted file mode 100644 index b45c080..0000000 --- a/src/general/qsort.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include -#include "test.h" - -static int scmp(const void *a, const void *b) -{ - return strcmp(*(char **)a, *(char **)b); -} - -static int icmp(const void *a, const void *b) -{ - return *(int*)a - *(int*)b; -} - -/* 26 items -- even */ -static char *s[] = { - "Bob", "Alice", "John", "Ceres", - "Helga", "Drepper", "Emeralda", "Zoran", - "Momo", "Frank", "Pema", "Xavier", - "Yeva", "Gedun", "Irina", "Nono", - "Wiener", "Vincent", "Tsering", "Karnica", - "Lulu", "Quincy", "Osama", "Riley", - "Ursula", "Sam" -}; -/* 23 items -- odd, prime */ -static int n[] = { - 879045, 394, 99405644, 33434, 232323, 4334, 5454, - 343, 45545, 454, 324, 22, 34344, 233, 45345, 343, - 848405, 3434, 3434344, 3535, 93994, 2230404, 4334 -}; - -int main(void) -{ - int i; - - qsort(s, sizeof(s)/sizeof(char *), sizeof(char *), scmp); - for (i=0; i 0) { - error("string sort failed at index %d\n", i); - for (i=0; i n[i+1]) { - error("integer sort failed at index %d\n", i); - for (i=0; i -#include -#include -#include -#include -#include -#include -#include "test.h" - -#define TEST(c, ...) \ - ( (c) || (error(#c " failed: " __VA_ARGS__),0) ) - -int main(void) -{ - char buf[100]; - struct timespec ts; - sem_t *sem, *sem2; - int val; - - clock_gettime(CLOCK_REALTIME, &ts); - snprintf(buf, sizeof buf, "/testsuite-%d-%d", (int)getpid(), (int)ts.tv_nsec); - - TEST((sem=sem_open(buf, O_CREAT|O_EXCL, 0700, 1)) != SEM_FAILED, - "could not open sem: %s\n", strerror(errno)); - errno = 0; - TEST(sem_open(buf, O_CREAT|O_EXCL, 0700, 1) == SEM_FAILED, - "reopening should fail with O_EXCL\n"); - TEST(errno == EEXIST, - "after reopen failure errno is \"%s\" (%d); want EEXIST (%d)\n", strerror(errno), errno, EEXIST); - - TEST(sem_getvalue(sem, &val) == 0, "failed to get sem value\n"); - TEST(val == 1, "wrong initial semaphore value: %d\n", val); - - TEST((sem2=sem_open(buf, 0)) == sem, - "could not reopen sem: got %p, want %p\n", sem2, sem); - - errno = 0; - TEST(sem_wait(sem) == 0, "%s\n", strerror(errno)); - TEST(sem_getvalue(sem2, &val) == 0, "%s\n", strerror(errno)); - TEST(val == 0, "wrong semaphore value on second handle: %d\n", val); - - errno = 0; - TEST(sem_trywait(sem) == -1 && errno == EAGAIN, - "trywait on locked sem: got errno \"%s\" (%d), want EAGAIN (%d)\n", strerror(errno), errno, EAGAIN); - - TEST(sem_post(sem) == 0, "%s\n", strerror(errno)); - TEST(sem_getvalue(sem2, &val) == 0, "%s\n", strerror(errno)); - TEST(val == 1, "wrong semaphore value on second handle: %d\n", val); - - TEST(sem_close(sem) == 0, "%s\n", strerror(errno)); - TEST(sem_close(sem) == 0, "%s\n", strerror(errno)); - TEST(sem_unlink(buf) == 0, "%s\n", strerror(errno)); - return test_status; -} diff --git a/src/general/snprintf.c b/src/general/snprintf.c deleted file mode 100644 index fefe814..0000000 --- a/src/general/snprintf.c +++ /dev/null @@ -1,184 +0,0 @@ -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 700 -#endif -#include -#include -#include -#include -#include -#include "test.h" - -#define DISABLE_SLOW_TESTS - -#define TEST(r, f, x, m) ( \ - ((r) = (f)) == (x) || \ - (error("%s failed (" m ")\n", #f, r, x), 0) ) - -#define TEST_S(s, x, m) ( \ - !strcmp((s),(x)) || \ - (error("[%s] != [%s] (%s)\n", s, x, m), 0) ) - -static const struct { - const char *fmt; - int i; - const char *expect; -} int_tests[] = { - /* width, precision, alignment */ - { "%04d", 12, "0012" }, - { "%.3d", 12, "012" }, - { "%3d", 12, " 12" }, - { "%-3d", 12, "12 " }, - { "%+3d", 12, "+12" }, - { "%+-5d", 12, "+12 " }, - { "%+- 5d", 12, "+12 " }, - { "%- 5d", 12, " 12 " }, - { "% d", 12, " 12" }, - { "%0-5d", 12, "12 " }, - { "%-05d", 12, "12 " }, - - /* ...explicit precision of 0 shall be no characters. */ - { "%.0d", 0, "" }, - { "%.0o", 0, "" }, - { "%#.0d", 0, "" }, - { "%#.0o", 0, "" }, - { "%#.0x", 0, "" }, - - /* ...but it still has to honor width and flags. */ - { "%2.0u", 0, " " }, - { "%02.0u", 0, " " }, - { "%2.0d", 0, " " }, - { "%02.0d", 0, " " }, - { "% .0d", 0, " " }, - { "%+.0d", 0, "+" }, - - /* hex: test alt form and case */ - { "%x", 63, "3f" }, - { "%#x", 63, "0x3f" }, - { "%X", 63, "3F" }, - - /* octal: test alt form */ - { "%o", 15, "17" }, - { "%#o", 15, "017" }, - - { NULL, 0.0, NULL } -}; - -static const struct { - const char *fmt; - double f; - const char *expect; -} fp_tests[] = { - /* basic form, handling of exponent/precision for 0 */ - { "%a", 0.0, "0x0p+0" }, - { "%e", 0.0, "0.000000e+00" }, - { "%f", 0.0, "0.000000" }, - { "%g", 0.0, "0" }, - { "%#g", 0.0, "0.00000" }, - { "%la", 0.0, "0x0p+0" }, - { "%le", 0.0, "0.000000e+00" }, - { "%lf", 0.0, "0.000000" }, - { "%lg", 0.0, "0" }, - { "%#lg", 0.0, "0.00000" }, - - /* rounding */ - { "%f", 1.1, "1.100000" }, - { "%f", 1.2, "1.200000" }, - { "%f", 1.3, "1.300000" }, - { "%f", 1.4, "1.400000" }, - { "%f", 1.5, "1.500000" }, - { "%.4f", 1.06125, "1.0612" }, - { "%.2f", 1.375, "1.38" }, - { "%.1f", 1.375, "1.4" }, - { "%.1lf", 1.375, "1.4" }, - { "%.15f", 1.1, "1.100000000000000" }, - { "%.16f", 1.1, "1.1000000000000001" }, - { "%.17f", 1.1, "1.10000000000000009" }, - { "%.2e", 1500001.0, "1.50e+06" }, - { "%.2e", 1505000.0, "1.50e+06" }, - { "%.2e", 1505000.00000095367431640625, "1.51e+06" }, - { "%.2e", 1505001.0, "1.51e+06" }, - { "%.2e", 1506000.0, "1.51e+06" }, - - /* correctness in DBL_DIG places */ - { "%.15g", 1.23456789012345, "1.23456789012345" }, - - /* correct choice of notation for %g */ - { "%g", 0.0001, "0.0001" }, - { "%g", 0.00001, "1e-05" }, - { "%g", 123456, "123456" }, - { "%g", 1234567, "1.23457e+06" }, - { "%.7g", 1234567, "1234567" }, - { "%.7g", 12345678, "1.234568e+07" }, - { "%.8g", 0.1, "0.1" }, - { "%.9g", 0.1, "0.1" }, - { "%.10g", 0.1, "0.1" }, - { "%.11g", 0.1, "0.1" }, - - /* pi in double precision, printed to a few extra places */ - { "%.15f", M_PI, "3.141592653589793" }, - { "%.18f", M_PI, "3.141592653589793116" }, - - /* exact conversion of large integers */ - { "%.0f", 340282366920938463463374607431768211456.0, - "340282366920938463463374607431768211456" }, - - { NULL, 0.0, NULL } -}; - -int main(void) -{ - int i, j, k; - char b[2000]; - - TEST(i, snprintf(0, 0, "%d", 123456), 6, "length returned %d != %d"); - TEST(i, snprintf(0, 0, "%.4s", "hello"), 4, "length returned %d != %d"); - TEST(i, snprintf(b, 0, "%.0s", "goodbye"), 0, "length returned %d != %d"); - - strcpy(b, "xxxxxxxx"); - TEST(i, snprintf(b, 4, "%d", 123456), 6, "length returned %d != %d"); - TEST_S(b, "123", "incorrect output"); - TEST(i, b[5], 'x', "buffer overrun"); - - /* Perform ascii arithmetic to test printing tiny doubles */ - TEST(i, snprintf(b, sizeof b, "%.1022f", 0x1p-1021), 1024, "%d != %d"); - b[1] = '0'; - for (i=0; i<1021; i++) { - for (k=0, j=1023; j>0; j--) { - if (b[j]<'5') b[j]+=b[j]-'0'+k, k=0; - else b[j]+=b[j]-'0'-10+k, k=1; - } - } - TEST(i, b[1], '1', "'%c' != '%c'"); - for (j=2; b[j]=='0'; j++); - TEST(i, j, 1024, "%d != %d"); - - -#ifndef DISABLE_SLOW_TESTS - errno = 0; - TEST(i, snprintf(NULL, 0, "%.*u", 2147483647, 0), 2147483647, "cannot print max length %d"); - TEST(i, snprintf(NULL, 0, "%.*u ", 2147483647, 0), -1, "integer overflow %d"); - TEST(i, errno, EOVERFLOW, "after overflow: %d != %d"); -#endif - for (j=0; int_tests[j].fmt; j++) { - i = snprintf(b, sizeof b, int_tests[j].fmt, int_tests[j].i); - if (i != strlen(int_tests[j].expect)) { - error("snprintf(b, sizeof b, \"%s\", %d) returned %d wanted %d\n", - int_tests[j].fmt, int_tests[j].i, i, strlen(int_tests[j].expect)); - } - if (strcmp(b, int_tests[j].expect) != 0) - error("bad integer conversion: got \"%s\", want \"%s\"\n", b, int_tests[j].expect); - } - - for (j=0; fp_tests[j].fmt; j++) { - i = snprintf(b, sizeof b, fp_tests[j].fmt, fp_tests[j].f); - if (i != strlen(fp_tests[j].expect)) { - error("snprintf(b, sizeof b, \"%s\", %f) returned %d wanted %d\n", - fp_tests[j].fmt, fp_tests[j].f, i, strlen(fp_tests[j].expect)); - } - if (strcmp(b, fp_tests[j].expect) != 0) - error("bad floating-point conversion: got \"%s\", want \"%s\"\n", b, fp_tests[j].expect); - } - - TEST(i, snprintf(0, 0, "%.4a", 1.0), 11, "%d != %d"); - return test_status; -} diff --git a/src/general/spawn.c b/src/general/spawn.c deleted file mode 100644 index 707b1a5..0000000 --- a/src/general/spawn.c +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 700 -#endif -#include -#include -#include -#include -#include -#include -#include -#include "test.h" - -#define TEST(f, x) (void)( \ - (r = (f)) == (x) || \ - error("%s failed, got %d want %d\n", #f, r, x) ) - -#define TEST_E(f) (void)( \ - (errno = 0), (f) || \ - error("%s failed (errno = %d \"%s\")\n", #f, errno, strerror(errno)) ) - -int main(void) -{ - int r; - char foo[10]; - int p[2]; - pid_t pid; - int status; - posix_spawn_file_actions_t fa; - - TEST_E(!pipe(p)); - TEST(posix_spawn_file_actions_init(&fa), 0); - TEST(posix_spawn_file_actions_addclose(&fa, p[0]), 0); - TEST(posix_spawn_file_actions_adddup2(&fa, p[1], 1), 0); - TEST(posix_spawn_file_actions_addclose(&fa, p[1]), 0); - TEST(posix_spawnp(&pid, "echo", &fa, 0, (char *[]){"echo","hello",0}, 0), 0); - close(p[1]); - TEST(waitpid(pid, &status, 0), pid); - TEST(read(p[0], foo, sizeof foo), 6); - close(p[0]); - TEST(posix_spawn_file_actions_destroy(&fa), 0); - return test_status; -} diff --git a/src/general/sscanf.c b/src/general/sscanf.c deleted file mode 100644 index a087c21..0000000 --- a/src/general/sscanf.c +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include -#include -#include "test.h" - -#define TEST(r, f, x, m) ( \ - ((r) = (f)) == (x) || \ - (error("%s failed (" m ")\n", #f, r, x), 0) ) - -#define TEST_S(s, x, m) ( \ - !strcmp((s),(x)) || \ - (error("[%s] != [%s] (%s)\n", s, x, m), 0) ) - -#define TEST_F(x) ( \ - TEST(i, sscanf(# x, "%lf", &d), 1, "got %d fields, expected %d"), \ - TEST(t, d, (double)x, "%g != %g") ) - -int main(void) -{ - int i; - char a[100], b[100]; - int x, y, z, u, v; - double d, t; - - TEST(i, sscanf("hello, world\n", "%s %s", a, b), 2, "only %d fields, expected %d"); - TEST_S(a, "hello,", ""); - TEST_S(b, "world", ""); - - TEST(i, sscanf("hello, world\n", "%[hel]%s", a, b), 2, "only %d fields, expected %d"); - TEST_S(a, "hell", ""); - TEST_S(b, "o,", ""); - - TEST(i, sscanf("hello, world\n", "%[hel] %s", a, b), 2, "only %d fields, expected %d"); - TEST_S(a, "hell", ""); - TEST_S(b, "o,", ""); - - a[8] = 'X'; - a[9] = 0; - TEST(i, sscanf("hello, world\n", "%8c%8c", a, b), 1, "%d fields, expected %d"); - TEST_S(a, "hello, wX", ""); - - TEST(i, sscanf("56789 0123 56a72", "%2d%d%*d %[0123456789]\n", &x, &y, a), 3, "only %d fields, expected %d"); - TEST(i, x, 56, "%d != %d"); - TEST(i, y, 789, "%d != %d"); - TEST_S(a, "56", ""); - - TEST(i, sscanf("011 0x100 11 0x100 100", "%i %i %o %x %x\n", &x, &y, &z, &u, &v), 5, "only %d fields, expected %d"); - TEST(i, x, 9, "%d != %d"); - TEST(i, y, 256, "%d != %d"); - TEST(i, z, 9, "%d != %d"); - TEST(i, u, 256, "%d != %d"); - TEST(i, v, 256, "%d != %d"); - - TEST(i, sscanf("20 xyz", "%d %d\n", &x, &y), 1, "only %d fields, expected %d"); - TEST(i, x, 20, "%d != %d"); - - TEST(i, sscanf("xyz", "%d\n", &x, &y), 0, "got %d fields, expected no match (%d)"); - - TEST(i, sscanf("", "%d\n", &x, &y), -1, "got %d fields, expected input failure (%d)"); - - TEST(i, sscanf(" 12345 6", "%2d%d%d", &x, &y, &z), 3, "only %d fields, expected %d"); - TEST(i, x, 12, "%d != %d"); - TEST(i, y, 345, "%d != %d"); - TEST(i, z, 6, "%d != %d"); - - TEST(i, sscanf(" 0x12 0x34", "%5i%2i", &x, &y), 1, "got %d fields, expected %d"); - TEST(i, x, 0x12, "%d != %d"); - - TEST_F(123); - TEST_F(123.0); - TEST_F(123.0e+0); - TEST_F(123.0e+4); - TEST_F(1.234e1234); - TEST_F(1.234e-1234); - TEST_F(1.234e56789); - TEST_F(1.234e-56789); - TEST_F(-0.5); - TEST_F(0.1); - TEST_F(0.2); - TEST_F(0.1e-10); - TEST_F(0x1234p56); - - TEST(i, sscanf("10e", "%lf", &d), 0, "got %d fields, expected no match (%d)"); - TEST(i, sscanf("", "%lf\n", &d), -1, "got %d fields, expected input failure (%d)"); - return test_status; -} diff --git a/src/general/sscanf_long.c b/src/general/sscanf_long.c deleted file mode 100644 index a26999d..0000000 --- a/src/general/sscanf_long.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "test.h" - -static void setrl(int r, long lim) -{ - struct rlimit rl; - - if (getrlimit(r, &rl)) - error("getrlimit %d: %s\n", r, strerror(errno)); - rl.rlim_cur = lim; - if (setrlimit(r, &rl)) - error("setrlimit %d: %s\n", r, strerror(errno)); -} - -int main(void) -{ - enum {n = 8*1024*1024}; - char *s = malloc(n); - int i; - float f; - char c; - - if (!s) - return error("out of memory"); - setrl(RLIMIT_STACK, 128*1024); - - for (i = 0; i < n; i++) s[i] = '1'; - s[n-3] = ' '; - s[n-1] = 0; - - /* - * stack overflow if scanf copies s on the stack (glibc) - * same issue with %d except then storing the conversion - * result is undefined behaviour - */ - i = sscanf(s, "%f %c", &f, &c); - - if (i != 2) - error("sscanf returned %d, want 2\n", i); - if (f != INFINITY) - error("sscanf(longnum, \"%%f\") read %f, want inf\n", f); - if (c != '1') - error("sscanf(\"1\", %%c) read '%c', want '1'\n", c); - free(s); - return test_status; -} diff --git a/src/general/string.c b/src/general/string.c deleted file mode 100644 index 2e06eb9..0000000 --- a/src/general/string.c +++ /dev/null @@ -1,116 +0,0 @@ -#define _BSD_SOURCE -#include -#include -#include "test.h" - -/* r = place to store result - * f = function call to test (or any expression) - * x = expected result - * m = message to print on failure (with formats for r & x) -**/ - -#define TEST(r, f, x, m) ( \ - ((r) = (f)) == (x) || \ - (error("%s failed (" m ")\n", #f, r, x), 0) ) - -#define TEST_S(s, x, m) ( \ - !strcmp((s),(x)) || \ - (error("[%s] != [%s] (%s)\n", s, x, m), 0) ) - -int main(void) -{ - char b[32]; - char *s; - int i; - - b[16]='a'; b[17]='b'; b[18]='c'; b[19]=0; - TEST(s, strcpy(b, b+16), b, "wrong return %p != %p"); - TEST_S(s, "abc", "strcpy gave incorrect string"); - TEST(s, strcpy(b+1, b+16), b+1, "wrong return %p != %p"); - TEST_S(s, "abc", "strcpy gave incorrect string"); - TEST(s, strcpy(b+2, b+16), b+2, "wrong return %p != %p"); - TEST_S(s, "abc", "strcpy gave incorrect string"); - TEST(s, strcpy(b+3, b+16), b+3, "wrong return %p != %p"); - TEST_S(s, "abc", "strcpy gave incorrect string"); - - TEST(s, strcpy(b+1, b+17), b+1, "wrong return %p != %p"); - TEST_S(s, "bc", "strcpy gave incorrect string"); - TEST(s, strcpy(b+2, b+18), b+2, "wrong return %p != %p"); - TEST_S(s, "c", "strcpy gave incorrect string"); - TEST(s, strcpy(b+3, b+19), b+3, "wrong return %p != %p"); - TEST_S(s, "", "strcpy gave incorrect string"); - - TEST(s, memset(b, 'x', sizeof b), b, "wrong return %p != %p"); - TEST(s, strncpy(b, "abc", sizeof b - 1), b, "wrong return %p != %p"); - TEST(i, memcmp(b, "abc\0\0\0\0", 8), 0, "strncpy fails to zero-pad dest"); - TEST(i, b[sizeof b - 1], 'x', "strncpy overruns buffer when n > strlen(src)"); - - b[3] = 'x'; b[4] = 0; - strncpy(b, "abc", 3); - TEST(i, b[2], 'c', "strncpy fails to copy last byte: %hhu != %hhu"); - TEST(i, b[3], 'x', "strncpy overruns buffer to null-terminate: %hhu != %hhu"); - - TEST(i, !strncmp("abcd", "abce", 3), 1, "strncmp compares past n"); - TEST(i, !!strncmp("abc", "abd", 3), 1, "strncmp fails to compare n-1st byte"); - - strcpy(b, "abc"); - TEST(s, strncat(b, "123456", 3), b, "%p != %p"); - TEST(i, b[6], 0, "strncat failed to null-terminate (%d)"); - TEST_S(s, "abc123", "strncat gave incorrect string"); - - strcpy(b, "aaababccdd0001122223"); - TEST(s, strchr(b, 'b'), b+3, "%p != %p"); - TEST(s, strrchr(b, 'b'), b+5, "%p != %p"); - TEST(i, strspn(b, "abcd"), 10, "%d != %d"); - TEST(i, strcspn(b, "0123"), 10, "%d != %d"); - TEST(s, strpbrk(b, "0123"), b+10, "%d != %d"); - - strcpy(b, "abc 123; xyz; foo"); - TEST(s, strtok(b, " "), b, "%p != %p"); - TEST_S(s, "abc", "strtok result"); - - TEST(s, strtok(NULL, ";"), b+4, "%p != %p"); - TEST_S(s, " 123", "strtok result"); - - TEST(s, strtok(NULL, " ;"), b+11, "%p != %p"); - TEST_S(s, "xyz", "strtok result"); - - TEST(s, strtok(NULL, " ;"), b+16, "%p != %p"); - TEST_S(s, "foo", "strtok result"); - -#ifdef HAVE_BSD_STRL - memset(b, 'x', sizeof b); - TEST(i, strlcpy(b, "abc", sizeof b - 1), 3, "length %d != %d"); - TEST(i, b[3], 0, "strlcpy did not null-terminate short string (%d)"); - TEST(i, b[4], 'x', "strlcpy wrote extra bytes (%d)"); - - memset(b, 'x', sizeof b); - TEST(i, strlcpy(b, "abc", 2), 3, "length %d != %d"); - TEST(i, b[0], 'a', "strlcpy did not copy character %d"); - TEST(i, b[1], 0, "strlcpy did not null-terminate long string (%d)"); - - memset(b, 'x', sizeof b); - TEST(i, strlcpy(b, "abc", 3), 3, "length %d != %d"); - TEST(i, b[2], 0, "strlcpy did not null-terminate l-length string (%d)"); - - TEST(i, strlcpy(NULL, "abc", 0), 3, "length %d != %d"); - - memcpy(b, "abc\0\0\0x\0", 8); - TEST(i, strlcat(b, "123", sizeof b), 6, "length %d != %d"); - TEST_S(b, "abc123", "strlcat result"); - - memcpy(b, "abc\0\0\0x\0", 8); - TEST(i, strlcat(b, "123", 6), 6, "length %d != %d"); - TEST_S(b, "abc12", "strlcat result"); - TEST(i, b[6], 'x', "strlcat wrote past string %d != %d"); - - memcpy(b, "abc\0\0\0x\0", 8); - TEST(i, strlcat(b, "123", 4), 6, "length %d != %d"); - TEST_S(b, "abc", "strlcat result"); - - memcpy(b, "abc\0\0\0x\0", 8); - TEST(i, strlcat(b, "123", 3), 6, "length %d != %d"); - TEST_S(b, "abc", "strlcat result"); -#endif - return test_status; -} diff --git a/src/general/string_memmem.c b/src/general/string_memmem.c deleted file mode 100644 index d21164a..0000000 --- a/src/general/string_memmem.c +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE 1 -#endif -#include -#include "test.h" - -#define N(s, sub) { \ - char *p = s; \ - char *q = memmem(p, strlen(p), sub, strlen(sub)); \ - if (q) \ - error("memmem(%s,%s) returned str+%d, wanted 0\n", #s, #sub, q-p); \ -} - -#define T(s, sub, n) { \ - char *p = s; \ - char *q = memmem(p, strlen(p), sub, strlen(sub)); \ - if (q == 0) \ - error("memmem(%s,%s) returned 0, wanted str+%d\n", #s, #sub, n); \ - else if (q - p != n) \ - error("memmem(%s,%s) returned str+%d, wanted str+%d\n", #s, #sub, q-p, n); \ -} - -int main(void) -{ - N("", "a") - N("a", "aa") - N("a", "b") - N("aa", "ab") - N("aa", "aaa") - N("abba", "aba") - N("abc abc", "abcd") - N("0-1-2-3-4-5-6-7-8-9", "-3-4-56-7-8-") - N("0-1-2-3-4-5-6-7-8-9", "-3-4-5+6-7-8-") - N("_ _ _\xff_ _ _", "_\x7f_") - N("_ _ _\x7f_ _ _", "_\xff_") - - T("", "", 0) - T("abcd", "", 0) - T("abcd", "a", 0) - T("abcd", "b", 1) - T("abcd", "c", 2) - T("abcd", "d", 3) - T("abcd", "ab", 0) - T("abcd", "bc", 1) - T("abcd", "cd", 2) - T("ababa", "baba", 1) - T("ababab", "babab", 1) - T("abababa", "bababa", 1) - T("abababab", "bababab", 1) - T("ababababa", "babababa", 1) - T("nanabanabanana", "aba", 3) - T("nanabanabanana", "ban", 4) - T("nanabanabanana", "anab", 1) - T("nanabanabanana", "banana", 8) - T("_ _\xff_ _", "_\xff_", 2) - - return test_status; -} diff --git a/src/general/string_strchr.c b/src/general/string_strchr.c deleted file mode 100644 index c05d881..0000000 --- a/src/general/string_strchr.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include "test.h" - -#define N(s, c) { \ - char *p = s; \ - char *q = strchr(p, c); \ - if (q) \ - error("strchr(%s,%s) returned str+%d, wanted 0\n", #s, #c, q-p); \ -} - -#define T(s, c, n) { \ - char *p = s; \ - char *q = strchr(p, c); \ - if (q == 0) \ - error("strchr(%s,%s) returned 0, wanted str+%d\n", #s, #c, n); \ - else if (q - p != n) \ - error("strchr(%s,%s) returned str+%d, wanted str+%d\n", #s, #c, q-p, n); \ -} - -int main(void) -{ - int i; - char a[128]; - char s[256]; - - for (i = 0; i < 128; i++) - a[i] = (i+1) & 127; - for (i = 0; i < 256; i++) - *((unsigned char*)s+i) = i+1; - - N("", 'a') - N("a", 'b') - N("abc abc", 'x') - N(a, 128) - N(a, 255) - - T("", 0, 0) - T("a", 'a', 0) - T("a", 'a'+256, 0) - T("a", 0, 1) - T("ab", 'b', 1) - T("aab", 'b', 2) - T("aaab", 'b', 3) - T("aaaab", 'b', 4) - T("aaaaab", 'b', 5) - T("aaaaaab", 'b', 6) - T("abc abc", 'c', 2) - T(s, 1, 0) - T(s, 2, 1) - T(s, 10, 9) - T(s, 11, 10) - T(s, 127, 126) - T(s, 128, 127) - T(s, 255, 254) - T(s, 0, 255) - - return test_status; -} diff --git a/src/general/string_strcspn.c b/src/general/string_strcspn.c deleted file mode 100644 index 87fcd10..0000000 --- a/src/general/string_strcspn.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include -#include "test.h" - -#define T(s, c, n) { \ - char *p = s; \ - char *q = c; \ - size_t r = strcspn(p, q); \ - if (r != n) \ - error("strcspn(%s,%s) returned %lu, wanted %lu\n", #s, #c, (unsigned long)r, (unsigned long)(n)); \ -} - -int main(void) -{ - int i; - char a[128]; - char s[256]; - - for (i = 0; i < 128; i++) - a[i] = (i+1) & 127; - for (i = 0; i < 256; i++) - *((unsigned char*)s+i) = i+1; - - T("", "", 0) - T("a", "", 1) - T("", "a", 0) - T("abc", "cde", 2) - T("abc", "ccc", 2) - T("abc", a, 0) - T("\xff\x80 abc", a, 2) - T(s, "\xff", 254) - - return test_status; -} diff --git a/src/general/string_strstr.c b/src/general/string_strstr.c deleted file mode 100644 index 2e3b352..0000000 --- a/src/general/string_strstr.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include "test.h" - -#define N(s, sub) { \ - char *p = s; \ - char *q = strstr(p, sub); \ - if (q) \ - error("strstr(%s,%s) returned str+%d, wanted 0\n", #s, #sub, q-p); \ -} - -#define T(s, sub, n) { \ - char *p = s; \ - char *q = strstr(p, sub); \ - if (q == 0) \ - error("strstr(%s,%s) returned 0, wanted str+%d\n", #s, #sub, n); \ - else if (q - p != n) \ - error("strstr(%s,%s) returned str+%d, wanted str+%d\n", #s, #sub, q-p, n); \ -} - -int main(void) -{ - N("", "a") - N("a", "aa") - N("a", "b") - N("aa", "ab") - N("aa", "aaa") - N("abba", "aba") - N("abc abc", "abcd") - N("0-1-2-3-4-5-6-7-8-9", "-3-4-56-7-8-") - N("0-1-2-3-4-5-6-7-8-9", "-3-4-5+6-7-8-") - N("_ _ _\xff_ _ _", "_\x7f_") - N("_ _ _\x7f_ _ _", "_\xff_") - - T("", "", 0) - T("abcd", "", 0) - T("abcd", "a", 0) - T("abcd", "b", 1) - T("abcd", "c", 2) - T("abcd", "d", 3) - T("abcd", "ab", 0) - T("abcd", "bc", 1) - T("abcd", "cd", 2) - T("ababa", "baba", 1) - T("ababab", "babab", 1) - T("abababa", "bababa", 1) - T("abababab", "bababab", 1) - T("ababababa", "babababa", 1) - T("nanabanabanana", "aba", 3) - T("nanabanabanana", "ban", 4) - T("nanabanabanana", "anab", 1) - T("nanabanabanana", "banana", 8) - T("_ _\xff_ _", "_\xff_", 2) - - return test_status; -} diff --git a/src/general/strtod.c b/src/general/strtod.c deleted file mode 100644 index c6967ac..0000000 --- a/src/general/strtod.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include -#include -#include "test.h" - -#define length(x) (sizeof(x) / sizeof *(x)) - -static struct { - char *s; - double f; -} t[] = { - {"0", 0.0}, - {"00.00", 0.0}, - {"-.00000", -0.0}, - {"1e+1000000", INFINITY}, - {"1e-1000000", 0}, - // 2^-1074 * 0.5 - eps - {".2470328229206232720882843964341106861825299013071623822127928412503377536351043e-323", 0}, - // 2^-1074 * 0.5 + eps - {".2470328229206232720882843964341106861825299013071623822127928412503377536351044e-323", 0x1p-1074}, - // 2^-1074 * 1.5 - eps - {".7410984687618698162648531893023320585475897039214871466383785237510132609053131e-323", 0x1p-1074}, - // 2^-1074 * 1.5 + eps - {".7410984687618698162648531893023320585475897039214871466383785237510132609053132e-323", 0x1p-1073}, - // 2^-1022 + 2^-1075 - eps - {".2225073858507201630123055637955676152503612414573018013083228724049586647606759e-307", 0x1p-1022}, - // 2^-1022 + 2^-1075 + eps - {".2225073858507201630123055637955676152503612414573018013083228724049586647606760e-307", 0x1.0000000000001p-1022}, - // 2^1024 - 2^970 - eps - {"17976931348623158079372897140530341507993413271003782693617377898044" - "49682927647509466490179775872070963302864166928879109465555478519404" - "02630657488671505820681908902000708383676273854845817711531764475730" - "27006985557136695962284291481986083493647529271907416844436551070434" - "2711559699508093042880177904174497791.999999999999999999999999999999", 0x1.fffffffffffffp1023}, - // 2^1024 - 2^970 - {"17976931348623158079372897140530341507993413271003782693617377898044" - "49682927647509466490179775872070963302864166928879109465555478519404" - "02630657488671505820681908902000708383676273854845817711531764475730" - "27006985557136695962284291481986083493647529271907416844436551070434" - "2711559699508093042880177904174497792", INFINITY}, - // some random numbers - {".5961860348131807091861002266453941950428e00", 0.59618603481318067}, // 0x1.313f4bc3b584cp-1 - {"1.815013169218038729887460898733526957442e-1", 0.18150131692180388}, // 0x1.73b6f662e1712p-3 - {"42.07082357534453600681618685682257590772e-2", 0.42070823575344535}, // 0x1.aece23c6e028dp-2 - {"665.4686306516261456328973225579833470816e-3", 0.66546863065162609}, // 0x1.54b84dea53453p-1 - {"6101.852922970868621786690495485449831753e-4", 0.61018529229708685}, // 0x1.386a34e5d516bp-1 - {"76966.95208236968077849464348875471158549e-5", 0.76966952082369677}, // 0x1.8a121f9954dfap-1 - {"250506.5322228682496132604807222923702304e-6", 0.25050653222286823}, // 0x1.0084c8cd538c2p-2 - {"2740037.230228005325852424697698331177377e-7", 0.27400372302280052}, // 0x1.18946e9575ef4p-2 - {"20723093.50049742645941529268715428324490e-8", 0.20723093500497428}, // 0x1.a868b14486e4dp-3 - {"0.7900280238081604956226011047460238748912e1", 7.9002802380816046}, // 0x1.f99e3100f2eaep+2 - {"0.9822860653737296848190558448760465863597e2", 98.228606537372968}, // 0x1.88ea17d506accp+6 - {"0.7468949723190370809405570560160405324869e3", 746.89497231903704}, // 0x1.75728e73f48b7p+9 - {"0.1630268320282728475980459844271031751665e4", 1630.2683202827284}, // 0x1.97912c28d5cbp+10 - {"0.4637168629719170695109918769645492022088e5", 46371.686297191707}, // 0x1.6a475f6258737p+15 - {"0.6537805944497711554209461686415872067523e6", 653780.59444977110}, // 0x1.3f3a9305bb86cp+19 - {"0.2346324356502437045212230713960457676531e6", 234632.43565024371}, // 0x1.ca4437c3631eap+17 - {"0.9709481716420048341897258980454298205278e8", 97094817.164200485}, // 0x1.7263284a8242cp+26 - {"0.4996908522051874110779982354932499499602e9", 499690852.20518744}, // 0x1.dc8ad6434872ap+28 -}; - -int main(void) -{ - int i; - double x; - char *p; - - for (i = 0; i < length(t); i++) { - x = strtod(t[i].s, &p); - if (x != t[i].f) - error("strtod(\"%s\") want %a got %a\n", t[i].s, t[i].f, x); - } - return test_status; -} - diff --git a/src/general/strtod_long.c b/src/general/strtod_long.c deleted file mode 100644 index d2db2e8..0000000 --- a/src/general/strtod_long.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -#include -#include "test.h" - -int main(void) -{ - double x, want = .1111111111111111111111; - char buf[40000]; - - memset(buf, '1', sizeof buf); - buf[0] = '.'; - buf[sizeof buf - 1] = 0; - - if ((x=strtod(buf, 0)) != want) - error("strtod(.11[...]1) got %a want %a\n", x, want); - return test_status; -} - diff --git a/src/general/strtod_simple.c b/src/general/strtod_simple.c deleted file mode 100644 index c95dc9e..0000000 --- a/src/general/strtod_simple.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include -#include -#include "test.h" - -/* r = place to store result - * f = function call to test (or any expression) - * x = expected result - * m = message to print on failure (with formats for r & x) -**/ - -#define TEST(r, f, x, m) ( \ - ((r) = (f)) == (x) || \ - (error("%s failed (" m ")\n", #f, r, x, r-x), 0) ) - -int main(void) -{ - int i; - double d, d2; - char buf[1000]; - - for (i=0; i<100; i++) { - d = sin(i); - snprintf(buf, sizeof buf, "%.300f", d); - TEST(d2, strtod(buf, 0), d, "round trip fail %a != %a (%a)"); - } - - TEST(d, strtod("0x1p4", 0), 16.0, "hex float %a != %a"); - TEST(d, strtod("0x1.1p4", 0), 17.0, "hex float %a != %a"); - return test_status; -} - diff --git a/src/general/strtof.c b/src/general/strtof.c deleted file mode 100644 index 29876bc..0000000 --- a/src/general/strtof.c +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include -#include -#include "test.h" - -#define length(x) (sizeof(x) / sizeof *(x)) - -static struct { - char *s; - float f; -} t[] = { - // 2^-149 * 0.5 - eps - {".7006492321624085354618647916449580656401309709382578858785341419448955413429303e-45", 0}, - // 2^-149 * 0.5 + eps - {".7006492321624085354618647916449580656401309709382578858785341419448955413429304e-45", 0x1p-149}, - // 2^-149 * 0.5 - eps - {".2101947696487225606385594374934874196920392912814773657635602425834686624028790e-44", 0x1p-149}, - // 2^-149 * 0.5 + eps - {".2101947696487225606385594374934874196920392912814773657635602425834686624028791e-44", 0x1p-148}, - // 2^-126 + 2^-150 - eps - {".1175494420887210724209590083408724842314472120785184615334540294131831453944281e-37", 0x1p-126}, - // 2^-126 + 2^-150 + eps - {".1175494420887210724209590083408724842314472120785184615334540294131831453944282e-37", 0x1.000002p-126}, - // 2^128 - 2^103 - eps - {"340282356779733661637539395458142568447.9999999999999999999", 0x1.fffffep127}, - // 2^128 - 2^103 - {"340282356779733661637539395458142568448", INFINITY}, -}; - -int main(void) -{ - int i; - float x; - char *p; - - for (i = 0; i < length(t); i++) { - x = strtof(t[i].s, &p); - if (x != t[i].f) - error("strtof(\"%s\") want %a got %a\n", t[i].s, t[i].f, x); - } - return test_status; -} diff --git a/src/general/strtol.c b/src/general/strtol.c deleted file mode 100644 index 81df887..0000000 --- a/src/general/strtol.c +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include -#include -#include "test.h" - -/* r = place to store result - * f = function call to test (or any expression) - * x = expected result - * m = message to print on failure (with formats for r & x) -**/ - -#define TEST(r, f, x, m) ( \ - errno = 0, msg = #f, ((r) = (f)) == (x) || \ - (error("%s failed (" m ")\n", #f, r, x), 0) ) - -#define TEST2(r, f, x, m) ( \ - ((r) = (f)) == (x) || \ - (error("%s failed (" m ")\n", msg, r, x), 0) ) - -int main(void) -{ - int i; - long l; - unsigned long ul; - char *msg=""; - char *s, *c; - - TEST(l, atol("2147483647"), 2147483647L, "max 32bit signed %ld != %ld"); - TEST(l, strtol("2147483647", 0, 0), 2147483647L, "max 32bit signed %ld != %ld"); - TEST(ul, strtoul("4294967295", 0, 0), 4294967295UL, "max 32bit unsigned %lu != %lu"); - - if (sizeof(long) == 4) { - TEST(l, strtol(s="2147483648", &c, 0), 2147483647L, "uncaught overflow %ld != %ld"); - TEST2(i, c-s, 10, "wrong final position %d != %d"); - TEST2(i, errno, ERANGE, "missing errno %d != %d"); - TEST(l, strtol(s="-2147483649", &c, 0), -2147483647L-1, "uncaught overflow %ld != %ld"); - TEST2(i, c-s, 11, "wrong final position %d != %d"); - TEST2(i, errno, ERANGE, "missing errno %d != %d"); - TEST(ul, strtoul(s="4294967296", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu"); - TEST2(i, c-s, 10, "wrong final position %d != %d"); - TEST2(i, errno, ERANGE, "missing errno %d != %d"); - TEST(ul, strtoul(s="-1", &c, 0), -1UL, "rejected negative %lu != %lu"); - TEST2(i, c-s, 2, "wrong final position %d != %d"); - TEST2(i, errno, 0, "spurious errno %d != %d"); - TEST(ul, strtoul(s="-2", &c, 0), -2UL, "rejected negative %lu != %lu"); - TEST2(i, c-s, 2, "wrong final position %d != %d"); - TEST2(i, errno, 0, "spurious errno %d != %d"); - TEST(ul, strtoul(s="-2147483648", &c, 0), -2147483648UL, "rejected negative %lu != %lu"); - TEST2(i, c-s, 11, "wrong final position %d != %d"); - TEST2(i, errno, 0, "spurious errno %d != %d"); - TEST(ul, strtoul(s="-2147483649", &c, 0), -2147483649UL, "rejected negative %lu != %lu"); - TEST2(i, c-s, 11, "wrong final position %d != %d"); - TEST2(i, errno, 0, "spurious errno %d != %d"); - } else { - TEST(i, 0, 1, "64bit tests not implemented"); - } - - TEST(l, strtol("z", 0, 36), 35, "%ld != %ld"); - TEST(l, strtol("00010010001101000101011001111000", 0, 2), 0x12345678, "%ld != %ld"); - TEST(l, strtol(s="0F5F", &c, 16), 0x0f5f, "%ld != %ld"); - - TEST(l, strtol(s="0xz", &c, 16), 0, "%ld != %ld"); - TEST2(i, c-s, 1, "wrong final position %ld != %ld"); - - TEST(l, strtol(s="0x1234", &c, 16), 0x1234, "%ld != %ld"); - TEST2(i, c-s, 6, "wrong final position %ld != %ld"); - - c = NULL; - TEST(l, strtol(s="123", &c, 37), 0, "%ld != %ld"); - TEST2(i, c-s, 0, "wrong final position %d != %d"); - TEST2(i, errno, EINVAL, "%d != %d"); - return test_status; -} diff --git a/src/general/strtold.c b/src/general/strtold.c deleted file mode 100644 index e37f7f0..0000000 --- a/src/general/strtold.c +++ /dev/null @@ -1,94 +0,0 @@ -#include -#include -#include -#include -#include "test.h" - -#define length(x) (sizeof(x) / sizeof *(x)) - -static struct { - char *s; - long double f; -} t[] = { - {"0", 0.0}, - {"12.345", 12.345L}, - {"1.2345e1", 12.345L}, - {"1e+1000000", INFINITY}, - {"1e-1000000", 0}, -#if LDBL_MANT_DIG == 53 - // 2^-1074 * 0.5 - eps - {".2470328229206232720882843964341106861825299013071623822127928412503377536351043e-323", 0}, - // 2^-1074 * 0.5 + eps - {".2470328229206232720882843964341106861825299013071623822127928412503377536351044e-323", 0x1p-1074}, - // 2^-1074 * 1.5 - eps - {".7410984687618698162648531893023320585475897039214871466383785237510132609053131e-323", 0x1p-1074}, - // 2^-1074 * 1.5 + eps - {".7410984687618698162648531893023320585475897039214871466383785237510132609053132e-323", 0x1p-1073}, - // 2^-1022 + 2^-1075 - eps - {".2225073858507201630123055637955676152503612414573018013083228724049586647606759e-307", 0x1p-1022}, - // 2^-1022 + 2^-1075 + eps - {".2225073858507201630123055637955676152503612414573018013083228724049586647606760e-307", 0x1.0000000000001p-1022}, - // 2^1024 - 2^970 - eps - {"17976931348623158079372897140530341507993413271003782693617377898044" - "49682927647509466490179775872070963302864166928879109465555478519404" - "02630657488671505820681908902000708383676273854845817711531764475730" - "27006985557136695962284291481986083493647529271907416844436551070434" - "2711559699508093042880177904174497791.999999999999999999999999999999", 0x1.fffffffffffffp1023}, - // 2^1024 - 2^970 - {"17976931348623158079372897140530341507993413271003782693617377898044" - "49682927647509466490179775872070963302864166928879109465555478519404" - "02630657488671505820681908902000708383676273854845817711531764475730" - "27006985557136695962284291481986083493647529271907416844436551070434" - "2711559699508093042880177904174497792", INFINITY}, - // some random numbers - {".5961860348131807091861002266453941950428e00", 0.59618603481318067}, // 0x1.313f4bc3b584cp-1 - {"1.815013169218038729887460898733526957442e-1", 0.18150131692180388}, // 0x1.73b6f662e1712p-3 - {"42.07082357534453600681618685682257590772e-2", 0.42070823575344535}, // 0x1.aece23c6e028dp-2 - {"665.4686306516261456328973225579833470816e-3", 0.66546863065162609}, // 0x1.54b84dea53453p-1 - {"6101.852922970868621786690495485449831753e-4", 0.61018529229708685}, // 0x1.386a34e5d516bp-1 - {"76966.95208236968077849464348875471158549e-5", 0.76966952082369677}, // 0x1.8a121f9954dfap-1 - {"250506.5322228682496132604807222923702304e-6", 0.25050653222286823}, // 0x1.0084c8cd538c2p-2 - {"2740037.230228005325852424697698331177377e-7", 0.27400372302280052}, // 0x1.18946e9575ef4p-2 - {"20723093.50049742645941529268715428324490e-8", 0.20723093500497428}, // 0x1.a868b14486e4dp-3 - {"0.7900280238081604956226011047460238748912e1", 7.9002802380816046}, // 0x1.f99e3100f2eaep+2 - {"0.9822860653737296848190558448760465863597e2", 98.228606537372968}, // 0x1.88ea17d506accp+6 - {"0.7468949723190370809405570560160405324869e3", 746.89497231903704}, // 0x1.75728e73f48b7p+9 - {"0.1630268320282728475980459844271031751665e4", 1630.2683202827284}, // 0x1.97912c28d5cbp+10 - {"0.4637168629719170695109918769645492022088e5", 46371.686297191707}, // 0x1.6a475f6258737p+15 - {"0.6537805944497711554209461686415872067523e6", 653780.59444977110}, // 0x1.3f3a9305bb86cp+19 - {"0.2346324356502437045212230713960457676531e6", 234632.43565024371}, // 0x1.ca4437c3631eap+17 - {"0.9709481716420048341897258980454298205278e8", 97094817.164200485}, // 0x1.7263284a8242cp+26 - {"0.4996908522051874110779982354932499499602e9", 499690852.20518744}, // 0x1.dc8ad6434872ap+28 -#elif LDBL_MANT_DIG == 64 - // 2^-16445 * 0.5 - eps - {".1822599765941237301264202966809709908199525407846781671860490243514185844316698e-4950", 0}, - // 2^-16445 * 0.5 + eps - {".1822599765941237301264202966809709908199525407846781671860490243514185844316699e-4950", 0x1p-16445L}, - // 2^-16445 * 1.5 - eps - {".5467799297823711903792608900429129724598576223540345015581470730542557532950096e-4950", 0x1p-16445L}, - // 2^-16445 * 1.5 + eps - {".5467799297823711903792608900429129724598576223540345015581470730542557532950097e-4950", 0x1p-16444L}, - // 2^-16382 + 2^-16446 - eps - {".3362103143112093506444937793915876332724499641527442230928779770593420866576777e-4931", 0x1p-16382L}, - // 2^-16382 + 2^-16446 + eps - {".3362103143112093506444937793915876332724499641527442230928779770593420866576778e-4931", 0x1.0000000000000002p-16382L}, - // 2^16384 - 2^16319 - eps - {"118973149535723176505351158982948.86679662540046955672e4900", 0x1.fffffffffffffffep16383L}, - // 2^16384 - 2^16319 + eps - {"118973149535723176505351158982948.86679662540046955673e4900", INFINITY}, -#endif -}; - -int main(void) -{ - int i; - long double x; - char *p; - - for (i = 0; i < length(t); i++) { - x = strtold(t[i].s, &p); - if (x != t[i].f) - error("strtold(\"%s\") want %La got %La\n", t[i].s, t[i].f, x); - } - return test_status; -} diff --git a/src/general/swprintf.c b/src/general/swprintf.c deleted file mode 100644 index 10a8380..0000000 --- a/src/general/swprintf.c +++ /dev/null @@ -1,151 +0,0 @@ -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 700 -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include "test.h" - -#define TEST(r, f, x, m) ( \ - ((r) = (f)) == (x) || \ - (error("%s failed (" m ")\n", #f, r, x), 0) ) - -#define TEST_S(s, x, m) ( \ - !wcscmp((s),(x)) || \ - (error("[%ls] != [%ls] (%s)\n", s, x, m), 0) ) - -static const struct { - const wchar_t *fmt; - int i; - const wchar_t *expect; -} int_tests[] = { - /* width, precision, alignment */ - { L"%04d", 12, L"0012" }, - { L"%.3d", 12, L"012" }, - { L"%3d", 12, L" 12" }, - { L"%-3d", 12, L"12 " }, - { L"%+3d", 12, L"+12" }, - { L"%+-5d", 12, L"+12 " }, - { L"%+- 5d", 12, L"+12 " }, - { L"%- 5d", 12, L" 12 " }, - { L"% d", 12, L" 12" }, - { L"%0-5d", 12, L"12 " }, - { L"%-05d", 12, L"12 " }, - - /* ...explicit precision of 0 shall be no characters. */ - { L"%.0d", 0, L"" }, - { L"%.0o", 0, L"" }, - { L"%#.0d", 0, L"" }, - { L"%#.0o", 0, L"" }, - { L"%#.0x", 0, L"" }, - - /* hex: test alt form and case */ - { L"%x", 63, L"3f" }, - { L"%#x", 63, L"0x3f" }, - { L"%X", 63, L"3F" }, - - /* octal: test alt form */ - { L"%o", 15, L"17" }, - { L"%#o", 15, L"017" }, - - { NULL, 0.0, NULL } -}; - -static const struct { - const wchar_t *fmt; - double f; - const wchar_t *expect; -} fp_tests[] = { - /* basic form, handling of exponent/precision for 0 */ - { L"%e", 0.0, L"0.000000e+00" }, - { L"%f", 0.0, L"0.000000" }, - { L"%g", 0.0, L"0" }, - { L"%#g", 0.0, L"0.00000" }, - - /* rounding */ - { L"%f", 1.1, L"1.100000" }, - { L"%f", 1.2, L"1.200000" }, - { L"%f", 1.3, L"1.300000" }, - { L"%f", 1.4, L"1.400000" }, - { L"%f", 1.5, L"1.500000" }, - - /* correctness in DBL_DIG places */ - { L"%.15g", 1.23456789012345, L"1.23456789012345" }, - - /* correct choice of notation for %g */ - { L"%g", 0.0001, L"0.0001" }, - { L"%g", 0.00001, L"1e-05" }, - { L"%g", 123456, L"123456" }, - { L"%g", 1234567, L"1.23457e+06" }, - { L"%.7g", 1234567, L"1234567" }, - { L"%.7g", 12345678, L"1.234568e+07" }, - - /* pi in double precision, printed to a few extra places */ - { L"%.15f", M_PI, L"3.141592653589793" }, - { L"%.18f", M_PI, L"3.141592653589793116" }, - - /* exact conversion of large integers */ - { L"%.0f", 340282366920938463463374607431768211456.0, - L"340282366920938463463374607431768211456" }, - - { NULL, 0.0, NULL } -}; - -int main(void) -{ - int i, j; - wchar_t b[500]; - - (void)( - setlocale(LC_CTYPE, "en_US.UTF-8") || - setlocale(LC_CTYPE, "en_GB.UTF-8") || - setlocale(LC_CTYPE, "en.UTF-8") || - setlocale(LC_CTYPE, "POSIX.UTF-8") || - setlocale(LC_CTYPE, "C.UTF-8") || - setlocale(LC_CTYPE, "UTF-8") || - setlocale(LC_CTYPE, "") ); - - TEST(i, strcmp(nl_langinfo(CODESET), "UTF-8"), 0, "no UTF-8 locale; tests might fail"); - - TEST(i, swprintf(0, 0, L"%d", 123456)<0, 1, "%d != %d"); - - TEST(i, swprintf(b, 2, L"%lc", 0xc0), 1, "%d != %d"); - TEST(i, b[0], 0xc0, "wrong character %x != %x"); - TEST(i, swprintf(b, 2, L"%lc", 0x20ac), 1, "%d != %d"); - TEST(i, b[0], 0x20ac, "wrong character %x != %x"); - TEST(i, swprintf(b, 3, L"%s", "\xc3\x80!"), 2, "%d != %d"); - TEST(i, b[0], 0xc0, "wrong character %x != %x"); - TEST(i, swprintf(b, 2, L"%.1s", "\xc3\x80!"), 1, "%d != %d"); - TEST(i, b[0], 0xc0, "wrong character %x != %x"); - - wcscpy(b, L"xxxxxxxx"); - TEST(i, swprintf(b, 4, L"%d", 123456)<0, 1, "%d != %d"); - TEST_S(b, L"123", "incorrect output"); - TEST(i, b[5], 'x', "buffer overrun"); - - for (j=0; int_tests[j].fmt; j++) { - i = swprintf(b, sizeof b, int_tests[j].fmt, int_tests[j].i); - if (i != wcslen(int_tests[j].expect)) { - error("swprintf(b, sizeof b, \"%ls\", %d) returned %d wanted %d\n", - int_tests[j].fmt, int_tests[j].i, i, wcslen(int_tests[j].expect)); - } - if (wcscmp(b, int_tests[j].expect) != 0) - error("bad integer conversion: got \"%ls\", want \"%ls\"\n", b, int_tests[j].expect); - } - - for (j=0; fp_tests[j].fmt; j++) { - i = swprintf(b, sizeof b, fp_tests[j].fmt, fp_tests[j].f); - if (i != wcslen(fp_tests[j].expect)) { - error("swprintf(b, sizeof b, \"%ls\", %f) returned %d wanted %d\n", - fp_tests[j].fmt, fp_tests[j].f, i, wcslen(fp_tests[j].expect)); - } - if (wcscmp(b, fp_tests[j].expect) != 0) - error("bad floating-point conversion: got \"%ls\", want \"%ls\"\n", b, fp_tests[j].expect); - } - return test_status; -} diff --git a/src/general/test.h b/src/general/test.h deleted file mode 100644 index a17c185..0000000 --- a/src/general/test.h +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#define error(...) test_error(__FILE__, __LINE__, __VA_ARGS__) - -/* TODO: not thread-safe nor fork-safe */ -static int test_status; - -static int test_error(const char *n, int l, const char *s, ...) -{ - va_list ap; - - if (test_status == 0) - printf("FAIL\n"); - test_status = 1; - printf(" ERROR %s:%d: ", n, l); - va_start(ap, s); - vprintf(s, ap); - va_end(ap); - return -1; -} - diff --git a/src/general/tgmath.c b/src/general/tgmath.c deleted file mode 100644 index 8cc2c3e..0000000 --- a/src/general/tgmath.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include "test.h" - -int main(void) -{ - long i; - - i = lrint(123456789.1f) & 0x7fffffff; - if (i != 123456792) - error("lrint(123456789.1f)&0x7fffffff want 123456792 got %ld\n", i); - i = lrint(123456789.1) & 0x7fffffff; - if (i != 123456789) - error("lrint(123456789.1)&0x7fffffff want 123456789 got %ld\n", i); - - if (sqrt(2.0f) != 1.41421353816986083984375) - error("sqrt(2.0f) want 0x1.6a09e6p+0 got %a\n", sqrt(2.0f)); - if (sqrt(2.0) != 1.414213562373095145474621858738828450441360) - error("sqrt(2.0) want 0x1.6a09e667f3bcdp+0 got %a\n", sqrt(2.0)); - if (sqrt(2) != 1.414213562373095145474621858738828450441360) - error("sqrt(2) want 0x1.6a09e667f3bcdp+0 got %a\n", sqrt(2.0)); - - if (sizeof pow(sqrt(8),0.5f) != sizeof(double)) - error("sizeof pow(sqrt(8),0.5f) want %d got %d\n", (int)sizeof(double), (int)sizeof pow(sqrt(8),0.5f)); - if (sizeof pow(2.0,0.5) != sizeof(double)) - error("sizeof pow(2.0,0.5) want %d got %d\n", (int)sizeof(double), (int)sizeof pow(2.0,0.5)); - if (sizeof pow(2.0f,0.5f) != sizeof(float)) - error("sizeof pow(2.0f,0.5f) want %d got %d\n", (int)sizeof(float), (int)sizeof pow(2.0f,0.5f)); - if (sizeof pow(2.0,0.5+0*I) != sizeof(double complex)) - error("sizeof pow(2.0,0.5+0*I) want %d got %d\n", (int)sizeof(double complex), (int)sizeof pow(2.0,0.5+0*I)); - - if (pow(2.0,0.5) != 1.414213562373095145474621858738828450441360) - error("pow(2.0,0.5) want 0x1.6a09e667f3bcdp+0 got %a\n", pow(2.0,0.5)); - if (pow(2,0.5) != 1.414213562373095145474621858738828450441360) - error("pow(2,0.5) want 0x1.6a09e667f3bcdp+0 got %a\n", pow(2,0.5)); - if (pow(2,0.5f) != 1.414213562373095145474621858738828450441360) - error("pow(2,0.5f) want 0x1.6a09e667f3bcdp+0 got %a\n", pow(2,0.5f)); - - return test_status; -} diff --git a/src/general/time.c b/src/general/time.c deleted file mode 100644 index 27598b8..0000000 --- a/src/general/time.c +++ /dev/null @@ -1,76 +0,0 @@ -#define _XOPEN_SOURCE 700 -#include -#include -#include -#include "test.h" - -/* We use this instead of memcmp because some broken C libraries - * add additional nonstandard fields to struct tm... */ - -int tm_cmp(struct tm tm1, struct tm tm2) -{ - return tm1.tm_sec != tm2.tm_sec || - tm1.tm_min != tm2.tm_min || - tm1.tm_hour != tm2.tm_hour || - tm1.tm_mday != tm2.tm_mday || - tm1.tm_mon != tm2.tm_mon || - tm1.tm_year != tm2.tm_year || - tm1.tm_wday != tm2.tm_wday || - tm1.tm_yday != tm2.tm_yday || - tm1.tm_isdst!= tm2.tm_isdst; -} - -char *tm_str(struct tm tm) -{ - static int i; - static char b[4][64]; - i = (i+1)%4; - snprintf(b[i], sizeof b[i], - "s=%02d m=%02d h=%02d mday=%02d mon=%02d year=%04d wday=%d yday=%d isdst=%d", - tm.tm_sec, tm.tm_min, tm.tm_hour, - tm.tm_mday, tm.tm_mon, tm.tm_year, - tm.tm_wday, tm.tm_yday, tm.tm_isdst); - return b[i]; -} - -#define TM(ss,mm,hh,md,mo,yr,wd,yd,dst) (struct tm){ \ - .tm_sec = ss, .tm_min = mm, .tm_hour = hh, \ - .tm_mday = md, .tm_mon = mo, .tm_year = yr, \ - .tm_wday = wd, .tm_yday = yd, .tm_isdst = dst } - -#define TM_EPOCH TM(0,0,0,1,0,70,4,0,0) -#define TM_Y2038_1S TM(7,14,3,19,0,138,2,18,0) -#define TM_Y2038 TM(8,14,3,19,0,138,2,18,0) - -#define TEST_TM(r,x,m) (!tm_cmp((r),(x)) || \ - (error("%s failed:\n\tresult: %s\n\texpect: %s\n", \ - m, tm_str(r), tm_str(x)), 0) ) - -#define TEST(r, f, x, m) ( \ - ((r) = (f)) == (x) || \ - (error("%s failed (" m ")\n", #f, r, x), 0) ) - -int main(void) -{ - struct tm tm, *tm_p; - time_t t; - - putenv("TZ=GMT"); - tzset(); - - t=0; tm_p = gmtime(&t); - TEST_TM(*tm_p, TM_EPOCH, "gmtime(0)"); - - tm = TM_Y2038_1S; - t = mktime(&tm); - tm = *(gmtime(&t)); - TEST_TM(*tm_p, TM_Y2038_1S, "mktime/gmtime(Y2038-1)"); - - tm = TM_Y2038; - t = mktime(&tm); - tm = *(gmtime(&t)); - TEST_TM(*tm_p, TM_Y2038, "mktime/gmtime(Y2038)"); - - /* FIXME: set a TZ var and check DST boundary conditions */ - return test_status; -} diff --git a/src/general/tls_align.c b/src/general/tls_align.c deleted file mode 100644 index 505abf2..0000000 --- a/src/general/tls_align.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "test.h" - -extern struct { - char *name; - unsigned size; - unsigned align; - unsigned long addr; -} t[4]; - -int main() -{ - int i; - - for (i = 0; i < sizeof t/sizeof *t; i++) { - if (!t[i].name) - error("name is not set for t[%d]\n", i); - if (t[i].addr & (t[i].align-1)) - error("bad alignment: %s, size: %u, align: %u, addr: 0x%lx\n", - t[i].name, t[i].size, t[i].align, t[i].addr); - } - return test_status; -} diff --git a/src/general/tls_align_dlopen.c b/src/general/tls_align_dlopen.c deleted file mode 100644 index 64517e1..0000000 --- a/src/general/tls_align_dlopen.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include "test.h" - -int main() -{ - int i; - void *h; - struct { - char *name; - unsigned size; - unsigned align; - unsigned long addr; - } *t; - - h = dlopen("./tls_align_dso.so", RTLD_LAZY); - if (!h) - error("dlopen failed\n"); - t = dlsym(h, "t"); - if (!t) - error("dlsym failed\n"); - - for (i = 0; i < 4; i++) { - if (!t[i].name) - error("name is not set for t[%d]\n", i); - if (t[i].addr & (t[i].align-1)) - error("bad alignment: %s, size: %u, align: %u, addr: 0x%lx\n", - t[i].name, t[i].size, t[i].align, t[i].addr); - } - return test_status; -} diff --git a/src/general/tls_align_dso.c b/src/general/tls_align_dso.c deleted file mode 100644 index 9ca759e..0000000 --- a/src/general/tls_align_dso.c +++ /dev/null @@ -1,30 +0,0 @@ -__thread char c1 = 1; -__thread char xchar = 2; -__thread char c2 = 3; -__thread short xshort = 4; -__thread char c3 = 5; -__thread int xint = 6; -__thread char c4 = 7; -__thread long long xllong = 8; - -struct { - char *name; - unsigned size; - unsigned align; - unsigned long addr; -} t[4]; - -#define entry(i,x) \ - t[i].name = #x; \ - t[i].size = sizeof x; \ - t[i].align = __alignof__(x); \ - t[i].addr = (unsigned long)&x; - -__attribute__((constructor)) static void init(void) -{ - entry(0, xchar) - entry(1, xshort) - entry(2, xint) - entry(3, xllong) -} - diff --git a/src/general/tls_init.c b/src/general/tls_init.c deleted file mode 100644 index 8a43829..0000000 --- a/src/general/tls_init.c +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include "test.h" - -__thread int tls_fix = 23; -__thread int tls_zero; - -static void *f(void *arg) -{ - if (tls_fix != 23) - error("fixed init failed: want 23 got %d\n", tls_fix); - if (tls_zero != 0) - error("zero init failed: want 0 got %d\n", tls_zero); - tls_fix++; - tls_zero++; - return 0; -} - -#define CHECK(f) do{ if(f) error("%s failed.\n", #f); }while(0) -#define length(a) (sizeof(a)/sizeof*(a)) - -int main() -{ - pthread_t t[5]; - int i, j; - - if (tls_fix != 23) - error("fixed init failed: want 23 got %d\n", tls_fix); - if (tls_zero != 0) - error("zero init failed: want 0 got %d\n", tls_zero); - - for (j = 0; j < 2; j++) { - for (i = 0; i < length(t); i++) { - CHECK(pthread_create(t+i, 0, f, 0)); - tls_fix++; - tls_zero++; - } - for (i = 0; i < length(t); i++) - CHECK(pthread_join(t[i], 0)); - } - - return test_status; -} diff --git a/src/general/udiv.c b/src/general/udiv.c deleted file mode 100644 index e5b6d2c..0000000 --- a/src/general/udiv.c +++ /dev/null @@ -1,168 +0,0 @@ -#include "test.h" -#include - -/* -static uint64_t randstate = 0x123456789abcdef0ull; -static uint64_t rnd(void) { - randstate = 6364136223846793005ull*randstate + 1; - return randstate; -} -void test_maketest() -{ - int i; - uint64_t x,y; - for (i = 0; i < 128; i++) { - x = rnd(); - y = rnd()>>(i/2); - if (!y) - continue; - printf("0x%llxull, 0x%llxull, 0x%llxull, 0x%llxull,\n", x, y, x/y, x%y); - } -} -*/ - -static struct { - uint64_t x, y, div, mod; -} t[] = { -0x8ddb1a43e77c4031ull, 0x5950e8c33d34979eull, 0x1ull, 0x348a3180aa47a893ull, -0x723f4114006c08c7ull, 0x817de530db2b43fcull, 0x0ull, 0x723f4114006c08c7ull, -0x47811fa5f00f74dull, 0x3d98e7d3fcd5d5c5ull, 0x0ull, 0x47811fa5f00f74dull, -0x51ffcc7cdc989d43ull, 0x36be8bd6746b70e4ull, 0x1ull, 0x1b4140a6682d2c5full, -0x57bf9128512fe829ull, 0x197b3858155d498dull, 0x3ull, 0xb4de82011180b82ull, -0x89fc1c5968fa817full, 0xdcea797734c7115ull, 0x9ull, 0xdb838065b4a87c2ull, -0x4ed5264cf7092ec5ull, 0xde40d1e15ef3e74ull, 0x5ull, 0x960e4b6895cf681ull, -0xffd86b253d97317bull, 0x13f9ff2d24b6d6f4ull, 0xcull, 0x1020750785051e0bull, -0x8771fa2da656a721ull, 0x9210fe654c59bfcull, 0xeull, 0x7a31b9503881f59ull, -0xb5961d12bcd3e937ull, 0xbdb5a33662f547aull, 0xfull, 0x3bbd40fc00df611ull, -0x93c79eecdac7ed3dull, 0x6f267c57ea2b7b5ull, 0x15ull, 0x1e51bb9776edb64ull, -0x6b93ffce49f1a4b3ull, 0x3583d1f9702ee03ull, 0x20ull, 0x8c5bdb6993e453ull, -0x138aefcc98ce5d19ull, 0x117002fa7600b11ull, 0x11ull, 0x103eca27b6da0f8ull, -0xb3da641cef491fefull, 0x357615f638334b8ull, 0x35ull, 0x2c33b5d551f35d7ull, -0x71c4b06e463912b5ull, 0x1c286ad9e8f5229ull, 0x40ull, 0x1230506a2648875ull, -0x97d4cf7df046d6ebull, 0x1e9412f5c77b2b8ull, 0x4full, 0xd9b1e06756b023ull, -0x1428f04bd490ea11ull, 0x9d97f29a897c93ull, 0x20ull, 0x75f1f8836157b1ull, -0x35256c76832705a7ull, 0xa962f1a447dcd7ull, 0x50ull, 0x3680f32cb20277ull, -0x2969e82bd9347f2dull, 0x723d68574d4156ull, 0x5cull, 0x5bd6ac79710445ull, -0x9061a12aae71a823ull, 0x4186d8a1a66175ull, 0x234ull, 0x48be68be2f25full, -0x695b8d33ef342e09ull, 0x3ed1fe1a998fe3ull, 0x1adull, 0x15a6615bde0ea2ull, -0x46b4dd1e06367a5full, 0xa04e70622e4e8ull, 0x70eull, 0x64750bc0b9dafull, -0xd68b05ba7eee12a5ull, 0x72ab3fb682444ull, 0x1defull, 0x3c437fc988329ull, -0x1e59cc2ac508f85bull, 0xeb15ae6d4d7f9ull, 0x210ull, 0xc00aeae0b86cbull, -0x296f8d2c76a0901ull, 0xf65628b31b01ull, 0x2b0ull, 0xf14566117651ull, -0x7036f5ad7cbc5e17ull, 0xa09d3bfcf72cfull, 0xb2dull, 0x72236db564ab4ull, -0x915d6883c575ad1dull, 0x3a38d68d3a38eull, 0x27f2ull, 0x241de6f7a6ee1ull, -0x845ba74f5adfa793ull, 0x2f6950e58d00bull, 0x2caaull, 0x249dc90239c45ull, -0xb910d16c54805af9ull, 0x1fc2ca5c99a7aull, 0x5d3aull, 0x1771487b50955ull, -0x27a2e280bcf990cfull, 0x389aa0c0b0cc0ull, 0xb34ull, 0x9d71d12eb9cfull, -0x1e032f04a5372e95ull, 0x63c2a1d58710ull, 0x4d04ull, 0x154ce4414255ull, -0x3a1a5659908495cbull, 0x279dcd85418aull, 0x17775ull, 0x132c6f9c7bb9ull, -0xd769a376e5e103f1ull, 0xadacb670e0c7ull, 0x13d85ull, 0x8ad256e5d18eull, -0x269f4f4baaaf287ull, 0x1aed2ad9daf0ull, 0x16f3ull, 0x426550f80b7ull, -0x6700daeeb87a770dull, 0xeca7ab1aa93ull, 0x6f6c5ull, 0x70d9466f1eeull, -0xd0201f3783c2a303ull, 0x3a0c01aa3e6aull, 0x395e1ull, 0x18b33b9015d9ull, -0xca3f2e00d291e3e9ull, 0xbe0e048cd94ull, 0x1106c2ull, 0x37f7fc0a1c1ull, -0xec4d240dc289633full, 0x4f8aadb7483ull, 0x2f8855ull, 0x46e0db91bc0ull, -0xd7967b29e2e36685ull, 0xe61d902db27ull, 0xefd69ull, 0x36811fff886ull, -0xe3ecd4374320af3bull, 0x4edd0edd0a0ull, 0x2e3defull, 0x4ad0da4c9dbull, -0x7a08fe1d98b4dae1ull, 0x6bced9c0c15ull, 0x121c89ull, 0x40c856617a4ull, -0x34435992a5c9c2f7ull, 0x4f4a94c109full, 0xa8bc9ull, 0x94c5d46120ull, -0x6fd0027468f1dcfdull, 0x597186b0153ull, 0x140060ull, 0x16f26555dddull, -0x4fe37c1db1619a73ull, 0x47a0c30bd15ull, 0x11d861ull, 0x5964fb3d7eull, -0x77aa77f86d07c8d9ull, 0x3a39cf03d65ull, 0x20e21cull, 0x37f7fede7cdull, -0xc072e76ad59cf1afull, 0x3a786701dull, 0x34a98c59ull, 0x22b6b1b9aull, -0xfb8e8f1f7781ba75ull, 0xe8ca427d3eull, 0x114a34dull, 0xa344eb94cfull, -0x160e34cf590444abull, 0xe2388f12feull, 0x18f574ull, 0xc303329393ull, -0x2509ddea3a648dd1ull, 0xec762d81bcull, 0x281955ull, 0xc0463d1e65ull, -0xc9ba10cd6eafcf67ull, 0x96a51d06f7ull, 0x156ce72ull, 0x133e2df369ull, -0x1dd4fe261b4adeedull, 0x2736e25406ull, 0xc2bfefull, 0x1354c1f353ull, -0x480258f92fc38de3ull, 0x2599b52bb0ull, 0x1ea450cull, 0x2879f11a3ull, -0x5a3257b1114109c9ull, 0x2978f9f1aaull, 0x22cc30aull, 0x1317311b25ull, -0xf4eeda8f34ab3c1full, 0x1aa70450d9ull, 0x9309d64ull, 0x1187b6925bull, -0x3c2c319ca8612a65ull, 0x73fc01eceull, 0x84d0088ull, 0x3165accf5ull, -0x4f6034e74a16561bull, 0x1f29d53707ull, 0x28c0daaull, 0xd88e07075ull, -0x206665a7072f1cc1ull, 0xda87e7ceaull, 0x25f48c1ull, 0xd3ddb2057ull, -0x100c559d7db417d7ull, 0xb907ebbc2ull, 0x1634188ull, 0xa2eae16c7ull, -0x64c5f83691b47cddull, 0x5aced6ebbull, 0x11c17fb7ull, 0x344109030ull, -0x32a812777eaf7d53ull, 0x1cb63fe4full, 0x1c3a9675ull, 0xb113f938ull, -0x67478d96865ca6b9ull, 0x142fa03aull, 0x51dcb463dull, 0x11359ce7ull, -0x71024e740deb428full, 0x142d3885ull, 0x599d9edd5ull, 0x13b1ae6ull, -0x52c78160b090b655ull, 0xd02101c6ull, 0x65d1b205ull, 0x1c0a0177ull, -0x16917d5f9fde38bull, 0xfb1566c7ull, 0x17029e0ull, 0x1bbe166bull, -0xa6ee688a0d1387b1ull, 0x22c4d384ull, 0x4cd19afcfull, 0x77143f5ull, -0x74babc1be2ed9c47ull, 0x22eda9a6ull, 0x3578b1967ull, 0x189b247dull, -0x7c5cbf2dfc1db6cdull, 0x5f09c060ull, 0x14efd44d4ull, 0x5210e74dull, -0x7c046071c1ac68c3ull, 0x3696c8e6ull, 0x24596d86bull, 0x26060a1ull, -0x84728ab55d399fa9ull, 0x267d7771ull, 0x370ea7405ull, 0x255d1674ull, -0x99f57100ef5404ffull, 0x10c0df86ull, 0x9308fef0dull, 0x9009131ull, -0x3f4c0514b0df5e45ull, 0xf2c3810ull, 0x42bf84d39ull, 0x3aa12b5ull, -0xd01edb572821ecfbull, 0x2a443aeull, 0x4ec8b88639ull, 0x111c73dull, -0xeecb08561bd0cea1ull, 0xbeca231ull, 0x140692508bull, 0x9b36e06ull, -0x8c856facc6335cb7ull, 0x398eab4ull, 0x271008c7a5ull, 0x922ab3ull, -0x23fb9839e8358cbdull, 0x24deb54ull, 0xf9d714151ull, 0xb9c329ull, -0x2005d5de30015033ull, 0x47c06dbull, 0x7240bccbaull, 0x104d115ull, -0x67d59c29e076f499ull, 0x179f009ull, 0x465554ac22ull, 0x10b0767ull, -0x32d2dd34369c836full, 0x13d3fbfull, 0x2902f2fb54ull, 0x7553c3ull, -0x3960c3c99fdc2235ull, 0x1b808baull, 0x21618743cdull, 0x11e7743ull, -0x343bad5adfa9726bull, 0xeef444ull, 0x37f58c51a6ull, 0x3d8a53ull, -0x7a4aadd7b4e5f191ull, 0x129c9ull, 0x6921bb5a2a53ull, 0x6b66ull, -0x9eb7dae5d71c5927ull, 0x31d7f5ull, 0x32f2ff2c6d5ull, 0x22c4eull, -0x1b285999316afeadull, 0x115477ull, 0x1912cf6611eull, 0x801bbull, -0x917aee3d84b533a3ull, 0x71d26full, 0x1473408589aull, 0x6e74ddull, -0x18e6a86b0473a589ull, 0x50a12ull, 0x4f0fabc67d4ull, 0x210a1ull, -0xf22c9887813bbddfull, 0x5b17aull, 0x2a897505c07bull, 0x1f841ull, -0xef7a551239d60225ull, 0x7fb5aull, 0x1e00b98e188bull, 0x41847ull, -0xffd2ad0e77b73dbull, 0x146f14ull, 0xc8500600a3ull, 0xba1full, -0x76743abdfb91f081ull, 0xd5888ull, 0x8e0303c479cull, 0x245a1ull, -0xc2eeb030bcff9197ull, 0x7a4e8ull, 0x198034e02c37ull, 0x343bfull, -0x63cc9c23f0ed0c9dull, 0x6c1e5ull, 0xec4d5841041ull, 0x38178ull, -0x7ad70f846e8f1313ull, 0x7fdf5ull, 0xf5ecec69bc9ull, 0x756b6ull, -0x60de3d71574eb279ull, 0x6ea3ull, 0xe02421997a61ull, 0x18b6ull, -0xd27054901c68b44full, 0x2dd0full, 0x497d639c8f46ull, 0xe135ull, -0xbcf297b8f0dbfe15ull, 0xcf17ull, 0xe992af0ca1abull, 0x32b8ull, -0x96c3ae70323ef14bull, 0xbbdcull, 0xcd7329b68d81ull, 0x1b6full, -0xdc1a13cfa4d3cb71ull, 0xdb16ull, 0x1012fe5ed296full, 0x46e7ull, -0xa1d40a2986f40607ull, 0x8067ull, 0x142a473fdb7beull, 0x1895ull, -0x227f92ef6daab68dull, 0x15ecull, 0x192dda5d5ed25ull, 0xf71ull, -0xc0a4a7810015ee83ull, 0x6064ull, 0x1ffa220762fc8ull, 0x4463ull, -0xd38b6eb9f0e71b69ull, 0x1909ull, 0x8732ce2cc77f4ull, 0xfd5ull, -0x2e588bdb751a66bfull, 0x229cull, 0x156d025c70d97ull, 0x10bbull, -0xd90f7e11dcbd1605ull, 0x760ull, 0x1d6e934381ba2eull, 0x2c5ull, -0x60ab67a4e5aeabbull, 0x1bf7ull, 0x374f26f3e3edull, 0x210ull, -0x224f627be76a8261ull, 0x4f4ull, 0x6ed4d3882b567ull, 0x35ull, -0x300d1ab91bd0b677ull, 0xe9cull, 0x34a002fb76e63ull, 0x823ull, -0x2a63d80e0c52fc7dull, 0x32ull, 0xd90970ebc4383full, 0x2full, -0xb0e94bbc1f90c5f3ull, 0x3b3ull, 0x2fd2ef70381c52ull, 0x29dull, -0x2b5dc22562dbe059ull, 0x30aull, 0xe45055015fff5ull, 0x1c7ull, -0x4a7fd1078807d52full, 0x18dull, 0x300a32f60677d4ull, 0x16bull, -0x41a01ee8ab0849f5ull, 0x13cull, 0x352a3971f57e9dull, 0x29ull, -0x95a7287ad5f6602bull, 0x1d0ull, 0x529130d1034a23ull, 0xbbull, -0x723bacc76bd51551ull, 0x16ull, 0x53142091089af83ull, 0xfull, -0x81c49febaa2ca2e7ull, 0xcdull, 0xa20d44956f5bf4ull, 0x83ull, -0x11593d6b3f54de6dull, 0x63ull, 0x2cdc6b1a7f9078ull, 0x5ull, -0x756c82d6f7069963ull, 0x5cull, 0x146bea3ba565525ull, 0x17ull, -0xda882ab2a88c0149ull, 0x1bull, 0x8180194d6d5c728ull, 0x11ull, -0xbb03671751a7ff9full, 0x20ull, 0x5d81b38ba8d3ffcull, 0x1full, -0x6884fa0a8f0c99e5ull, 0x12ull, 0x5ce7fab40d6088cull, 0xdull, -0x5052a2953c528441ull, 0x7ull, 0xb7984f0bf79809bull, 0x4ull, -0x58dd1583185ecb57ull, 0x9ull, 0x9dfad0e90ee1697ull, 0x8ull, -0xaa6870c376df5c5dull, 0x3ull, 0x38cd7aebd24a741full, 0x0ull, -0x4b21d01617167e39ull, 0x2ull, 0x2590e80b0b8b3f1cull, 0x1ull, -}; - -int main(void) -{ - uint64_t x, y, div, mod; - int i; - - for (i = 0; i < sizeof t/sizeof *t; i++) { - x = t[i].x; - y = t[i].y; - div = x / y; - mod = x % y; - if (div != t[i].div) - error("udiv %llu/%llu want %llu got %llu\n", x, y, t[i].div, div); - if (mod != t[i].mod) - error("umod %llu%%%llu want %llu got %llu\n", x, y, t[i].mod, mod); - } - return test_status; -} diff --git a/src/general/ungetc.c b/src/general/ungetc.c deleted file mode 100644 index 9003a1c..0000000 --- a/src/general/ungetc.c +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include -#include -#include -#include "test.h" - -#define TEST(r, f, x, m) ( \ - errno = 0, ((r) = (f)) == (x) || \ - (error("%s failed (" m ")\n", #f, r, x, strerror(errno)), 0) ) - -#define TEST_S(s, x, m) ( \ - !strcmp((s),(x)) || \ - (error("[%s] != [%s] (%s)\n", s, x, m), 0) ) - -int main(void) -{ - int i; - char a[100]; - FILE *f; - - TEST(i, !(f = tmpfile()), 0, "failed to create temp file %d!=%d (%s)"); - - if (!f) return test_status; - - TEST(i, fprintf(f, "hello, world\n"), 13, "%d != %d (%m)"); - TEST(i, fseek(f, 0, SEEK_SET), 0, "%d != %d (%m)"); - - TEST(i, feof(f), 0, "%d != %d"); - TEST(i, fgetc(f), 'h', "'%c' != '%c'"); - TEST(i, ftell(f), 1, "%d != %d"); - TEST(i, ungetc('x', f), 'x', "%d != %d"); - TEST(i, ftell(f), 0, "%d != %d"); - TEST(i, fscanf(f, "%[h]", a), 0, "got %d fields, expected %d"); - TEST(i, ftell(f), 0, "%d != %d"); - TEST(i, fgetc(f), 'x', "'%c' != '%c'"); - TEST(i, ftell(f), 1, "%d != %d"); - - TEST(i, fseek(f, 0, SEEK_SET), 0, "%d != %d"); - TEST(i, ungetc('x', f), 'x', "%d != %d"); - TEST(i, fread(a, 1, sizeof a, f), 14, "read %d, expected %d"); - a[14] = 0; - TEST_S(a, "xhello, world\n", "mismatch reading ungot character"); - - TEST(i, fseek(f, 0, SEEK_SET), 0, "%d != %d"); - TEST(i, fscanf(f, "%[x]", a), 0, "got %d fields, expected %d"); - TEST(i, ungetc('x', f), 'x', "unget failed after fscanf: %d != %d"); - TEST(i, fgetc(f), 'x', "'%c' != '%c'"); - TEST(i, fgetc(f), 'h', "'%c' != '%c'"); - - fclose(f); - return test_status; -} diff --git a/src/general/wcstol.c b/src/general/wcstol.c deleted file mode 100644 index abd76af..0000000 --- a/src/general/wcstol.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include -#include -#include -#include "test.h" - -#define TEST(r, f, x, m) ( \ - errno = 0, msg = #f, ((r) = (f)) == (x) || \ - (error("%s failed (" m ")\n", #f, r, x), 0) ) - -#define TEST2(r, f, x, m) ( \ - ((r) = (f)) == (x) || \ - (error("%s failed (" m ")\n", msg, r, x), 0) ) - -int main(void) -{ - int i; - long l; - unsigned long ul; - char *msg=""; - wchar_t *s, *c; - - TEST(l, wcstol(L"2147483647", 0, 0), 2147483647L, "max 32bit signed %ld != %ld"); - TEST(ul, wcstoul(L"4294967295", 0, 0), 4294967295UL, "max 32bit unsigned %lu != %lu"); - - if (sizeof(long) == 4) { - TEST(l, wcstol(s=L"2147483648", &c, 0), 2147483647L, "uncaught overflow %ld != %ld"); - TEST2(i, c-s, 10, "wrong final position %d != %d"); - TEST2(i, errno, ERANGE, "missing errno %d != %d"); - TEST(l, wcstol(s=L"-2147483649", &c, 0), -2147483647L-1, "uncaught overflow %ld != %ld"); - TEST2(i, c-s, 11, "wrong final position %d != %d"); - TEST2(i, errno, ERANGE, "missing errno %d != %d"); - TEST(ul, wcstoul(s=L"4294967296", &c, 0), 4294967295UL, "uncaught overflow %lu != %lu"); - TEST2(i, c-s, 10, "wrong final position %d != %d"); - TEST2(i, errno, ERANGE, "missing errno %d != %d"); - TEST(ul, wcstoul(s=L"-1", &c, 0), -1UL, "rejected negative %lu != %lu"); - TEST2(i, c-s, 2, "wrong final position %d != %d"); - TEST2(i, errno, 0, "spurious errno %d != %d"); - TEST(ul, wcstoul(s=L"-2", &c, 0), -2UL, "rejected negative %lu != %lu"); - TEST2(i, c-s, 2, "wrong final position %d != %d"); - TEST2(i, errno, 0, "spurious errno %d != %d"); - TEST(ul, wcstoul(s=L"-2147483648", &c, 0), -2147483648UL, "rejected negative %lu != %lu"); - TEST2(i, c-s, 11, "wrong final position %d != %d"); - TEST2(i, errno, 0, "spurious errno %d != %d"); - TEST(ul, wcstoul(s=L"-2147483649", &c, 0), -2147483649UL, "rejected negative %lu != %lu"); - TEST2(i, c-s, 11, "wrong final position %d != %d"); - TEST2(i, errno, 0, "spurious errno %d != %d"); - } else { - TEST(i, 0, 1, "64bit tests not implemented"); - } - - TEST(l, wcstol(L"z", 0, 36), 35, "%ld != %ld"); - TEST(l, wcstol(L"00010010001101000101011001111000", 0, 2), 0x12345678, "%ld != %ld"); - - TEST(l, wcstol(s=L"0xz", &c, 16), 0, "%ld != %ld"); - TEST2(i, c-s, 1, "wrong final position %ld != %ld"); - - TEST(l, wcstol(s=L"0x1234", &c, 16), 0x1234, "%ld != %ld"); - TEST2(i, c-s, 6, "wrong final position %ld != %ld"); - - c = NULL; - TEST(l, wcstol(s=L"123", &c, 37), 0, "%ld != %ld"); - TEST2(i, c-s, 0, "wrong final position %d != %d"); - TEST2(i, errno, EINVAL, "%d != %d"); - return test_status; -}