From 745440b1e766c3ca5534f4ce7f6c4fec27a3b487 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sun, 19 May 2019 12:52:06 -0400 Subject: [PATCH] Wrote array manipulation functions. Now to convert events.c to use them. --- common/alloc.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ common/uipriv.h | 24 ++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/common/alloc.c b/common/alloc.c index ce90c453..17106e46 100644 --- a/common/alloc.c +++ b/common/alloc.c @@ -29,3 +29,68 @@ void uiprivFree(void *p) { free(p); } + +void *uiprivArrayAppend(uiprivArray *arr, size_t n) +{ + return uiprivArrayInsertAt(arr, arr->len, n); +} + +void *uiprivArrayInsertAt(uiprivArray *arr, size_t pos, size_t n) +{ + uint8_t *old, *new; + size_t nBytes; + + 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 = uiprivRealloc(arr->buf, + arr->cap * arr->elemsize, + (arr->cap + nGrow) * arr->elemsize, + arr->what); + arr->cap += nGrow; + } + arr->len += n; + + nBytes = n * arr->elemsize; + new = ((uint8_t *) (arr->buf)) + (pos * arr->elemsize); + old = new + nBytes; + memmove(old, new, nBytes); + memset(new, 0, nBytes); + return new; +} + +void uiprivArrayDelete(uiprivArray *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, nBytesDeleted); + memset(src, 0, nBytesRemaining); + arr->len -= n; +} + +void uiprivArrayDeleteItem(uiprivArray *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 + uiprivArrayDelete(arr, (p8 - buf8) / arr->elemsize, n); +} + +void *uiprivArrayBsearch(uiprivArray *arr, const void *key, int (*compare)(const void *, const void *)) +{ + return bsearch(key, arr->buf, arr->len, arr->elemsize, compare); +} + +void uiprivArrayQsort(uiprivArray *arr, int (*compare)(const void *, const void *)) +{ + qsort(arr->buf, arr->len, arr->elemsize, compare); +} diff --git a/common/uipriv.h b/common/uipriv.h index c4d8ef12..9ffdf57c 100644 --- a/common/uipriv.h +++ b/common/uipriv.h @@ -14,6 +14,30 @@ extern int uiprivInitReturnErrorf(uiInitError *err, const char *msg, ...); extern void *uiprivAlloc(size_t n, const char *what); extern void *uiprivRealloc(void *p, size_t old, size_t new, const char *what); extern void uiprivFree(void *p); +typedef struct uiprivArray uiprivArray; +struct uiprivArray { + void *buf; + size_t len; + size_t cap; + size_t elemsize; + size_t nGrow; + const char *what; +}; +#define uiprivInitArray(arr, T, grow) \ + memset(&arr, 0, sizeof (uiprivArray)); \ + arr.elemsize = sizeof (T); \ + arr.nGrow = grow; \ + arr.what = #T "[]"; +#define uiprivFreeArray(arr) \ + uiprivFree(arr.buf); \ + memset(&arr, 0, sizeof (uiprivArray); +#define uiprivArrayAt(arr, T, n) (((T *) (arr.buf)) + (n)) +extern void *uiprivArrayAppend(uiprivArray *arr, size_t n); +extern void *uiprivArrayInsertAt(uiprivArray *arr, size_t pos, size_t n); +extern void uiprivArrayDelete(uiprivArray *arr, size_t pos, size_t n); +extern void uiprivArrayDeleteItem(uiprivArray *arr, void *p, size_t n); +extern void *uiprivArrayBsearch(uiprivArray *arr, const void *key, int (*compare)(const void *, const void *)); +extern void uiprivArrayQsort(uiprivArray *arr, int (*compare)(const void *, const void *)); // errors.c extern void uiprivInternalError(const char *fmt, ...);