richterm

"terminal emulator" with support for text fonts and images for plan9
git clone git://nsmpr.xyz/richterm.git
Log | Files | Refs | README

commit a2ed7dd5873d2ac5113b21735688737fab330191
parent 421a152dfb5147bee67a07afcd5ab1d3c07b28e1
Author: Pavel Renev <an2qzavok@gmail.com>
Date:   Tue, 24 Aug 2021 01:03:24 +0000

array: add arrayinsert, fix bug in arraygrow, rework some functions to copy memory from/to a pointer, if supplied

Diffstat:
Marray.c | 66+++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Marray.h | 12++++++------
2 files changed, 57 insertions(+), 21 deletions(-)

diff --git a/array.c b/array.c @@ -3,6 +3,16 @@ #include "array.h" +int +_arraycheck(Array *ap, long n, char *s) +{ + if ((n < 0) || (n >= ap->count)) { + werrstr("%s: out of bounds", s); + return -1; + } + return 0; +} + Array * arraycreate(long size, long n, void (*free)(void *)) { @@ -26,9 +36,10 @@ arrayfree(Array *ap) qlock(ap->l); if (ap->free != nil) { for (i = 0; i < ap->count; i ++) { - void **v; - v = arrayget(ap, i); - ap->free(*v); + void *v; + v = nil; + arrayget(ap, i, &v); + if (v != nil) ap->free(v); } } qunlock(ap->l); @@ -36,21 +47,25 @@ arrayfree(Array *ap) } void * -arraygrow(Array *ap, long n) +arraygrow(Array *ap, long n, void *v) { - void *v; + void *ve; if (n < 0) { werrstr("arraygrow: negative growth size"); return nil; } - v = arrayend(ap); + ve = arrayend(ap); qlock(ap->l); ap->count += n; if (ap->count > ap->n) { ap->n += ap->n; + if (ap->count > ap->n) ap->n = ap->count; ap->p = realloc(ap->p, ap->size * ap->n); } - memset(v, 0, ap->size * n); + memset(ve, 0, ap->size * ap->n); + if (v != nil) { + memcpy(ve, v, n * ap->size); + } qunlock(ap->l); return (void *)(ap->p + ap->size * (ap->count - n)); } @@ -59,10 +74,7 @@ int arraydel(Array *ap, long n) { char *v; - if ((n < 0) || (n >= ap->count)) { - werrstr("arraydel: out of bounds"); - return -1; - } + if (_arraycheck(ap, n, "arraydel") != 0) return -1; qlock(ap->l); v = ap->p + ap->size * n; if (ap->free != nil) ap->free(v); @@ -73,12 +85,14 @@ arraydel(Array *ap, long n) } void * -arrayget(Array *ap, long n) +arrayget(Array *ap, long n, void *v) { - if ((n < 0) || (n >= ap->count)) { - werrstr("arrayget: out of bounds"); - return nil; + if (_arraycheck(ap, n, "arrayget") != 0) return nil; + qlock(ap->l); + if (v != nil) { + memcpy(v, ap->p + ap->size * n, ap->size); } + qunlock(ap->l); return (void *)(ap->p + ap->size * n); } @@ -87,3 +101,25 @@ arrayend(Array *ap) { return (void *)(ap->p + ap->size * ap->count); } + +void * +arrayinsert(Array *ap, long n, long m, void *v) +{ + void *vs, *vn; + if (n == ap->count) { + vs = arraygrow(ap, m, v); + return vs; + } + if (_arraycheck(ap, n, "arrayinsert") != 0) return nil; + arraygrow(ap, m, nil); + vs = arrayget(ap, n, nil); + vn = arrayget(ap, n + m, nil); + qlock(ap->l); + memcpy(vn, vs, (ap->count - n - m) * ap->size); + memset(vs, 0, m * ap->size); + if (v != nil) { + memcpy(vs, v, m * ap->size); + } + qunlock(ap->l); + return vs; +} diff --git a/array.h b/array.h @@ -9,9 +9,10 @@ struct Array { void (*free)(void *); }; -Array * arraycreate(long, long, void (*free)(void *)); -void arrayfree(Array *); -void * arraygrow(Array *, long); +Array * arraycreate(long size, long n, void (*free)(void *)); int arraydel(Array *, long); -void * arrayget(Array *, long); -void * arrayend(Array *); -\ No newline at end of file +void arrayfree(Array *); +void * arraygrow(Array *, long, void *); +void * arrayget(Array *, long, void *); +void * arrayend(Array *); +void * arrayinsert(Array *, long, long, void *);