From 2d8764f06bec8948c6bef3189f33dcd2f2295c0d Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sun, 19 May 2019 17:55:31 -0400 Subject: [PATCH] Split the testing allocation and print functions into their own file, and added uiprivArray as testingprivArray. Switching everything to use testingprivArray will come next. --- test/lib/meson.build | 1 + test/lib/testing.c | 104 +++++------------------------- test/lib/testingpriv.c | 141 +++++++++++++++++++++++++++++++++++++++++ test/lib/testingpriv.h | 39 ++++++++++++ 4 files changed, 197 insertions(+), 88 deletions(-) create mode 100644 test/lib/testingpriv.c create mode 100644 test/lib/testingpriv.h diff --git a/test/lib/meson.build b/test/lib/meson.build index 403922db..7a444989 100644 --- a/test/lib/meson.build +++ b/test/lib/meson.build @@ -2,6 +2,7 @@ libui_test_sources += [ 'lib/testing.c', + 'lib/testingpriv.c', 'lib/timer.c', ] diff --git a/test/lib/testing.c b/test/lib/testing.c index 028e824f..784131db 100644 --- a/test/lib/testing.c +++ b/test/lib/testing.c @@ -9,79 +9,7 @@ #include #include "timer.h" #include "testing.h" - -static void internalError(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - fprintf(stderr, "** testing internal error: "); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "; aborting\n"); - va_end(ap); - abort(); -} - -static void *mustMalloc(size_t n, const char *what) -{ - void *p; - - p = malloc(n); - if (p == NULL) - internalError("memory exhausted allocating %s", what); - memset(p, 0, n); - return p; -} - -#define mustNew(T) ((T *) mustMalloc(sizeof (T), #T)) -#define mustNewArray(T, n) ((T *) mustMalloc(n * sizeof (T), #T "[]")) - -static void *mustRealloc(void *p, size_t old, size_t new, const char *what) -{ - p = realloc(p, new); - if (p == NULL) - internalError("memory exhausted reallocating %s", what); - if (new > old) - memset(((uint8_t *) p) + old, 0, new - old); - return p; -} - -#define mustResizeArray(x, T, old, new) ((T *) mustRealloc(x, old * sizeof (T), new * sizeof (T), #T "[]")) - -static void mustFree(void *p) -{ - free(p); -} - -static int mustvsnprintf(char *s, size_t n, const char *format, va_list ap) -{ - int ret; - - ret = vsnprintf(s, n, format, ap); - if (ret < 0) - internalError("encoding error in vsnprintf(); this likely means your call to testingTLogf() and the like is invalid"); - return ret; -} - -static int mustsnprintf(char *s, size_t n, const char *format, ...) -{ - va_list ap; - int ret; - - va_start(ap, format); - ret = mustvsnprintf(s, n, format, ap); - va_end(ap); - return ret; -} - -static char *muststrdup(const char *s) -{ - char *t; - - t = (char *) mustMalloc((strlen(s) + 1) * sizeof (char), "char[]"); - strcpy(t, s); - return t; -} +#include "testingpriv.h" // a struct outbuf of NULL writes directly to stdout struct outbuf { @@ -110,7 +38,7 @@ static void outbufCopyStr(struct outbuf *o, const char *str, size_t len) prevcap = o->cap; o->cap += grow; - o->buf = mustResizeArray(o->buf, char, prevcap, o->cap); + o->buf = testingprivResizeArray(o->buf, char, prevcap, o->cap); } memmove(o->buf + o->len, str, len * sizeof (char)); o->len += len; @@ -133,11 +61,11 @@ static void outbufVprintf(struct outbuf *o, int indent, const char *format, va_l int firstLine = 1; va_copy(ap2, ap); - n = mustvsnprintf(NULL, 0, format, ap2); + n = testingprivVsnprintf(NULL, 0, format, ap2); // TODO handle n < 0 case va_end(ap2); - buf = mustNewArray(char, n + 1); - mustvsnprintf(buf, n + 1, format, ap); + buf = testingprivNewArray(char, n + 1); + testingprivVsnprintf(buf, n + 1, format, ap); // strip trailing blank lines while (buf[n - 1] == '\n') @@ -165,7 +93,7 @@ static void outbufVprintf(struct outbuf *o, int indent, const char *format, va_l outbufCopyStr(o, lineStart, strlen(lineStart)); outbufAddNewline(o); - mustFree(buf); + testingprivFree(buf); } static void outbufPrintf(struct outbuf *o, int indent, const char *format, ...) @@ -227,7 +155,7 @@ static void initTest(testingT *t, const char *name, void (*f)(testingT *), const { memset(t, 0, sizeof (testingT)); t->name = name; - t->computedName = muststrdup(name); + t->computedName = testingprivStrdup(name); t->f = f; t->file = file; t->line = line; @@ -251,7 +179,7 @@ void testingprivSetRegisterTest(testingSet **pset, const char *name, void (*f)(t if (pset != NULL) { set = *pset; if (set == NULL) { - set = mustNew(testingSet); + set = testingprivNew(testingSet); *pset = set; } } @@ -260,7 +188,7 @@ void testingprivSetRegisterTest(testingSet **pset, const char *name, void (*f)(t prevcap = set->cap; set->cap += nGrow; - set->tests = mustResizeArray(set->tests, testingT, prevcap, set->cap); + set->tests = testingprivResizeArray(set->tests, testingT, prevcap, set->cap); } initTest(set->tests + set->len, name, f, file, line); set->len++; @@ -367,17 +295,17 @@ void testingprivTLogvfFull(testingT *t, const char *file, long line, const char int n, n2; // TODO extract filename from file - n = mustsnprintf(NULL, 0, "%s:%ld: ", file, line); + n = testingprivSnprintf(NULL, 0, "%s:%ld: ", file, line); // TODO handle n < 0 case va_copy(ap2, ap); - n2 = mustvsnprintf(NULL, 0, format, ap2); + n2 = testingprivVsnprintf(NULL, 0, format, ap2); // TODO handle n2 < 0 case va_end(ap2); - buf = mustNewArray(char, n + n2 + 1); - mustsnprintf(buf, n + 1, "%s:%ld: ", file, line); - mustvsnprintf(buf + n, n2 + 1, format, ap); + buf = testingprivNewArray(char, n + n2 + 1); + testingprivSnprintf(buf, n + 1, "%s:%ld: ", file, line); + testingprivVsnprintf(buf + n, n2 + 1, format, ap); outbufPrintf(&(t->output), t->indent, "%s", buf); - mustFree(buf); + testingprivFree(buf); } void testingTFail(testingT *t) @@ -412,7 +340,7 @@ void testingTDefer(testingT *t, void (*f)(testingT *t, void *data), void *data) { struct defer *d; - d = mustNew(struct defer); + d = testingprivNew(struct defer); d->f = f; d->data = data; // add to the head of the list so defers are run in reverse order of how they were added diff --git a/test/lib/testingpriv.c b/test/lib/testingpriv.c new file mode 100644 index 00000000..852c25be --- /dev/null +++ b/test/lib/testingpriv.c @@ -0,0 +1,141 @@ +// 19 may 2019 +#include +#include +#include +#include "testing.h" +#include "testingpriv.h" + +void testingprivInternalError(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fprintf(stderr, "** testing internal error: "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "; aborting\n"); + va_end(ap); + abort(); +} + +void *testingprivAlloc(size_t n, const char *what) +{ + void *p; + + p = malloc(n); + if (p == NULL) + testingprivInternalError("memory exhausted allocating %s", what); + memset(p, 0, n); + return p; +} + +void *testingprivRealloc(void *p, size_t old, size_t new, const char *what) +{ + p = realloc(p, new); + if (p == NULL) + testingprivInternalError("memory exhausted reallocating %s", what); + if (new > old) + memset(((uint8_t *) p) + old, 0, new - old); + return p; +} + +void testingprivFree(void *p) +{ + free(p); +} + +void *testingprivArrayAppend(testingprivArray *arr, size_t n) +{ + return testingprivArrayInsertAt(arr, arr->len, n); +} + +void *testingprivArrayInsertAt(testingprivArray *arr, size_t pos, size_t n) +{ + uint8_t *old, *new; + size_t nBytesAdded, nBytesRemaining; + + if ((arr->len + n) >= arr->cap) { + size_t nGrow; + + // always grow by a perfect multiple of arr->nGrow + nGrow = n + (arr->nGrow - (n % arr->nGrow)); + arr->buf = testingprivRealloc(arr->buf, + arr->cap * arr->elemsize, + (arr->cap + nGrow) * arr->elemsize, + arr->what); + arr->cap += nGrow; + } + arr->len += n; + + nBytesRemaining = (arr->len - pos) * arr->elemsize; + nBytesAdded = n * arr->elemsize; + new = ((uint8_t *) (arr->buf)) + (pos * arr->elemsize); + old = new + nBytesAdded; + memmove(old, new, nBytesRemaining); + memset(new, 0, nBytesAdded); + return new; +} + +void testingprivArrayDelete(testingprivArray *arr, size_t pos, size_t n) +{ + uint8_t *src, *dest; + size_t nBytesDeleted, nBytesRemaining; + + nBytesDeleted = n * arr->elemsize; + nBytesRemaining = (arr->len - pos - n) * arr->elemsize; + dest = ((uint8_t *) (arr->buf)) + (pos * arr->elemsize); + src = dest + nBytesDeleted; + memmove(dest, src, nBytesRemaining); + src = dest + nBytesRemaining; + memset(src, 0, nBytesDeleted); + arr->len -= n; +} + +void testingprivArrayDeleteItem(testingprivArray *arr, void *p, size_t n) +{ + uint8_t *p8, *buf8; + + p8 = (uint8_t *) p; + buf8 = (uint8_t *) (arr->buf); + // TODO write this in a way that doesn't mix ptrdiff_t and size_t + testingprivArrayDelete(arr, (p8 - buf8) / arr->elemsize, n); +} + +void *testingprivArrayBsearch(const testingprivArray *arr, const void *key, int (*compare)(const void *, const void *)) +{ + return bsearch(key, arr->buf, arr->len, arr->elemsize, compare); +} + +void testingprivArrayQsort(testingprivArray *arr, int (*compare)(const void *, const void *)) +{ + qsort(arr->buf, arr->len, arr->elemsize, compare); +} + +int testingprivVsnprintf(char *s, size_t n, const char *format, va_list ap) +{ + int ret; + + ret = vsnprintf(s, n, format, ap); + if (ret < 0) + testingprivInternalError("encoding error in vsnprintf(); this likely means your call to testingTLogf() and the like is invalid"); + return ret; +} + +int testingprivSnprintf(char *s, size_t n, const char *format, ...) +{ + va_list ap; + int ret; + + va_start(ap, format); + ret = testingprivVsnprintf(s, n, format, ap); + va_end(ap); + return ret; +} + +char *testingprivStrdup(const char *s) +{ + char *t; + + t = (char *) testingprivAlloc((strlen(s) + 1) * sizeof (char), "char[]"); + strcpy(t, s); + return t; +} diff --git a/test/lib/testingpriv.h b/test/lib/testingpriv.h new file mode 100644 index 00000000..760620ae --- /dev/null +++ b/test/lib/testingpriv.h @@ -0,0 +1,39 @@ +// 19 may 2019 + +extern void testingprivInternalError(const char *fmt, ...); + +extern void *testingprivAlloc(size_t n, const char *what); +#define testingprivNew(T) ((T *) testingprivAlloc(sizeof (T), #T)) +#define testingprivNewArray(T, n) ((T *) testingprivAlloc(n * sizeof (T), #T "[]")) +extern void *testingprivRealloc(void *p, size_t old, size_t new, const char *what); +#define testingprivResizeArray(x, T, old, new) ((T *) testingprivRealloc(x, old * sizeof (T), new * sizeof (T), #T "[]")) +extern void testingprivFree(void *p); + +typedef struct testingprivArray testingprivArray; +struct testingprivArray { + void *buf; + size_t len; + size_t cap; + size_t elemsize; + size_t nGrow; + const char *what; +}; +#define testingprivArrayInit(arr, T, grow, whatstr) \ + memset(&(arr), 0, sizeof (testingprivArray)); \ + arr.elemsize = sizeof (T); \ + arr.nGrow = grow; \ + arr.what = whatstr; +#define testingprivArrayFree(arr) \ + testingprivFree(arr.buf); \ + memset(&arr, 0, sizeof (testingprivArray); +#define testingprivArrayAt(arr, T, n) (((T *) (arr.buf)) + (n)) +extern void *testingprivArrayAppend(testingprivArray *arr, size_t n); +extern void *testingprivArrayInsertAt(testingprivArray *arr, size_t pos, size_t n); +extern void testingprivArrayDelete(testingprivArray *arr, size_t pos, size_t n); +extern void testingprivArrayDeleteItem(testingprivArray *arr, void *p, size_t n); +extern void *testingprivArrayBsearch(const testingprivArray *arr, const void *key, int (*compare)(const void *, const void *)); +extern void testingprivArrayQsort(testingprivArray *arr, int (*compare)(const void *, const void *)); + +extern int testingprivVsnprintf(char *s, size_t n, const char *format, va_list ap); +extern int testingprivSnprintf(char *s, size_t n, const char *format, ...); +extern char *testingprivStrdup(const char *s);