From d8ccc87fed8a4c588e4ad9279e62925f416d36b3 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sun, 25 Nov 2018 23:05:59 +0100 Subject: Some fixes and add wide-character string duplication functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- aligned_wcsndup.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 aligned_wcsndup.c (limited to 'aligned_wcsndup.c') diff --git a/aligned_wcsndup.c b/aligned_wcsndup.c new file mode 100644 index 0000000..f3fbf23 --- /dev/null +++ b/aligned_wcsndup.c @@ -0,0 +1,34 @@ +/* See LICENSE file for copyright and license details. */ +#include "libsimple.h" +#ifndef TEST + + +wchar_t * +libsimple_aligned_wcsndup(const wchar_t *s, size_t alignment, size_t n) +{ + size_t size; + void *ret; + if (LIBSIMPLE_UMUL_OVERFLOW_NONZERO(n + 1, sizeof(wchar_t), &size, SIZE_MAX)) { + errno = ENOMEM; + enprintf(status, "wcsdup:"); + } + size = size + (alignment - size % alignment) % alignment; + ret = aligned_alloc(alignment, size); + if (!ret) + return NULL; + wmemcpy(ret, s, n); + ret[n] = 0; + return ret; +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif -- cgit v1.2.3-70-g09d2 From a2fc726a6225ceb94dba367cf5acfe597ce11d74 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Thu, 29 Nov 2018 21:25:44 +0100 Subject: A bunch of stuff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 9 + README | 4 +- aligned_wcsndup.c | 4 +- aligned_wmemdup.c | 2 +- allocn.c | 12 +- enaligned_realloc.c | 25 ++ enaligned_reallocarray.c | 25 ++ enrealloc.c | 2 +- enreallocarray.c | 25 ++ envaligned_reallocn.c | 25 ++ enwcsndup.c | 2 +- enwmemdup.c | 2 +- libsimple-arg.h | 30 +- libsimple.h | 97 ++++- libsimple/aligned_realloc.h | 655 ++++++++++++++++++++++++++++++++ libsimple/aligned_strdup.h | 8 +- libsimple/aligned_strndup.h | 8 +- libsimple/aligned_wcsdup.h | 8 +- libsimple/aligned_wcsndup.h | 8 +- libsimple/aligned_wmemdup.h | 14 +- libsimple/realloc.h | 260 ++++++++++++- libsimple/wcsdup.h | 12 +- libsimple/wcsndup.h | 17 +- libsimple/wmemdup.h | 16 +- man0/libsimple.h.0 | 245 +++++++++++- man3/aligned_realloc.3libsimple | 1 + man3/aligned_reallocarray.3libsimple | 1 + man3/aligned_reallocarrayf.3libsimple | 1 + man3/aligned_reallocf.3libsimple | 1 + man3/aligned_reallocfn.3libsimple | 1 + man3/aligned_reallocn.3libsimple | 1 + man3/aligned_strdup.3libsimple | 1 + man3/aligned_strdupa.3libsimple | 1 + man3/aligned_strndup.3libsimple | 1 + man3/aligned_strndupa.3libsimple | 1 + man3/aligned_wcsdup.3libsimple | 1 + man3/aligned_wcsdupa.3libsimple | 1 + man3/aligned_wcsndup.3libsimple | 1 + man3/aligned_wcsndupa.3libsimple | 1 + man3/aligned_wmemdup.3libsimple | 1 + man3/aligned_wmemdupa.3libsimple | 1 + man3/ealigned_realloc.3libsimple | 1 + man3/ealigned_reallocarray.3libsimple | 1 + man3/ealigned_reallocn.3libsimple | 1 + man3/ealigned_strdup.3libsimple | 1 + man3/ealigned_strndup.3libsimple | 1 + man3/ealigned_wcsdup.3libsimple | 1 + man3/ealigned_wcsndup.3libsimple | 1 + man3/ealigned_wmemdup.3libsimple | 1 + man3/enaligned_realloc.3libsimple | 1 + man3/enaligned_reallocarray.3libsimple | 1 + man3/enaligned_reallocn.3libsimple | 1 + man3/enaligned_strdup.3libsimple | 1 + man3/enaligned_strndup.3libsimple | 1 + man3/enaligned_wcsdup.3libsimple | 1 + man3/enaligned_wcsndup.3libsimple | 1 + man3/enaligned_wmemdup.3libsimple | 1 + man3/enreallocarray.3libsimple | 1 + man3/envaligned_reallocn.3libsimple | 1 + man3/enwcsdup.3libsimple | 1 + man3/enwcsndup.3libsimple | 1 + man3/enwmemdup.3libsimple | 1 + man3/ereallocarray.3libsimple | 1 + man3/evaligned_reallocn.3libsimple | 1 + man3/ewcsdup.3libsimple | 1 + man3/ewcsndup.3libsimple | 1 + man3/ewmemdup.3libsimple | 1 + man3/libsimple_aligned_allocz.3 | 10 + man3/libsimple_aligned_memdup.3 | 11 +- man3/libsimple_aligned_realloc.3 | 200 ++++++++++ man3/libsimple_aligned_reallocarray.3 | 202 ++++++++++ man3/libsimple_aligned_reallocarrayf.3 | 154 ++++++++ man3/libsimple_aligned_reallocf.3 | 152 ++++++++ man3/libsimple_aligned_reallocfn.3 | 1 + man3/libsimple_aligned_reallocn.3 | 1 + man3/libsimple_aligned_strdup.3 | 151 ++++++++ man3/libsimple_aligned_strdupa.3 | 1 + man3/libsimple_aligned_strndup.3 | 154 ++++++++ man3/libsimple_aligned_strndupa.3 | 1 + man3/libsimple_aligned_wcsdup.3 | 151 ++++++++ man3/libsimple_aligned_wcsdupa.3 | 1 + man3/libsimple_aligned_wcsndup.3 | 156 ++++++++ man3/libsimple_aligned_wcsndupa.3 | 1 + man3/libsimple_aligned_wmemdup.3 | 155 ++++++++ man3/libsimple_aligned_wmemdupa.3 | 1 + man3/libsimple_ealigned_realloc.3 | 1 + man3/libsimple_ealigned_reallocarray.3 | 1 + man3/libsimple_ealigned_reallocn.3 | 1 + man3/libsimple_ealigned_strdup.3 | 1 + man3/libsimple_ealigned_strndup.3 | 1 + man3/libsimple_ealigned_wcsdup.3 | 1 + man3/libsimple_ealigned_wcsndup.3 | 1 + man3/libsimple_ealigned_wmemdup.3 | 1 + man3/libsimple_enaligned_alloc.3 | 10 + man3/libsimple_enaligned_realloc.3 | 1 + man3/libsimple_enaligned_reallocarray.3 | 1 + man3/libsimple_enaligned_reallocn.3 | 1 + man3/libsimple_enaligned_strdup.3 | 1 + man3/libsimple_enaligned_strndup.3 | 1 + man3/libsimple_enaligned_wcsdup.3 | 1 + man3/libsimple_enaligned_wcsndup.3 | 1 + man3/libsimple_enaligned_wmemdup.3 | 1 + man3/libsimple_encalloc.3 | 10 + man3/libsimple_enmalloc.3 | 10 + man3/libsimple_enposix_memalign.3 | 10 + man3/libsimple_enrealloc.3 | 10 + man3/libsimple_enreallocarray.3 | 1 + man3/libsimple_enstrdup.3 | 8 +- man3/libsimple_enstrndup.3 | 8 +- man3/libsimple_envaligned_reallocn.3 | 1 + man3/libsimple_enwcsdup.3 | 124 ++++++ man3/libsimple_enwcsndup.3 | 1 + man3/libsimple_enwmemdup.3 | 1 + man3/libsimple_ereallocarray.3 | 1 + man3/libsimple_evaligned_reallocn.3 | 1 + man3/libsimple_ewcsdup.3 | 1 + man3/libsimple_ewcsndup.3 | 1 + man3/libsimple_ewmemdup.3 | 1 + man3/libsimple_mallocz.3 | 10 + man3/libsimple_memalign.3 | 10 + man3/libsimple_memalignz.3 | 10 + man3/libsimple_memdup.3 | 10 +- man3/libsimple_posix_memalignz.3 | 10 + man3/libsimple_pvalloc.3 | 10 + man3/libsimple_pvallocz.3 | 10 + man3/libsimple_reallocarray.3 | 191 ++++++++++ man3/libsimple_reallocarrayf.3 | 143 +++++++ man3/libsimple_reallocf.3 | 141 +++++++ man3/libsimple_reallocfn.3 | 1 + man3/libsimple_valigned_allocn.3 | 10 + man3/libsimple_valigned_alloczn.3 | 10 + man3/libsimple_valigned_reallocfn.3 | 177 +++++++++ man3/libsimple_valigned_reallocn.3 | 267 +++++++++++++ man3/libsimple_valloc.3 | 10 + man3/libsimple_vallocz.3 | 10 + man3/libsimple_varrayalloc.3 | 10 + man3/libsimple_vcallocn.3 | 10 + man3/libsimple_vmallocn.3 | 10 + man3/libsimple_vmalloczn.3 | 10 + man3/libsimple_vmemalignn.3 | 10 + man3/libsimple_vmemalignzn.3 | 10 + man3/libsimple_vmemalloc.3 | 10 + man3/libsimple_vposix_memalignn.3 | 10 + man3/libsimple_vposix_memalignzn.3 | 10 + man3/libsimple_vpvallocn.3 | 10 + man3/libsimple_vpvalloczn.3 | 10 + man3/libsimple_vreallocfn.3 | 166 ++++++++ man3/libsimple_vreallocn.3 | 17 +- man3/libsimple_vvallocn.3 | 10 + man3/libsimple_vvalloczn.3 | 10 + man3/libsimple_wcsdupa.3 | 1 + man3/libsimple_wcsndup.3 | 155 ++++++++ man3/libsimple_wcsndupa.3 | 1 + man3/libsimple_wmemdup.3 | 155 ++++++++ man3/libsimple_wmemdupa.3 | 1 + man3/reallocarray.3libsimple | 1 + man3/reallocarrayf.3libsimple | 1 + man3/reallocf.3libsimple | 1 + man3/reallocfn.3libsimple | 1 + man3/valigned_reallocfn.3libsimple | 1 + man3/valigned_reallocn.3libsimple | 1 + man3/vreallocfn.3libsimple | 1 + man3/wcsdupa.3libsimple | 1 + man3/wcsndup.3libsimple | 1 + man3/wcsndupa.3libsimple | 1 + man3/wmemdup.3libsimple | 1 + man3/wmemdupa.3libsimple | 1 + wcsndup.c | 7 +- 168 files changed, 4861 insertions(+), 89 deletions(-) create mode 100644 enaligned_realloc.c create mode 100644 enaligned_reallocarray.c create mode 100644 enreallocarray.c create mode 100644 envaligned_reallocn.c create mode 100644 libsimple/aligned_realloc.h create mode 120000 man3/aligned_realloc.3libsimple create mode 120000 man3/aligned_reallocarray.3libsimple create mode 120000 man3/aligned_reallocarrayf.3libsimple create mode 120000 man3/aligned_reallocf.3libsimple create mode 120000 man3/aligned_reallocfn.3libsimple create mode 120000 man3/aligned_reallocn.3libsimple create mode 120000 man3/aligned_strdup.3libsimple create mode 120000 man3/aligned_strdupa.3libsimple create mode 120000 man3/aligned_strndup.3libsimple create mode 120000 man3/aligned_strndupa.3libsimple create mode 120000 man3/aligned_wcsdup.3libsimple create mode 120000 man3/aligned_wcsdupa.3libsimple create mode 120000 man3/aligned_wcsndup.3libsimple create mode 120000 man3/aligned_wcsndupa.3libsimple create mode 120000 man3/aligned_wmemdup.3libsimple create mode 120000 man3/aligned_wmemdupa.3libsimple create mode 120000 man3/ealigned_realloc.3libsimple create mode 120000 man3/ealigned_reallocarray.3libsimple create mode 120000 man3/ealigned_reallocn.3libsimple create mode 120000 man3/ealigned_strdup.3libsimple create mode 120000 man3/ealigned_strndup.3libsimple create mode 120000 man3/ealigned_wcsdup.3libsimple create mode 120000 man3/ealigned_wcsndup.3libsimple create mode 120000 man3/ealigned_wmemdup.3libsimple create mode 120000 man3/enaligned_realloc.3libsimple create mode 120000 man3/enaligned_reallocarray.3libsimple create mode 120000 man3/enaligned_reallocn.3libsimple create mode 120000 man3/enaligned_strdup.3libsimple create mode 120000 man3/enaligned_strndup.3libsimple create mode 120000 man3/enaligned_wcsdup.3libsimple create mode 120000 man3/enaligned_wcsndup.3libsimple create mode 120000 man3/enaligned_wmemdup.3libsimple create mode 120000 man3/enreallocarray.3libsimple create mode 120000 man3/envaligned_reallocn.3libsimple create mode 120000 man3/enwcsdup.3libsimple create mode 120000 man3/enwcsndup.3libsimple create mode 120000 man3/enwmemdup.3libsimple create mode 120000 man3/ereallocarray.3libsimple create mode 120000 man3/evaligned_reallocn.3libsimple create mode 120000 man3/ewcsdup.3libsimple create mode 120000 man3/ewcsndup.3libsimple create mode 120000 man3/ewmemdup.3libsimple create mode 100644 man3/libsimple_aligned_realloc.3 create mode 100644 man3/libsimple_aligned_reallocarray.3 create mode 100644 man3/libsimple_aligned_reallocarrayf.3 create mode 100644 man3/libsimple_aligned_reallocf.3 create mode 120000 man3/libsimple_aligned_reallocfn.3 create mode 120000 man3/libsimple_aligned_reallocn.3 create mode 100644 man3/libsimple_aligned_strdup.3 create mode 120000 man3/libsimple_aligned_strdupa.3 create mode 100644 man3/libsimple_aligned_strndup.3 create mode 120000 man3/libsimple_aligned_strndupa.3 create mode 100644 man3/libsimple_aligned_wcsdup.3 create mode 120000 man3/libsimple_aligned_wcsdupa.3 create mode 100644 man3/libsimple_aligned_wcsndup.3 create mode 120000 man3/libsimple_aligned_wcsndupa.3 create mode 100644 man3/libsimple_aligned_wmemdup.3 create mode 120000 man3/libsimple_aligned_wmemdupa.3 create mode 120000 man3/libsimple_ealigned_realloc.3 create mode 120000 man3/libsimple_ealigned_reallocarray.3 create mode 120000 man3/libsimple_ealigned_reallocn.3 create mode 120000 man3/libsimple_ealigned_strdup.3 create mode 120000 man3/libsimple_ealigned_strndup.3 create mode 120000 man3/libsimple_ealigned_wcsdup.3 create mode 120000 man3/libsimple_ealigned_wcsndup.3 create mode 120000 man3/libsimple_ealigned_wmemdup.3 create mode 120000 man3/libsimple_enaligned_realloc.3 create mode 120000 man3/libsimple_enaligned_reallocarray.3 create mode 120000 man3/libsimple_enaligned_reallocn.3 create mode 120000 man3/libsimple_enaligned_strdup.3 create mode 120000 man3/libsimple_enaligned_strndup.3 create mode 120000 man3/libsimple_enaligned_wcsdup.3 create mode 120000 man3/libsimple_enaligned_wcsndup.3 create mode 120000 man3/libsimple_enaligned_wmemdup.3 create mode 120000 man3/libsimple_enreallocarray.3 create mode 120000 man3/libsimple_envaligned_reallocn.3 create mode 100644 man3/libsimple_enwcsdup.3 create mode 120000 man3/libsimple_enwcsndup.3 create mode 120000 man3/libsimple_enwmemdup.3 create mode 120000 man3/libsimple_ereallocarray.3 create mode 120000 man3/libsimple_evaligned_reallocn.3 create mode 120000 man3/libsimple_ewcsdup.3 create mode 120000 man3/libsimple_ewcsndup.3 create mode 120000 man3/libsimple_ewmemdup.3 create mode 100644 man3/libsimple_reallocarray.3 create mode 100644 man3/libsimple_reallocarrayf.3 create mode 100644 man3/libsimple_reallocf.3 create mode 120000 man3/libsimple_reallocfn.3 create mode 100644 man3/libsimple_valigned_reallocfn.3 create mode 100644 man3/libsimple_valigned_reallocn.3 create mode 100644 man3/libsimple_vreallocfn.3 create mode 120000 man3/libsimple_wcsdupa.3 create mode 100644 man3/libsimple_wcsndup.3 create mode 120000 man3/libsimple_wcsndupa.3 create mode 100644 man3/libsimple_wmemdup.3 create mode 120000 man3/libsimple_wmemdupa.3 create mode 120000 man3/reallocarray.3libsimple create mode 120000 man3/reallocarrayf.3libsimple create mode 120000 man3/reallocf.3libsimple create mode 120000 man3/reallocfn.3libsimple create mode 120000 man3/valigned_reallocfn.3libsimple create mode 120000 man3/valigned_reallocn.3libsimple create mode 120000 man3/vreallocfn.3libsimple create mode 120000 man3/wcsdupa.3libsimple create mode 120000 man3/wcsndup.3libsimple create mode 120000 man3/wcsndupa.3libsimple create mode 120000 man3/wmemdup.3libsimple create mode 120000 man3/wmemdupa.3libsimple (limited to 'aligned_wcsndup.c') diff --git a/Makefile b/Makefile index 1111419..1a8e05e 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ SUBHDR =\ libsimple/aligned_alloc.h\ libsimple/aligned_allocz.h\ libsimple/aligned_memdup.h\ + libsimple/aligned_realloc.h\ libsimple/aligned_strdup.h\ libsimple/aligned_strndup.h\ libsimple/aligned_wcsdup.h\ @@ -49,6 +50,8 @@ HDR =\ OBJ =\ aligned_memdup.o\ aligned_strndup.o\ + aligned_wcsndup.o\ + aligned_wmemdup.o\ allocn.o\ asprintf.o\ difftimespec.o\ @@ -57,6 +60,8 @@ OBJ =\ doubletotimeval.o\ enaligned_allocz.o\ enaligned_memdup.o\ + enaligned_realloc.o\ + enaligned_reallocarray.o\ enaligned_strdup.o\ enaligned_strndup.o\ encalloc.o\ @@ -64,9 +69,11 @@ OBJ =\ enmemdup.o\ enposix_memalignz.o\ enrealloc.o\ + enreallocarray.o\ enstrdup.o\ enstrndup.o\ envaligned_alloczn.o\ + envaligned_reallocn.o\ envmalloczn.o\ envmemalloc.o\ envposix_memalignzn.o\ @@ -186,6 +193,8 @@ OBJ =\ vmemalloc.o\ vputenvf.o\ vweprintf.o\ + wcsndup.o\ + wmemdup.o\ libsimple.o MAN0 =\ diff --git a/README b/README index 0effbc4..1de7b5c 100644 --- a/README +++ b/README @@ -21,10 +21,10 @@ and , the naming scheme of these functions is: = wcsn for wide-character strings that may not be NUL-terminated = wmem for wide-character arrays - = str if is str, wsc, strn, or wscn + = str if is str, wcs, strn, or wcsn = mem if is mem or wmem - = chrnul if is str, wsc, strn, or wscn + = chrnul if is str, wcs, strn, or wcsn = scan if is mem or wmem [case] = if case-sensitive diff --git a/aligned_wcsndup.c b/aligned_wcsndup.c index f3fbf23..1839316 100644 --- a/aligned_wcsndup.c +++ b/aligned_wcsndup.c @@ -7,10 +7,10 @@ wchar_t * libsimple_aligned_wcsndup(const wchar_t *s, size_t alignment, size_t n) { size_t size; - void *ret; + wchar_t *ret; if (LIBSIMPLE_UMUL_OVERFLOW_NONZERO(n + 1, sizeof(wchar_t), &size, SIZE_MAX)) { errno = ENOMEM; - enprintf(status, "wcsdup:"); + return NULL; } size = size + (alignment - size % alignment) % alignment; ret = aligned_alloc(alignment, size); diff --git a/aligned_wmemdup.c b/aligned_wmemdup.c index bda654d..c92e17f 100644 --- a/aligned_wmemdup.c +++ b/aligned_wmemdup.c @@ -10,7 +10,7 @@ libsimple_aligned_wmemdup(const wchar_t *s, size_t alignment, size_t n) void *ret; if (LIBSIMPLE_UMUL_OVERFLOW_NONZERO(n, sizeof(wchar_t), &size, SIZE_MAX)) { errno = ENOMEM; - enprintf(status, "wcsdup:"); + return NULL; } size = size + (alignment - size % alignment) % alignment; ret = aligned_alloc(alignment, size ? size : alignment); diff --git a/allocn.c b/allocn.c index d54542c..ce4fbad 100644 --- a/allocn.c +++ b/allocn.c @@ -15,11 +15,10 @@ alloc_size_product(int *errp, size_t n, va_list ap) n = va_arg(ap, size_t); if (!n) break; - if (n >= SIZE_MAX / prod) { + if (LIBSIMPLE_UMUL_OVERFLOW_NONZERO(n, prod, &prod, SIZE_MAX)) { *errp = ENOMEM; return 0; } - prod *= n; } return prod; } @@ -62,6 +61,15 @@ libsimple_vposix_memalignzn(void **memptr, int clear, size_t alignment, size_t n return ret; } +#ifdef LIBSIMPLE_HAVE_ALIGNED_REALLOC +void * +libsimple_valigned_reallocn(void *ptr, size_t alignment, size_t n, va_list ap) /* TODO test (aligned_reallocn) */ +{ + n = alloc_size_product(&errno, n, ap); + return !n ? NULL : aligned_realloc(ptr, alignment, n); +} +#endif + #else #include "test.h" diff --git a/enaligned_realloc.c b/enaligned_realloc.c new file mode 100644 index 0000000..9ae1612 --- /dev/null +++ b/enaligned_realloc.c @@ -0,0 +1,25 @@ +/* See LICENSE file for copyright and license details. */ +#include "libsimple.h" +#ifndef TEST + + +void * +libsimple_enaligned_realloc(int status, void *ptr, size_t alignment, size_t n) /* TODO test (ealigned_realloc) */ +{ + void *ret = aligned_realloc(ptr, alignment, n); + if (!ret) + enprintf(status, "aligned_realloc:"); + return ret; +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/enaligned_reallocarray.c b/enaligned_reallocarray.c new file mode 100644 index 0000000..35050ec --- /dev/null +++ b/enaligned_reallocarray.c @@ -0,0 +1,25 @@ +/* See LICENSE file for copyright and license details. */ +#include "libsimple.h" +#ifndef TEST + + +void * +libsimple_enaligned_reallocarray(int status, void *ptr, size_t alignment, size_t n, size_t m) /* TODO test (ealigned_reallocarray) */ +{ + void *ret = aligned_reallocarray(ptr, alignment, n, m); + if (!ret) + enprintf(status, "aligned_reallocarray:"); + return ret; +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/enrealloc.c b/enrealloc.c index 878674c..b27cb18 100644 --- a/enrealloc.c +++ b/enrealloc.c @@ -6,7 +6,7 @@ void * libsimple_enrealloc(int status, void *ptr, size_t n) { - char *ret = realloc(ptr, n); + void *ret = realloc(ptr, n); if (!ret) enprintf(status, "realloc:"); return ret; diff --git a/enreallocarray.c b/enreallocarray.c new file mode 100644 index 0000000..c988994 --- /dev/null +++ b/enreallocarray.c @@ -0,0 +1,25 @@ +/* See LICENSE file for copyright and license details. */ +#include "libsimple.h" +#ifndef TEST + + +void * +libsimple_enreallocarray(int status, void *ptr, size_t n, size_t m) /* TODO test */ +{ + void *ret = reallocarray(ptr, n, m); + if (!ret) + enprintf(status, "reallocarray:"); + return ret; +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/envaligned_reallocn.c b/envaligned_reallocn.c new file mode 100644 index 0000000..747e8c8 --- /dev/null +++ b/envaligned_reallocn.c @@ -0,0 +1,25 @@ +/* See LICENSE file for copyright and license details. */ +#include "libsimple.h" +#ifndef TEST + + +void * +libsimple_envaligned_reallocn(int status, void *ptr, size_t alignment, size_t n, va_list ap) /* TODO test (evaligned_reallocn, aligned_reallocn, enaligned_reallocn, ealigned_reallocn) */ +{ + void *ret = valigned_reallocn(ptr, alignment, n, ap); + if (!ret) + enprintf(status, "valigned_reallocn:"); + return ret; +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/enwcsndup.c b/enwcsndup.c index 551311d..f08da34 100644 --- a/enwcsndup.c +++ b/enwcsndup.c @@ -6,7 +6,7 @@ wchar_t * libsimple_enwcsndup(int status, const wchar_t *s, size_t n) /* TODO test */ { - wchar_t *ret = wcsndup(s, n); + wchar_t *ret = libsimple_wcsndup(s, n); if (!ret) enprintf(status, "wcsndup:"); return ret; diff --git a/enwmemdup.c b/enwmemdup.c index 8f99007..fb8c8dc 100644 --- a/enwmemdup.c +++ b/enwmemdup.c @@ -6,7 +6,7 @@ wchar_t * libsimple_enwmemdup(int status, const wchar_t *s, size_t n) /* TODO test */ { - wchar_t *ret = wmemdup(s, n); + wchar_t *ret = libsimple_wmemdup(s, n); if (!ret) enprintf(status, "wmemdup:"); return ret; diff --git a/libsimple-arg.h b/libsimple-arg.h index 1f4291c..983f4c8 100644 --- a/libsimple-arg.h +++ b/libsimple-arg.h @@ -398,8 +398,19 @@ struct longopt { #define USAGE(SYNOPSIS)\ NUSAGE(1, SYNOPSIS) + +/* Intended for internal use only */ +#if __STDC_VERSION__ >= 201112L +# define _LIBSIMPLE_NORETURN _Noreturn +#elif defined(__GNUC__) || defined(__clang__) +# define _LIBSIMPLE_NORETURN __attribute__((noreturn)) +#else +# define _LIBSIMPLE_NORETURN +#endif + + /** - * Define the function `static void usage(void)` + * Define the function `static _Noreturn void usage(void)` * that prints the error message * "usage: %s %s\n", argv0, SYNOPSIS * or @@ -412,26 +423,15 @@ struct longopt { * @param SYNOPSIS:const char * Description of the command line argument syntax * @parma STATUS:int The exit value for the process */ -#if defined(__GNUC__) || defined(__clang__) -# define NUSAGE(STATUS, SYNOPSIS)\ - __attribute__((noreturn))\ - static void usage(void)\ - {\ - const char *syn = SYNOPSIS ? SYNOPSIS : "";\ - fprintf(stderr, "usage: %s%s%s\n", argv0, *syn ? " " : "", syn);\ - exit(STATUS);\ - }\ - char *argv0 = NULL -#else -# define NUSAGE(STATUS, SYNOPSIS)\ - static void usage(void)\ +#define NUSAGE(STATUS, SYNOPSIS)\ + static _LIBSIMPLE_NORETURN void\ + usage(void)\ {\ const char *syn = SYNOPSIS ? SYNOPSIS : "";\ fprintf(stderr, "usage: %s%s%s\n", argv0, *syn ? " " : "", syn);\ exit(STATUS);\ }\ char *argv0 = NULL -#endif #endif diff --git a/libsimple.h b/libsimple.h index 941d864..e97ac27 100644 --- a/libsimple.h +++ b/libsimple.h @@ -43,13 +43,54 @@ #include + #if defined(__GNUC__) && !defined(__clang__) # define _LIBSIMPLE_GCC_ONLY(x) x +# define _LIBSIMPLE_NON_GCC_ONLY(x) #else # define _LIBSIMPLE_GCC_ONLY(x) +# define _LIBSIMPLE_NON_GCC_ONLY(x) x +#endif + +#if __STDC_VERSION__ >= 199409L +# define _LIBSIMPLE_C95_ONLY(x) x +# define _LIBSIMPLE_PRE_C95_ONLY(x) +#else +# define _LIBSIMPLE_C95_ONLY(x) +# define _LIBSIMPLE_PRE_C95_ONLY(x) x #endif +#if __STDC_VERSION__ >= 199901L +# define _LIBSIMPLE_C99_ONLY(x) x +# define _LIBSIMPLE_PRE_C99_ONLY(x) +#else +# define _LIBSIMPLE_C99_ONLY(x) +# define _LIBSIMPLE_PRE_C99_ONLY(x) x +#endif +#if __STDC_VERSION__ >= 201112L +# define _LIBSIMPLE_C11_ONLY(x) x +# define _LIBSIMPLE_PRE_C11_ONLY(x) +#else +# define _LIBSIMPLE_C11_ONLY(x) +# define _LIBSIMPLE_PRE_C11_ONLY(x) x +#endif + +#if __STDC_VERSION__ >= 201710L +# define _LIBSIMPLE_C17_ONLY(x) x +# define _LIBSIMPLE_PRE_C17_ONLY(x) +#else +# define _LIBSIMPLE_C17_ONLY(x) +# define _LIBSIMPLE_PRE_C17_ONLY(x) x +#endif + + +#define _libsimple_assume_aligned_as(TYPE)\ + _LIBSIMPLE_C11_ONLY(__assume_aligned__(_Alignof(TYPE)))\ + _LIBSIMPLE_PRE_C11_ONLY(_LIBSIMPLE_GCC_ONLY__assume_aligned__(__alignof(TYPE))) + + +#include "libsimple/overflow.h" #include "libsimple/printf.h" #include "libsimple/definitions.h" #include "libsimple/memalloc.h" @@ -69,6 +110,7 @@ #include "libsimple/malloc.h" #include "libsimple/calloc.h" #include "libsimple/realloc.h" +#include "libsimple/aligned_realloc.h" #include "libsimple/memalignz.h" #include "libsimple/memalign.h" #include "libsimple/vallocz.h" @@ -86,7 +128,6 @@ #include "libsimple/array.h" #include "libsimple/str.h" #include "libsimple/strn.h" -#include "libsimple/overflow.h" /** @@ -149,4 +190,58 @@ libsimple_unlist(void *__list, size_t __i, size_t *__np, size_t __width) #endif +#define _LIBSIMPLE_REMOVE_CONST(X, TYPE, ...) (*(TYPE *)(void *)&(X)) +#define LIBSIMPLE_REMOVE_CONST(...) _LIBSIMPLE_REMOVE_CONST(__VA_ARGS__, void *) /* TODO test, doc, man */ +#ifndef REMOVE_CONST +# define REMOVE_CONST(...) LIBSIMPLE_REMOVE_CONST(__VA_ARGS__) +#endif + + +#define LIBSIMPLE_PREFETCH_RDONLY(ADDRESS, LOCALITY) /* void */ /* TODO test, doc, man */\ + _LIBSIMPLE_GCC_ONLY(__builtin_prefetch(ADDRESS, 0, LOCALITY)) +#ifndef PREFETCH_RDONLY +# define PREFETCH_RDONLY(...) LIBSIMPLE_PREFETCH_RDONLY(__VA_ARGS__) +#endif + + +#define LIBSIMPLE_PREFETCH_RDWR(ADDRESS, LOCALITY) /* void */ /* TODO test, doc, man */\ + _LIBSIMPLE_GCC_ONLY(__builtin_prefetch(ADDRESS, 1, LOCALITY)) +#ifndef PREFETCH_RDWR +# define PREFETCH_RDWR(...) LIBSIMPLE_PREFETCH_RDWR(__VA_ARGS__) +#endif + + +#define _LIBSIMPLE_ASSUME_ALIGNED(PTR, ALIGNMENT, ...)\ + _LIBSIMPLE_GCC_ONLY(__builtin_assume_aligned(PTR, ALIGNMENT)) +#if defined(__GNUC__) && !defined(__clang__) +# define LIBSIMPLE_ASSUME_ALIGNED(PTR, ...) /* returns PTR */ /* TODO test, doc, man */\ + _LIBSIMPLE_GCC_ONLY(__builtin_assume_aligned(PTR, ##__VA_ARGS__,\ + _LIBSIMPLE_C11_ONLY(_Alignof(PTR))\ + _LIBSIMPLE_PREC11_ONLY(__alignof(PTR)))) +#endif +#ifndef ASSUME_ALIGNED +# define ASSUME_ALIGNED(...) LIBSIMPLE_ASSUME_ALIGNED(__VA_ARGS__) +#endif + + +#define LIBSIMPLE_ASSUME_MISALIGNED(PTR, ALIGNMENT, OFFSET) /* returns PTR */ /* TODO test, doc, man */\ + __builtin_assume_aligned(PTR, ALIGNMENT, OFFSET) +#ifndef ASSUME_MISALIGNED +# define ASSUME_MISALIGNED(...) LIBSIMPLE_ASSUME_MISALIGNED(__VA_ARGS__) +#endif + + +#define LIBSIMPLE_UNROLLED(N) _LIBSIMPLE_GCC_ONLY(_LIBSIMPLE_C11_ONLY(_Pragma("GCC unroll "#N))) /* TODO test, doc, man */ +#ifndef UNROLLED +# define UNROLLED(N) LIBSIMPLE_UNROLLED(N) +#endif + + +#define LIBSIMPLE_SIMDLOOP _LIBSIMPLE_GCC_ONLY(_LIBSIMPLE_C11_ONLY(_Pragma("GCC ivdep"))) /* TODO test, doc, man */ +#ifndef SIMDLOOP +# define SIMDLOOP LIBSIMPLE_SIMDLOOP +#endif + + + #endif diff --git a/libsimple/aligned_realloc.h b/libsimple/aligned_realloc.h new file mode 100644 index 0000000..f0350e1 --- /dev/null +++ b/libsimple/aligned_realloc.h @@ -0,0 +1,655 @@ +/* See LICENSE file for copyright and license details. */ + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * This function may not be supported, check for the + * existance of the macro `LIBSIMPLE_HAVE_ALIGNED_REALLOC` + * to determine if it is supported + * + * @param status The exit value for the process in case of failure + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n The number of bytes to allocate, the behaviour of + * this function is unspecified for the value 0 + * @return Either `ptr` or a unique pointer with at least + * the specified size; `NULL` on failure + * @throws EINVAL `n` is 0 + * @throws EINVAL `alignment` is not a valid alignment + * @throws ENOMEM Could not allocated enough memory + * @throws ENOSYS Not implemented (requires non-standard libc functions) + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(2), __alloc_size__(3), __warn_unused_result__))) +#if defined(__GLIBC__) +# define LIBSIMPLE_HAVE_ALIGNED_REALLOC +# include +static inline void * +libsimple_aligned_realloc(void *__ptr, size_t __alignment, size_t __n) /* TODO test, musl */ +{ + size_t __old = malloc_usable_size(__ptr); +#if __STDC_VERSION__ >= 201112L || defined(_ISOC11_SOURCE) + size_t __extra = (__alignment - __n % __alignment) % __alignment; + void *__new = aligned_alloc(__alignment, __n + __extra); +#else + void *__new = memalign(__alignment, __n); +#endif + if (__new) { + memcpy(__new, __ptr, __old < __n ? __old : __n); + free(__ptr); + } + return __new; +} +#else +static inline void * +libsimple_aligned_realloc(void *__ptr, size_t __alignment, size_t __n) +{ + (void) __ptr; + (void) __alignment; + (void) __n; + errno = ENOSYS; + return NULL; +} +#endif +#ifndef aligned_realloc +# define aligned_realloc libsimple_aligned_realloc +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * On failure, the `libsimple_enprintf` function is called, + * cause the program to print an error message and exit, + * see `libsimple_enprintf` for more information + * + * This function may not be supported, check for the + * existance of the macro `LIBSIMPLE_HAVE_ALIGNED_REALLOC` + * to determine if it is supported + * + * @param status The exit value for the process in case of failure + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n The number of bytes to allocate, the behaviour of + * this function is unspecified for the value 0 + * @return Either `ptr` or a unique pointer with at least + * the specified size + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(3), __alloc_size__(4), __warn_unused_result__, __returns_nonnull__))) +void *libsimple_enaligned_realloc(int, void *, size_t, size_t); +#ifndef enaligned_realloc +# define enaligned_realloc libsimple_enaligned_realloc +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * On failure, the `libsimple_eprintf` function is called, + * cause the program to print an error message and exit, + * see `libsimple_eprintf` for more information + * + * This function may not be supported, check for the + * existance of the macro `LIBSIMPLE_HAVE_ALIGNED_REALLOC` + * to determine if it is supported + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n The number of bytes to allocate, the behaviour of + * this function is unspecified for the value 0 + * @return Either `ptr` or a unique pointer with at least + * the specified size + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(2), __alloc_size__(3), __warn_unused_result__, __returns_nonnull__))) +static inline void *libsimple_ealigned_realloc(void *__ptr, size_t __alignment, size_t __n) +{ return libsimple_enaligned_realloc(libsimple_default_failure_exit, __ptr, __alignment, __n); } +#ifndef ealigned_realloc +# define ealigned_realloc libsimple_ealigned_realloc +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is deallocated. If `ptr` + * is `NULL` a new allocation is made. + * + * The allocation size will be at least `n * m` + * + * This function may not be supported, check for the + * existance of the macro `LIBSIMPLE_HAVE_ALIGNED_REALLOC` + * to determine if it is supported + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n The number of bytes to allocate, the behaviour of + * this function is unspecified for the value 0 + * @return Either `ptr` or a unique pointer with at least + * the specified size; `NULL` on failure + * @throws EINVAL `n` is 0 + * @throws EINVAL `alignment` is not a valid alignment + * @throws ENOMEM Could not allocated enough memory + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(2), __alloc_size__(3), __warn_unused_result__))) +static inline void * +libsimple_aligned_reallocf(void *__ptr, size_t __alignment, size_t __n) /* TODO test */ +{ + void *__new = __n ? libsimple_aligned_realloc(__ptr, __alignment, __n) : NULL; + if (!__new) + free(__ptr); + return NULL; +} +#ifndef aligned_reallocf +# define aligned_reallocf libsimple_aligned_reallocf +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * The allocation size will be at least `n * m` + * + * This function may not be supported, check for the + * existance of the macro `LIBSIMPLE_HAVE_ALIGNED_REALLOC` + * to determine if it is supported + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n The number of elements to allocate, the behaviour of + * this function is unspecified for the value 0 + * @param m Size, in bytes, of each element, the behaviour of + * this function is unspecified for the value 0 + * @return Either `ptr` or a unique pointer with at least + * the specified size; `NULL` on failure + * @throws EINVAL `n` or `m` is 0 + * @throws EINVAL `alignment` is not a valid alignment + * @throws ENOMEM Could not allocated enough memory + * @throws ENOSYS Not implemented (requires non-standard libc functions) + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(2), __alloc_size__(3, 4), __warn_unused_result__))) +static inline void * +libsimple_aligned_reallocarray(void *__ptr, size_t __alignment, size_t __n, size_t __m) /* TODO test */ +{ + if (LIBSIMPLE_UMUL_OVERFLOW(__n, __m, &__n, SIZE_MAX)) { + errno = ENOMEM; + return NULL; + } + return libsimple_aligned_realloc(__ptr, __alignment, __n); +} +#ifndef aligned_reallocarray +# define aligned_reallocarray libsimple_aligned_reallocarray +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * On failure, the `libsimple_enprintf` function is called, + * cause the program to print an error message and exit, + * see `libsimple_enprintf` for more information + * + * The allocation size will be at least `n * m` + * + * This function may not be supported, check for the + * existance of the macro `LIBSIMPLE_HAVE_ALIGNED_REALLOC` + * to determine if it is supported + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n The number of elements to allocate, the behaviour of + * this function is unspecified for the value 0 + * @param m Size, in bytes, of each element, the behaviour of + * this function is unspecified for the value 0 + * @return Either `ptr` or a unique pointer with at least + * the specified size + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(3), __alloc_size__(4, 5), __warn_unused_result__, __returns_nonnull__))) +void *libsimple_enaligned_reallocarray(int, void *, size_t, size_t, size_t); +#ifndef enaligned_reallocarray +# define enaligned_reallocarray libsimple_enaligned_reallocarray +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * On failure, the `libsimple_eprintf` function is called, + * cause the program to print an error message and exit, + * see `libsimple_eprintf` for more information + * + * The allocation size will be at least `n * m` + * + * This function may not be supported, check for the + * existance of the macro `LIBSIMPLE_HAVE_ALIGNED_REALLOC` + * to determine if it is supported + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n The number of elements to allocate, the behaviour of + * this function is unspecified for the value 0 + * @param m Size, in bytes, of each element, the behaviour of + * this function is unspecified for the value 0 + * @return Either `ptr` or a unique pointer with at least + * the specified size + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(2), __alloc_size__(3, 4), __warn_unused_result__, __returns_nonnull__))) +static inline void *libsimple_ealigned_reallocarray(void *__ptr, size_t __alignment, size_t __n, size_t __m) +{ return libsimple_enaligned_reallocarray(libsimple_default_failure_exit, __ptr, __alignment, __n, __m); } +#ifndef ealigned_reallocarray +# define ealigned_reallocarray libsimple_ealigned_reallocarray +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is deallocated. If `ptr` + * is `NULL` a new allocation is made. + * + * The allocation size will be at least `n * m` + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n The number of elements to allocate, the behaviour of + * this function is unspecified for the value 0 + * @param m Size, in bytes, of each element, the behaviour of + * this function is unspecified for the value 0 + * @return Either `ptr` or a unique pointer with at least + * the specified size; `NULL` on failure + * @throws EINVAL `n` or `m` is 0 + * @throws EINVAL `alignment` is not a valid alignment + * @throws ENOMEM Could not allocated enough memory + * @throws ENOSYS Not implemented (requires non-standard libc functions) + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(2), __alloc_size__(3, 4), __warn_unused_result__))) +static inline void * +libsimple_aligned_reallocarrayf(void *__ptr, size_t __alignment, size_t __n, size_t __m) /* TODO test */ +{ + void *__new = (__n && __m) ? libsimple_aligned_reallocarray(__ptr, __alignment, __n, __m) : NULL; + if (!__new) + free(__ptr); + return NULL; +} +#ifndef aligned_reallocarrayf +# define aligned_reallocarrayf libsimple_aligned_reallocarrayf +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * The product of all arguments, up to the first 0, + * will be used as the number of bytes to allocated + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * This function may not be supported, check for the + * existance of the macro `LIBSIMPLE_HAVE_ALIGNED_REALLOC` + * to determine if it is supported + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n First factor for the allocation size, must not be 0 + * @param ap The rest of the factors for the allocation size, + * all arguments should have the type `size_t`, and + * list must end with 0 (which is not factor) + * @return Either `ptr` or a unique pointer with at least + * the specified size; `NULL` on failure + * @throws EINVAL `n` is 0 + * @throws EINVAL `alignment` is not a valid alignment + * @throws ENOMEM Could not allocated enough memory + * @throws ENOSYS Not implemented (requires non-standard libc functions) + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(2), __warn_unused_result__))) +void *libsimple_valigned_reallocn(void *, size_t, size_t, va_list); +#ifndef valigned_reallocn +# define valigned_reallocn libsimple_valigned_reallocn +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * The product of all arguments except `status`, up to the + * first 0, will be used as the number of bytes to allocated + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * On failure, the `libsimple_enprintf` function is called, + * cause the program to print an error message and exit, + * see `libsimple_enprintf` for more information + * + * This function may not be supported, check for the + * existance of the macro `LIBSIMPLE_HAVE_ALIGNED_REALLOC` + * to determine if it is supported + * + * @param status The exit value for the process in case of failure + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n First factor for the allocation size, must not be 0 + * @param ap The rest of the factors for the allocation size, + * all arguments should have the type `size_t`, and + * list must end with 0 (which is not factor) + * @return Either `ptr` or a unique pointer with at least + * the specified size + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(3), __warn_unused_result__, __returns_nonnull__))) +void *libsimple_envaligned_reallocn(int, void *, size_t, size_t, va_list); +#ifndef envaligned_reallocn +# define envaligned_reallocn libsimple_envaligned_reallocn +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * The product of all arguments, up to the first 0, + * will be used as the number of bytes to allocated + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * On failure, the `libsimple_eprintf` function is called, + * cause the program to print an error message and exit, + * see `libsimple_eprintf` for more information + * + * This function may not be supported, check for the + * existance of the macro `LIBSIMPLE_HAVE_ALIGNED_REALLOC` + * to determine if it is supported + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n First factor for the allocation size, must not be 0 + * @param ap The rest of the factors for the allocation size, + * all arguments should have the type `size_t`, and + * list must end with 0 (which is not factor) + * @return Either `ptr` or a unique pointer with at least + * the specified size + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(2), __warn_unused_result__, __returns_nonnull__))) +static inline void *libsimple_evaligned_reallocn(void *__ptr, size_t __alignment, size_t __n, va_list __ap) +{ return libsimple_envaligned_reallocn(libsimple_default_failure_exit, __ptr, __alignment, __n, __ap); } +#ifndef evaligned_reallocn +# define evaligned_reallocn libsimple_evaligned_reallocn +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * The product of all arguments, up to the first 0, + * will be used as the number of bytes to allocated + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is deallocated. If `ptr` + * is `NULL` a new allocation is made. + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n First factor for the allocation size, must not be 0 + * @param ap The rest of the factors for the allocation size, + * all arguments should have the type `size_t`, and + * list must end with 0 (which is not factor) + * @return Either `ptr` or a unique pointer with at least + * the specified size; `NULL` on failure + * @throws EINVAL `n` is 0 + * @throws EINVAL `alignment` is not a valid alignment + * @throws ENOMEM Could not allocated enough memory + * @throws ENOSYS Not implemented (requires non-standard libc functions) + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(2), __warn_unused_result__))) +static inline void * +libsimple_valigned_reallocfn(void *__ptr, size_t __alignment, size_t __n, va_list __ap) /* TODO test (aligned_reallocfn) */ +{ + void *__new = libsimple_valigned_reallocn(__ptr, __alignment, __n, __ap); + if (!__new) + free(__ptr); + return __new; +} +#ifndef valigned_reallocfn +# define valigned_reallocfn libsimple_aligned_reallocnf +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * The product of all arguments, up to the first 0, + * will be used as the number of bytes to allocated + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * This function may not be supported, check for the + * existance of the macro `LIBSIMPLE_HAVE_ALIGNED_REALLOC` + * to determine if it is supported + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n First factor for the allocation size, must not be 0 + * @param ... The rest of the factors for the allocation size, + * all arguments should have the type `size_t`, and + * list must end with 0 (which is not factor) + * @return Either `ptr` or a unique pointer with at least + * the specified size; `NULL` on failure + * @throws EINVAL `n` is 0 + * @throws EINVAL `alignment` is not a valid alignment + * @throws ENOMEM Could not allocated enough memory + * @throws ENOSYS Not implemented (requires non-standard libc functions) + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(2), __warn_unused_result__))) +static inline void * +libsimple_aligned_reallocn(void *__ptr, size_t __alignment, size_t __n, ... /*, (size_t)0 */) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_valigned_reallocn(__ptr, __alignment, __n, __ap); + va_end(__ap); +} +#ifndef aligned_reallocn +# define aligned_reallocn libsimple_aligned_reallocn +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * The product of all arguments except `status`, up to the + * first 0, will be used as the number of bytes to allocated + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * On failure, the `libsimple_enprintf` function is called, + * cause the program to print an error message and exit, + * see `libsimple_enprintf` for more information + * + * This function may not be supported, check for the + * existance of the macro `LIBSIMPLE_HAVE_ALIGNED_REALLOC` + * to determine if it is supported + * + * @param status The exit value for the process in case of failure + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n First factor for the allocation size, must not be 0 + * @param ... The rest of the factors for the allocation size, + * all arguments should have the type `size_t`, and + * list must end with 0 (which is not factor) + * @return Either `ptr` or a unique pointer with at least + * the specified size + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(3), __warn_unused_result__, __returns_nonnull__))) +static inline void * +libsimple_enaligned_reallocn(int __status, void *__ptr, size_t __alignment, size_t __n, ... /*, (size_t)0 */) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_envaligned_reallocn(__status, __ptr, __alignment, __n, __ap); + va_end(__ap); +} +#ifndef enaligned_reallocn +# define enaligned_reallocn libsimple_enaligned_reallocn +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * The product of all arguments, up to the first 0, + * will be used as the number of bytes to allocated + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * On failure, the `libsimple_eprintf` function is called, + * cause the program to print an error message and exit, + * see `libsimple_eprintf` for more information + * + * This function may not be supported, check for the + * existance of the macro `LIBSIMPLE_HAVE_ALIGNED_REALLOC` + * to determine if it is supported + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n First factor for the allocation size, must not be 0 + * @param ... The rest of the factors for the allocation size, + * all arguments should have the type `size_t`, and + * list must end with 0 (which is not factor) + * @return Either `ptr` or a unique pointer with at least + * the specified size + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(2), __warn_unused_result__, __returns_nonnull__))) +static inline void * +libsimple_ealigned_reallocn(void *__ptr, size_t __alignment, size_t __n, ... /*, (size_t)0 */) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_evaligned_reallocn(__ptr, __alignment, __n, __ap); + va_end(__ap); +} +#ifndef ealigned_reallocn +# define ealigned_reallocn libsimple_ealigned_reallocn +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with custom alignment as the new alignment + * + * The product of all arguments, up to the first 0, + * will be used as the number of bytes to allocated + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is deallocated. If `ptr` + * is `NULL` a new allocation is made. + * + * This function may not be supported, check for the + * existance of the macro `LIBSIMPLE_HAVE_ALIGNED_REALLOC` + * to determine if it is supported + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param alignment The alignment of the new pointer + * @param n First factor for the allocation size, must not be 0 + * @param ... The rest of the factors for the allocation size, + * all arguments should have the type `size_t`, and + * list must end with 0 (which is not factor) + * @return Either `ptr` or a unique pointer with at least + * the specified size; `NULL` on failure + * @throws EINVAL `n` is 0 + * @throws EINVAL `alignment` is not a valid alignment + * @throws ENOMEM Could not allocated enough memory + * @throws ENOSYS Not implemented (requires non-standard libc functions) + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_align__(2), __warn_unused_result__))) +static inline void * +libsimple_aligned_reallocfn(void *__ptr, size_t __alignment, size_t __n, ... /*, (size_t)0 */) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_valigned_reallocfn(__ptr, __alignment, __n, __ap); + va_end(__ap); +} +#ifndef aligned_reallocfn +# define aligned_reallocfn libsimple_aligned_reallocfn +#endif diff --git a/libsimple/aligned_strdup.h b/libsimple/aligned_strdup.h index 514a4da..267c03e 100644 --- a/libsimple/aligned_strdup.h +++ b/libsimple/aligned_strdup.h @@ -9,7 +9,7 @@ * @return :char * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_aligned_strdupa(s, alignment) /* TODO test, man */\ +# define libsimple_aligned_strdupa(s, alignment) /* TODO test */\ ({\ const char *__s = (s);\ size_t __n = strlen(__s) + 1;\ @@ -37,7 +37,7 @@ * @return Duplicate of `s`, `NULL` on failure */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __nonnull__, __warn_unused_result__))) -static inline char *libsimple_aligned_strdup(const char * __s, size_t __alignment) /* TODO test, man */ +static inline char *libsimple_aligned_strdup(const char * __s, size_t __alignment) /* TODO test */ { return libsimple_aligned_memdup(__s, __alignment, strlen(__s) + 1); } #ifndef aligned_strdup # define aligned_strdup libsimple_aligned_strdup @@ -53,7 +53,7 @@ static inline char *libsimple_aligned_strdup(const char * __s, size_t __alignmen * @return Duplicate of `s` */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(3), __nonnull__, __warn_unused_result__, __returns_nonnull__))) -char *libsimple_enaligned_strdup(int, const char *, size_t); /* TODO man */ +char *libsimple_enaligned_strdup(int, const char *, size_t); #ifndef enaligned_strdup # define enaligned_strdup libsimple_enaligned_strdup #endif @@ -67,7 +67,7 @@ char *libsimple_enaligned_strdup(int, const char *, size_t); /* TODO man */ * @return Duplicate of `s` */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __nonnull__, __warn_unused_result__, __returns_nonnull__))) -static inline char *libsimple_ealigned_strdup(const char *__s, size_t __alignment) /* TODO man */ +static inline char *libsimple_ealigned_strdup(const char *__s, size_t __alignment) { return libsimple_enaligned_strdup(libsimple_default_failure_exit, __s, __alignment); } #ifndef ealigned_strdup # define ealigned_strdup libsimple_ealigned_strdup diff --git a/libsimple/aligned_strndup.h b/libsimple/aligned_strndup.h index c51b351..51d50c8 100644 --- a/libsimple/aligned_strndup.h +++ b/libsimple/aligned_strndup.h @@ -10,7 +10,7 @@ * @return :char * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_aligned_strndupa(s, alignment, n) /* TODO test, man */\ +# define libsimple_aligned_strndupa(s, alignment, n) /* TODO test */\ ({\ const char *__s = (s);\ size_t __n = strnlen(__s, n);\ @@ -41,7 +41,7 @@ * @return Duplicate of `s`, `NULL` on failure */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __nonnull__, __warn_unused_result__))) -char *libsimple_aligned_strndup(const char * __s, size_t __alignment, size_t __n); /* TODO man */ +char *libsimple_aligned_strndup(const char * __s, size_t __alignment, size_t __n); #ifndef aligned_strndup # define aligned_strndup libsimple_aligned_strndup #endif @@ -57,7 +57,7 @@ char *libsimple_aligned_strndup(const char * __s, size_t __alignment, size_t __n * @return Duplicate of `s` */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(3), __nonnull__, __warn_unused_result__, __returns_nonnull__))) -char *libsimple_enaligned_strndup(int, const char *, size_t, size_t); /* TODO man */ +char *libsimple_enaligned_strndup(int, const char *, size_t, size_t); #ifndef enaligned_strndup # define enaligned_strndup libsimple_enaligned_strndup #endif @@ -72,7 +72,7 @@ char *libsimple_enaligned_strndup(int, const char *, size_t, size_t); /* TODO ma * @return Duplicate of `s` */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __nonnull__, __warn_unused_result__, __returns_nonnull__))) -static inline char *libsimple_ealigned_strndup(const char *__s, size_t __alignment, size_t __n) /* TODO man */ +static inline char *libsimple_ealigned_strndup(const char *__s, size_t __alignment, size_t __n) { return libsimple_enaligned_strndup(libsimple_default_failure_exit, __s, __alignment, __n); } #ifndef ealigned_strndup # define ealigned_strndup libsimple_ealigned_strndup diff --git a/libsimple/aligned_wcsdup.h b/libsimple/aligned_wcsdup.h index 3d5e96b..8832c58 100644 --- a/libsimple/aligned_wcsdup.h +++ b/libsimple/aligned_wcsdup.h @@ -9,7 +9,7 @@ * @return :wchar_t * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_aligned_wcsdupa(s, alignment) /* TODO test, man */\ +# define libsimple_aligned_wcsdupa(s, alignment) /* TODO test */\ ({\ const wchar_t *__s = (s);\ size_t __n = wcslen(__s) + 1;\ @@ -37,7 +37,7 @@ * @return Duplicate of `s`, `NULL` on failure */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __nonnull__, __warn_unused_result__))) -static inline wchar_t *libsimple_aligned_wcsdup(const wchar_t * __s, size_t __alignment) /* TODO test, man */ +static inline wchar_t *libsimple_aligned_wcsdup(const wchar_t * __s, size_t __alignment) /* TODO test */ { return libsimple_aligned_wmemdup(__s, __alignment, wcslen(__s) + 1); } #ifndef aligned_wcsdup # define aligned_wcsdup libsimple_aligned_wcsdup @@ -53,7 +53,7 @@ static inline wchar_t *libsimple_aligned_wcsdup(const wchar_t * __s, size_t __al * @return Duplicate of `s` */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(3), __nonnull__, __warn_unused_result__, __returns_nonnull__))) -wchar_t *libsimple_enaligned_wcsdup(int, const wchar_t *, size_t); /* TODO man */ +wchar_t *libsimple_enaligned_wcsdup(int, const wchar_t *, size_t); #ifndef enaligned_wcsdup # define enaligned_wcsdup libsimple_enaligned_wcsdup #endif @@ -67,7 +67,7 @@ wchar_t *libsimple_enaligned_wcsdup(int, const wchar_t *, size_t); /* TODO man * * @return Duplicate of `s` */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __nonnull__, __warn_unused_result__, __returns_nonnull__))) -static inline wchar_t *libsimple_ealigned_wcsdup(const wchar_t *__s, size_t __alignment) /* TODO test, man */ +static inline wchar_t *libsimple_ealigned_wcsdup(const wchar_t *__s, size_t __alignment) /* TODO test */ { return libsimple_enaligned_wcsdup(libsimple_default_failure_exit, __s, __alignment); } #ifndef ealigned_wcsdup # define ealigned_wcsdup libsimple_ealigned_wcsdup diff --git a/libsimple/aligned_wcsndup.h b/libsimple/aligned_wcsndup.h index b75f661..5f3f1e4 100644 --- a/libsimple/aligned_wcsndup.h +++ b/libsimple/aligned_wcsndup.h @@ -10,7 +10,7 @@ * @return :wchar_t * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_aligned_wcsndupa(s, alignment, n) /* TODO test, man */\ +# define libsimple_aligned_wcsndupa(s, alignment, n) /* TODO test */\ ({\ const wchar_t *__s = (s);\ size_t __n = wcsnlen(__s, n);\ @@ -41,7 +41,7 @@ * @return Duplicate of `s`, `NULL` on failure */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __nonnull__, __warn_unused_result__))) -wchar_t *libsimple_aligned_wcsndup(const wchar_t * __s, size_t __alignment, size_t __n); /* TODO man */ +wchar_t *libsimple_aligned_wcsndup(const wchar_t * __s, size_t __alignment, size_t __n); #ifndef aligned_wcsndup # define aligned_wcsndup libsimple_aligned_wcsndup #endif @@ -57,7 +57,7 @@ wchar_t *libsimple_aligned_wcsndup(const wchar_t * __s, size_t __alignment, size * @return Duplicate of `s` */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(3), __nonnull__, __warn_unused_result__, __returns_nonnull__))) -wchar_t *libsimple_enaligned_wcsndup(int, const wchar_t *, size_t, size_t); /* TODO man */ +wchar_t *libsimple_enaligned_wcsndup(int, const wchar_t *, size_t, size_t); #ifndef enaligned_wcsndup # define enaligned_wcsndup libsimple_enaligned_wcsndup #endif @@ -72,7 +72,7 @@ wchar_t *libsimple_enaligned_wcsndup(int, const wchar_t *, size_t, size_t); /* T * @return Duplicate of `s` */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __nonnull__, __warn_unused_result__, __returns_nonnull__))) -static inline wchar_t *libsimple_ealigned_wcsndup(const wchar_t *__s, size_t __alignment, size_t __n) /* TODO test, man */ +static inline wchar_t *libsimple_ealigned_wcsndup(const wchar_t *__s, size_t __alignment, size_t __n) /* TODO test */ { return libsimple_enaligned_wcsndup(libsimple_default_failure_exit, __s, __alignment, __n); } #ifndef ealigned_wcsndup # define ealigned_wcsndup libsimple_ealigned_wcsndup diff --git a/libsimple/aligned_wmemdup.h b/libsimple/aligned_wmemdup.h index 1ab537e..bac1d0a 100644 --- a/libsimple/aligned_wmemdup.h +++ b/libsimple/aligned_wmemdup.h @@ -10,7 +10,7 @@ * @return :wchar_t * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_aligned_wmemdupa(s, alignment, n) /* TODO test, man */\ +# define libsimple_aligned_wmemdupa(s, alignment, n) /* TODO test */\ ({\ const wchar_t *__s = (s);\ size_t __n = (n);\ @@ -40,8 +40,8 @@ * @param n The number of wide characters to copy * @return Duplicate of `s`, `NULL` on failure */ -_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_size__(3), __nonnull__, __warn_unused_result__))) -wchar_t *libsimple_aligned_wmemdup(const wchar_t *, size_t, size_t); /* TODO man */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __alloc_size__(3), __nonnull__, __warn_unused_result__))) +wchar_t *libsimple_aligned_wmemdup(const wchar_t *, size_t, size_t); #ifndef aligned_wmemdup # define aligned_wmemdup libsimple_aligned_wmemdup #endif @@ -56,8 +56,8 @@ wchar_t *libsimple_aligned_wmemdup(const wchar_t *, size_t, size_t); /* TODO man * @param n The number of wide characters to copy * @return Duplicate of `s` */ -_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_size__(4), __warn_unused_result__, __returns_nonnull__))) -wchar_t *libsimple_enaligned_wmemdup(int, const wchar_t *, size_t, size_t); /* TODO man */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(3), __alloc_size__(4), __warn_unused_result__, __returns_nonnull__))) +wchar_t *libsimple_enaligned_wmemdup(int, const wchar_t *, size_t, size_t); #ifndef enaligned_wmemdup # define enaligned_wmemdup libsimple_enaligned_wmemdup #endif @@ -71,8 +71,8 @@ wchar_t *libsimple_enaligned_wmemdup(int, const wchar_t *, size_t, size_t); /* T * @param n The number of wide characters to copy * @return Duplicate of `s` */ -_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_size__(3), __warn_unused_result__, __returns_nonnull__))) -static inline wchar_t *libsimple_ealigned_wmemdup(const wchar_t *__s, size_t __alignment, size_t __n) /* TODO test, man */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __alloc_size__(3), __warn_unused_result__, __returns_nonnull__))) +static inline wchar_t *libsimple_ealigned_wmemdup(const wchar_t *__s, size_t __alignment, size_t __n) /* TODO test */ { return libsimple_enaligned_wmemdup(libsimple_default_failure_exit, __s, __alignment, __n); } #ifndef ealigned_wmemdup # define ealigned_wmemdup libsimple_ealigned_wmemdup diff --git a/libsimple/realloc.h b/libsimple/realloc.h index 8ece86d..f976556 100644 --- a/libsimple/realloc.h +++ b/libsimple/realloc.h @@ -203,7 +203,7 @@ libsimple_enreallocn(int __status, void *__ptr, size_t __n, ... /*, (size_t)0 */ */ _LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_size__(2), __warn_unused_result__, __returns_nonnull__))) static inline void *libsimple_erealloc(void *__ptr, size_t __n) -{ return enrealloc(libsimple_default_failure_exit, __ptr, __n); } +{ return libsimple_enrealloc(libsimple_default_failure_exit, __ptr, __n); } #ifndef erealloc # define erealloc libsimple_erealloc #endif @@ -283,3 +283,261 @@ libsimple_ereallocn(void *__ptr, size_t __n, ... /*, (size_t)0 */) #ifndef ereallocn # define ereallocn libsimple_ereallocn #endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with default alignment (`alignof(max_align_t)`) + * as the new alignment + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is deallocated. If `ptr` + * is `NULL` a new allocation is made. + * + * The allocation size will be at least `n * m` + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param n The number of bytes to allocate, the behaviour of + * this function is unspecified for the value 0 + * @return Either `ptr` or a unique pointer with at least + * the specified size and with the alignment + * `alignof(max_align_t)`; `NULL` on failure + * @throws EINVAL `n` is 0 + * @throws ENOMEM Could not allocated enough memory + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_size__(2), __warn_unused_result__))) +static inline void * +libsimple_reallocf(void *__ptr, size_t __n) /* TODO test */ +{ + void *__new = __n ? realloc(__ptr, __n) : NULL; + if (!__new) + free(__ptr); + return __new; +} +#ifndef reallocf +# define reallocf libsimple_reallocf +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with default alignment (`alignof(max_align_t)`) + * as the new alignment + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * The allocation size will be at least `n * m` + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param n The number of elements to allocate, the behaviour of + * this function is unspecified for the value 0 + * @param m Size, in bytes, of each element, the behaviour of + * this function is unspecified for the value 0 + * @return Either `ptr` or a unique pointer with at least + * the specified size and with the alignment + * `alignof(max_align_t)`; `NULL` on failure + * @throws EINVAL `n` or `m` is 0 + * @throws ENOMEM Could not allocated enough memory + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_size__(2, 3), __warn_unused_result__))) +static inline void * +libsimple_reallocarray(void *__ptr, size_t __n, size_t __m) /* TODO test */ +{ + if (LIBSIMPLE_UMUL_OVERFLOW(__n, __m, &__n, SIZE_MAX)) { + errno = ENOMEM; + return NULL; + } + return realloc(__ptr, __n); +} +#ifndef reallocarray +# define reallocarray libsimple_reallocarray +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with default alignment (`alignof(max_align_t)`) + * as the new alignment + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * On failure, the `libsimple_enprintf` function is called, + * cause the program to print an error message and exit, + * see `libsimple_enprintf` for more information + * + * The allocation size will be at least `n * m` + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param n The number of elements to allocate, the behaviour of + * this function is unspecified for the value 0 + * @param m Size, in bytes, of each element, the behaviour of + * this function is unspecified for the value 0 + * @return Either `ptr` or a unique pointer with at least + * the specified size and with the alignment + * `alignof(max_align_t)` + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_size__(3, 4), __warn_unused_result__, __returns_nonnull__))) +void *libsimple_enreallocarray(int, void *, size_t, size_t); +#ifndef enreallocarray +# define enreallocarray libsimple_enreallocarray +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with default alignment (`alignof(max_align_t)`) + * as the new alignment + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is still valid. If `ptr` + * is `NULL` a new allocation is made. + * + * On failure, the `libsimple_eprintf` function is called, + * cause the program to print an error message and exit, + * see `libsimple_eprintf` for more information + * + * The allocation size will be at least `n * m` + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param n The number of elements to allocate, the behaviour of + * this function is unspecified for the value 0 + * @param m Size, in bytes, of each element, the behaviour of + * this function is unspecified for the value 0 + * @return Either `ptr` or a unique pointer with at least + * the specified size and with the alignment + * `alignof(max_align_t)` + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_size__(2, 3), __warn_unused_result__, __returns_nonnull__))) +static inline void *libsimple_ereallocarray(void *__ptr, size_t __n, size_t __m) /* TODO test */ +{ return libsimple_enreallocarray(libsimple_default_failure_exit, __ptr, __n, __m); } +#ifndef ereallocarray +# define ereallocarray libsimple_ereallocarray +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with default alignment (`alignof(max_align_t)`) + * as the new alignment + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is deallocated. If `ptr` + * is `NULL` a new allocation is made. + * + * The allocation size will be at least `n * m` + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param n The number of elements to allocate, the behaviour of + * this function is unspecified for the value 0 + * @param m Size, in bytes, of each element, the behaviour of + * this function is unspecified for the value 0 + * @return Either `ptr` or a unique pointer with at least + * the specified size and with the alignment + * `alignof(max_align_t)`; `NULL` on failure + * @throws EINVAL `n` or `m` is 0 + * @throws ENOMEM Could not allocated enough memory + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_size__(2, 3), __warn_unused_result__))) +static inline void * +libsimple_reallocarrayf(void *__ptr, size_t __n, size_t __m) /* TODO test */ +{ + void *__new = __n ? libsimple_reallocarray(__ptr, __n, __m) : NULL; + if (!__new) + free(__ptr); + return __new; +} +#ifndef reallocarrayf +# define reallocarrayf libsimple_reallocarrayf +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with default alignment (`alignof(max_align_t)`) + * as the new alignment + * + * The product of all arguments, up to the first 0, + * will be used as the number of bytes to allocated + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is deallocated. If `ptr` + * is `NULL` a new allocation is made. + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param n First factor for the allocation size, must not be 0 + * @param ap The rest of the factors for the allocation size, + * all arguments should have the type `size_t`, and + * list must end with 0 (which is not factor) + * @return Either `ptr` or a unique pointer with at least + * the specified size and with the alignment + * `alignof(max_align_t)`; `NULL` on failure + * @throws EINVAL `n` is 0 + * @throws ENOMEM Could not allocated enough memory + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__))) +static inline void * +libsimple_vreallocfn(void *__ptr, size_t __n, va_list __ap) /* TODO test (reallocfn) */ +{ + void *__new = libsimple_vreallocn(__ptr, __n, __ap); + if (!__new) + free(__ptr); + return __new; +} +#ifndef vreallocfn +# define vreallocfn libsimple_vreallocfn +#endif + + +/** + * Dynamically reallocates heap allocated, uninitialised, + * memory with default alignment (`alignof(max_align_t)`) + * as the new alignment + * + * The product of all arguments, up to the first 0, + * will be used as the number of bytes to allocated + * + * On success, either `ptr` is returned, or a new non-null + * pointer is returned with the same content (truncated to + * `n` bytes if size shrunk), in which case `ptr` is + * deallocated. On failure `ptr` is deallocated. If `ptr` + * is `NULL` a new allocation is made. + * + * @param ptr Pointer to reallocated, `NULL` for a new allocation + * @param n First factor for the allocation size, must not be 0 + * @param ... The rest of the factors for the allocation size, + * all arguments should have the type `size_t`, and + * list must end with 0 (which is not factor) + * @return Either `ptr` or a unique pointer with at least + * the specified size and with the alignment + * `alignof(max_align_t)`; `NULL` on failure + * @throws EINVAL `n` is 0 + * @throws ENOMEM Could not allocated enough memory + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__))) +static inline void * +libsimple_reallocfn(void *__ptr, size_t __n, ... /*, (size_t)0 */) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_vreallocfn(__ptr, __n, __ap); + va_end(__ap); +} +#ifndef reallocfn +# define reallocfn libsimple_reallocfn +#endif diff --git a/libsimple/wcsdup.h b/libsimple/wcsdup.h index 685b8ac..b85d265 100644 --- a/libsimple/wcsdup.h +++ b/libsimple/wcsdup.h @@ -8,7 +8,7 @@ * @return :wchar_t * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_wcsdupa(s) /* TODO test, man */\ +# define libsimple_wcsdupa(s)\ ({\ const wchar_t *__s = (s);\ size_t __n = wcslen(__s) + 1;\ @@ -28,8 +28,9 @@ * @param s The string to copy * @return Duplicate of `s` */ -_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __nonnull__, __warn_unused_result__, __returns_nonnull__))) -wchar_t *libsimple_enwcsdup(int, const wchar_t *); /* TODO man */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, _libsimple_assume_aligned_as(wchar_t), __nonnull__, + __warn_unused_result__, __returns_nonnull__))) +wchar_t *libsimple_enwcsdup(int, const wchar_t *); #ifndef enwcsdup # define enwcsdup libsimple_enwcsdup #endif @@ -41,8 +42,9 @@ wchar_t *libsimple_enwcsdup(int, const wchar_t *); /* TODO man */ * @param s The string to copy * @return Duplicate of `s` */ -_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __nonnull__, __warn_unused_result__, __returns_nonnull__))) -static inline wchar_t *libsimple_ewcsdup(const wchar_t *__s) /* TODO man */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, _libsimple_assume_aligned_as(wchar_t), + __nonnull__, __warn_unused_result__, __returns_nonnull__))) +static inline wchar_t *libsimple_ewcsdup(const wchar_t *__s) { return enwcsdup(libsimple_default_failure_exit, __s); } #ifndef ewcsdup # define ewcsdup libsimple_ewcsdup diff --git a/libsimple/wcsndup.h b/libsimple/wcsndup.h index 399b5e5..664294d 100644 --- a/libsimple/wcsndup.h +++ b/libsimple/wcsndup.h @@ -9,7 +9,7 @@ * @return :wchar_t * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_wcsndupa(s, n) /* TODO test, man */\ +# define libsimple_wcsndupa(s, n) /* TODO test */\ ({\ const wchar_t *__s = (s);\ size_t __n = wcsnlen(__s, n);\ @@ -32,8 +32,9 @@ * @param n The maximum number of wide characters to copy * @return Duplicate of `s` */ -_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __nonnull__, __warn_unused_result__, __returns_nonnull__))) -wchar_t *libsimple_wcsndup(const wchar_t *, size_t); /* TODO man */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, _libsimple_assume_aligned_as(wchar_t), __nonnull__, + __warn_unused_result__, __returns_nonnull__))) +wchar_t *libsimple_wcsndup(const wchar_t *, size_t); #ifndef wcsndup # define wcsndup libsimple_wcsndup #endif @@ -47,8 +48,9 @@ wchar_t *libsimple_wcsndup(const wchar_t *, size_t); /* TODO man */ * @param n The maximum number of wide characters to copy * @return Duplicate of `s` */ -_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __nonnull__, __warn_unused_result__, __returns_nonnull__))) -wchar_t *libsimple_enwcsndup(int, const wchar_t *, size_t); /* TODO man */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, _libsimple_assume_aligned_as(wchar_t), __nonnull__, + __warn_unused_result__, __returns_nonnull__))) +wchar_t *libsimple_enwcsndup(int, const wchar_t *, size_t); #ifndef enwcsndup # define enwcsndup libsimple_enwcsndup #endif @@ -61,8 +63,9 @@ wchar_t *libsimple_enwcsndup(int, const wchar_t *, size_t); /* TODO man */ * @param n The maximum number of wide characters to copy * @return Duplicate of `s` */ -_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __nonnull__, __warn_unused_result__, __returns_nonnull__))) -static inline wchar_t *libsimple_ewcsndup(const wchar_t *__s, size_t __n) /* TODO test, man */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, _libsimple_assume_aligned_as(wchar_t), + __nonnull__, __warn_unused_result__, __returns_nonnull__))) +static inline wchar_t *libsimple_ewcsndup(const wchar_t *__s, size_t __n) /* TODO test */ { return libsimple_enwcsndup(libsimple_default_failure_exit, __s, __n); } #ifndef ewcsndup # define ewcsndup libsimple_ewcsndup diff --git a/libsimple/wmemdup.h b/libsimple/wmemdup.h index 5d6730e..85bfea4 100644 --- a/libsimple/wmemdup.h +++ b/libsimple/wmemdup.h @@ -9,7 +9,7 @@ * @return :wchar_t * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_wmemdupa(s, n) /* TODO test, man */\ +# define libsimple_wmemdupa(s, n) /* TODO test */\ ({\ const wchar_t *__s = (s);\ size_t __n = (n);\ @@ -29,8 +29,8 @@ * @param n The number of wide characters to copy * @return Duplicate of `s`, `NULL` on failure */ -_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_size__(2), __nonnull__, __warn_unused_result__))) -wchar_t *libsimple_wmemdup(const wchar_t *, size_t); /* TODO man */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, _libsimple_assume_aligned_as(wchar_t), __alloc_size__(2), __warn_unused_result__))) +wchar_t *libsimple_wmemdup(const wchar_t *, size_t); #ifndef wmemdup # define wmemdup libsimple_wmemdup #endif @@ -44,8 +44,9 @@ wchar_t *libsimple_wmemdup(const wchar_t *, size_t); /* TODO man */ * @param n The number of wide characters to copy * @return Duplicate of `s` */ -_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_size__(3), __warn_unused_result__, __returns_nonnull__))) -wchar_t *libsimple_enwmemdup(int, const wchar_t *, size_t); /* TODO man */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, _libsimple_assume_aligned_as(wchar_t), __alloc_size__(3), + __warn_unused_result__, __returns_nonnull__))) +wchar_t *libsimple_enwmemdup(int, const wchar_t *, size_t); #ifndef enwmemdup # define enwmemdup libsimple_enwmemdup #endif @@ -58,8 +59,9 @@ wchar_t *libsimple_enwmemdup(int, const wchar_t *, size_t); /* TODO man */ * @param n The number of wide characters to copy * @return Duplicate of `s` */ -_LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_size__(2), __warn_unused_result__, __returns_nonnull__))) -static inline wchar_t *libsimple_ewmemdup(const wchar_t *__s, size_t __n) /* TODO test, man */ +_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, _libsimple_assume_aligned_as(wchar_t), __alloc_size__(2), + __warn_unused_result__, __returns_nonnull__))) +static inline wchar_t *libsimple_ewmemdup(const wchar_t *__s, size_t __n) /* TODO test */ { return libsimple_enwmemdup(libsimple_default_failure_exit, __s, __n); } #ifndef ewmemdup # define ewmemdup libsimple_ewmemdup diff --git a/man0/libsimple.h.0 b/man0/libsimple.h.0 index 32b15e8..5e18253 100644 --- a/man0/libsimple.h.0 +++ b/man0/libsimple.h.0 @@ -268,7 +268,201 @@ new pointer with a custom alignment. .TP .BR libsimple_aligned_memdupa (3) -Duplicate an array of bytes onto the stack. +Duplicate an array of bytes onto the stack, +with custom alignment. + +.TP +.BR libsimple_aligned_realloc (3), +.RS 0 +.BR libsimple_ealigned_realloc (3), +.br +.BR libsimple_enaligned_realloc (3) +.RE +.RS +Version of +.BR realloc (3) +with custom alignment. +.RE + +.TP +.BR libsimple_aligned_reallocf (3) +Version of +.BR realloc (3) +with custom alignment that deallocates +the pointer on failure. + +.TP +.BR libsimple_aligned_reallocarray (3), +.RS 0 +.BR libsimple_ealigned_reallocarray (3), +.br +.BR libsimple_enaligned_reallocarray (3) +.RE +.RS +Version of +.BR realloc (3) +with custom alignment that, like +.BR calloc (3), +takes two size arguments. +.RE + +.TP +.BR libsimple_aligned_reallocarrayf (3) +Version of +.BR realloc (3) +with custom alignment that, like +.BR calloc (3), +takes two size arguments, and that +deallocates the pointer on failure. + +.TP +.BR libsimple_aligned_reallocfn (3), +.RS 0 +.BR libsimple_valigned_reallocfn (3) +.RE +.RS +Version of +.BR realloc (3) +that take the product of multiple arguments +as the allocation size, and that +deallocates the pointer on failure. +.RE + +.TP +.BR libsimple_aligned_reallocn (3), +.RS 0 +.BR libsimple_ealigned_reallocn (3), +.br +.BR libsimple_enaligned_reallocn (3), +.br +.BR libsimple_valigned_reallocn (3), +.br +.BR libsimple_evaligned_reallocn (3), +.br +.BR libsimple_envaligned_reallocn (3) +.RE +.RS +Version of +.BR realloc (3) +that take the product of multiple arguments +as the allocation size. +.RE + +.TP +.BR libsimple_reallocarray (3), +.RS 0 +.BR libsimple_ereallocarray (3), +.br +.BR libsimple_enreallocarray (3) +.RE +.RS +Version of +.BR realloc (3) +that, like +.BR calloc (3), +takes to size arguments. +.RE + +.TP +.BR libsimple_reallocarrayf (3) +Version of +.BR realloc (3) +that, like +.BR calloc (3), +takes to size arguments, and that +deallocates the pointer on failure. + +.TP +.BR libsimple_reallocf (3) +Version of +.BR realloc (3) +that deallocates the pointer on failure. + +.TP +.BR libsimple_reallocfn (3), +.RS 0 +.BR libsimple_vreallocfn (3) +.RE +.RS +Version of +.BR realloc (3) +that take the product of multiple arguments +as the allocation size, and that +deallocates the pointer on failure. +.RE + +.TP +.BR libsimple_aligned_strdup (3), +.RS 0 +.BR libsimple_ealigned_strdup (3), +.br +.BR libsimple_enaligned_strdup (3), +.br +.BR libsimple_aligned_strndup (3), +.br +.BR libsimple_ealigned_strndup (3), +.br +.BR libsimple_enaligned_strndup (3) +.RE +.RS +Duplicate a string into a new pointer +with a custom alignment. +.RE + +.TP +.BR libsimple_aligned_strdupa (3), +.RS 0 +.BR libsimple_aligned_strndupa (3) +.RE +.RS +Duplicate a string onto the stack, +with custom alignment. +.RE + +.TP +.BR libsimple_aligned_wcsdup (3), +.RS 0 +.BR libsimple_ealigned_wcsdup (3), +.br +.BR libsimple_enaligned_wcsdup (3), +.br +.BR libsimple_aligned_wcsndup (3), +.br +.BR libsimple_ealigned_wcsndup (3), +.br +.BR libsimple_enaligned_wcsndup (3) +.RE +.RS +Duplicate a wide-character string into a +new pointer with a custom alignment. +.RE + +.TP +.BR libsimple_aligned_wcsdupa (3), +.RS 0 +.BR libsimple_aligned_wcsndupa (3) +.RE +.RS +Duplicate a wide-character string onto +the stack, with custom alignment. +.RE + +.TP +.BR libsimple_aligned_wmemdup (3), +.RS 0 +.BR libsimple_ealigned_wmemdup (3), +.br +.BR libsimple_enaligned_wmemdup (3) +.RE +.RS +Duplicate an array of wide characters into +a new pointer with a custom alignment. +.RE + +.TP +.BR libsimple_aligned_wmemdupa (3) +Duplicate an array of wide characters onto +the stack, with custom alignment. .TP .BR libsimple_asprintf (3), @@ -285,7 +479,8 @@ Format a string and allocate a sufficient large string. .BR libsimple_vasprintfa (3) .RE .RS -Format a string and allocate a sufficient large string onto the stack. +Format a string and allocate a sufficient large +string onto the stack. .RE .TP @@ -1536,6 +1731,52 @@ that take the product of multiple arguments as the allocation size and conditionally initialises the memory. .RE +.TP +.BR libsimple_ewcsdup (3), +.RS 0 +.BR libsimple_enwcsdup (3), +.br +.BR libsimple_wcsndup (3), +.br +.BR libsimple_ewcsndup (3), +.br +.BR libsimple_enwcsndup (3) +.RE +.RS +Duplicate a wide-character string. +.RE + +.TP +.BR libsimple_wcsdupa (3), +.RS 0 +.BR libsimple_wcsndupa (3) +.RE +.RS +Versions of +.BR wcsdup (3), +and +.BR libsimple_wcsndup (3) +that allocate the string on the stack. +.RE + +.TP +.BR libsimple_wmemdup (3), +.RS 0 +.BR libsimple_ewmemdup (3), +.br +.BR libsimple_enwmemdup (3) +.RE +.RS +Duplicate an array of wide character. +.RE + +.TP +.BR libsimple_wmemdupa (3) +Version of +.BR libsimple_wmemdup (3) +that allocate the string on the stack. +.RE + .SH APPLICATION USAGE None. .SH RATIONALE diff --git a/man3/aligned_realloc.3libsimple b/man3/aligned_realloc.3libsimple new file mode 120000 index 0000000..45a72de --- /dev/null +++ b/man3/aligned_realloc.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_realloc.3 \ No newline at end of file diff --git a/man3/aligned_reallocarray.3libsimple b/man3/aligned_reallocarray.3libsimple new file mode 120000 index 0000000..fb3f8b9 --- /dev/null +++ b/man3/aligned_reallocarray.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_reallocarray.3 \ No newline at end of file diff --git a/man3/aligned_reallocarrayf.3libsimple b/man3/aligned_reallocarrayf.3libsimple new file mode 120000 index 0000000..8670b37 --- /dev/null +++ b/man3/aligned_reallocarrayf.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_reallocarrayf.3 \ No newline at end of file diff --git a/man3/aligned_reallocf.3libsimple b/man3/aligned_reallocf.3libsimple new file mode 120000 index 0000000..656041f --- /dev/null +++ b/man3/aligned_reallocf.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_reallocf.3 \ No newline at end of file diff --git a/man3/aligned_reallocfn.3libsimple b/man3/aligned_reallocfn.3libsimple new file mode 120000 index 0000000..73c5a60 --- /dev/null +++ b/man3/aligned_reallocfn.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_reallocfn.3 \ No newline at end of file diff --git a/man3/aligned_reallocn.3libsimple b/man3/aligned_reallocn.3libsimple new file mode 120000 index 0000000..3a6b8aa --- /dev/null +++ b/man3/aligned_reallocn.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_reallocn.3 \ No newline at end of file diff --git a/man3/aligned_strdup.3libsimple b/man3/aligned_strdup.3libsimple new file mode 120000 index 0000000..005dc6f --- /dev/null +++ b/man3/aligned_strdup.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_strdup.3 \ No newline at end of file diff --git a/man3/aligned_strdupa.3libsimple b/man3/aligned_strdupa.3libsimple new file mode 120000 index 0000000..1cc07db --- /dev/null +++ b/man3/aligned_strdupa.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_strdupa.3 \ No newline at end of file diff --git a/man3/aligned_strndup.3libsimple b/man3/aligned_strndup.3libsimple new file mode 120000 index 0000000..4be204c --- /dev/null +++ b/man3/aligned_strndup.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_strndup.3 \ No newline at end of file diff --git a/man3/aligned_strndupa.3libsimple b/man3/aligned_strndupa.3libsimple new file mode 120000 index 0000000..40eec87 --- /dev/null +++ b/man3/aligned_strndupa.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_strndupa.3 \ No newline at end of file diff --git a/man3/aligned_wcsdup.3libsimple b/man3/aligned_wcsdup.3libsimple new file mode 120000 index 0000000..cb194a0 --- /dev/null +++ b/man3/aligned_wcsdup.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_wcsdup.3 \ No newline at end of file diff --git a/man3/aligned_wcsdupa.3libsimple b/man3/aligned_wcsdupa.3libsimple new file mode 120000 index 0000000..1e2225d --- /dev/null +++ b/man3/aligned_wcsdupa.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_wcsdupa.3 \ No newline at end of file diff --git a/man3/aligned_wcsndup.3libsimple b/man3/aligned_wcsndup.3libsimple new file mode 120000 index 0000000..043dad0 --- /dev/null +++ b/man3/aligned_wcsndup.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_wcsndup.3 \ No newline at end of file diff --git a/man3/aligned_wcsndupa.3libsimple b/man3/aligned_wcsndupa.3libsimple new file mode 120000 index 0000000..d24f553 --- /dev/null +++ b/man3/aligned_wcsndupa.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_wcsndupa.3 \ No newline at end of file diff --git a/man3/aligned_wmemdup.3libsimple b/man3/aligned_wmemdup.3libsimple new file mode 120000 index 0000000..264a7e1 --- /dev/null +++ b/man3/aligned_wmemdup.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_wmemdup.3 \ No newline at end of file diff --git a/man3/aligned_wmemdupa.3libsimple b/man3/aligned_wmemdupa.3libsimple new file mode 120000 index 0000000..567563a --- /dev/null +++ b/man3/aligned_wmemdupa.3libsimple @@ -0,0 +1 @@ +libsimple_aligned_wmemdupa.3 \ No newline at end of file diff --git a/man3/ealigned_realloc.3libsimple b/man3/ealigned_realloc.3libsimple new file mode 120000 index 0000000..dbb92ec --- /dev/null +++ b/man3/ealigned_realloc.3libsimple @@ -0,0 +1 @@ +libsimple_ealigned_realloc.3 \ No newline at end of file diff --git a/man3/ealigned_reallocarray.3libsimple b/man3/ealigned_reallocarray.3libsimple new file mode 120000 index 0000000..2d830d6 --- /dev/null +++ b/man3/ealigned_reallocarray.3libsimple @@ -0,0 +1 @@ +libsimple_ealigned_reallocarray.3 \ No newline at end of file diff --git a/man3/ealigned_reallocn.3libsimple b/man3/ealigned_reallocn.3libsimple new file mode 120000 index 0000000..d61ddf8 --- /dev/null +++ b/man3/ealigned_reallocn.3libsimple @@ -0,0 +1 @@ +libsimple_ealigned_reallocn.3 \ No newline at end of file diff --git a/man3/ealigned_strdup.3libsimple b/man3/ealigned_strdup.3libsimple new file mode 120000 index 0000000..eb5cf8d --- /dev/null +++ b/man3/ealigned_strdup.3libsimple @@ -0,0 +1 @@ +libsimple_ealigned_strdup.3 \ No newline at end of file diff --git a/man3/ealigned_strndup.3libsimple b/man3/ealigned_strndup.3libsimple new file mode 120000 index 0000000..50b1c4a --- /dev/null +++ b/man3/ealigned_strndup.3libsimple @@ -0,0 +1 @@ +libsimple_ealigned_strndup.3 \ No newline at end of file diff --git a/man3/ealigned_wcsdup.3libsimple b/man3/ealigned_wcsdup.3libsimple new file mode 120000 index 0000000..01ef193 --- /dev/null +++ b/man3/ealigned_wcsdup.3libsimple @@ -0,0 +1 @@ +libsimple_ealigned_wcsdup.3 \ No newline at end of file diff --git a/man3/ealigned_wcsndup.3libsimple b/man3/ealigned_wcsndup.3libsimple new file mode 120000 index 0000000..87cfe1b --- /dev/null +++ b/man3/ealigned_wcsndup.3libsimple @@ -0,0 +1 @@ +libsimple_ealigned_wcsndup.3 \ No newline at end of file diff --git a/man3/ealigned_wmemdup.3libsimple b/man3/ealigned_wmemdup.3libsimple new file mode 120000 index 0000000..0029c68 --- /dev/null +++ b/man3/ealigned_wmemdup.3libsimple @@ -0,0 +1 @@ +libsimple_ealigned_wmemdup.3 \ No newline at end of file diff --git a/man3/enaligned_realloc.3libsimple b/man3/enaligned_realloc.3libsimple new file mode 120000 index 0000000..2d95e24 --- /dev/null +++ b/man3/enaligned_realloc.3libsimple @@ -0,0 +1 @@ +libsimple_enaligned_realloc.3 \ No newline at end of file diff --git a/man3/enaligned_reallocarray.3libsimple b/man3/enaligned_reallocarray.3libsimple new file mode 120000 index 0000000..1b2e0f8 --- /dev/null +++ b/man3/enaligned_reallocarray.3libsimple @@ -0,0 +1 @@ +libsimple_enaligned_reallocarray.3 \ No newline at end of file diff --git a/man3/enaligned_reallocn.3libsimple b/man3/enaligned_reallocn.3libsimple new file mode 120000 index 0000000..ce4ea5d --- /dev/null +++ b/man3/enaligned_reallocn.3libsimple @@ -0,0 +1 @@ +libsimple_enaligned_reallocn.3 \ No newline at end of file diff --git a/man3/enaligned_strdup.3libsimple b/man3/enaligned_strdup.3libsimple new file mode 120000 index 0000000..83e40a2 --- /dev/null +++ b/man3/enaligned_strdup.3libsimple @@ -0,0 +1 @@ +libsimple_enaligned_strdup.3 \ No newline at end of file diff --git a/man3/enaligned_strndup.3libsimple b/man3/enaligned_strndup.3libsimple new file mode 120000 index 0000000..2b79c93 --- /dev/null +++ b/man3/enaligned_strndup.3libsimple @@ -0,0 +1 @@ +libsimple_enaligned_strndup.3 \ No newline at end of file diff --git a/man3/enaligned_wcsdup.3libsimple b/man3/enaligned_wcsdup.3libsimple new file mode 120000 index 0000000..c52f2c8 --- /dev/null +++ b/man3/enaligned_wcsdup.3libsimple @@ -0,0 +1 @@ +libsimple_enaligned_wcsdup.3 \ No newline at end of file diff --git a/man3/enaligned_wcsndup.3libsimple b/man3/enaligned_wcsndup.3libsimple new file mode 120000 index 0000000..f5772b1 --- /dev/null +++ b/man3/enaligned_wcsndup.3libsimple @@ -0,0 +1 @@ +libsimple_enaligned_wcsndup.3 \ No newline at end of file diff --git a/man3/enaligned_wmemdup.3libsimple b/man3/enaligned_wmemdup.3libsimple new file mode 120000 index 0000000..07321e1 --- /dev/null +++ b/man3/enaligned_wmemdup.3libsimple @@ -0,0 +1 @@ +libsimple_enaligned_wmemdup.3 \ No newline at end of file diff --git a/man3/enreallocarray.3libsimple b/man3/enreallocarray.3libsimple new file mode 120000 index 0000000..5f83973 --- /dev/null +++ b/man3/enreallocarray.3libsimple @@ -0,0 +1 @@ +libsimple_enreallocarray.3 \ No newline at end of file diff --git a/man3/envaligned_reallocn.3libsimple b/man3/envaligned_reallocn.3libsimple new file mode 120000 index 0000000..36205a3 --- /dev/null +++ b/man3/envaligned_reallocn.3libsimple @@ -0,0 +1 @@ +libsimple_envaligned_reallocn.3 \ No newline at end of file diff --git a/man3/enwcsdup.3libsimple b/man3/enwcsdup.3libsimple new file mode 120000 index 0000000..85a85a6 --- /dev/null +++ b/man3/enwcsdup.3libsimple @@ -0,0 +1 @@ +libsimple_enwcsdup.3 \ No newline at end of file diff --git a/man3/enwcsndup.3libsimple b/man3/enwcsndup.3libsimple new file mode 120000 index 0000000..801d72f --- /dev/null +++ b/man3/enwcsndup.3libsimple @@ -0,0 +1 @@ +libsimple_enwcsndup.3 \ No newline at end of file diff --git a/man3/enwmemdup.3libsimple b/man3/enwmemdup.3libsimple new file mode 120000 index 0000000..b2983f6 --- /dev/null +++ b/man3/enwmemdup.3libsimple @@ -0,0 +1 @@ +libsimple_enwmemdup.3 \ No newline at end of file diff --git a/man3/ereallocarray.3libsimple b/man3/ereallocarray.3libsimple new file mode 120000 index 0000000..3e43375 --- /dev/null +++ b/man3/ereallocarray.3libsimple @@ -0,0 +1 @@ +libsimple_ereallocarray.3 \ No newline at end of file diff --git a/man3/evaligned_reallocn.3libsimple b/man3/evaligned_reallocn.3libsimple new file mode 120000 index 0000000..b7dde1d --- /dev/null +++ b/man3/evaligned_reallocn.3libsimple @@ -0,0 +1 @@ +libsimple_evaligned_reallocn.3 \ No newline at end of file diff --git a/man3/ewcsdup.3libsimple b/man3/ewcsdup.3libsimple new file mode 120000 index 0000000..5c84dbe --- /dev/null +++ b/man3/ewcsdup.3libsimple @@ -0,0 +1 @@ +libsimple_ewcsdup.3 \ No newline at end of file diff --git a/man3/ewcsndup.3libsimple b/man3/ewcsndup.3libsimple new file mode 120000 index 0000000..09026d6 --- /dev/null +++ b/man3/ewcsndup.3libsimple @@ -0,0 +1 @@ +libsimple_ewcsndup.3 \ No newline at end of file diff --git a/man3/ewmemdup.3libsimple b/man3/ewmemdup.3libsimple new file mode 120000 index 0000000..3cbe8cf --- /dev/null +++ b/man3/ewmemdup.3libsimple @@ -0,0 +1 @@ +libsimple_ewmemdup.3 \ No newline at end of file diff --git a/man3/libsimple_aligned_allocz.3 b/man3/libsimple_aligned_allocz.3 index 751cf4f..260436f 100644 --- a/man3/libsimple_aligned_allocz.3 +++ b/man3/libsimple_aligned_allocz.3 @@ -163,7 +163,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_aligned_memdup.3 b/man3/libsimple_aligned_memdup.3 index 6cd287a..7550d80 100644 --- a/man3/libsimple_aligned_memdup.3 +++ b/man3/libsimple_aligned_memdup.3 @@ -29,7 +29,7 @@ Link with .SH DESCRIPTION The .BR libsimple_aligned_memdup () -function constructs allocates memory with the alignment +function allocates memory with the alignment specified in the .I alignment parameter and copies @@ -146,7 +146,8 @@ None. None. .SH SEE ALSO .BR libsimple_memdup (3), -.BR libsimple_enstrndup (3), -.BR libsimple_enstrdup (3), -.BR strndup (3), -.BR strdup (3) +.BR libsimple_aligned_strndup (3), +.BR libsimple_aligned_strdup (3), +.BR libsimple_aligned_wcsdup (3), +.BR libsimple_aligned_wcsndup (3), +.BR libsimple_aligned_wmemdup (3) diff --git a/man3/libsimple_aligned_realloc.3 b/man3/libsimple_aligned_realloc.3 new file mode 100644 index 0000000..1cede46 --- /dev/null +++ b/man3/libsimple_aligned_realloc.3 @@ -0,0 +1,200 @@ +.TH LIBSIMPLE_ALIGNED_REALLOC 3 2018-11-29 libsimple +.SH NAME +libsimple_aligned_realloc \- reallocate memory and customise alignment +.SH SYNOPSIS +.nf +#include + +static inline void *libsimple_aligned_realloc(void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP); +void *libsimple_enaligned_realloc(int \fIstatus\fP, void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP); +static inline void *libsimple_ealigned_realloc(void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP); + +#ifndef aligned_realloc +# define aligned_realloc libsimple_aligned_realloc +#endif +#ifndef enaligned_realloc +# define enaligned_realloc libsimple_enaligned_realloc +#endif +#ifndef ealigned_realloc +# define ealigned_realloc libsimple_ealigned_realloc +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_aligned_realloc (), +.BR libsimple_enaligned_realloc (), +and +.BR libsimple_ealigned_realloc () +functions reallocate memory allocated on +the heap and return the older pointer or a new +pointer with the alignment of +.I alignment +to the allocated memory of +.I n +bytes. The behaviour is unspecified if +.I n +is 0. The returned pointer will contain the +same content as +.IR ptr , +but truncated to +.I n +bytes if it is smaller or with the new bytes +unitialised if it is larger. If a new pointer +is returned, rather than +.IR ptr , +.I ptr +is deallocated; +.I ptr +is not deallocated on failure. The function +.BR free (3) +shall be called with the returned pointer as +input when the allocated memory is no longer needed. +.PP +The +.BR libsimple_enaligned_realloc () +and +.BR libsimple_ealigned_realloc () +functions will terminate the process if the memory +cannot be allocated, by calling the +.BR libsimple_enprintf () +and +.BR libsimple_eprintf () +functions, respectively. +On failure, the process's exit value will be +.I status +if the +.BR libsimple_enaligned_realloc () +function is used or +.IR libsimple_default_failure_exit (3) +if the +.BR libsimple_ealigned_realloc () +function is used. +.SH RETURN VALUE +The +.BR libsimple_aligned_realloc (), +.BR libsimple_enaligned_realloc (), +and +.BR libsimple_ealigned_realloc () +functions return a pointer to the allocated memory +upon success completion; otherwise the +.BR libsimple_aligned_realloc () +function returns +.B NULL +and set +.I errno +it indicate the error, and the +.BR libsimple_enaligned_realloc () +and +.BR libsimple_ealigned_realloc () +functions terminated the process. +.SH ERRORS +The +.BR libsimple_aligned_realloc () +function will fail for the reasons specified for the +.BR realloc (3) +function, and if: +.TP +.B EINVAL +.I alignment +is an invalid alignment (usually it needs to be an power of 2). +.TP +.B ENOSYS +The function is not implemented. The function requires +non-standard libc functions, and is therefore not supported +for all libc implementations. + +The function is implemented if and only if the macro +.B LIBSIMPLE_HAVE_ALIGNED_REALLOC +is defined by the library. +.PP +The +.BR libsimple_enaligned_realloc () +and +.BR libsimple_ealigned_realloc () +functions will terminate the process on failure. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_aligned_realloc (), +.br +.BR libsimple_enaligned_realloc (), +.br +.BR libsimple_ealigned_realloc () +T} Thread safety MT-Safe +T{ +.BR libsimple_aligned_realloc (), +.br +.BR libsimple_enaligned_realloc (), +.br +.BR libsimple_ealigned_realloc () +T} Async-signal safety AS-Safe +T{ +.BR libsimple_aligned_realloc (), +.br +.BR libsimple_enaligned_realloc (), +.br +.BR libsimple_ealigned_realloc () +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_enmalloc (3), +.BR libsimple_mallocz (3), +.BR libsimple_vmallocn (3), +.BR libsimple_vmalloczn (3), +.BR libsimple_encalloc (3), +.BR libsimple_vcallocn (3), +.BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), +.BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), +.BR libsimple_memalign (3), +.BR libsimple_memalignz (3), +.BR libsimple_vmemalignn (3), +.BR libsimple_vmemalignzn (3), +.BR libsimple_enposix_memalign (3), +.BR libsimple_posix_memalignz (3), +.BR libsimple_vposix_memalignn (3), +.BR libsimple_vposix_memalignzn (3), +.BR libsimple_enaligned_alloc (3), +.BR libsimple_aligned_allocz (3), +.BR libsimple_valigned_allocn (3), +.BR libsimple_valigned_alloczn (3), +.BR libsimple_pvalloc (3), +.BR libsimple_pvallocz (3), +.BR libsimple_vpvallocn (3), +.BR libsimple_vpvalloczn (3), +.BR libsimple_valloc (3), +.BR libsimple_vallocz (3), +.BR libsimple_vvallocn (3), +.BR libsimple_vvalloczn (3), +.BR libsimple_vmemalloc (3), +.BR libsimple_varrayalloc (3), +.BR malloc (3) diff --git a/man3/libsimple_aligned_reallocarray.3 b/man3/libsimple_aligned_reallocarray.3 new file mode 100644 index 0000000..b6b6e8f --- /dev/null +++ b/man3/libsimple_aligned_reallocarray.3 @@ -0,0 +1,202 @@ +.TH LIBSIMPLE_ALIGNED_REALLOCARRAY 3 2018-11-29 libsimple +.SH NAME +libsimple_aligned_reallocarray \- reallocate memory and customise alignment +.SH SYNOPSIS +.nf +#include + +static inline void *libsimple_aligned_reallocarray(void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP, size_t \fIm\fP); +void *libsimple_enaligned_reallocarray(int \fIstatus\fP, void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP, size_t \fIm\fP); +static inline void *libsimple_ealigned_reallocarray(void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP, size_t \fIm\fP); + +#ifndef aligned_reallocarray +# define aligned_reallocarray libsimple_aligned_reallocarray +#endif +#ifndef enaligned_reallocarray +# define enaligned_reallocarray libsimple_enaligned_reallocarray +#endif +#ifndef ealigned_reallocarray +# define ealigned_reallocarray libsimple_ealigned_reallocarray +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_aligned_reallocarray (), +.BR libsimple_enaligned_reallocarray (), +and +.BR libsimple_ealigned_reallocarray () +functions reallocate memory allocated on +the heap and return the older pointer or a new +pointer with the alignment of +.I alignment +to the allocated memory of +.I n*m +bytes. The behaviour is unspecified if +.I n +or +.I m +is 0. The returned pointer will contain the +same content as +.IR ptr , +but truncated to +.I n*m +bytes if it is smaller or with the new bytes +unitialised if it is larger. If a new pointer +is returned, rather than +.IR ptr , +.I ptr +is deallocated; +.I ptr +is not deallocated on failure. The function +.BR free (3) +shall be called with the returned pointer as +input when the allocated memory is no longer needed. +.PP +The +.BR libsimple_enaligned_reallocarray () +and +.BR libsimple_ealigned_reallocarray () +functions will terminate the process if the memory +cannot be allocated, by calling the +.BR libsimple_enprintf () +and +.BR libsimple_eprintf () +functions, respectively. +On failure, the process's exit value will be +.I status +if the +.BR libsimple_enaligned_reallocarray () +function is used or +.IR libsimple_default_failure_exit (3) +if the +.BR libsimple_ealigned_reallocarray () +function is used. +.SH RETURN VALUE +The +.BR libsimple_aligned_reallocarray (), +.BR libsimple_enaligned_reallocarray (), +and +.BR libsimple_ealigned_reallocarray () +functions return a pointer to the allocated memory +upon success completion; otherwise the +.BR libsimple_aligned_reallocarray () +function returns +.B NULL +and set +.I errno +it indicate the error, and the +.BR libsimple_enaligned_reallocarray () +and +.BR libsimple_ealigned_reallocarray () +functions terminated the process. +.SH ERRORS +The +.BR libsimple_aligned_reallocarray () +function will fail for the reasons specified for the +.BR realloc (3) +function, and if: +.TP +.B EINVAL +.I alignment +is an invalid alignment (usually it needs to be an power of 2). +.TP +.B ENOSYS +The function is not implemented. The function requires +non-standard libc functions, and is therefore not supported +for all libc implementations. + +The function is implemented if and only if the macro +.B LIBSIMPLE_HAVE_ALIGNED_REALLOC +is defined by the library. +.PP +The +.BR libsimple_enaligned_reallocarray () +and +.BR libsimple_ealigned_reallocarray () +functions will terminate the process on failure. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_aligned_reallocarray (), +.br +.BR libsimple_enaligned_reallocarray (), +.br +.BR libsimple_ealigned_reallocarray () +T} Thread safety MT-Safe +T{ +.BR libsimple_aligned_reallocarray (), +.br +.BR libsimple_enaligned_reallocarray (), +.br +.BR libsimple_ealigned_reallocarray () +T} Async-signal safety AS-Safe +T{ +.BR libsimple_aligned_reallocarray (), +.br +.BR libsimple_enaligned_reallocarray (), +.br +.BR libsimple_ealigned_reallocarray () +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_enmalloc (3), +.BR libsimple_mallocz (3), +.BR libsimple_vmallocn (3), +.BR libsimple_vmalloczn (3), +.BR libsimple_encalloc (3), +.BR libsimple_vcallocn (3), +.BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), +.BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), +.BR libsimple_memalign (3), +.BR libsimple_memalignz (3), +.BR libsimple_vmemalignn (3), +.BR libsimple_vmemalignzn (3), +.BR libsimple_enposix_memalign (3), +.BR libsimple_posix_memalignz (3), +.BR libsimple_vposix_memalignn (3), +.BR libsimple_vposix_memalignzn (3), +.BR libsimple_enaligned_alloc (3), +.BR libsimple_aligned_allocz (3), +.BR libsimple_valigned_allocn (3), +.BR libsimple_valigned_alloczn (3), +.BR libsimple_pvalloc (3), +.BR libsimple_pvallocz (3), +.BR libsimple_vpvallocn (3), +.BR libsimple_vpvalloczn (3), +.BR libsimple_valloc (3), +.BR libsimple_vallocz (3), +.BR libsimple_vvallocn (3), +.BR libsimple_vvalloczn (3), +.BR libsimple_vmemalloc (3), +.BR libsimple_varrayalloc (3), +.BR malloc (3) diff --git a/man3/libsimple_aligned_reallocarrayf.3 b/man3/libsimple_aligned_reallocarrayf.3 new file mode 100644 index 0000000..0f83ad9 --- /dev/null +++ b/man3/libsimple_aligned_reallocarrayf.3 @@ -0,0 +1,154 @@ +.TH LIBSIMPLE_ALIGNED_REALLOCARRAYF 3 2018-11-29 libsimple +.SH NAME +libsimple_aligned_reallocarrayf \- reallocate memory and customise alignment +.SH SYNOPSIS +.nf +#include + +static inline void *libsimple_aligned_reallocarrayf(void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP, size_t \fIm\fP); + +#ifndef aligned_reallocarrayf +# define aligned_reallocarrayf libsimple_aligned_reallocarrayf +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_aligned_reallocarrayf () +function reallocates memory allocated on +the heap and return the older pointer or a new +pointer with the alignment of +.I alignment +to the allocated memory of +.I n*m +bytes. The returned pointer will contain the +same content as +.IR ptr , +but truncated to +.I n*m +bytes if it is smaller or with the new bytes +unitialised if it is larger. If a new pointer +is returned, rather than +.IR ptr , +.I ptr +is deallocated; +.I ptr +is deallocated on failure. The function +.BR free (3) +shall be called with the returned pointer as +input when the allocated memory is no longer needed. +.PP +If +.I n +or +.I m +is 0, +.I ptr +is deallocaed and +.B NULL +is returned, however portable applications should, +unless the namespaced alias is used, assume the +behaviour is unspecifed in this case. +.SH RETURN VALUE +The +.BR libsimple_aligned_reallocarrayf (), +function returns a pointer to the allocated memory +upon success completion; otherwise the +.BR libsimple_aligned_reallocarrayf () +function returns +.B NULL +and set +.I errno +it indicate the error. +.SH ERRORS +The +.BR libsimple_aligned_reallocarrayf () +function will fail for the reasons specified for the +.BR realloc (3) +function, and if: +.TP +.B EINVAL +.I alignment +is an invalid alignment (usually it needs to be an power of 2). +.TP +.B ENOSYS +The function is not implemented. The function requires +non-standard libc functions, and is therefore not supported +for all libc implementations. + +The function is implemented if and only if the macro +.B LIBSIMPLE_HAVE_ALIGNED_REALLOC +is defined by the library. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_aligned_reallocarrayf () +T} Thread safety MT-Safe +T{ +.BR libsimple_aligned_reallocarrayf () +T} Async-signal safety AS-Safe +T{ +.BR libsimple_aligned_reallocarrayf () +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_enmalloc (3), +.BR libsimple_mallocz (3), +.BR libsimple_vmallocn (3), +.BR libsimple_vmalloczn (3), +.BR libsimple_encalloc (3), +.BR libsimple_vcallocn (3), +.BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), +.BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_vreallocfn (3), +.BR libsimple_memalign (3), +.BR libsimple_memalignz (3), +.BR libsimple_vmemalignn (3), +.BR libsimple_vmemalignzn (3), +.BR libsimple_enposix_memalign (3), +.BR libsimple_posix_memalignz (3), +.BR libsimple_vposix_memalignn (3), +.BR libsimple_vposix_memalignzn (3), +.BR libsimple_enaligned_alloc (3), +.BR libsimple_aligned_allocz (3), +.BR libsimple_valigned_allocn (3), +.BR libsimple_valigned_alloczn (3), +.BR libsimple_pvalloc (3), +.BR libsimple_pvallocz (3), +.BR libsimple_vpvallocn (3), +.BR libsimple_vpvalloczn (3), +.BR libsimple_valloc (3), +.BR libsimple_vallocz (3), +.BR libsimple_vvallocn (3), +.BR libsimple_vvalloczn (3), +.BR libsimple_vmemalloc (3), +.BR libsimple_varrayalloc (3), +.BR malloc (3) diff --git a/man3/libsimple_aligned_reallocf.3 b/man3/libsimple_aligned_reallocf.3 new file mode 100644 index 0000000..a83e258 --- /dev/null +++ b/man3/libsimple_aligned_reallocf.3 @@ -0,0 +1,152 @@ +.TH LIBSIMPLE_ALIGNED_REALLOCF 3 2018-11-29 libsimple +.SH NAME +libsimple_aligned_reallocf \- reallocate memory and customise alignment +.SH SYNOPSIS +.nf +#include + +static inline void *libsimple_aligned_reallocf(void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP); + +#ifndef aligned_reallocf +# define aligned_reallocf libsimple_aligned_reallocf +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_aligned_reallocf () +function reallocates memory allocated on +the heap and return the older pointer or a new +pointer with the alignment of +.I alignment +to the allocated memory of +.I n +bytes. The returned pointer will contain the +same content as +.IR ptr , +but truncated to +.I n +bytes if it is smaller or with the new bytes +unitialised if it is larger. If a new pointer +is returned, rather than +.IR ptr , +.I ptr +is deallocated; +.I ptr +is deallocated on failure. The function +.BR free (3) +shall be called with the returned pointer as +input when the allocated memory is no longer needed. +.PP +If +.I n +is 0, +.I ptr +is deallocaed and +.B NULL +is returned, however portable applications should, +unless the namespaced alias is used, assume the +behaviour is unspecifed in this case. +.SH RETURN VALUE +The +.BR libsimple_aligned_reallocf (), +function returns a pointer to the allocated memory +upon success completion; otherwise the +.BR libsimple_aligned_reallocf () +function returns +.B NULL +and set +.I errno +it indicate the error. +.SH ERRORS +The +.BR libsimple_aligned_reallocf () +function will fail for the reasons specified for the +.BR realloc (3) +function, and if: +.TP +.B EINVAL +.I alignment +is an invalid alignment (usually it needs to be an power of 2). +.TP +.B ENOSYS +The function is not implemented. The function requires +non-standard libc functions, and is therefore not supported +for all libc implementations. + +The function is implemented if and only if the macro +.B LIBSIMPLE_HAVE_ALIGNED_REALLOC +is defined by the library. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_aligned_reallocf () +T} Thread safety MT-Safe +T{ +.BR libsimple_aligned_reallocf () +T} Async-signal safety AS-Safe +T{ +.BR libsimple_aligned_reallocf () +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_enmalloc (3), +.BR libsimple_mallocz (3), +.BR libsimple_vmallocn (3), +.BR libsimple_vmalloczn (3), +.BR libsimple_encalloc (3), +.BR libsimple_vcallocn (3), +.BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), +.BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), +.BR libsimple_memalign (3), +.BR libsimple_memalignz (3), +.BR libsimple_vmemalignn (3), +.BR libsimple_vmemalignzn (3), +.BR libsimple_enposix_memalign (3), +.BR libsimple_posix_memalignz (3), +.BR libsimple_vposix_memalignn (3), +.BR libsimple_vposix_memalignzn (3), +.BR libsimple_enaligned_alloc (3), +.BR libsimple_aligned_allocz (3), +.BR libsimple_valigned_allocn (3), +.BR libsimple_valigned_alloczn (3), +.BR libsimple_pvalloc (3), +.BR libsimple_pvallocz (3), +.BR libsimple_vpvallocn (3), +.BR libsimple_vpvalloczn (3), +.BR libsimple_valloc (3), +.BR libsimple_vallocz (3), +.BR libsimple_vvallocn (3), +.BR libsimple_vvalloczn (3), +.BR libsimple_vmemalloc (3), +.BR libsimple_varrayalloc (3), +.BR malloc (3) diff --git a/man3/libsimple_aligned_reallocfn.3 b/man3/libsimple_aligned_reallocfn.3 new file mode 120000 index 0000000..1ba44a5 --- /dev/null +++ b/man3/libsimple_aligned_reallocfn.3 @@ -0,0 +1 @@ +libsimple_valigned_reallocfn.3 \ No newline at end of file diff --git a/man3/libsimple_aligned_reallocn.3 b/man3/libsimple_aligned_reallocn.3 new file mode 120000 index 0000000..7c3a84f --- /dev/null +++ b/man3/libsimple_aligned_reallocn.3 @@ -0,0 +1 @@ +libsimple_valigned_reallocn.3 \ No newline at end of file diff --git a/man3/libsimple_aligned_strdup.3 b/man3/libsimple_aligned_strdup.3 new file mode 100644 index 0000000..d6c99fb --- /dev/null +++ b/man3/libsimple_aligned_strdup.3 @@ -0,0 +1,151 @@ +.TH LIBSIMPLE_ALIGNED_STRDUP 3 2018-11-27 libsimple +.SH NAME +libsimple_aligned_strdup, libsimple_aligned_strdupa \- duplicate a string +.SH SYNOPSIS +.nf +#include + +char *libsimple_aligned_strdupa(const char *\fIs\fP, size_t \fIn\fP); +char *libsimple_aligned_strdup(const char *\fIs\fP, size_t \fIn\fP); +char *libsimple_enaligned_strdup(int \fIstatus\fP, const char *\fIs\fP, size_t \fIn\fP); +static inline char *libsimple_ealigned_strdup(const char *\fIs\fP, size_t \fIn\fP); + +#ifndef aligned_strdupa +# define aligned_strdupa libsimple_aligned_strdupa +#endif +#ifndef aligned_strdup +# define aligned_strdup libsimple_aligned_strdup +#endif +#ifndef enaligned_strdup +# define enaligned_strdup libsimple_enaligned_strdup +#endif +#ifndef ealigned_strdup +# define ealigned_strdup libsimple_ealigned_strdup +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_aligned_strdup () +function allocates memory with the alignment +specified in the +.I alignment +parameter and copies the string +.I s +into the new allocation. +.PP +The +.BR libsimple_enaligned_strdup () +and +.BR libsimple_ealigned_strdup () +functions are versions of the +.BR libsimple_aligned_strdup () +function that call the +.BR libsimple_enprintf (3) +function on failure, causing the process to print +an error message and exit. See +.BR libsimple_enprintf (3) +for more information. +.PP +The +.BR libsimple_strdupa () +function is implemented as a macro and is a version +of the +.BR libsimple_strdup () +function that uses allocates the memory on the stack +rather than on the heap, causing the return pointer +to become invalid when the calling function returns. +It is only available when compling with GCC or Clang. +.SH RETURN VALUE +Upon successful completion, the +.BR libsimple_aligned_strdupa (), +.BR libsimple_aligned_strdup (), +.BR libsimple_enaligned_strdup (), +and +.BR libsimple_ealigned_strdup () +functions return a non-null pointer, on failure the +.BR libsimple_aligned_strdup () +function returns +.B NULL +and set +.I errno +to indicate the error, and the +.BR libsimple_enaligned_strdup (), +and +.BR libsimple_ealigned_strdup () +functions exit the process. The +.BR libsimple_aligned_strdupa () +function cannot fail, however the kernel +can kill the thread, and possibly the process, with a +.B SIGSEGV +signal if the memory cannot be allocated. +.PP +The returned pointer should be deallocated when it +is no longer needed, except for the pointer returned +by the +.BR libsimple_aligned_strdupa () +function, it is automatically deallocated when the +calling function returns. +.SH ERRORS +The +.BR libsimple_aligned_strdup () +function may fail for any reason specified for the +.BR aligned_alloc (3) +function. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_aligned_strdupa (), +.br +.BR libsimple_aligned_strdup (), +.br +.BR libsimple_enaligned_strdup (), +.br +.BR libsimple_ealigned_strdup (), +T} Thread safety MT-Safe +T{ +.BR libsimple_aligned_strdupa (), +.br +.BR libsimple_aligned_strdup (), +.br +.BR libsimple_enaligned_strdup (), +.br +.BR libsimple_ealigned_strdup (), +T} Async-signal safety AS-Safe +T{ +.BR libsimple_aligned_strdupa (), +.br +.BR libsimple_aligned_strdup (), +.br +.BR libsimple_enaligned_strdup (), +.br +.BR libsimple_ealigned_strdup (), +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_aligned_strndup (3), +.BR libsimple_aligned_memdup (3), +.BR libsimple_aligned_wcsdup (3), +.BR libsimple_aligned_wcsndup (3), +.BR libsimple_aligned_wmemdup (3), +.BR strdup (3) diff --git a/man3/libsimple_aligned_strdupa.3 b/man3/libsimple_aligned_strdupa.3 new file mode 120000 index 0000000..005dc6f --- /dev/null +++ b/man3/libsimple_aligned_strdupa.3 @@ -0,0 +1 @@ +libsimple_aligned_strdup.3 \ No newline at end of file diff --git a/man3/libsimple_aligned_strndup.3 b/man3/libsimple_aligned_strndup.3 new file mode 100644 index 0000000..cdc7603 --- /dev/null +++ b/man3/libsimple_aligned_strndup.3 @@ -0,0 +1,154 @@ +.TH LIBSIMPLE_ALIGNED_STRNDUP 3 2018-11-27 libsimple +.SH NAME +libsimple_aligned_strndup, libsimple_aligned_strndupa \- duplicate a string +.SH SYNOPSIS +.nf +#include + +char *libsimple_aligned_strndupa(const char *\fIs\fP, size_t \fIalignment\fP, size_t \fIn\fP); +char *libsimple_aligned_strndup(const char *\fIs\fP, size_t \fIalignment\fP, size_t \fIn\fP); +char *libsimple_enaligned_strndup(int \fIstatus\fP, const char *\fIs\fP, size_t \fIalignment\fP, size_t \fIn\fP); +static inline char *libsimple_ealigned_strndup(const char *\fIs\fP, size_t \fIalignment\fP, size_t \fIn\fP); + +#ifndef aligned_strndupa +# define aligned_strndupa libsimple_aligned_strndupa +#endif +#ifndef aligned_strndup +# define aligned_strndup libsimple_aligned_strndup +#endif +#ifndef enaligned_strndup +# define enaligned_strndup libsimple_enaligned_strndup +#endif +#ifndef ealigned_strndup +# define ealigned_strndup libsimple_ealigned_strndup +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_aligned_strndup () +function allocates memory with the alignment +specified in the +.I alignment +parameter and copies the string +.I s +into the new allocation, up to the +.IR n th +byte. A NUL byte will always be written +to the end of the new string. +.PP +The +.BR libsimple_enaligned_strndup () +and +.BR libsimple_ealigned_strndup () +functions are versions of the +.BR libsimple_aligned_strndup () +function that call the +.BR libsimple_enprintf (3) +function on failure, causing the process to print +an error message and exit. See +.BR libsimple_enprintf (3) +for more information. +.PP +The +.BR libsimple_strndupa () +function is implemented as a macro and is a version +of the +.BR libsimple_strndup () +function that uses allocates the memory on the stack +rather than on the heap, causing the return pointer +to become invalid when the calling function returns. +It is only available when compling with GCC or Clang. +.SH RETURN VALUE +Upon successful completion, the +.BR libsimple_aligned_strndupa (), +.BR libsimple_aligned_strndup (), +.BR libsimple_enaligned_strndup (), +and +.BR libsimple_ealigned_strndup () +functions return a non-null pointer, on failure the +.BR libsimple_aligned_strndup () +function returns +.B NULL +and set +.I errno +to indicate the error, and the +.BR libsimple_enaligned_strndup (), +and +.BR libsimple_ealigned_strndup () +functions exit the process. The +.BR libsimple_aligned_strndupa () +function cannot fail, however the kernel +can kill the thread, and possibly the process, with a +.B SIGSEGV +signal if the memory cannot be allocated. +.PP +The returned pointer should be deallocated when it +is no longer needed, except for the pointer returned +by the +.BR libsimple_aligned_strndupa () +function, it is automatically deallocated when the +calling function returns. +.SH ERRORS +The +.BR libsimple_aligned_strndup () +function may fail for any reason specified for the +.BR aligned_alloc (3) +function. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_aligned_strndupa (), +.br +.BR libsimple_aligned_strndup (), +.br +.BR libsimple_enaligned_strndup (), +.br +.BR libsimple_ealigned_strndup (), +T} Thread safety MT-Safe +T{ +.BR libsimple_aligned_strndupa (), +.br +.BR libsimple_aligned_strndup (), +.br +.BR libsimple_enaligned_strndup (), +.br +.BR libsimple_ealigned_strndup (), +T} Async-signal safety AS-Safe +T{ +.BR libsimple_aligned_strndupa (), +.br +.BR libsimple_aligned_strndup (), +.br +.BR libsimple_enaligned_strndup (), +.br +.BR libsimple_ealigned_strndup (), +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_aligned_strdup (3), +.BR libsimple_aligned_memdup (3), +.BR libsimple_aligned_wcsdup (3), +.BR libsimple_aligned_wcsndup (3), +.BR libsimple_aligned_wmemdup (3), +.BR strndup (3) diff --git a/man3/libsimple_aligned_strndupa.3 b/man3/libsimple_aligned_strndupa.3 new file mode 120000 index 0000000..4be204c --- /dev/null +++ b/man3/libsimple_aligned_strndupa.3 @@ -0,0 +1 @@ +libsimple_aligned_strndup.3 \ No newline at end of file diff --git a/man3/libsimple_aligned_wcsdup.3 b/man3/libsimple_aligned_wcsdup.3 new file mode 100644 index 0000000..72b0a46 --- /dev/null +++ b/man3/libsimple_aligned_wcsdup.3 @@ -0,0 +1,151 @@ +.TH LIBSIMPLE_ALIGNED_WCSDUP 3 2018-11-27 libsimple +.SH NAME +libsimple_aligned_wcsdup, libsimple_aligned_wcsdupa \- duplicate a wide-character string +.SH SYNOPSIS +.nf +#include + +wchar_t *libsimple_aligned_wcsdupa(const wchar_t *\fIs\fP, size_t \fIalignment\fP); +wchar_t *libsimple_aligned_wcsdup(const wchar_t *\fIs\fP, size_t \fIalignment\fP); +wchar_t *libsimple_enaligned_wcsdup(int \fIstatus\fP, const wchar_t *\fIs\fP, size_t \fIalignment\fP); +static inline wchar_t *libsimple_ealigned_wcsdup(const wchar_t *\fIs\fP, size_t \fIalignment\fP); + +#ifndef aligned_wcsdupa +# define aligned_wcsdupa libsimple_aligned_wcsdupa +#endif +#ifndef aligned_wcsdup +# define aligned_wcsdup libsimple_aligned_wcsdup +#endif +#ifndef enaligned_wcsdup +# define enaligned_wcsdup libsimple_enaligned_wcsdup +#endif +#ifndef ealigned_wcsdup +# define ealigned_wcsdup libsimple_ealigned_wcsdup +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_aligned_wcsdup () +function allocates memory with the alignment +specified in the +.I alignment +parameter and copies the wide-character string +.I s +into the new allocation. +.PP +The +.BR libsimple_enaligned_wcsdup () +and +.BR libsimple_ealigned_wcsdup () +functions are versions of the +.BR libsimple_aligned_wcsdup () +function that call the +.BR libsimple_enprintf (3) +function on failure, causing the process to print +an error message and exit. See +.BR libsimple_enprintf (3) +for more information. +.PP +The +.BR libsimple_wcsdupa () +function is implemented as a macro and is a version +of the +.BR libsimple_wcsdup () +function that uses allocates the memory on the stack +rather than on the heap, causing the return pointer +to become invalid when the calling function returns. +It is only available when compling with GCC or Clang. +.SH RETURN VALUE +Upon successful completion, the +.BR libsimple_aligned_wcsdupa (), +.BR libsimple_aligned_wcsdup (), +.BR libsimple_enaligned_wcsdup (), +and +.BR libsimple_ealigned_wcsdup () +functions return a non-null pointer, on failure the +.BR libsimple_aligned_wcsdup () +function returns +.B NULL +and set +.I errno +to indicate the error, and the +.BR libsimple_enaligned_wcsdup (), +and +.BR libsimple_ealigned_wcsdup () +functions exit the process. The +.BR libsimple_aligned_wcsdupa () +function cannot fail, however the kernel +can kill the thread, and possibly the process, with a +.B SIGSEGV +signal if the memory cannot be allocated. +.PP +The returned pointer should be deallocated when it +is no longer needed, except for the pointer returned +by the +.BR libsimple_aligned_wcsdupa () +function, it is automatically deallocated when the +calling function returns. +.SH ERRORS +The +.BR libsimple_aligned_wcsdup () +function may fail for any reason specified for the +.BR aligned_alloc (3) +function. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_aligned_wcsdupa (), +.br +.BR libsimple_aligned_wcsdup (), +.br +.BR libsimple_enaligned_wcsdup (), +.br +.BR libsimple_ealigned_wcsdup (), +T} Thread safety MT-Safe +T{ +.BR libsimple_aligned_wcsdupa (), +.br +.BR libsimple_aligned_wcsdup (), +.br +.BR libsimple_enaligned_wcsdup (), +.br +.BR libsimple_ealigned_wcsdup (), +T} Async-signal safety AS-Safe +T{ +.BR libsimple_aligned_wcsdupa (), +.br +.BR libsimple_aligned_wcsdup (), +.br +.BR libsimple_enaligned_wcsdup (), +.br +.BR libsimple_ealigned_wcsdup (), +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_aligned_strndup (3), +.BR libsimple_aligned_strdup (3), +.BR libsimple_aligned_memdup (3), +.BR libsimple_aligned_wcsndup (3), +.BR libsimple_aligned_wmemdup (3), +.BR wcsdup (3) diff --git a/man3/libsimple_aligned_wcsdupa.3 b/man3/libsimple_aligned_wcsdupa.3 new file mode 120000 index 0000000..cb194a0 --- /dev/null +++ b/man3/libsimple_aligned_wcsdupa.3 @@ -0,0 +1 @@ +libsimple_aligned_wcsdup.3 \ No newline at end of file diff --git a/man3/libsimple_aligned_wcsndup.3 b/man3/libsimple_aligned_wcsndup.3 new file mode 100644 index 0000000..e49aed1 --- /dev/null +++ b/man3/libsimple_aligned_wcsndup.3 @@ -0,0 +1,156 @@ +.TH LIBSIMPLE_ALIGNED_WCSNDUP 3 2018-11-27 libsimple +.SH NAME +libsimple_aligned_wcsndup, libsimple_aligned_wcsndupa \- duplicate a wide-character string +.SH SYNOPSIS +.nf +#include + +wchar_t *libsimple_aligned_wcsndupa(const wchar_t *\fIs\fP, size_t \fIalignment\fP, size_t \fIn\fP); +wchar_t *libsimple_aligned_wcsndup(const wchar_t *\fIs\fP, size_t \fIalignment\fP, size_t \fIn\fP); +wchar_t *libsimple_enaligned_wcsndup(int \fIstatus\fP, const wchar_t *\fIs\fP, size_t \fIalignment\fP, size_t \fIn\fP); +static inline wchar_t *libsimple_ealigned_wcsndup(const wchar_t *\fIs\fP, size_t \fIalignment\fP, size_t \fIn\fP); + +#ifndef aligned_wcsndupa +# define aligned_wcsndupa libsimple_aligned_wcsndupa +#endif +#ifndef aligned_wcsndup +# define aligned_wcsndup libsimple_aligned_wcsndup +#endif +#ifndef enaligned_wcsndup +# define enaligned_wcsndup libsimple_enaligned_wcsndup +#endif +#ifndef ealigned_wcsndup +# define ealigned_wcsndup libsimple_ealigned_wcsndup +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_aligned_wcsndup () +function allocates memory with the alignment +specified in the +.I alignment +parameter and copies the wide-character string +.I s +into the new allocation, up to the +.IR n th +wide character +.RB ( wchar_t ). +A NUL wide-character will always be written +to the end of the new string. +.PP +The +.BR libsimple_enaligned_wcsndup () +and +.BR libsimple_ealigned_wcsndup () +functions are versions of the +.BR libsimple_aligned_wcsndup () +function that call the +.BR libsimple_enprintf (3) +function on failure, causing the process to print +an error message and exit. See +.BR libsimple_enprintf (3) +for more information. +.PP +The +.BR libsimple_wcsndupa () +function is implemented as a macro and is a version +of the +.BR libsimple_wcsndup () +function that uses allocates the memory on the stack +rather than on the heap, causing the return pointer +to become invalid when the calling function returns. +It is only available when compling with GCC or Clang. +.SH RETURN VALUE +Upon successful completion, the +.BR libsimple_aligned_wcsndupa (), +.BR libsimple_aligned_wcsndup (), +.BR libsimple_enaligned_wcsndup (), +and +.BR libsimple_ealigned_wcsndup () +functions return a non-null pointer, on failure the +.BR libsimple_aligned_wcsndup () +function returns +.B NULL +and set +.I errno +to indicate the error, and the +.BR libsimple_enaligned_wcsndup (), +and +.BR libsimple_ealigned_wcsndup () +functions exit the process. The +.BR libsimple_aligned_wcsndupa () +function cannot fail, however the kernel +can kill the thread, and possibly the process, with a +.B SIGSEGV +signal if the memory cannot be allocated. +.PP +The returned pointer should be deallocated when it +is no longer needed, except for the pointer returned +by the +.BR libsimple_aligned_wcsndupa () +function, it is automatically deallocated when the +calling function returns. +.SH ERRORS +The +.BR libsimple_aligned_wcsndup () +function may fail for any reason specified for the +.BR aligned_alloc (3) +function. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_aligned_wcsndupa (), +.br +.BR libsimple_aligned_wcsndup (), +.br +.BR libsimple_enaligned_wcsndup (), +.br +.BR libsimple_ealigned_wcsndup (), +T} Thread safety MT-Safe +T{ +.BR libsimple_aligned_wcsndupa (), +.br +.BR libsimple_aligned_wcsndup (), +.br +.BR libsimple_enaligned_wcsndup (), +.br +.BR libsimple_ealigned_wcsndup (), +T} Async-signal safety AS-Safe +T{ +.BR libsimple_aligned_wcsndupa (), +.br +.BR libsimple_aligned_wcsndup (), +.br +.BR libsimple_enaligned_wcsndup (), +.br +.BR libsimple_ealigned_wcsndup (), +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_wcsndup (3), +.BR libsimple_aligned_strndup (3), +.BR libsimple_aligned_strdup (3), +.BR libsimple_aligned_memdup (3), +.BR libsimple_aligned_wcsdup (3), +.BR libsimple_aligned_wmemdup (3) diff --git a/man3/libsimple_aligned_wcsndupa.3 b/man3/libsimple_aligned_wcsndupa.3 new file mode 120000 index 0000000..043dad0 --- /dev/null +++ b/man3/libsimple_aligned_wcsndupa.3 @@ -0,0 +1 @@ +libsimple_aligned_wcsndup.3 \ No newline at end of file diff --git a/man3/libsimple_aligned_wmemdup.3 b/man3/libsimple_aligned_wmemdup.3 new file mode 100644 index 0000000..21cc643 --- /dev/null +++ b/man3/libsimple_aligned_wmemdup.3 @@ -0,0 +1,155 @@ +.TH LIBSIMPLE_ALIGNED_WMEMDUP 3 2018-11-27 libsimple +.SH NAME +libsimple_aligned_wmemdup, libsimple_aligned_wmemdupa \- duplicate a wide-character array +.SH SYNOPSIS +.nf +#include + +wchar_t *libsimple_aligned_wmemdupa(const wchar_t *\fIs\fP, size_t \fIalignment\fP, size_t \fIn\fP); +wchar_t *libsimple_aligned_wmemdup(const wchar_t *\fIs\fP, size_t \fIalignment\fP, size_t \fIn\fP); +wchar_t *libsimple_enaligned_wmemdup(int \fIstatus\fP, const wchar_t *\fIs\fP, size_t \fIalignment\fP, size_t \fIn\fP); +static inline wchar_t *libsimple_ealigned_wmemdup(const wchar_t *\fIs\fP, size_t \fIalignment\fP, size_t \fIn\fP); + +#ifndef aligned_wmemdupa +# define aligned_wmemdupa libsimple_aligned_wmemdupa +#endif +#ifndef aligned_wmemdup +# define aligned_wmemdup libsimple_aligned_wmemdup +#endif +#ifndef enaligned_wmemdup +# define enaligned_wmemdup libsimple_enaligned_wmemdup +#endif +#ifndef ealigned_wmemdup +# define ealigned_wmemdup libsimple_ealigned_wmemdup +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_aligned_wmemdup () +function allocates memory with the alignment +specified in the +.I alignment +parameter and copies +.I n +first wide characters +.RB ( wchar_t ) +from +.I s +into the new allocation. +.PP +The +.BR libsimple_enaligned_wmemdup () +and +.BR libsimple_ealigned_wmemdup () +functions are versions of the +.BR libsimple_aligned_wmemdup () +function that call the +.BR libsimple_enprintf (3) +function on failure, causing the process to print +an error message and exit. See +.BR libsimple_enprintf (3) +for more information. +.PP +The +.BR libsimple_wmemdupa () +function is implemented as a macro and is a version +of the +.BR libsimple_wmemdup () +function that uses allocates the memory on the stack +rather than on the heap, causing the return pointer +to become invalid when the calling function returns. +It is only available when compling with GCC or Clang. +.SH RETURN VALUE +Upon successful completion, the +.BR libsimple_aligned_wmemdupa (), +.BR libsimple_aligned_wmemdup (), +.BR libsimple_enaligned_wmemdup (), +and +.BR libsimple_ealigned_wmemdup () +functions return a non-null pointer, on failure the +.BR libsimple_aligned_wmemdup () +function returns +.B NULL +and set +.I errno +to indicate the error, and the +.BR libsimple_enaligned_wmemdup (), +and +.BR libsimple_ealigned_wmemdup () +functions exit the process. The +.BR libsimple_aligned_wmemdupa () +function cannot fail, however the kernel +can kill the thread, and possibly the process, with a +.B SIGSEGV +signal if the memory cannot be allocated. +.PP +The returned pointer should be deallocated when it +is no longer needed, except for the pointer returned +by the +.BR libsimple_aligned_wmemdupa () +function, it is automatically deallocated when the +calling function returns. +.SH ERRORS +The +.BR libsimple_aligned_wmemdup () +function may fail for any reason specified for the +.BR aligned_alloc (3) +function. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_aligned_wmemdupa (), +.br +.BR libsimple_aligned_wmemdup (), +.br +.BR libsimple_enaligned_wmemdup (), +.br +.BR libsimple_ealigned_wmemdup (), +T} Thread safety MT-Safe +T{ +.BR libsimple_aligned_wmemdupa (), +.br +.BR libsimple_aligned_wmemdup (), +.br +.BR libsimple_enaligned_wmemdup (), +.br +.BR libsimple_ealigned_wmemdup (), +T} Async-signal safety AS-Safe +T{ +.BR libsimple_aligned_wmemdupa (), +.br +.BR libsimple_aligned_wmemdup (), +.br +.BR libsimple_enaligned_wmemdup (), +.br +.BR libsimple_ealigned_wmemdup (), +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_wmemdup (3), +.BR libsimple_aligned_strndup (3), +.BR libsimple_aligned_strdup (3), +.BR libsimple_aligned_memdup (3), +.BR libsimple_aligned_wcsdup (3), +.BR libsimple_aligned_wcsndup (3) diff --git a/man3/libsimple_aligned_wmemdupa.3 b/man3/libsimple_aligned_wmemdupa.3 new file mode 120000 index 0000000..264a7e1 --- /dev/null +++ b/man3/libsimple_aligned_wmemdupa.3 @@ -0,0 +1 @@ +libsimple_aligned_wmemdup.3 \ No newline at end of file diff --git a/man3/libsimple_ealigned_realloc.3 b/man3/libsimple_ealigned_realloc.3 new file mode 120000 index 0000000..2d95e24 --- /dev/null +++ b/man3/libsimple_ealigned_realloc.3 @@ -0,0 +1 @@ +libsimple_enaligned_realloc.3 \ No newline at end of file diff --git a/man3/libsimple_ealigned_reallocarray.3 b/man3/libsimple_ealigned_reallocarray.3 new file mode 120000 index 0000000..1b2e0f8 --- /dev/null +++ b/man3/libsimple_ealigned_reallocarray.3 @@ -0,0 +1 @@ +libsimple_enaligned_reallocarray.3 \ No newline at end of file diff --git a/man3/libsimple_ealigned_reallocn.3 b/man3/libsimple_ealigned_reallocn.3 new file mode 120000 index 0000000..b7dde1d --- /dev/null +++ b/man3/libsimple_ealigned_reallocn.3 @@ -0,0 +1 @@ +libsimple_evaligned_reallocn.3 \ No newline at end of file diff --git a/man3/libsimple_ealigned_strdup.3 b/man3/libsimple_ealigned_strdup.3 new file mode 120000 index 0000000..83e40a2 --- /dev/null +++ b/man3/libsimple_ealigned_strdup.3 @@ -0,0 +1 @@ +libsimple_enaligned_strdup.3 \ No newline at end of file diff --git a/man3/libsimple_ealigned_strndup.3 b/man3/libsimple_ealigned_strndup.3 new file mode 120000 index 0000000..2b79c93 --- /dev/null +++ b/man3/libsimple_ealigned_strndup.3 @@ -0,0 +1 @@ +libsimple_enaligned_strndup.3 \ No newline at end of file diff --git a/man3/libsimple_ealigned_wcsdup.3 b/man3/libsimple_ealigned_wcsdup.3 new file mode 120000 index 0000000..c52f2c8 --- /dev/null +++ b/man3/libsimple_ealigned_wcsdup.3 @@ -0,0 +1 @@ +libsimple_enaligned_wcsdup.3 \ No newline at end of file diff --git a/man3/libsimple_ealigned_wcsndup.3 b/man3/libsimple_ealigned_wcsndup.3 new file mode 120000 index 0000000..f5772b1 --- /dev/null +++ b/man3/libsimple_ealigned_wcsndup.3 @@ -0,0 +1 @@ +libsimple_enaligned_wcsndup.3 \ No newline at end of file diff --git a/man3/libsimple_ealigned_wmemdup.3 b/man3/libsimple_ealigned_wmemdup.3 new file mode 120000 index 0000000..07321e1 --- /dev/null +++ b/man3/libsimple_ealigned_wmemdup.3 @@ -0,0 +1 @@ +libsimple_enaligned_wmemdup.3 \ No newline at end of file diff --git a/man3/libsimple_enaligned_alloc.3 b/man3/libsimple_enaligned_alloc.3 index 1ea36cb..0f22da1 100644 --- a/man3/libsimple_enaligned_alloc.3 +++ b/man3/libsimple_enaligned_alloc.3 @@ -124,7 +124,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_enaligned_realloc.3 b/man3/libsimple_enaligned_realloc.3 new file mode 120000 index 0000000..45a72de --- /dev/null +++ b/man3/libsimple_enaligned_realloc.3 @@ -0,0 +1 @@ +libsimple_aligned_realloc.3 \ No newline at end of file diff --git a/man3/libsimple_enaligned_reallocarray.3 b/man3/libsimple_enaligned_reallocarray.3 new file mode 120000 index 0000000..fb3f8b9 --- /dev/null +++ b/man3/libsimple_enaligned_reallocarray.3 @@ -0,0 +1 @@ +libsimple_aligned_reallocarray.3 \ No newline at end of file diff --git a/man3/libsimple_enaligned_reallocn.3 b/man3/libsimple_enaligned_reallocn.3 new file mode 120000 index 0000000..36205a3 --- /dev/null +++ b/man3/libsimple_enaligned_reallocn.3 @@ -0,0 +1 @@ +libsimple_envaligned_reallocn.3 \ No newline at end of file diff --git a/man3/libsimple_enaligned_strdup.3 b/man3/libsimple_enaligned_strdup.3 new file mode 120000 index 0000000..005dc6f --- /dev/null +++ b/man3/libsimple_enaligned_strdup.3 @@ -0,0 +1 @@ +libsimple_aligned_strdup.3 \ No newline at end of file diff --git a/man3/libsimple_enaligned_strndup.3 b/man3/libsimple_enaligned_strndup.3 new file mode 120000 index 0000000..4be204c --- /dev/null +++ b/man3/libsimple_enaligned_strndup.3 @@ -0,0 +1 @@ +libsimple_aligned_strndup.3 \ No newline at end of file diff --git a/man3/libsimple_enaligned_wcsdup.3 b/man3/libsimple_enaligned_wcsdup.3 new file mode 120000 index 0000000..cb194a0 --- /dev/null +++ b/man3/libsimple_enaligned_wcsdup.3 @@ -0,0 +1 @@ +libsimple_aligned_wcsdup.3 \ No newline at end of file diff --git a/man3/libsimple_enaligned_wcsndup.3 b/man3/libsimple_enaligned_wcsndup.3 new file mode 120000 index 0000000..043dad0 --- /dev/null +++ b/man3/libsimple_enaligned_wcsndup.3 @@ -0,0 +1 @@ +libsimple_aligned_wcsndup.3 \ No newline at end of file diff --git a/man3/libsimple_enaligned_wmemdup.3 b/man3/libsimple_enaligned_wmemdup.3 new file mode 120000 index 0000000..264a7e1 --- /dev/null +++ b/man3/libsimple_enaligned_wmemdup.3 @@ -0,0 +1 @@ +libsimple_aligned_wmemdup.3 \ No newline at end of file diff --git a/man3/libsimple_encalloc.3 b/man3/libsimple_encalloc.3 index a8696e6..d14d59a 100644 --- a/man3/libsimple_encalloc.3 +++ b/man3/libsimple_encalloc.3 @@ -128,7 +128,17 @@ None. .BR libsimple_vmalloczn (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_enmalloc.3 b/man3/libsimple_enmalloc.3 index 796eafd..85cea36 100644 --- a/man3/libsimple_enmalloc.3 +++ b/man3/libsimple_enmalloc.3 @@ -124,7 +124,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_enposix_memalign.3 b/man3/libsimple_enposix_memalign.3 index c1157f3..0ae9417 100644 --- a/man3/libsimple_enposix_memalign.3 +++ b/man3/libsimple_enposix_memalign.3 @@ -128,7 +128,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_enrealloc.3 b/man3/libsimple_enrealloc.3 index 5262193..385a95e 100644 --- a/man3/libsimple_enrealloc.3 +++ b/man3/libsimple_enrealloc.3 @@ -135,7 +135,17 @@ None. .BR libsimple_vmalloczn (3), .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_enreallocarray.3 b/man3/libsimple_enreallocarray.3 new file mode 120000 index 0000000..9cb5fe4 --- /dev/null +++ b/man3/libsimple_enreallocarray.3 @@ -0,0 +1 @@ +libsimple_reallocarray.3 \ No newline at end of file diff --git a/man3/libsimple_enstrdup.3 b/man3/libsimple_enstrdup.3 index 4a2aa4f..17cd547 100644 --- a/man3/libsimple_enstrdup.3 +++ b/man3/libsimple_enstrdup.3 @@ -113,8 +113,12 @@ None. .SH BUGS None. .SH SEE ALSO +.BR libsimple_aligned_strdup (3), .BR libsimple_enstrndup (3), .BR libsimple_memdup (3), -.BR libsimple_aligned_memdup (3), +.BR libsimple_enwcsdup (3), +.BR libsimple_wcsndup (3), +.BR libsimple_wmemdup (3), .BR strndup (3), -.BR strdup (3) +.BR strdup (3), +.BR wcsdup (3) diff --git a/man3/libsimple_enstrndup.3 b/man3/libsimple_enstrndup.3 index 66272b0..6b7b23b 100644 --- a/man3/libsimple_enstrndup.3 +++ b/man3/libsimple_enstrndup.3 @@ -113,8 +113,12 @@ None. .SH BUGS None. .SH SEE ALSO +.BR libsimple_aligned_strndup (3), .BR libsimple_enstrdup (3), .BR libsimple_memdup (3), -.BR libsimple_aligned_memdup (3), +.BR libsimple_enwcsdup (3), +.BR libsimple_wcsndup (3), +.BR libsimple_wmemdup (3), .BR strndup (3), -.BR strdup (3) +.BR strdup (3), +.BR wcsdup (3) diff --git a/man3/libsimple_envaligned_reallocn.3 b/man3/libsimple_envaligned_reallocn.3 new file mode 120000 index 0000000..7c3a84f --- /dev/null +++ b/man3/libsimple_envaligned_reallocn.3 @@ -0,0 +1 @@ +libsimple_valigned_reallocn.3 \ No newline at end of file diff --git a/man3/libsimple_enwcsdup.3 b/man3/libsimple_enwcsdup.3 new file mode 100644 index 0000000..5f2a93a --- /dev/null +++ b/man3/libsimple_enwcsdup.3 @@ -0,0 +1,124 @@ +.TH LIBSIMPLE_ENWCSDUP 3 2018-11-27 libsimple +.SH NAME +libsimple_enwcsdup, libsimple_wcsdupa \- duplicate a wide-character string +.SH SYNOPSIS +.nf +#include + +wchar_t *libsimple_wcsdupa(const wchar_t *\fIs\fP); +wchar_t *libsimple_enwcsdup(int \fIstatus\fP, const wchar_t *\fIs\fP); +static inline char *libsimple_ewcsdup(const wchar_t *\fIs\fP); + +#ifndef wcsdupa +# define wcsdupa libsimple_wcsdupa +#endif +#ifndef enwcsdup +# define enwcsdup libsimple_enwcsdup +#endif +#ifndef ewcsdup +# define ewcsdup libsimple_ewcsdup +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_enwcsdup () +and +.BR libsimple_ewcsdup () +functions are versions of the +.BR wcsdup (3) +function that call the +.BR libsimple_enprintf (3) +function on failure, causing the process to print +an error message and exit. See +.BR libsimple_enprintf (3) +for more information. +.PP +The +.BR libsimple_wcsdupa () +function is implemented as a macro and is a version +of the +.BR wcsdup (3) +function that uses allocates the memory on the stack +rather than on the heap, causing the return pointer +to become invalid when the calling function returns. +It is only available when compling with GCC or Clang. +.SH RETURN VALUE +Upon successful completion, the +.BR libsimple_wcsdupa (), +.BR libsimple_enwcsdup (), +and +.BR libsimple_ewcsdup () +functions return a non-null pointer, on failure the +.BR libsimple_enwcsdup (), +and +.BR libsimple_ewcsdup () +functions exit the process. The +.BR libsimple_wcsdupa () +function cannot fail, however the kernel +can kill the thread, and possibly the process, with a +.B SIGSEGV +signal if the memory cannot be allocated. +.PP +The returned pointer should be deallocated when it +is no longer needed, except for the pointer returned +by the +.BR libsimple_wcsdupa () +function, it is automatically deallocated when the +calling function returns. +.SH ERRORS +None. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_wcsdupa (), +.br +.BR libsimple_enwcsdup (), +.br +.BR libsimple_ewcsdup (), +T} Thread safety MT-Safe +T{ +.BR libsimple_wcsdupa (), +.br +.BR libsimple_enwcsdup (), +.br +.BR libsimple_ewcsdup (), +T} Async-signal safety AS-Safe +T{ +.BR libsimple_wcsdupa (), +.br +.BR libsimple_enwcsdup (), +.br +.BR libsimple_ewcsdup (), +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_aligned_wcsdup (3), +.BR libsimple_enstrdup (3), +.BR libsimple_enstrndup (3), +.BR libsimple_memdup (3), +.BR libsimple_wcsndup (3), +.BR libsimple_wmemdup (3), +.BR strndup (3), +.BR strdup (3), +.BR wcsdup (3) diff --git a/man3/libsimple_enwcsndup.3 b/man3/libsimple_enwcsndup.3 new file mode 120000 index 0000000..57c8250 --- /dev/null +++ b/man3/libsimple_enwcsndup.3 @@ -0,0 +1 @@ +libsimple_wcsndup.3 \ No newline at end of file diff --git a/man3/libsimple_enwmemdup.3 b/man3/libsimple_enwmemdup.3 new file mode 120000 index 0000000..93381ef --- /dev/null +++ b/man3/libsimple_enwmemdup.3 @@ -0,0 +1 @@ +libsimple_wmemdup.3 \ No newline at end of file diff --git a/man3/libsimple_ereallocarray.3 b/man3/libsimple_ereallocarray.3 new file mode 120000 index 0000000..5f83973 --- /dev/null +++ b/man3/libsimple_ereallocarray.3 @@ -0,0 +1 @@ +libsimple_enreallocarray.3 \ No newline at end of file diff --git a/man3/libsimple_evaligned_reallocn.3 b/man3/libsimple_evaligned_reallocn.3 new file mode 120000 index 0000000..36205a3 --- /dev/null +++ b/man3/libsimple_evaligned_reallocn.3 @@ -0,0 +1 @@ +libsimple_envaligned_reallocn.3 \ No newline at end of file diff --git a/man3/libsimple_ewcsdup.3 b/man3/libsimple_ewcsdup.3 new file mode 120000 index 0000000..85a85a6 --- /dev/null +++ b/man3/libsimple_ewcsdup.3 @@ -0,0 +1 @@ +libsimple_enwcsdup.3 \ No newline at end of file diff --git a/man3/libsimple_ewcsndup.3 b/man3/libsimple_ewcsndup.3 new file mode 120000 index 0000000..801d72f --- /dev/null +++ b/man3/libsimple_ewcsndup.3 @@ -0,0 +1 @@ +libsimple_enwcsndup.3 \ No newline at end of file diff --git a/man3/libsimple_ewmemdup.3 b/man3/libsimple_ewmemdup.3 new file mode 120000 index 0000000..b2983f6 --- /dev/null +++ b/man3/libsimple_ewmemdup.3 @@ -0,0 +1 @@ +libsimple_enwmemdup.3 \ No newline at end of file diff --git a/man3/libsimple_mallocz.3 b/man3/libsimple_mallocz.3 index 86254ec..d0cac6f 100644 --- a/man3/libsimple_mallocz.3 +++ b/man3/libsimple_mallocz.3 @@ -161,7 +161,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_memalign.3 b/man3/libsimple_memalign.3 index 8bf04a1..e462bef 100644 --- a/man3/libsimple_memalign.3 +++ b/man3/libsimple_memalign.3 @@ -164,7 +164,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), .BR libsimple_vmemalignzn (3), diff --git a/man3/libsimple_memalignz.3 b/man3/libsimple_memalignz.3 index 11a70d7..3ad1985 100644 --- a/man3/libsimple_memalignz.3 +++ b/man3/libsimple_memalignz.3 @@ -158,7 +158,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_vmemalignn (3), .BR libsimple_vmemalignzn (3), diff --git a/man3/libsimple_memdup.3 b/man3/libsimple_memdup.3 index e111574..d11de28 100644 --- a/man3/libsimple_memdup.3 +++ b/man3/libsimple_memdup.3 @@ -29,7 +29,7 @@ Link with .SH DESCRIPTION The .BR libsimple_memdup () -function constructs allocates memory and copies +function allocates memory and copies .I n first bytes from .I s @@ -91,7 +91,7 @@ calling function returns. The .BR libsimple_memdup () function may fail for any reason specified for the -.BR alloc (3) +.BR malloc (3) function. .SH ATTRIBUTES For an explanation of the terms used in this section, see @@ -145,5 +145,9 @@ None. .BR libsimple_aligned_memdup (3), .BR libsimple_enstrndup (3), .BR libsimple_enstrdup (3), +.BR libsimple_enwcsdup (3), +.BR libsimple_wcsndup (3), +.BR libsimple_wmemdup (3), .BR strndup (3), -.BR strdup (3) +.BR strdup (3), +.BR wcsdup (3) diff --git a/man3/libsimple_posix_memalignz.3 b/man3/libsimple_posix_memalignz.3 index 3ea4655..27d7894 100644 --- a/man3/libsimple_posix_memalignz.3 +++ b/man3/libsimple_posix_memalignz.3 @@ -162,7 +162,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_pvalloc.3 b/man3/libsimple_pvalloc.3 index b6cf4c6..bd83c76 100644 --- a/man3/libsimple_pvalloc.3 +++ b/man3/libsimple_pvalloc.3 @@ -156,7 +156,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_pvallocz.3 b/man3/libsimple_pvallocz.3 index c758fcd..b020ac1 100644 --- a/man3/libsimple_pvallocz.3 +++ b/man3/libsimple_pvallocz.3 @@ -155,7 +155,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_reallocarray.3 b/man3/libsimple_reallocarray.3 new file mode 100644 index 0000000..ba4af5a --- /dev/null +++ b/man3/libsimple_reallocarray.3 @@ -0,0 +1,191 @@ +.TH LIBSIMPLE_REALLOCARRAY 3 2018-11-29 libsimple +.SH NAME +libsimple_reallocarray \- reallocate memory +.SH SYNOPSIS +.nf +#include + +static inline void *libsimple_reallocarray(void *\fIptr\fP, size_t \fIn\fP, size_t \fIm\fP); +static inline void *libsimple_enreallocarray(int \fIstatus\fP, void *\fIptr\fP, size_t \fIn\fP, size_t \fIm\fP); +static inline void *libsimple_ereallocarray(void *\fIptr\fP, size_t \fIn\fP, size_t \fIm\fP); + +#ifndef reallocarray +# define reallocarray libsimple_reallocarray +#endif +#ifndef enreallocarray +# define enreallocarray libsimple_enreallocarray +#endif +#ifndef ereallocarray +# define ereallocarray libsimple_ereallocarray +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_reallocarray (), +.BR libsimple_enreallocarray (), +and +.BR libsimple_ereallocarray () +functions are wrappers for the +.BR realloc (3) +function, they reallocate memory allocated on +the heap and return the older pointer or a new +pointer with the alignment of +.I alignof(max_align_t) +to the allocated memory of +.I n*m +bytes. The behaviour is unspecified if +.I n +or +.I m +is 0. The returned pointer will contain the +same content as +.IR ptr , +but truncated to +.I n*m +bytes if it is smaller or with the new bytes +unitialised if it is larger. If a new pointer +is returned, rather than +.IR ptr , +.I ptr +is deallocated; +.I ptr +is not deallocated on failure. The function +.BR free (3) +shall be called with the returned pointer as +input when the allocated memory is no longer needed. +.PP +The +.BR libsimple_enreallocarray () +and +.BR libsimple_ereallocarray () +functions will terminate the process if the memory +cannot be allocated, by calling the +.BR libsimple_enprintf () +and +.BR libsimple_eprintf () +functions, respectively. +On failure, the process's exit value will be +.I status +if the +.BR libsimple_enreallocarray () +function is used or +.IR libsimple_default_failure_exit (3) +if the +.BR libsimple_ereallocarray () +function is used. +.SH RETURN VALUE +The +.BR libsimple_reallocarray (), +.BR libsimple_enreallocarray (), +and +.BR libsimple_ereallocarray () +functions return a pointer to the allocated memory +upon success completion; otherwise the +.BR libsimple_reallocarray () +function returns +.B NULL +and set +.I errno +it indicate the error, and the +.BR libsimple_enreallocarray () +and +.BR libsimple_ereallocarray () +functions terminated the process. +.SH ERRORS +The +.BR libsimple_reallocarray () +function will fail for the reasons specified for the +.BR realloc (3) +function. +.PP +The +.BR libsimple_enreallocarray () +and +.BR libsimple_ereallocarray () +functions will terminate the process on failure. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_reallocarray (), +.br +.BR libsimple_enreallocarray (), +.br +.BR libsimple_ereallocarray () +T} Thread safety MT-Safe +T{ +.BR libsimple_reallocarray (), +.br +.BR libsimple_enreallocarray (), +.br +.BR libsimple_ereallocarray () +T} Async-signal safety AS-Safe +T{ +.BR libsimple_reallocarray (), +.br +.BR libsimple_enreallocarray (), +.br +.BR libsimple_ereallocarray () +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_enmalloc (3), +.BR libsimple_mallocz (3), +.BR libsimple_vmallocn (3), +.BR libsimple_vmalloczn (3), +.BR libsimple_encalloc (3), +.BR libsimple_vcallocn (3), +.BR libsimple_enrealloc (3), +.BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), +.BR libsimple_memalign (3), +.BR libsimple_memalignz (3), +.BR libsimple_vmemalignn (3), +.BR libsimple_vmemalignzn (3), +.BR libsimple_enposix_memalign (3), +.BR libsimple_posix_memalignz (3), +.BR libsimple_vposix_memalignn (3), +.BR libsimple_vposix_memalignzn (3), +.BR libsimple_enaligned_alloc (3), +.BR libsimple_aligned_allocz (3), +.BR libsimple_valigned_allocn (3), +.BR libsimple_valigned_alloczn (3), +.BR libsimple_pvalloc (3), +.BR libsimple_pvallocz (3), +.BR libsimple_vpvallocn (3), +.BR libsimple_vpvalloczn (3), +.BR libsimple_valloc (3), +.BR libsimple_vallocz (3), +.BR libsimple_vvallocn (3), +.BR libsimple_vvalloczn (3), +.BR libsimple_vmemalloc (3), +.BR libsimple_varrayalloc (3), +.BR malloc (3) diff --git a/man3/libsimple_reallocarrayf.3 b/man3/libsimple_reallocarrayf.3 new file mode 100644 index 0000000..540a27b --- /dev/null +++ b/man3/libsimple_reallocarrayf.3 @@ -0,0 +1,143 @@ +.TH LIBSIMPLE_REALLOCARRAYF 3 2018-11-29 libsimple +.SH NAME +libsimple_reallocarrayf \- reallocate memory +.SH SYNOPSIS +.nf +#include + +static inline void *libsimple_reallocarrayf(void *\fIptr\fP, size_t \fIn\fP, size_t \fIm\fP); + +#ifndef reallocarrayf +# define reallocarrayf libsimple_reallocarrayf +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_reallocarrayf () +function is a wrapper for the +.BR realloc(3) +function that reallocates memory allocated on +the heap and return the older pointer or a new +pointer with the alignment of +.I alignof(max_align_t) +to the allocated memory of +.I n*m +bytes. The returned pointer will contain the +same content as +.IR ptr , +but truncated to +.I n*m +bytes if it is smaller or with the new bytes +unitialised if it is larger. If a new pointer +is returned, rather than +.IR ptr , +.I ptr +is deallocated; +.I ptr +is deallocated on failure. The function +.BR free (3) +shall be called with the returned pointer as +input when the allocated memory is no longer needed. +.PP +If +.I n +or +.I m +is 0, +.I ptr +is deallocaed and +.B NULL +is returned, however portable applications should, +unless the namespaced alias is used, assume the +behaviour is unspecifed in this case. +.SH RETURN VALUE +The +.BR libsimple_reallocarrayf (), +function returns a pointer to the allocated memory +upon success completion; otherwise the +.BR libsimple_reallocarrayf () +function returns +.B NULL +and set +.I errno +it indicate the error. +.SH ERRORS +The +.BR libsimple_reallocarrayf () +function will fail for the reasons specified for the +.BR realloc (3) +function. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_reallocarrayf () +T} Thread safety MT-Safe +T{ +.BR libsimple_reallocarrayf () +T} Async-signal safety AS-Safe +T{ +.BR libsimple_reallocarrayf () +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_enmalloc (3), +.BR libsimple_mallocz (3), +.BR libsimple_vmallocn (3), +.BR libsimple_vmalloczn (3), +.BR libsimple_encalloc (3), +.BR libsimple_vcallocn (3), +.BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), +.BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), +.BR libsimple_memalign (3), +.BR libsimple_memalignz (3), +.BR libsimple_vmemalignn (3), +.BR libsimple_vmemalignzn (3), +.BR libsimple_enposix_memalign (3), +.BR libsimple_posix_memalignz (3), +.BR libsimple_vposix_memalignn (3), +.BR libsimple_vposix_memalignzn (3), +.BR libsimple_enaligned_alloc (3), +.BR libsimple_aligned_allocz (3), +.BR libsimple_valigned_allocn (3), +.BR libsimple_valigned_alloczn (3), +.BR libsimple_pvalloc (3), +.BR libsimple_pvallocz (3), +.BR libsimple_vpvallocn (3), +.BR libsimple_vpvalloczn (3), +.BR libsimple_valloc (3), +.BR libsimple_vallocz (3), +.BR libsimple_vvallocn (3), +.BR libsimple_vvalloczn (3), +.BR libsimple_vmemalloc (3), +.BR libsimple_varrayalloc (3), +.BR malloc (3) diff --git a/man3/libsimple_reallocf.3 b/man3/libsimple_reallocf.3 new file mode 100644 index 0000000..86a5480 --- /dev/null +++ b/man3/libsimple_reallocf.3 @@ -0,0 +1,141 @@ +.TH LIBSIMPLE_REALLOCF 3 2018-11-29 libsimple +.SH NAME +libsimple_reallocf \- reallocate memory +.SH SYNOPSIS +.nf +#include + +static inline void *libsimple_reallocf(void *\fIptr\fP, size_t \fIn\fP); + +#ifndef reallocf +# define reallocf libsimple_reallocf +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_reallocf () +function is a wrapper for the +.BR realloc(3) +function that reallocates memory allocated on +the heap and return the older pointer or a new +pointer with the alignment of +.I alignof(max_align_t) +to the allocated memory of +.I n +bytes. The returned pointer will contain the +same content as +.IR ptr , +but truncated to +.I n +bytes if it is smaller or with the new bytes +unitialised if it is larger. If a new pointer +is returned, rather than +.IR ptr , +.I ptr +is deallocated; +.I ptr +is deallocated on failure. The function +.BR free (3) +shall be called with the returned pointer as +input when the allocated memory is no longer needed. +.PP +If +.I n +is 0, +.I ptr +is deallocaed and +.B NULL +is returned, however portable applications should, +unless the namespaced alias is used, assume the +behaviour is unspecifed in this case. +.SH RETURN VALUE +The +.BR libsimple_reallocf (), +function returns a pointer to the allocated memory +upon success completion; otherwise the +.BR libsimple_reallocf () +function returns +.B NULL +and set +.I errno +it indicate the error. +.SH ERRORS +The +.BR libsimple_reallocf () +function will fail for the reasons specified for the +.BR realloc (3) +function. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_reallocf () +T} Thread safety MT-Safe +T{ +.BR libsimple_reallocf () +T} Async-signal safety AS-Safe +T{ +.BR libsimple_reallocf () +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_enmalloc (3), +.BR libsimple_mallocz (3), +.BR libsimple_vmallocn (3), +.BR libsimple_vmalloczn (3), +.BR libsimple_encalloc (3), +.BR libsimple_vcallocn (3), +.BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), +.BR libsimple_vreallocn (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), +.BR libsimple_memalign (3), +.BR libsimple_memalignz (3), +.BR libsimple_vmemalignn (3), +.BR libsimple_vmemalignzn (3), +.BR libsimple_enposix_memalign (3), +.BR libsimple_posix_memalignz (3), +.BR libsimple_vposix_memalignn (3), +.BR libsimple_vposix_memalignzn (3), +.BR libsimple_enaligned_alloc (3), +.BR libsimple_aligned_allocz (3), +.BR libsimple_valigned_allocn (3), +.BR libsimple_valigned_alloczn (3), +.BR libsimple_pvalloc (3), +.BR libsimple_pvallocz (3), +.BR libsimple_vpvallocn (3), +.BR libsimple_vpvalloczn (3), +.BR libsimple_valloc (3), +.BR libsimple_vallocz (3), +.BR libsimple_vvallocn (3), +.BR libsimple_vvalloczn (3), +.BR libsimple_vmemalloc (3), +.BR libsimple_varrayalloc (3), +.BR malloc (3) diff --git a/man3/libsimple_reallocfn.3 b/man3/libsimple_reallocfn.3 new file mode 120000 index 0000000..d06b871 --- /dev/null +++ b/man3/libsimple_reallocfn.3 @@ -0,0 +1 @@ +libsimple_vreallocfn.3 \ No newline at end of file diff --git a/man3/libsimple_valigned_allocn.3 b/man3/libsimple_valigned_allocn.3 index 2600571..5444536 100644 --- a/man3/libsimple_valigned_allocn.3 +++ b/man3/libsimple_valigned_allocn.3 @@ -213,7 +213,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_valigned_alloczn.3 b/man3/libsimple_valigned_alloczn.3 index 9f68adb..16395d7 100644 --- a/man3/libsimple_valigned_alloczn.3 +++ b/man3/libsimple_valigned_alloczn.3 @@ -216,7 +216,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_valigned_reallocfn.3 b/man3/libsimple_valigned_reallocfn.3 new file mode 100644 index 0000000..929797c --- /dev/null +++ b/man3/libsimple_valigned_reallocfn.3 @@ -0,0 +1,177 @@ +.TH LIBSIMPLE_VALIGNED_REALLOCFN 3 2018-11-28 libsimple +.SH NAME +libsimple_valigned_reallocfn \- reallocate memory and customise alignment +.SH SYNOPSIS +.nf +#include + +static inline void *libsimple_valigned_reallocfn(void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP, va_list \fIap\fP); +static inline void *libsimple_aligned_reallocfn(void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP, ..., /* (size_t)0 */); + +#ifndef valigned_reallocfn +# define valigned_reallocfn libsimple_valigned_reallocfn +#endif +#ifndef aligned_reallocfn +# define aligned_reallocfn libsimple_aligned_reallocfn +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_aligned_reallocfn () +function reallocates memory allocated on the +heap and return the older pointer or a new +pointer with the alignment of +.I alignment +to the allocated memory of +.I N +bytes, where +.I N +is the product of +.I n +and all following arguments (which should have the type +.BR size_t ) +up to the first 0; +.I n +must not be 0. The returned pointer will contain the +same content as +.IR ptr , +but truncated to +.I N +bytes if it is smaller or with the new bytes +unitialised if it is larger. If a new pointer +is returned, rather than +.IR ptr , +.I ptr +is deallocated; +.I ptr +is also deallocated on failure. The function +.BR free (3) +shall be called with the returned pointer as +input when the allocated memory is no longer needed. +.PP +The +.BR libsimple_valigned_reallocfn () +function is a version of the +.BR libsimple_aligned_reallocfn () +function that use +.B va_list +instead of variadic arguments. +.SH RETURN VALUE +The +.BR libsimple_valigned_reallocfn () +and +.BR libsimple_aligned_reallocfn (), +functions return a pointer to the allocated memory +upon success completion; otherwise the +.BR libsimple_valigned_reallocfn () +and +.BR libsimple_aligned_reallocfn () +functions return +.B NULL +and set +.I errno +it indicate the error. +.SH ERRORS +The +.BR libsimple_vreallocn (), +.BR libsimple_reallocn () +function will fail for the reasons specified for the +.BR realloc (3) +function, and if: +.TP +.B EINVAL +.I n +is 0. +.TP +.B EINVAL +.I alignment +is an invalid alignment (usually it needs to be an power of 2). +.TP +.B ENOSYS +The function is not implemented. The function requires +non-standard libc functions, and is therefore not supported +for all libc implementations. + +The function is implemented if and only if the macro +.B LIBSIMPLE_HAVE_ALIGNED_REALLOC +is defined by the library. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_valigned_reallocfn (), +.br +.BR libsimple_aligned_reallocfn () +T} Thread safety MT-Safe +T{ +.BR libsimple_valigned_reallocfn (), +.br +.BR libsimple_aligned_reallocfn () +T} Async-signal safety AS-Safe +T{ +.BR libsimple_valigned_reallocfn (), +.br +.BR libsimple_aligned_reallocfn () +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_enmalloc (3), +.BR libsimple_mallocz (3), +.BR libsimple_vmallocn (3), +.BR libsimple_vmalloczn (3), +.BR libsimple_encalloc (3), +.BR libsimple_vcallocn (3), +.BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), +.BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_memalign (3), +.BR libsimple_memalignz (3), +.BR libsimple_vmemalignn (3), +.BR libsimple_vmemalignzn (3), +.BR libsimple_enposix_memalign (3), +.BR libsimple_posix_memalignz (3), +.BR libsimple_vposix_memalignn (3), +.BR libsimple_vposix_memalignzn (3), +.BR libsimple_enaligned_alloc (3), +.BR libsimple_aligned_allocz (3), +.BR libsimple_valigned_allocn (3), +.BR libsimple_valigned_alloczn (3), +.BR libsimple_pvalloc (3), +.BR libsimple_pvallocz (3), +.BR libsimple_vpvallocn (3), +.BR libsimple_vpvalloczn (3), +.BR libsimple_valloc (3), +.BR libsimple_vallocz (3), +.BR libsimple_vvallocn (3), +.BR libsimple_vvalloczn (3), +.BR libsimple_vmemalloc (3), +.BR libsimple_varrayalloc (3), +.BR malloc (3) diff --git a/man3/libsimple_valigned_reallocn.3 b/man3/libsimple_valigned_reallocn.3 new file mode 100644 index 0000000..8925ab8 --- /dev/null +++ b/man3/libsimple_valigned_reallocn.3 @@ -0,0 +1,267 @@ +.TH LIBSIMPLE_VALIGNED_REALLOCN 3 2018-11-28 libsimple +.SH NAME +libsimple_valigned_reallocn \- reallocate memory and customise alignment +.SH SYNOPSIS +.nf +#include + +void *libsimple_valigned_reallocn(void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP, va_list \fIap\fP); +void *libsimple_envaligned_reallocn(int \fIstatus\fP, void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP, va_list \fIap\fP); +static inline void *libsimple_evaligned_reallocn(void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP, va_list \fIap\fP); +static inline void *libsimple_aligned_reallocn(void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP, ..., /* (size_t)0 */); +static inline void *libsimple_enaligned_reallocn(int \fIstatus\fP, void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP, ..., /* (size_t)0 */); +static inline void *libsimple_ealigned_reallocn(void *\fIptr\fP, size_t \fIalignment\fP, size_t \fIn\fP, ..., /* (size_t)0 */); + +#ifndef valigned_reallocn +# define valigned_reallocn libsimple_valigned_reallocn +#endif +#ifndef envaligned_reallocn +# define envaligned_reallocn libsimple_envaligned_reallocn +#endif +#ifndef evaligned_reallocn +# define evaligned_reallocn libsimple_evaligned_reallocn +#endif +#ifndef aligned_reallocn +# define aligned_reallocn libsimple_aligned_reallocn +#endif +#ifndef enaligned_reallocn +# define enaligned_reallocn libsimple_enaligned_reallocn +#endif +#ifndef ealigned_reallocn +# define ealigned_reallocn libsimple_ealigned_reallocn +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_aligned_reallocn (), +.BR libsimple_enaligned_reallocn (), +and +.BR libsimple_ealigned_reallocn () +functions are wrappers for the +.BR realloc (3) +function, they reallocate memory allocated on +the heap and return the older pointer or a new +pointer with the alignment of +.I alignment +to the allocated memory of +.I N +bytes, where +.I N +is the product of +.I n +and all following arguments (which should have the type +.BR size_t ) +up to the first 0; +.I n +must not be 0. The returned pointer will contain the +same content as +.IR ptr , +but truncated to +.I N +bytes if it is smaller or with the new bytes +unitialised if it is larger. If a new pointer +is returned, rather than +.IR ptr , +.I ptr +is deallocated; +.I ptr +is not deallocated on failure. The function +.BR free (3) +shall be called with the returned pointer as +input when the allocated memory is no longer needed. +.PP +The +.BR libsimple_enaligned_reallocn () +and +.BR libsimple_ealigned_reallocn () +functions will terminate the process if the memory +cannot be allocated, by calling the +.BR libsimple_enprintf () +and +.BR libsimple_eprintf () +functions, respectively. +On failure, the process's exit value will be +.I status +if the +.BR libsimple_enaligned_reallocn () +function is used or +.IR libsimple_default_failure_exit (3) +if the +.BR libsimple_ealigned_reallocn () +function is used. +.PP +The +.BR libsimple_valigned_reallocn (), +.BR libsimple_envaligned_reallocn (), +and +.BR libsimple_evaligned_reallocn () +functions are versions of the +.BR libsimple_aligned_reallocn (), +.BR libsimple_enaligned_reallocn (), +and +.BR libsimple_ealigned_reallocn (), +respectively, that use +.B va_list +instead of variadic arguments. +.SH RETURN VALUE +The +.BR libsimple_valigned_reallocn (), +.BR libsimple_envaligned_reallocn (), +.BR libsimple_evaligned_reallocn (), +.BR libsimple_aligned_reallocn (), +.BR libsimple_enaligned_reallocn (), +and +.BR libsimple_ealigned_reallocn () +functions return a pointer to the allocated memory +upon success completion; otherwise the +.BR libsimple_valigned_reallocn () +and +.BR libsimple_aligned_reallocn () +functions return +.B NULL +and set +.I errno +it indicate the error, and the +.BR libsimple_envaligned_reallocn (), +.BR libsimple_evaligned_reallocn (), +.BR libsimple_enaligned_reallocn (), +and +.BR libsimple_ealigned_reallocn () +functions terminated the process. +.SH ERRORS +The +.BR libsimple_valigned_reallocn () +and +.BR libsimple_aligned_reallocn () +functions will fail for the reasons specified for the +.BR realloc (3) +function, and if: +.TP +.B EINVAL +.I n +is 0. +.TP +.B EINVAL +.I alignment +is an invalid alignment (usually it needs to be an power of 2). +.TP +.B ENOSYS +The function is not implemented. The function requires +non-standard libc functions, and is therefore not supported +for all libc implementations. + +The function is implemented if and only if the macro +.B LIBSIMPLE_HAVE_ALIGNED_REALLOC +is defined by the library. +.PP +The +.BR libsimple_envaligned_reallocn (), +.BR libsimple_evaligned_reallocn (), +.BR libsimple_enaligned_reallocn (), +and +.BR libsimple_ealigned_reallocn () +functions will terminate the process on failure. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_valigned_reallocn (), +.br +.BR libsimple_envaligned_reallocn (), +.br +.BR libsimple_evaligned_reallocn (), +.br +.BR libsimple_aligned_reallocn (), +.br +.BR libsimple_enaligned_reallocn (), +.br +.BR libsimple_ealigned_reallocn () +T} Thread safety MT-Safe +T{ +.BR libsimple_valigned_reallocn (), +.br +.BR libsimple_envaligned_reallocn (), +.br +.BR libsimple_evaligned_reallocn (), +.br +.BR libsimple_aligned_reallocn (), +.br +.BR libsimple_enaligned_reallocn (), +.br +.BR libsimple_ealigned_reallocn () +T} Async-signal safety AS-Safe +T{ +.BR libsimple_valigned_reallocn (), +.br +.BR libsimple_envaligned_reallocn (), +.br +.BR libsimple_evaligned_reallocn (), +.br +.BR libsimple_aligned_reallocn (), +.br +.BR libsimple_enaligned_reallocn (), +.br +.BR libsimple_ealigned_reallocn () +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_enmalloc (3), +.BR libsimple_mallocz (3), +.BR libsimple_vmallocn (3), +.BR libsimple_vmalloczn (3), +.BR libsimple_encalloc (3), +.BR libsimple_vcallocn (3), +.BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), +.BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), +.BR libsimple_memalign (3), +.BR libsimple_memalignz (3), +.BR libsimple_vmemalignn (3), +.BR libsimple_vmemalignzn (3), +.BR libsimple_enposix_memalign (3), +.BR libsimple_posix_memalignz (3), +.BR libsimple_vposix_memalignn (3), +.BR libsimple_vposix_memalignzn (3), +.BR libsimple_enaligned_alloc (3), +.BR libsimple_aligned_allocz (3), +.BR libsimple_valigned_allocn (3), +.BR libsimple_valigned_alloczn (3), +.BR libsimple_pvalloc (3), +.BR libsimple_pvallocz (3), +.BR libsimple_vpvallocn (3), +.BR libsimple_vpvalloczn (3), +.BR libsimple_valloc (3), +.BR libsimple_vallocz (3), +.BR libsimple_vvallocn (3), +.BR libsimple_vvalloczn (3), +.BR libsimple_vmemalloc (3), +.BR libsimple_varrayalloc (3), +.BR malloc (3) diff --git a/man3/libsimple_valloc.3 b/man3/libsimple_valloc.3 index 84cce32..b7094e9 100644 --- a/man3/libsimple_valloc.3 +++ b/man3/libsimple_valloc.3 @@ -155,7 +155,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_vallocz.3 b/man3/libsimple_vallocz.3 index 3559a32..c888f4c 100644 --- a/man3/libsimple_vallocz.3 +++ b/man3/libsimple_vallocz.3 @@ -155,7 +155,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_varrayalloc.3 b/man3/libsimple_varrayalloc.3 index ceea9f1..380c76f 100644 --- a/man3/libsimple_varrayalloc.3 +++ b/man3/libsimple_varrayalloc.3 @@ -192,7 +192,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_vcallocn.3 b/man3/libsimple_vcallocn.3 index 0d1c71d..eda8ecf 100644 --- a/man3/libsimple_vcallocn.3 +++ b/man3/libsimple_vcallocn.3 @@ -204,7 +204,17 @@ None. .BR libsimple_vmalloczn (3), .BR libsimple_encalloc (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_vmallocn.3 b/man3/libsimple_vmallocn.3 index 0aed464..7c65c0b 100644 --- a/man3/libsimple_vmallocn.3 +++ b/man3/libsimple_vmallocn.3 @@ -204,7 +204,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_vmalloczn.3 b/man3/libsimple_vmalloczn.3 index 8b12b4a..19f9502 100644 --- a/man3/libsimple_vmalloczn.3 +++ b/man3/libsimple_vmalloczn.3 @@ -211,7 +211,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_vmemalignn.3 b/man3/libsimple_vmemalignn.3 index 8a6c5c1..a27dfbd 100644 --- a/man3/libsimple_vmemalignn.3 +++ b/man3/libsimple_vmemalignn.3 @@ -208,7 +208,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignzn (3), diff --git a/man3/libsimple_vmemalignzn.3 b/man3/libsimple_vmemalignzn.3 index f59b3a0..3421bde 100644 --- a/man3/libsimple_vmemalignzn.3 +++ b/man3/libsimple_vmemalignzn.3 @@ -211,7 +211,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_vmemalloc.3 b/man3/libsimple_vmemalloc.3 index e088af2..253a6e4 100644 --- a/man3/libsimple_vmemalloc.3 +++ b/man3/libsimple_vmemalloc.3 @@ -296,7 +296,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_vposix_memalignn.3 b/man3/libsimple_vposix_memalignn.3 index f05ab6b..eae3908 100644 --- a/man3/libsimple_vposix_memalignn.3 +++ b/man3/libsimple_vposix_memalignn.3 @@ -210,7 +210,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_vposix_memalignzn.3 b/man3/libsimple_vposix_memalignzn.3 index 481a4b1..ca9f0c1 100644 --- a/man3/libsimple_vposix_memalignzn.3 +++ b/man3/libsimple_vposix_memalignzn.3 @@ -213,7 +213,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_vpvallocn.3 b/man3/libsimple_vpvallocn.3 index 4c05134..2ebae43 100644 --- a/man3/libsimple_vpvallocn.3 +++ b/man3/libsimple_vpvallocn.3 @@ -206,7 +206,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_vpvalloczn.3 b/man3/libsimple_vpvalloczn.3 index be9f1c5..4f15a83 100644 --- a/man3/libsimple_vpvalloczn.3 +++ b/man3/libsimple_vpvalloczn.3 @@ -208,7 +208,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_vreallocfn.3 b/man3/libsimple_vreallocfn.3 new file mode 100644 index 0000000..8b75bf3 --- /dev/null +++ b/man3/libsimple_vreallocfn.3 @@ -0,0 +1,166 @@ +.TH LIBSIMPLE_VREALLOCFN 3 2018-11-28 libsimple +.SH NAME +libsimple_vreallocfn \- reallocate memory +.SH SYNOPSIS +.nf +#include + +static inline void *libsimple_vreallocfn(void *\fIptr\fP, size_t \fIn\fP, va_list \fIap\fP); +static inline void *libsimple_reallocfn(void *\fIptr\fP, size_t \fIn\fP, ..., /* (size_t)0 */); + +#ifndef vreallocfn +# define vreallocfn libsimple_vreallocfn +#endif +#ifndef reallocfn +# define reallocfn libsimple_reallocfn +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_reallocfn () +function is a wrapper for the +.BR realloc (3) +function, it reallocate memory allocated on +the heap and return the older pointer or a new +pointer with the alignment of +.I alignof(max_align_t) +to the allocated memory of +.I N +bytes, where +.I N +is the product of +.I n +and all following arguments (which should have the type +.BR size_t ) +up to the first 0; +.I n +must not be 0. The returned pointer will contain the +same content as +.IR ptr , +but truncated to +.I N +bytes if it is smaller or with the new bytes +unitialised if it is larger. If a new pointer +is returned, rather than +.IR ptr , +.I ptr +is deallocated; +.I ptr +is also deallocated on failure. The function +.BR free (3) +shall be called with the returned pointer as +input when the allocated memory is no longer needed. +.PP +The +.BR libsimple_vreallocfn () +function is a version of the +.BR libsimple_reallocfn () +function that use +.B va_list +instead of variadic arguments. +.SH RETURN VALUE +The +.BR libsimple_vreallocfn () +and +.BR libsimple_reallocfn (), +functions return a pointer to the allocated memory +upon success completion; otherwise the +.BR libsimple_vreallocfn () +and +.BR libsimple_reallocfn () +functions return +.B NULL +and set +.I errno +it indicate the error. +.SH ERRORS +The +.BR libsimple_vreallocn (), +.BR libsimple_reallocn () +function will fail for the reasons specified for the +.BR realloc (3) +function, and if: +.TP +.B EINVAL +.I n +is 0. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_vreallocfn (), +.br +.BR libsimple_reallocfn () +T} Thread safety MT-Safe +T{ +.BR libsimple_vreallocfn (), +.br +.BR libsimple_reallocfn () +T} Async-signal safety AS-Safe +T{ +.BR libsimple_vreallocfn (), +.br +.BR libsimple_reallocfn () +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_enmalloc (3), +.BR libsimple_mallocz (3), +.BR libsimple_vmallocn (3), +.BR libsimple_vmalloczn (3), +.BR libsimple_encalloc (3), +.BR libsimple_vcallocn (3), +.BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), +.BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), +.BR libsimple_memalign (3), +.BR libsimple_memalignz (3), +.BR libsimple_vmemalignn (3), +.BR libsimple_vmemalignzn (3), +.BR libsimple_enposix_memalign (3), +.BR libsimple_posix_memalignz (3), +.BR libsimple_vposix_memalignn (3), +.BR libsimple_vposix_memalignzn (3), +.BR libsimple_enaligned_alloc (3), +.BR libsimple_aligned_allocz (3), +.BR libsimple_valigned_allocn (3), +.BR libsimple_valigned_alloczn (3), +.BR libsimple_pvalloc (3), +.BR libsimple_pvallocz (3), +.BR libsimple_vpvallocn (3), +.BR libsimple_vpvalloczn (3), +.BR libsimple_valloc (3), +.BR libsimple_vallocz (3), +.BR libsimple_vvallocn (3), +.BR libsimple_vvalloczn (3), +.BR libsimple_vmemalloc (3), +.BR libsimple_varrayalloc (3), +.BR malloc (3) diff --git a/man3/libsimple_vreallocn.3 b/man3/libsimple_vreallocn.3 index 2f61307..8c728b1 100644 --- a/man3/libsimple_vreallocn.3 +++ b/man3/libsimple_vreallocn.3 @@ -43,7 +43,7 @@ and functions are wrappers for the .BR realloc (3) function, they reallocate memory allocated on -the heap and return the older pointer ot a new +the heap and return the older pointer or a new pointer with the alignment of .I alignof(max_align_t) to the allocated memory of @@ -133,9 +133,10 @@ and functions terminated the process. .SH ERRORS The -.BR libsimple_vreallocn (), +.BR libsimple_vreallocn () +and .BR libsimple_reallocn () -function will fail for the reasons specified for the +functions will fail for the reasons specified for the .BR realloc (3) function, and if: .TP @@ -218,6 +219,16 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_vvallocn.3 b/man3/libsimple_vvallocn.3 index e21d37b..08c74f7 100644 --- a/man3/libsimple_vvallocn.3 +++ b/man3/libsimple_vvallocn.3 @@ -205,7 +205,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_vvalloczn.3 b/man3/libsimple_vvalloczn.3 index 1b7a8e0..4541466 100644 --- a/man3/libsimple_vvalloczn.3 +++ b/man3/libsimple_vvalloczn.3 @@ -208,7 +208,17 @@ None. .BR libsimple_encalloc (3), .BR libsimple_vcallocn (3), .BR libsimple_enrealloc (3), +.BR libsimple_reallocarray (3), .BR libsimple_vreallocn (3), +.BR libsimple_reallocf (3), +.BR libsimple_reallocarrayf (3), +.BR libsimple_vreallocfn (3), +.BR libsimple_aligned_realloc (3), +.BR libsimple_aligned_reallocarray (3), +.BR libsimple_aligned_vreallocn (3), +.BR libsimple_aligned_reallocf (3), +.BR libsimple_aligned_reallocarrayf (3), +.BR libsimple_aligned_vreallocfn (3), .BR libsimple_memalign (3), .BR libsimple_memalignz (3), .BR libsimple_vmemalignn (3), diff --git a/man3/libsimple_wcsdupa.3 b/man3/libsimple_wcsdupa.3 new file mode 120000 index 0000000..85a85a6 --- /dev/null +++ b/man3/libsimple_wcsdupa.3 @@ -0,0 +1 @@ +libsimple_enwcsdup.3 \ No newline at end of file diff --git a/man3/libsimple_wcsndup.3 b/man3/libsimple_wcsndup.3 new file mode 100644 index 0000000..75f45fd --- /dev/null +++ b/man3/libsimple_wcsndup.3 @@ -0,0 +1,155 @@ +.TH LIBSIMPLE_WCSNDUP 3 2018-11-27 libsimple +.SH NAME +libsimple_wcsndup \- duplicate a wide-character string +.SH SYNOPSIS +.nf +#include + +wchar_t *libsimple_wcsndupa(const wchar_t *\fIs\fP, size_t \fIn\fP); +wchar_t *libsimple_wcsndup(const wchar_t *\fIs\fP, size_t \fIn\fP); +wchar_t *libsimple_enwcsndup(int \fIstatus\fP, const wchar_t *\fIs\fP, size_t \fIn\fP); +static inline wchar_t *libsimple_ewcsndup(const wchar_t *\fIs\fP, size_t \fIn\fP); + +#ifndef wcsndupa +# define wcsndupa libsimple_wcsndupa +#endif +#ifndef wcsndup +# define wcsndup libsimple_wcsndup +#endif +#ifndef enwcsndup +# define enwcsndup libsimple_enwcsndup +#endif +#ifndef ewcsndup +# define ewcsndup libsimple_ewcsndup +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_wcsndup () +function allocates memory and copies the string +.I s +into the new allocation, however only up to the +.I n +first wide-characters; a NUL wide-character will +always be written to the end of the new +wide-character string. +.PP +The +.BR libsimple_enwcsndup () +and +.BR libsimple_ewcsndup () +functions are versions of the +.BR libsimple_wcsndup () +function that call the +.BR libsimple_enprintf (3) +function on failure, causing the process to print +an error message and exit. See +.BR libsimple_enprintf (3) +for more information. +.PP +The +.BR libsimple_wcsndupa () +function is implemented as a macro and is a version +of the +.BR libsimple_wcsndup () +function that uses allocates the memory on the stack +rather than on the heap, causing the return pointer +to become invalid when the calling function returns. +It is only available when compling with GCC or Clang. +.SH RETURN VALUE +Upon successful completion, the +.BR libsimple_wcsndupa (), +.BR libsimple_wcsndup (), +.BR libsimple_enwcsndup (), +and +.BR libsimple_ewcsndup () +functions return a non-null pointer, on failure the +.BR libsimple_wcsndup () +function returns +.B NULL +and set +.I errno +to indicate the error, and the +.BR libsimple_enwcsndup (), +and +.BR libsimple_ewcsndup () +functions exit the process. The +.BR libsimple_wcsndupa () +function cannot fail, however the kernel +can kill the thread, and possibly the process, with a +.B SIGSEGV +signal if the memory cannot be allocated. +.PP +The returned pointer should be deallocated when it +is no longer needed, except for the pointer returned +by the +.BR libsimple_wcsndupa () +function, it is automatically deallocated when the +calling function returns. +.SH ERRORS +The +.BR libsimple_wcsndup () +function may fail for any reason specified for the +.BR malloc (3) +function. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_wcsndupa (), +.br +.BR libsimple_wcsndup (), +.br +.BR libsimple_enwcsndup (), +.br +.BR libsimple_ewcsndup (), +T} Thread safety MT-Safe +T{ +.BR libsimple_wcsndupa (), +.br +.BR libsimple_wcsndup (), +.br +.BR libsimple_enwcsndup (), +.br +.BR libsimple_ewcsndup (), +T} Async-signal safety AS-Safe +T{ +.BR libsimple_wcsndupa (), +.br +.BR libsimple_wcsndup (), +.br +.BR libsimple_enwcsndup (), +.br +.BR libsimple_ewcsndup (), +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_aligned_wcsndup (3), +.BR libsimple_enstrndup (3), +.BR libsimple_enstrdup (3), +.BR libsimple_memdup (3), +.BR libsimple_enwcsdup (3), +.BR libsimple_wmemdup (3), +.BR strndup (3), +.BR strdup (3), +.BR wcsdup (3) diff --git a/man3/libsimple_wcsndupa.3 b/man3/libsimple_wcsndupa.3 new file mode 120000 index 0000000..57c8250 --- /dev/null +++ b/man3/libsimple_wcsndupa.3 @@ -0,0 +1 @@ +libsimple_wcsndup.3 \ No newline at end of file diff --git a/man3/libsimple_wmemdup.3 b/man3/libsimple_wmemdup.3 new file mode 100644 index 0000000..9f27357 --- /dev/null +++ b/man3/libsimple_wmemdup.3 @@ -0,0 +1,155 @@ +.TH LIBSIMPLE_WMEMDUP 3 2018-11-27 libsimple +.SH NAME +libsimple_wmemdup \- duplicate a wide-character array +.SH SYNOPSIS +.nf +#include + +wchar_t *libsimple_wmemdupa(const wchar_t *\fIs\fP, size_t \fIn\fP); +wchar_t *libsimple_wmemdup(const wchar_t *\fIs\fP, size_t \fIn\fP); +wchar_t *libsimple_enwmemdup(int \fIstatus\fP, const wchar_t *\fIs\fP, size_t \fIn\fP); +static inline wchar_t *libsimple_ewmemdup(const wchar_t *\fIs\fP, size_t \fIn\fP); + +#ifndef wmemdupa +# define wmemdupa libsimple_wmemdupa +#endif +#ifndef wmemdup +# define wmemdup libsimple_wmemdup +#endif +#ifndef enwmemdup +# define enwmemdup libsimple_enwmemdup +#endif +#ifndef ewmemdup +# define ewmemdup libsimple_ewmemdup +#endif +.fi +.PP +Link with +.IR \-lsimple . +.SH DESCRIPTION +The +.BR libsimple_wmemdup () +function allocates memory and copies +.I n +first wide-characters +.RB ( wchar_t ) +from +.I s +into the new allocation. +.PP +The +.BR libsimple_enwmemdup () +and +.BR libsimple_ewmemdup () +functions are versions of the +.BR libsimple_wmemdup () +function that call the +.BR libsimple_enprintf (3) +function on failure, causing the process to print +an error message and exit. See +.BR libsimple_enprintf (3) +for more information. +.PP +The +.BR libsimple_wmemdupa () +function is implemented as a macro and is a version +of the +.BR libsimple_wmemdup () +function that uses allocates the memory on the stack +rather than on the heap, causing the return pointer +to become invalid when the calling function returns. +It is only available when compling with GCC or Clang. +.SH RETURN VALUE +Upon successful completion, the +.BR libsimple_wmemdupa (), +.BR libsimple_wmemdup (), +.BR libsimple_enwmemdup (), +and +.BR libsimple_ewmemdup () +functions return a non-null pointer, on failure the +.BR libsimple_wmemdup () +function returns +.B NULL +and set +.I errno +to indicate the error, and the +.BR libsimple_enwmemdup (), +and +.BR libsimple_ewmemdup () +functions exit the process. The +.BR libsimple_wmemdupa () +function cannot fail, however the kernel +can kill the thread, and possibly the process, with a +.B SIGSEGV +signal if the memory cannot be allocated. +.PP +The returned pointer should be deallocated when it +is no longer needed, except for the pointer returned +by the +.BR libsimple_wmemdupa () +function, it is automatically deallocated when the +calling function returns. +.SH ERRORS +The +.BR libsimple_wmemdup () +function may fail for any reason specified for the +.BR malloc (3) +function. +.SH ATTRIBUTES +For an explanation of the terms used in this section, see +.BR attributes (7). +.TS +allbox; +lb lb lb +l l l. +Interface Attribute Value +T{ +.BR libsimple_wmemdupa (), +.br +.BR libsimple_wmemdup (), +.br +.BR libsimple_enwmemdup (), +.br +.BR libsimple_ewmemdup (), +T} Thread safety MT-Safe +T{ +.BR libsimple_wmemdupa (), +.br +.BR libsimple_wmemdup (), +.br +.BR libsimple_enwmemdup (), +.br +.BR libsimple_ewmemdup (), +T} Async-signal safety AS-Safe +T{ +.BR libsimple_wmemdupa (), +.br +.BR libsimple_wmemdup (), +.br +.BR libsimple_enwmemdup (), +.br +.BR libsimple_ewmemdup (), +T} Async-cancel safety AC-Safe +.TE +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsimple_aligned_wmemdup (3), +.BR libsimple_enstrndup (3), +.BR libsimple_enstrdup (3), +.BR libsimple_memdup (3), +.BR libsimple_enwcsdup (3), +.BR libsimple_wcsndup (3), +.BR strndup (3), +.BR strdup (3), +.BR wcsdup (3) diff --git a/man3/libsimple_wmemdupa.3 b/man3/libsimple_wmemdupa.3 new file mode 120000 index 0000000..93381ef --- /dev/null +++ b/man3/libsimple_wmemdupa.3 @@ -0,0 +1 @@ +libsimple_wmemdup.3 \ No newline at end of file diff --git a/man3/reallocarray.3libsimple b/man3/reallocarray.3libsimple new file mode 120000 index 0000000..9cb5fe4 --- /dev/null +++ b/man3/reallocarray.3libsimple @@ -0,0 +1 @@ +libsimple_reallocarray.3 \ No newline at end of file diff --git a/man3/reallocarrayf.3libsimple b/man3/reallocarrayf.3libsimple new file mode 120000 index 0000000..c0ad147 --- /dev/null +++ b/man3/reallocarrayf.3libsimple @@ -0,0 +1 @@ +libsimple_reallocarrayf.3 \ No newline at end of file diff --git a/man3/reallocf.3libsimple b/man3/reallocf.3libsimple new file mode 120000 index 0000000..e60bee6 --- /dev/null +++ b/man3/reallocf.3libsimple @@ -0,0 +1 @@ +libsimple_reallocf.3 \ No newline at end of file diff --git a/man3/reallocfn.3libsimple b/man3/reallocfn.3libsimple new file mode 120000 index 0000000..7db99ff --- /dev/null +++ b/man3/reallocfn.3libsimple @@ -0,0 +1 @@ +libsimple_reallocfn.3 \ No newline at end of file diff --git a/man3/valigned_reallocfn.3libsimple b/man3/valigned_reallocfn.3libsimple new file mode 120000 index 0000000..1ba44a5 --- /dev/null +++ b/man3/valigned_reallocfn.3libsimple @@ -0,0 +1 @@ +libsimple_valigned_reallocfn.3 \ No newline at end of file diff --git a/man3/valigned_reallocn.3libsimple b/man3/valigned_reallocn.3libsimple new file mode 120000 index 0000000..7c3a84f --- /dev/null +++ b/man3/valigned_reallocn.3libsimple @@ -0,0 +1 @@ +libsimple_valigned_reallocn.3 \ No newline at end of file diff --git a/man3/vreallocfn.3libsimple b/man3/vreallocfn.3libsimple new file mode 120000 index 0000000..d06b871 --- /dev/null +++ b/man3/vreallocfn.3libsimple @@ -0,0 +1 @@ +libsimple_vreallocfn.3 \ No newline at end of file diff --git a/man3/wcsdupa.3libsimple b/man3/wcsdupa.3libsimple new file mode 120000 index 0000000..4555af1 --- /dev/null +++ b/man3/wcsdupa.3libsimple @@ -0,0 +1 @@ +libsimple_wcsdupa.3 \ No newline at end of file diff --git a/man3/wcsndup.3libsimple b/man3/wcsndup.3libsimple new file mode 120000 index 0000000..57c8250 --- /dev/null +++ b/man3/wcsndup.3libsimple @@ -0,0 +1 @@ +libsimple_wcsndup.3 \ No newline at end of file diff --git a/man3/wcsndupa.3libsimple b/man3/wcsndupa.3libsimple new file mode 120000 index 0000000..ac844a1 --- /dev/null +++ b/man3/wcsndupa.3libsimple @@ -0,0 +1 @@ +libsimple_wcsndupa.3 \ No newline at end of file diff --git a/man3/wmemdup.3libsimple b/man3/wmemdup.3libsimple new file mode 120000 index 0000000..93381ef --- /dev/null +++ b/man3/wmemdup.3libsimple @@ -0,0 +1 @@ +libsimple_wmemdup.3 \ No newline at end of file diff --git a/man3/wmemdupa.3libsimple b/man3/wmemdupa.3libsimple new file mode 120000 index 0000000..919c84e --- /dev/null +++ b/man3/wmemdupa.3libsimple @@ -0,0 +1 @@ +libsimple_wmemdupa.3 \ No newline at end of file diff --git a/wcsndup.c b/wcsndup.c index ba4e009..5b8f7cc 100644 --- a/wcsndup.c +++ b/wcsndup.c @@ -6,15 +6,16 @@ wchar_t * libsimple_wcsndup(const wchar_t *s, size_t n) /* TODO test */ { - size_t n = wcsnlen(s, n), size; + size_t size; wchar_t *ret; + n = wcsnlen(s, n); if (LIBSIMPLE_UMUL_OVERFLOW_NONZERO(n + 1, sizeof(wchar_t), &size, SIZE_MAX)) { errno = ENOMEM; - enprintf(status, "wcsdup:"); + return NULL; } ret = aligned_alloc(_Alignof(wchar_t), size); if (!ret) - enprintf(status, "wcsdup:"); + return NULL; wmemcpy(ret, s, n); ret[n] = 0; return ret; -- cgit v1.2.3-70-g09d2 From d1122de6bb461e0448897869b4406300c12f259f Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 15 Dec 2018 14:56:23 +0100 Subject: More tests and fix attributes on wcsndup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 6 + aligned_strndup.c | 81 ++++++++++++- aligned_wcsndup.c | 6 +- enaligned_realloc.c | 82 ++++++++++++- enaligned_reallocarray.c | 82 ++++++++++++- enaligned_strdup.c | 14 +++ enaligned_strndup.c | 6 +- enaligned_wcsdup.c | 55 ++++++++- enaligned_wcsndup.c | 111 ++++++++++++++++- enaligned_wmemdup.c | 41 ++++++- enreallocarray.c | 109 ++++++++++++++++- enwcsdup.c | 41 ++++++- enwcsndup.c | 109 ++++++++++++++++- enwmemdup.c | 49 +++++++- libsimple.c | 290 +++++++++++++++++++++++++++++++++++++------- libsimple/aligned_strdup.h | 4 +- libsimple/aligned_strndup.h | 2 +- libsimple/aligned_wcsdup.h | 8 +- libsimple/aligned_wcsndup.h | 4 +- libsimple/aligned_wmemdup.h | 6 +- libsimple/realloc.h | 4 +- libsimple/wcsndup.h | 6 +- libsimple/wmemdup.h | 4 +- test.c | 4 + test.h | 39 ++++++ wcsndup.c | 82 ++++++++++++- wmemdup.c | 23 +++- 27 files changed, 1184 insertions(+), 84 deletions(-) (limited to 'aligned_wcsndup.c') diff --git a/Makefile b/Makefile index 1a8e05e..50152f4 100644 --- a/Makefile +++ b/Makefile @@ -64,6 +64,9 @@ OBJ =\ enaligned_reallocarray.o\ enaligned_strdup.o\ enaligned_strndup.o\ + enaligned_wcsdup.o\ + enaligned_wcsndup.o\ + enaligned_wmemdup.o\ encalloc.o\ enmalloc.o\ enmemdup.o\ @@ -79,6 +82,9 @@ OBJ =\ envposix_memalignzn.o\ envputenvf.o\ envreallocn.o\ + enwcsdup.o\ + enwcsndup.o\ + enwmemdup.o\ memcasechr.o\ memcasechr_inv.o\ memcasecmp.o\ diff --git a/aligned_strndup.c b/aligned_strndup.c index a714387..f41fa8c 100644 --- a/aligned_strndup.c +++ b/aligned_strndup.c @@ -4,7 +4,7 @@ char * -libsimple_aligned_strndup(const char *s, size_t alignment, size_t n) /* TODO test */ +libsimple_aligned_strndup(const char *s, size_t alignment, size_t n) { char *ret; n = strnlen(s, n); @@ -23,6 +23,85 @@ libsimple_aligned_strndup(const char *s, size_t alignment, size_t n) /* TODO tes int main(void) { + struct allocinfo *info; + void *s; + + assert((s = libsimple_aligned_strndup("hello", 2, SIZE_MAX))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 6); + assert(info->alignment == 2); + assert(!info->zeroed); + } + assert(!memcmp(s, "hello", 6)); + free(s); + + assert((s = libsimple_aligned_strndup("hello", 2, 100))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 6); + assert(info->alignment == 2); + assert(!info->zeroed); + } + assert(!memcmp(s, "hello", 6)); + free(s); + + assert((s = libsimple_aligned_strndup("hello", 4, 6))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 8); + assert(info->alignment == 4); + assert(!info->zeroed); + } + assert(!memcmp(s, "hello", 6)); + free(s); + + assert((s = libsimple_aligned_strndup("hello", 8, 6))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 8); + assert(info->alignment == 8); + assert(!info->zeroed); + } + assert(!memcmp(s, "hello", 6)); + free(s); + + assert((s = libsimple_aligned_strndup("hello", 16, 6))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 16); + assert(info->alignment == 16); + assert(!info->zeroed); + } + assert(!memcmp(s, "hello", 6)); + free(s); + + assert((s = libsimple_aligned_strndup("hello", 2, 5))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 6); + assert(info->alignment == 2); + assert(!info->zeroed); + } + assert(!memcmp(s, "hello", 6)); + free(s); + + assert((s = libsimple_aligned_strndup("hello", 2, 4))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 6); + assert(info->alignment == 2); + assert(!info->zeroed); + } + assert(!memcmp(s, "hell", 5)); + free(s); + + if (have_custom_malloc()) { + alloc_fail_in = 1; + assert(!libsimple_aligned_strndup("hello", 2, 10) && errno == ENOMEM); + assert(!alloc_fail_in); + } + return 0; } diff --git a/aligned_wcsndup.c b/aligned_wcsndup.c index 1839316..90ce7f7 100644 --- a/aligned_wcsndup.c +++ b/aligned_wcsndup.c @@ -8,10 +8,8 @@ libsimple_aligned_wcsndup(const wchar_t *s, size_t alignment, size_t n) { size_t size; wchar_t *ret; - if (LIBSIMPLE_UMUL_OVERFLOW_NONZERO(n + 1, sizeof(wchar_t), &size, SIZE_MAX)) { - errno = ENOMEM; - return NULL; - } + n = wcsnlen(s, n); + size = (n + 1) * sizeof(wchar_t); size = size + (alignment - size % alignment) % alignment; ret = aligned_alloc(alignment, size); if (!ret) diff --git a/enaligned_realloc.c b/enaligned_realloc.c index 9ae1612..6d5ac4e 100644 --- a/enaligned_realloc.c +++ b/enaligned_realloc.c @@ -4,7 +4,7 @@ void * -libsimple_enaligned_realloc(int status, void *ptr, size_t alignment, size_t n) /* TODO test (ealigned_realloc) */ +libsimple_enaligned_realloc(int status, void *ptr, size_t alignment, size_t n) { void *ret = aligned_realloc(ptr, alignment, n); if (!ret) @@ -19,6 +19,86 @@ libsimple_enaligned_realloc(int status, void *ptr, size_t alignment, size_t n) / int main(void) { +#ifdef LIBSIMPLE_HAVE_ALIGNED_REALLOC + + struct allocinfo *info; + void *ptr, *old; + DEFINE_CACHELINE; + + assert((ptr = libsimple_enaligned_realloc(1, NULL, 16, 5))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 5 || info->size == info->alignment); + assert(!info->zeroed); + ASSERT_ALIGNMENT(info, 16); + info->refcount += 1; + } + stpcpy(ptr, "test"); + assert((ptr = libsimple_enaligned_realloc(1, old = ptr, 32, 10))); + assert(!strcmp(ptr, "test")); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 10 || info->size == info->alignment); + assert(!info->zeroed); + ASSERT_ALIGNMENT(info, 32); + assert(ptr != old); + free(old); + } + free(ptr); + + assert((ptr = libsimple_ealigned_realloc(NULL, 8, 5))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 5 || info->size == info->alignment); + assert(!info->zeroed); + ASSERT_ALIGNMENT(info, 8); + info->refcount += 1; + } + stpcpy(ptr, "test"); + assert((ptr = libsimple_ealigned_realloc(old = ptr, 64, 10))); + assert(!strcmp(ptr, "test")); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 10 || info->size == info->alignment); + assert(!info->zeroed); + ASSERT_ALIGNMENT(info, 64); + assert(ptr != old); + free(old); + } + free(ptr); + + if (have_custom_malloc()) { + alloc_fail_in = 1; + assert_exit_ptr(libsimple_enaligned_realloc(2, NULL, 8, 1)); + assert(exit_status == 2); + assert_stderr("%s: aligned_realloc: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + + libsimple_default_failure_exit = 104; + alloc_fail_in = 1; + assert_exit_ptr(libsimple_ealigned_realloc(NULL, 16, 1)); + assert(exit_status == 104); + assert_stderr("%s: aligned_realloc: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + libsimple_default_failure_exit = 1; + } + +#else + + assert_exit_ptr(libsimple_enaligned_realloc(2, NULL, 8, 1)); + assert(exit_status == 2); + assert_stderr("%s: aligned_realloc: %s\n", argv0, strerror(ENOSYS)); + + libsimple_default_failure_exit = 104; + alloc_fail_in = 1; + assert_exit_ptr(libsimple_ealigned_realloc(NULL, 16, 1)); + assert(exit_status == 104); + assert_stderr("%s: aligned_realloc: %s\n", argv0, strerror(ENOSYS)); + assert(!alloc_fail_in); + libsimple_default_failure_exit = 1; + +#endif + return 0; } diff --git a/enaligned_reallocarray.c b/enaligned_reallocarray.c index 35050ec..5a71207 100644 --- a/enaligned_reallocarray.c +++ b/enaligned_reallocarray.c @@ -4,7 +4,7 @@ void * -libsimple_enaligned_reallocarray(int status, void *ptr, size_t alignment, size_t n, size_t m) /* TODO test (ealigned_reallocarray) */ +libsimple_enaligned_reallocarray(int status, void *ptr, size_t alignment, size_t n, size_t m) { void *ret = aligned_reallocarray(ptr, alignment, n, m); if (!ret) @@ -19,6 +19,86 @@ libsimple_enaligned_reallocarray(int status, void *ptr, size_t alignment, size_t int main(void) { +#ifdef LIBSIMPLE_HAVE_ALIGNED_REALLOC + + struct allocinfo *info; + void *ptr, *old; + DEFINE_CACHELINE; + + assert((ptr = libsimple_enaligned_reallocarray(1, NULL, 16, 5, 2))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 10 || info->size == info->alignment); + assert(!info->zeroed); + ASSERT_ALIGNMENT(info, 16); + info->refcount += 1; + } + stpcpy(ptr, "test"); + assert((ptr = libsimple_enaligned_reallocarray(1, old = ptr, 32, 10, 3))); + assert(!strcmp(ptr, "test")); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 30 || info->size == info->alignment); + assert(!info->zeroed); + ASSERT_ALIGNMENT(info, 32); + assert(ptr != old); + free(old); + } + free(ptr); + + assert((ptr = libsimple_ealigned_reallocarray(NULL, 8, 5, 3))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 15 || info->size == 16); + assert(!info->zeroed); + ASSERT_ALIGNMENT(info, 8); + info->refcount += 1; + } + stpcpy(ptr, "test"); + assert((ptr = libsimple_ealigned_reallocarray(old = ptr, 64, 10, 4))); + assert(!strcmp(ptr, "test")); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 40 || info->size == info->alignment); + assert(!info->zeroed); + ASSERT_ALIGNMENT(info, 64); + assert(ptr != old); + free(old); + } + free(ptr); + + if (have_custom_malloc()) { + alloc_fail_in = 1; + assert_exit_ptr(libsimple_enaligned_reallocarray(2, NULL, 8, 1, 2)); + assert(exit_status == 2); + assert_stderr("%s: aligned_reallocarray: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + + libsimple_default_failure_exit = 104; + alloc_fail_in = 1; + assert_exit_ptr(libsimple_ealigned_reallocarray(NULL, 16, 1, 2)); + assert(exit_status == 104); + assert_stderr("%s: aligned_reallocarray: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + libsimple_default_failure_exit = 1; + } + +#else + + assert_exit_ptr(libsimple_enaligned_reallocarray(2, NULL, 8, 1, 2)); + assert(exit_status == 2); + assert_stderr("%s: aligned_reallocarray: %s\n", argv0, strerror(ENOSYS)); + + libsimple_default_failure_exit = 104; + alloc_fail_in = 1; + assert_exit_ptr(libsimple_ealigned_reallocarray(NULL, 16, 1, 2)); + assert(exit_status == 104); + assert_stderr("%s: aligned_reallocarray: %s\n", argv0, strerror(ENOSYS)); + assert(!alloc_fail_in); + libsimple_default_failure_exit = 1; + +#endif + return 0; } diff --git a/enaligned_strdup.c b/enaligned_strdup.c index 6390ab0..533ff56 100644 --- a/enaligned_strdup.c +++ b/enaligned_strdup.c @@ -42,6 +42,16 @@ main(void) assert(!memcmp(s, "test", 5)); free(s); + assert((s = libsimple_aligned_strdup("test", 4))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 8); + assert(info->alignment == 4); + assert(!info->zeroed); + } + assert(!memcmp(s, "test", 5)); + free(s); + if (have_custom_malloc()) { alloc_fail_in = 1; assert_exit_ptr(libsimple_enaligned_strdup(44, "hello", 2)); @@ -56,6 +66,10 @@ main(void) assert_stderr("%s: aligned_strdup: %s\n", argv0, strerror(ENOMEM)); assert(!alloc_fail_in); libsimple_default_failure_exit = 1; + + alloc_fail_in = 1; + assert(!libsimple_aligned_strdup("test", 16) && errno == ENOMEM); + assert(!alloc_fail_in); } return 0; diff --git a/enaligned_strndup.c b/enaligned_strndup.c index 7778cb2..6812d1c 100644 --- a/enaligned_strndup.c +++ b/enaligned_strndup.c @@ -8,7 +8,7 @@ libsimple_enaligned_strndup(int status, const char *s, size_t alignment, size_t { void *ret = aligned_strndup(s, alignment, n); if (!ret) - enprintf(status, "aligned_strdup:"); + enprintf(status, "aligned_strndup:"); return ret; } @@ -116,14 +116,14 @@ main(void) alloc_fail_in = 1; assert_exit_ptr(libsimple_enaligned_strndup(44, "hello", 2, 10)); assert(exit_status == 44); - assert_stderr("%s: aligned_strdup: %s\n", argv0, strerror(ENOMEM)); + assert_stderr("%s: aligned_strndup: %s\n", argv0, strerror(ENOMEM)); assert(!alloc_fail_in); libsimple_default_failure_exit = 55; alloc_fail_in = 1; assert_exit_ptr(libsimple_ealigned_strndup("test", 8, 10)); assert(exit_status == 55); - assert_stderr("%s: aligned_strdup: %s\n", argv0, strerror(ENOMEM)); + assert_stderr("%s: aligned_strndup: %s\n", argv0, strerror(ENOMEM)); assert(!alloc_fail_in); libsimple_default_failure_exit = 1; } diff --git a/enaligned_wcsdup.c b/enaligned_wcsdup.c index 17d0a4c..10d9669 100644 --- a/enaligned_wcsdup.c +++ b/enaligned_wcsdup.c @@ -4,7 +4,7 @@ wchar_t * -libsimple_enaligned_wcsdup(int status, const wchar_t *s, size_t alignment) /* TOOD test */ +libsimple_enaligned_wcsdup(int status, const wchar_t *s, size_t alignment) { void *ret = aligned_wcsdup(s, alignment); if (!ret) @@ -19,6 +19,59 @@ libsimple_enaligned_wcsdup(int status, const wchar_t *s, size_t alignment) /* TO int main(void) { + struct allocinfo *info; + void *s; + + assert((s = libsimple_enaligned_wcsdup(1, L"hello", 2))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 6 * sizeof(wchar_t)); + assert(info->alignment == 2); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"hello", 6)); + free(s); + + assert((s = libsimple_ealigned_wcsdup(L"test", 8))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 5 * sizeof(wchar_t) + (8 - 5 * sizeof(wchar_t) % 8) % 8); + assert(info->alignment == 8); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"test", 5)); + free(s); + + assert((s = libsimple_aligned_wcsdup(L"test", 4))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 5 * sizeof(wchar_t) + (4 - 5 * sizeof(wchar_t) % 4) % 4); + assert(info->alignment == 4); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"test", 5)); + free(s); + + if (have_custom_malloc()) { + alloc_fail_in = 1; + assert_exit_ptr(libsimple_enaligned_wcsdup(44, L"hello", 2)); + assert(exit_status == 44); + assert_stderr("%s: aligned_wcsdup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + + libsimple_default_failure_exit = 55; + alloc_fail_in = 1; + assert_exit_ptr(libsimple_ealigned_wcsdup(L"test", 8)); + assert(exit_status == 55); + assert_stderr("%s: aligned_wcsdup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + libsimple_default_failure_exit = 1; + + alloc_fail_in = 1; + assert(!libsimple_aligned_wcsdup(L"test", 16) && errno == ENOMEM); + assert(!alloc_fail_in); + } + return 0; } diff --git a/enaligned_wcsndup.c b/enaligned_wcsndup.c index 9b1aae8..32cce57 100644 --- a/enaligned_wcsndup.c +++ b/enaligned_wcsndup.c @@ -4,7 +4,7 @@ wchar_t * -libsimple_enaligned_wcsndup(int status, const wchar_t *s, size_t alignment, size_t n) /* TOOD test */ +libsimple_enaligned_wcsndup(int status, const wchar_t *s, size_t alignment, size_t n) { void *ret = aligned_wcsndup(s, alignment, n); if (!ret) @@ -19,6 +19,115 @@ libsimple_enaligned_wcsndup(int status, const wchar_t *s, size_t alignment, size int main(void) { + struct allocinfo *info; + void *s; + + assert((s = libsimple_enaligned_wcsndup(1, L"hello", 2, SIZE_MAX))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 6 * sizeof(wchar_t)); + assert(info->alignment == 2); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"hello", 6)); + free(s); + + assert((s = libsimple_ealigned_wcsndup(L"test", 8, SIZE_MAX))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 5 * sizeof(wchar_t) + (8 - 5 * sizeof(wchar_t) % 8) % 8); + assert(info->alignment == 8); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"test", 5)); + free(s); + + assert((s = libsimple_enaligned_wcsndup(1, L"hello", 2, 100))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 6 * sizeof(wchar_t)); + assert(info->alignment == 2); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"hello", 6)); + free(s); + + assert((s = libsimple_ealigned_wcsndup(L"test", 8, 100))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 5 * sizeof(wchar_t) + (8 - 5 * sizeof(wchar_t) % 8) % 8); + assert(info->alignment == 8); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"test", 5)); + free(s); + + assert((s = libsimple_enaligned_wcsndup(1, L"hello", 2, 6))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 6 * sizeof(wchar_t)); + assert(info->alignment == 2); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"hello", 6)); + free(s); + + assert((s = libsimple_ealigned_wcsndup(L"test", 8, 5))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 5 * sizeof(wchar_t) + (8 - 5 * sizeof(wchar_t) % 8) % 8); + assert(info->alignment == 8); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"test", 5)); + free(s); + + assert((s = libsimple_enaligned_wcsndup(1, L"hello", 2, 5))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 6 * sizeof(wchar_t)); + assert(info->alignment == 2); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"hello", 6)); + free(s); + + assert((s = libsimple_ealigned_wcsndup(L"test", 8, 4))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 5 * sizeof(wchar_t) + (8 - 5 * sizeof(wchar_t) % 8) % 8); + assert(info->alignment == 8); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"test", 5)); + free(s); + + assert((s = libsimple_enaligned_wcsndup(1, L"hello", 2, 4))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 5 * sizeof(wchar_t)); + assert(info->alignment == 2); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"hell", 5)); + free(s); + + if (have_custom_malloc()) { + alloc_fail_in = 1; + assert_exit_ptr(libsimple_enaligned_wcsndup(44, L"hello", 2, 10)); + assert(exit_status == 44); + assert_stderr("%s: aligned_wcsndup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + + libsimple_default_failure_exit = 55; + alloc_fail_in = 1; + assert_exit_ptr(libsimple_ealigned_wcsndup(L"test", 8, 10)); + assert(exit_status == 55); + assert_stderr("%s: aligned_wcsndup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + libsimple_default_failure_exit = 1; + } + return 0; } diff --git a/enaligned_wmemdup.c b/enaligned_wmemdup.c index e55e863..ad36238 100644 --- a/enaligned_wmemdup.c +++ b/enaligned_wmemdup.c @@ -4,7 +4,7 @@ wchar_t * -libsimple_enaligned_wmemdup(int status, const wchar_t *s, size_t alignment, size_t n) /* TOOD test */ +libsimple_enaligned_wmemdup(int status, const wchar_t *s, size_t alignment, size_t n) { void *ret = aligned_wmemdup(s, alignment, n); if (!ret) @@ -19,6 +19,45 @@ libsimple_enaligned_wmemdup(int status, const wchar_t *s, size_t alignment, size int main(void) { + struct allocinfo *info; + void *s; + + assert((s = libsimple_enaligned_wmemdup(1, L"hello", 2, 5))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 5 * sizeof(wchar_t)); + assert(info->alignment == 2); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"hello", 5)); + free(s); + + assert((s = libsimple_ealigned_wmemdup(L"test", 8, 5))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 5 * sizeof(wchar_t) + (8 - 5 * sizeof(wchar_t) % 8) % 8); + assert(info->alignment == 8); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"test", 5)); + free(s); + + if (have_custom_malloc()) { + alloc_fail_in = 1; + assert_exit_ptr(libsimple_enaligned_wmemdup(44, L"hello", 2, 2)); + assert(exit_status == 44); + assert_stderr("%s: aligned_wmemdup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + + libsimple_default_failure_exit = 55; + alloc_fail_in = 1; + assert_exit_ptr(libsimple_ealigned_wmemdup(L"test", 8, 2)); + assert(exit_status == 55); + assert_stderr("%s: aligned_wmemdup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + libsimple_default_failure_exit = 1; + } + return 0; } diff --git a/enreallocarray.c b/enreallocarray.c index c988994..c208626 100644 --- a/enreallocarray.c +++ b/enreallocarray.c @@ -4,7 +4,7 @@ void * -libsimple_enreallocarray(int status, void *ptr, size_t n, size_t m) /* TODO test */ +libsimple_enreallocarray(int status, void *ptr, size_t n, size_t m) { void *ret = reallocarray(ptr, n, m); if (!ret) @@ -19,6 +19,113 @@ libsimple_enreallocarray(int status, void *ptr, size_t n, size_t m) /* TODO test int main(void) { + struct allocinfo *info; + void *ptr, *old; + + assert((ptr = libsimple_enreallocarray(1, NULL, 5, 3))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 15); + assert(!info->zeroed); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); + info->refcount += 1; + } + stpcpy(ptr, "test"); + assert((ptr = libsimple_enreallocarray(1, old = ptr, 10, 2))); + assert(!strcmp(ptr, "test")); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 20); + assert(!info->zeroed); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); + assert(ptr != old); + free(old); + } + free(ptr); + + assert((ptr = libsimple_ereallocarray(NULL, 1, 5))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 5); + assert(!info->zeroed); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); + info->refcount += 1; + } + stpcpy(ptr, "test"); + assert((ptr = libsimple_ereallocarray(old = ptr, 10, 10))); + assert(!strcmp(ptr, "test")); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 100); + assert(!info->zeroed); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); + assert(ptr != old); + free(old); + } + free(ptr); + + assert((ptr = libsimple_reallocarray(NULL, 1, 5))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 5); + assert(!info->zeroed); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); + info->refcount += 1; + } + stpcpy(ptr, "test"); + assert((ptr = libsimple_reallocarray(old = ptr, 10, 10))); + assert(!strcmp(ptr, "test")); + if (have_custom_malloc()) { + assert((info = get_allocinfo(ptr))); + assert(info->size == 100); + assert(!info->zeroed); + assert(!((uintptr_t)ptr % (uintptr_t)(info->alignment))); + assert(ptr != old); + free(old); + } + free(ptr); + + if (have_custom_malloc()) { + alloc_fail_in = 1; + assert_exit_ptr(libsimple_enreallocarray(2, NULL, 1, 1)); + assert(exit_status == 2); + assert_stderr("%s: reallocarray: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + + libsimple_default_failure_exit = 104; + alloc_fail_in = 1; + assert_exit_ptr(libsimple_ereallocarray(NULL, 1, 1)); + assert(exit_status == 104); + assert_stderr("%s: reallocarray: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + libsimple_default_failure_exit = 1; + + alloc_fail_in = 1; + assert(!libsimple_reallocarray(NULL, 1, 1) && errno == ENOMEM); + assert(!alloc_fail_in); + } + +#if defined(__GNUC__) && !defined(__clang) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Walloc-size-larger-than=" +#endif + + assert_exit_ptr(libsimple_enreallocarray(3, NULL, SIZE_MAX, SIZE_MAX)); + assert(exit_status == 3); + assert_stderr("%s: reallocarray: %s\n", argv0, strerror(ENOMEM)); + + libsimple_default_failure_exit = 4; + assert_exit_ptr(libsimple_ereallocarray(NULL, SIZE_MAX, SIZE_MAX)); + assert(exit_status == 4); + assert_stderr("%s: reallocarray: %s\n", argv0, strerror(ENOMEM)); + libsimple_default_failure_exit = 1; + + assert(!libsimple_reallocarray(NULL, SIZE_MAX, SIZE_MAX) && errno == ENOMEM); + +#if defined(__GNUC__) && !defined(__clang) +# pragma GCC diagnostic pop +#endif + return 0; } diff --git a/enwcsdup.c b/enwcsdup.c index d9edbb0..1fa27c0 100644 --- a/enwcsdup.c +++ b/enwcsdup.c @@ -4,7 +4,7 @@ wchar_t * -libsimple_enwcsdup(int status, const wchar_t *s) /* TODO test */ +libsimple_enwcsdup(int status, const wchar_t *s) { size_t n = wcslen(s) + 1, size; wchar_t *ret; @@ -26,6 +26,45 @@ libsimple_enwcsdup(int status, const wchar_t *s) /* TODO test */ int main(void) { + struct allocinfo *info; + wchar_t *s; + + assert((s = libsimple_enwcsdup(1, L"hello"))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 6 * sizeof(wchar_t)); + assert(info->alignment == _Alignof(wchar_t)); + assert(!info->zeroed); + } + assert(!wcscmp(s, L"hello")); + free(s); + + assert((s = libsimple_ewcsdup(L"test"))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 5 * sizeof(wchar_t)); + assert(info->alignment == _Alignof(wchar_t)); + assert(!info->zeroed); + } + assert(!wcscmp(s, L"test")); + free(s); + + if (have_custom_malloc()) { + alloc_fail_in = 1; + assert_exit_ptr(libsimple_enwcsdup(18, L"hello")); + assert(exit_status == 18); + assert_stderr("%s: wcsdup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + + libsimple_default_failure_exit = 5; + alloc_fail_in = 1; + assert_exit_ptr(libsimple_ewcsdup(L"test")); + assert(exit_status == 5); + assert_stderr("%s: wcsdup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + libsimple_default_failure_exit = 1; + } + return 0; } diff --git a/enwcsndup.c b/enwcsndup.c index f08da34..105542c 100644 --- a/enwcsndup.c +++ b/enwcsndup.c @@ -4,7 +4,7 @@ wchar_t * -libsimple_enwcsndup(int status, const wchar_t *s, size_t n) /* TODO test */ +libsimple_enwcsndup(int status, const wchar_t *s, size_t n) { wchar_t *ret = libsimple_wcsndup(s, n); if (!ret) @@ -19,6 +19,113 @@ libsimple_enwcsndup(int status, const wchar_t *s, size_t n) /* TODO test */ int main(void) { + struct allocinfo *info; + wchar_t *s; + + assert((s = libsimple_enwcsndup(1, L"hello", 10))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 6 * sizeof(wchar_t)); + assert(info->alignment == _Alignof(wchar_t)); + assert(!info->zeroed); + } + assert(!wcscmp(s, L"hello")); + free(s); + + assert((s = libsimple_ewcsndup(L"test", 10))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 5 * sizeof(wchar_t)); + assert(info->alignment == _Alignof(wchar_t)); + assert(!info->zeroed); + } + assert(!wcscmp(s, L"test")); + free(s); + + assert((s = libsimple_enwcsndup(1, L"hello", 2))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 3 * sizeof(wchar_t)); + assert(info->alignment == _Alignof(wchar_t)); + assert(!info->zeroed); + } + assert(!wcscmp(s, L"he")); + free(s); + + assert((s = libsimple_ewcsndup(L"test", 3))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 4 * sizeof(wchar_t)); + assert(info->alignment == _Alignof(wchar_t)); + assert(!info->zeroed); + } + assert(!wcscmp(s, L"tes")); + free(s); + + assert((s = libsimple_enwcsndup(1, L"hello", 0))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 1 * sizeof(wchar_t)); + assert(info->alignment == _Alignof(wchar_t)); + assert(!info->zeroed); + } + assert(!wcscmp(s, L"")); + free(s); + + assert((s = libsimple_ewcsndup(L"test", 0))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 1 * sizeof(wchar_t)); + assert(info->alignment == _Alignof(wchar_t)); + assert(!info->zeroed); + } + assert(!wcscmp(s, L"")); + free(s); + + if (have_custom_malloc()) { + alloc_fail_in = 1; + assert_exit_ptr(libsimple_enwcsndup(24, L"hello", 10)); + assert(exit_status == 24); + assert_stderr("%s: wcsndup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + + libsimple_default_failure_exit = 25; + alloc_fail_in = 1; + assert_exit_ptr(libsimple_ewcsndup(L"test", 10)); + assert(exit_status == 25); + assert_stderr("%s: wcsndup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + libsimple_default_failure_exit = 1; + + alloc_fail_in = 1; + assert_exit_ptr(libsimple_enwcsndup(26, L"hello", 1)); + assert(exit_status == 26); + assert_stderr("%s: wcsndup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + + libsimple_default_failure_exit = 27; + alloc_fail_in = 1; + assert_exit_ptr(libsimple_ewcsndup(L"test", 2)); + assert(exit_status == 27); + assert_stderr("%s: wcsndup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + libsimple_default_failure_exit = 1; + + alloc_fail_in = 1; + assert_exit_ptr(libsimple_enwcsndup(28, L"hello", 0)); + assert(exit_status == 28); + assert_stderr("%s: wcsndup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + + libsimple_default_failure_exit = 29; + alloc_fail_in = 1; + assert_exit_ptr(libsimple_ewcsndup(L"test", 0)); + assert(exit_status == 29); + assert_stderr("%s: wcsndup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + libsimple_default_failure_exit = 1; + } + return 0; } diff --git a/enwmemdup.c b/enwmemdup.c index fb8c8dc..243c99e 100644 --- a/enwmemdup.c +++ b/enwmemdup.c @@ -4,7 +4,7 @@ wchar_t * -libsimple_enwmemdup(int status, const wchar_t *s, size_t n) /* TODO test */ +libsimple_enwmemdup(int status, const wchar_t *s, size_t n) { wchar_t *ret = libsimple_wmemdup(s, n); if (!ret) @@ -19,6 +19,53 @@ libsimple_enwmemdup(int status, const wchar_t *s, size_t n) /* TODO test */ int main(void) { + struct allocinfo *info; + wchar_t *s; + + assert((s = libsimple_enwmemdup(1, L"hello", 5))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 5 * sizeof(wchar_t)); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"hello", 5)); + free(s); + + assert((s = libsimple_ewmemdup(L"test", 5))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(s))); + assert(info->size == 5 * sizeof(wchar_t)); + assert(!info->zeroed); + } + assert(!wmemcmp(s, L"test", 5)); + free(s); + + if (have_custom_malloc()) { + alloc_fail_in = 1; + assert_exit_ptr(libsimple_enwmemdup(44, L"hello", 2)); + assert(exit_status == 44); + assert_stderr("%s: wmemdup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + + libsimple_default_failure_exit = 55; + alloc_fail_in = 1; + assert_exit_ptr(libsimple_ewmemdup(L"test", 2)); + assert(exit_status == 55); + assert_stderr("%s: wmemdup: %s\n", argv0, strerror(ENOMEM)); + assert(!alloc_fail_in); + libsimple_default_failure_exit = 1; + + assert_exit_ptr(libsimple_enwmemdup(41, NULL, SSIZE_MAX)); + assert(exit_status == 41); + assert_stderr("%s: wmemdup: %s\n", argv0, strerror(ENOMEM)); + + libsimple_default_failure_exit = 51; + assert_exit_ptr(libsimple_ewmemdup(NULL, SSIZE_MAX)); + assert(exit_status == 51); + assert_stderr("%s: wmemdup: %s\n", argv0, strerror(ENOMEM)); + libsimple_default_failure_exit = 1; + } + return 0; } diff --git a/libsimple.c b/libsimple.c index 4ef6ec2..a2ae4bc 100644 --- a/libsimple.c +++ b/libsimple.c @@ -6,27 +6,6 @@ #else #include "test.h" -static size_t -gcd(size_t u, size_t v) -{ - size_t t; - int shift = 0; - /* Not needed because u>0, v>0: if (!(u | v)) return u + v; */ - while (!((u | v) & 1)) u >>= 1, v >>= 1, shift++; - while (!(u & 1)) u >>= 1; - do { - while (!(v & 1)) v >>= 1; - if (u > v) t = u, u = v, v = t; - } while (v -= u); - return u << shift; -} - -static size_t -lcm(size_t u, size_t v) -{ - return u / gcd(u, v) * v; -} - static int test_timespec(double d, time_t sec, long int nsec, double rd, const char *s, const char *ss) { @@ -113,18 +92,13 @@ main(void) struct timespec ts, ts1, ts2; struct timeval tv1, tv2; const char *cs; + const wchar_t *cws; char buf[1024], *s; + wchar_t *ws; int intarray[10]; size_t i, j, n; - size_t pagesize, cacheline; - - pagesize = (size_t)sysconf(_SC_PAGESIZE); - -#ifdef _SC_LEVEL1_DCACHE_LINESIZE - cacheline = (size_t)sysconf(_SC_LEVEL1_DCACHE_LINESIZE); -#else - cacheline = 64; -#endif + DEFINE_PAGESIZE; + DEFINE_CACHELINE; assert(libsimple_default_failure_exit == 1); @@ -734,6 +708,7 @@ main(void) s = libsimple_memdupa(cs, n); assert(s); assert(s != cs); + assert(!((uintptr_t)s % _Alignof(max_align_t))); assert(!memcmp(s, cs, n)); } #else @@ -743,14 +718,253 @@ main(void) #ifdef libsimple_aligned_memdupa cs = "xyz"; for (n = 1; n < 4; n++) { - s = libsimple_aligned_memdupa(cs, 4 + i, n); + for (i = 1; i < 5; i++) { + s = libsimple_aligned_memdupa(cs, i, n); + assert(s); + assert(s != cs); + assert(!((uintptr_t)s % i)); + assert(!memcmp(s, cs, n)); + } + } +#else + fprintf(stderr, "warning: libsimple_aligned_memdupa missing\n"); +#endif + +#ifdef libsimple_aligned_strdupa + for (i = 1; i < 5; i++) { + cs = ""; + s = libsimple_aligned_strdupa(cs, i); assert(s); assert(s != cs); - assert(!((uintptr_t)s % (4 + i))); - assert(!memcmp(s, cs, n)); + assert(!((uintptr_t)s % i)); + assert(!strcmp(s, cs)); + + cs = "xyz"; + s = libsimple_aligned_strdupa(cs, i); + assert(s); + assert(s != cs); + assert(!((uintptr_t)s % i)); + assert(!strcmp(s, cs)); } #else - fprintf(stderr, "warning: libsimple_aligned_memdupa missing\n"); + fprintf(stderr, "warning: libsimple_aligned_strdupa missing\n"); +#endif + +#ifdef libsimple_aligned_strndupa + for (i = 1; i < 5; i++) { + cs = ""; + s = libsimple_aligned_strndupa(cs, i, 5); + assert(s); + assert(s != cs); + assert(!((uintptr_t)s % i)); + assert(!strcmp(s, "")); + + cs = "xyz"; + + s = libsimple_aligned_strndupa(cs, i, 5); + assert(s); + assert(s != cs); + assert(!((uintptr_t)s % i)); + assert(!strcmp(s, "xyz")); + + s = libsimple_aligned_strndupa(cs, i, 4); + assert(s); + assert(s != cs); + assert(!((uintptr_t)s % i)); + assert(!strcmp(s, "xyz")); + + s = libsimple_aligned_strndupa(cs, i, 3); + assert(s); + assert(s != cs); + assert(!((uintptr_t)s % i)); + assert(!strcmp(s, "xyz")); + + s = libsimple_aligned_strndupa(cs, i, 2); + assert(s); + assert(s != cs); + assert(!((uintptr_t)s % i)); + assert(!strcmp(s, "xy")); + + s = libsimple_aligned_strndupa(cs, i, 1); + assert(s); + assert(s != cs); + assert(!((uintptr_t)s % i)); + assert(!strcmp(s, "x")); + + s = libsimple_aligned_strndupa(cs, i, 0); + assert(s); + assert(s != cs); + assert(!((uintptr_t)s % i)); + assert(!strcmp(s, "")); + } +#else + fprintf(stderr, "warning: libsimple_aligned_strndupa missing\n"); +#endif + +#ifdef libsimple_wcsdupa + cws = L""; + ws = libsimple_wcsdupa(cws); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % _Alignof(wchar_t))); + assert(!wcscmp(ws, cws)); + + cws = L"xyz"; + ws = libsimple_wcsdupa(cws); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % _Alignof(wchar_t))); + assert(!wcscmp(ws, cws)); +#else + fprintf(stderr, "warning: libsimple_wcsdupa missing\n"); +#endif + +#ifdef libsimple_wcsndupa + cws = L""; + ws = libsimple_wcsndupa(cws, 5); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % _Alignof(wchar_t))); + assert(!wcscmp(ws, L"")); + + cws = L"xyz"; + + ws = libsimple_wcsndupa(cws, 5); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % _Alignof(wchar_t))); + assert(!wcscmp(ws, L"xyz")); + + ws = libsimple_wcsndupa(cws, 4); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % _Alignof(wchar_t))); + assert(!wcscmp(ws, L"xyz")); + + ws = libsimple_wcsndupa(cws, 3); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % _Alignof(wchar_t))); + assert(!wcscmp(ws, L"xyz")); + + ws = libsimple_wcsndupa(cws, 2); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % _Alignof(wchar_t))); + assert(!wcscmp(ws, L"xy")); + + ws = libsimple_wcsndupa(cws, 1); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % _Alignof(wchar_t))); + assert(!wcscmp(ws, L"x")); + + ws = libsimple_wcsndupa(cws, 0); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % _Alignof(wchar_t))); + assert(!wcscmp(ws, L"")); +#else + fprintf(stderr, "warning: libsimple_wcsndupa missing\n"); +#endif + +#ifdef libsimple_wmemdupa + cws = L"xyz"; + for (n = 1; n < 4; n++) { + ws = libsimple_wmemdupa(cws, n); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % _Alignof(wchar_t))); + assert(!wmemcmp(ws, cws, n)); + } +#else + fprintf(stderr, "warning: libsimple_wmemdupa missing\n"); +#endif + +#ifdef libsimple_aligned_wmemdupa + cws = L"xyz"; + for (n = 1; n < 4; n++) { + for (i = 1; i < 5; i++) { + ws = libsimple_aligned_wmemdupa(cws, i, n); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % i)); + assert(!wmemcmp(ws, cws, n)); + } + } +#else + fprintf(stderr, "warning: libsimple_aligned_wmemdupa missing\n"); +#endif + +#ifdef libsimple_aligned_wcsdupa + for (i = 1; i < 5; i++) { + cws = L""; + ws = libsimple_aligned_wcsdupa(cws, i); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % i)); + assert(!wcscmp(ws, cws)); + + cws = L"xyz"; + ws = libsimple_aligned_wcsdupa(cws, i); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % i)); + assert(!wcscmp(ws, cws)); + } +#else + fprintf(stderr, "warning: libsimple_aligned_wcsdupa missing\n"); +#endif + +#ifdef libsimple_aligned_wcsndupa + for (i = 1; i < 5; i++) { + cws = L""; + ws = libsimple_aligned_wcsndupa(cws, i, 5); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % i)); + assert(!wcscmp(ws, L"")); + + cws = L"xyz"; + + ws = libsimple_aligned_wcsndupa(cws, i, 5); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % i)); + assert(!wcscmp(ws, L"xyz")); + + ws = libsimple_aligned_wcsndupa(cws, i, 4); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % i)); + assert(!wcscmp(ws, L"xyz")); + + ws = libsimple_aligned_wcsndupa(cws, i, 3); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % i)); + assert(!wcscmp(ws, L"xyz")); + + ws = libsimple_aligned_wcsndupa(cws, i, 2); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % i)); + assert(!wcscmp(ws, L"xy")); + + ws = libsimple_aligned_wcsndupa(cws, i, 1); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % i)); + assert(!wcscmp(ws, L"x")); + + ws = libsimple_aligned_wcsndupa(cws, i, 0); + assert(ws); + assert(ws != cws); + assert(!((uintptr_t)ws % i)); + assert(!wcscmp(ws, L"")); + } +#else + fprintf(stderr, "warning: libsimple_aligned_wcsndupa missing\n"); #endif unsetenv("X"); @@ -1049,14 +1263,6 @@ main(void) tv2.tv_sec = 1, tv2.tv_usec = 0L; assert(libsimple_cmptimeval(&tv1, &tv2) == -1); -#define ASSERT_ALIGNMENT(INFO, ALIGN)\ - do {\ - assert((INFO)->alignment <= lcm(cacheline, ALIGN));\ - assert(!((INFO)->alignment % (ALIGN)));\ - if ((cacheline - (ALIGN) % cacheline) % cacheline + (INFO)->size % (ALIGN) > cacheline)\ - assert(!((INFO)->alignment % cacheline));\ - } while (0) - assert((ptr = libsimple_mallocz(0, 11))); if (have_custom_malloc()) { assert((info = get_allocinfo(ptr))); diff --git a/libsimple/aligned_strdup.h b/libsimple/aligned_strdup.h index 267c03e..07b7edf 100644 --- a/libsimple/aligned_strdup.h +++ b/libsimple/aligned_strdup.h @@ -9,7 +9,7 @@ * @return :char * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_aligned_strdupa(s, alignment) /* TODO test */\ +# define libsimple_aligned_strdupa(s, alignment)\ ({\ const char *__s = (s);\ size_t __n = strlen(__s) + 1;\ @@ -37,7 +37,7 @@ * @return Duplicate of `s`, `NULL` on failure */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __nonnull__, __warn_unused_result__))) -static inline char *libsimple_aligned_strdup(const char * __s, size_t __alignment) /* TODO test */ +static inline char *libsimple_aligned_strdup(const char * __s, size_t __alignment) { return libsimple_aligned_memdup(__s, __alignment, strlen(__s) + 1); } #ifndef aligned_strdup # define aligned_strdup libsimple_aligned_strdup diff --git a/libsimple/aligned_strndup.h b/libsimple/aligned_strndup.h index 51d50c8..16a3aac 100644 --- a/libsimple/aligned_strndup.h +++ b/libsimple/aligned_strndup.h @@ -10,7 +10,7 @@ * @return :char * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_aligned_strndupa(s, alignment, n) /* TODO test */\ +# define libsimple_aligned_strndupa(s, alignment, n)\ ({\ const char *__s = (s);\ size_t __n = strnlen(__s, n);\ diff --git a/libsimple/aligned_wcsdup.h b/libsimple/aligned_wcsdup.h index 8832c58..527d210 100644 --- a/libsimple/aligned_wcsdup.h +++ b/libsimple/aligned_wcsdup.h @@ -9,13 +9,13 @@ * @return :wchar_t * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_aligned_wcsdupa(s, alignment) /* TODO test */\ +# define libsimple_aligned_wcsdupa(s, alignment)\ ({\ const wchar_t *__s = (s);\ size_t __n = wcslen(__s) + 1;\ size_t __a = (alignment);\ uintptr_t __misalignment;\ - char *__r;\ + wchar_t *__r;\ __a += !__a;\ __r = alloca(__n * sizeof(wchar_t) + (__a - 1));\ __misalignment = (uintptr_t)__r % (uintptr_t)__a;\ @@ -37,7 +37,7 @@ * @return Duplicate of `s`, `NULL` on failure */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __nonnull__, __warn_unused_result__))) -static inline wchar_t *libsimple_aligned_wcsdup(const wchar_t * __s, size_t __alignment) /* TODO test */ +static inline wchar_t *libsimple_aligned_wcsdup(const wchar_t * __s, size_t __alignment) { return libsimple_aligned_wmemdup(__s, __alignment, wcslen(__s) + 1); } #ifndef aligned_wcsdup # define aligned_wcsdup libsimple_aligned_wcsdup @@ -67,7 +67,7 @@ wchar_t *libsimple_enaligned_wcsdup(int, const wchar_t *, size_t); * @return Duplicate of `s` */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __nonnull__, __warn_unused_result__, __returns_nonnull__))) -static inline wchar_t *libsimple_ealigned_wcsdup(const wchar_t *__s, size_t __alignment) /* TODO test */ +static inline wchar_t *libsimple_ealigned_wcsdup(const wchar_t *__s, size_t __alignment) { return libsimple_enaligned_wcsdup(libsimple_default_failure_exit, __s, __alignment); } #ifndef ealigned_wcsdup # define ealigned_wcsdup libsimple_ealigned_wcsdup diff --git a/libsimple/aligned_wcsndup.h b/libsimple/aligned_wcsndup.h index 5f3f1e4..015d1dc 100644 --- a/libsimple/aligned_wcsndup.h +++ b/libsimple/aligned_wcsndup.h @@ -10,7 +10,7 @@ * @return :wchar_t * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_aligned_wcsndupa(s, alignment, n) /* TODO test */\ +# define libsimple_aligned_wcsndupa(s, alignment, n)\ ({\ const wchar_t *__s = (s);\ size_t __n = wcsnlen(__s, n);\ @@ -72,7 +72,7 @@ wchar_t *libsimple_enaligned_wcsndup(int, const wchar_t *, size_t, size_t); * @return Duplicate of `s` */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __nonnull__, __warn_unused_result__, __returns_nonnull__))) -static inline wchar_t *libsimple_ealigned_wcsndup(const wchar_t *__s, size_t __alignment, size_t __n) /* TODO test */ +static inline wchar_t *libsimple_ealigned_wcsndup(const wchar_t *__s, size_t __alignment, size_t __n) { return libsimple_enaligned_wcsndup(libsimple_default_failure_exit, __s, __alignment, __n); } #ifndef ealigned_wcsndup # define ealigned_wcsndup libsimple_ealigned_wcsndup diff --git a/libsimple/aligned_wmemdup.h b/libsimple/aligned_wmemdup.h index bac1d0a..63a9d40 100644 --- a/libsimple/aligned_wmemdup.h +++ b/libsimple/aligned_wmemdup.h @@ -10,14 +10,14 @@ * @return :wchar_t * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_aligned_wmemdupa(s, alignment, n) /* TODO test */\ +# define libsimple_aligned_wmemdupa(s, alignment, n)\ ({\ const wchar_t *__s = (s);\ size_t __n = (n);\ size_t __a = (alignment);\ size_t __size;\ uintptr_t __misalignment;\ - char *__r;\ + wchar_t *__r;\ __a += !__a;\ __size = __n * sizeof(wchar_t) + (__a - 1);\ __r = alloca(__size + !__size);\ @@ -72,7 +72,7 @@ wchar_t *libsimple_enaligned_wmemdup(int, const wchar_t *, size_t, size_t); * @return Duplicate of `s` */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __alloc_size__(3), __warn_unused_result__, __returns_nonnull__))) -static inline wchar_t *libsimple_ealigned_wmemdup(const wchar_t *__s, size_t __alignment, size_t __n) /* TODO test */ +static inline wchar_t *libsimple_ealigned_wmemdup(const wchar_t *__s, size_t __alignment, size_t __n) { return libsimple_enaligned_wmemdup(libsimple_default_failure_exit, __s, __alignment, __n); } #ifndef ealigned_wmemdup # define ealigned_wmemdup libsimple_ealigned_wmemdup diff --git a/libsimple/realloc.h b/libsimple/realloc.h index f976556..b02c08a 100644 --- a/libsimple/realloc.h +++ b/libsimple/realloc.h @@ -347,7 +347,7 @@ libsimple_reallocf(void *__ptr, size_t __n) /* TODO test */ */ _LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_size__(2, 3), __warn_unused_result__))) static inline void * -libsimple_reallocarray(void *__ptr, size_t __n, size_t __m) /* TODO test */ +libsimple_reallocarray(void *__ptr, size_t __n, size_t __m) { if (LIBSIMPLE_UMUL_OVERFLOW(__n, __m, &__n, SIZE_MAX)) { errno = ENOMEM; @@ -420,7 +420,7 @@ void *libsimple_enreallocarray(int, void *, size_t, size_t); * `alignof(max_align_t)` */ _LIBSIMPLE_GCC_ONLY(__attribute__((__alloc_size__(2, 3), __warn_unused_result__, __returns_nonnull__))) -static inline void *libsimple_ereallocarray(void *__ptr, size_t __n, size_t __m) /* TODO test */ +static inline void *libsimple_ereallocarray(void *__ptr, size_t __n, size_t __m) { return libsimple_enreallocarray(libsimple_default_failure_exit, __ptr, __n, __m); } #ifndef ereallocarray # define ereallocarray libsimple_ereallocarray diff --git a/libsimple/wcsndup.h b/libsimple/wcsndup.h index 664294d..31e9118 100644 --- a/libsimple/wcsndup.h +++ b/libsimple/wcsndup.h @@ -9,7 +9,7 @@ * @return :wchar_t * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_wcsndupa(s, n) /* TODO test */\ +# define libsimple_wcsndupa(s, n)\ ({\ const wchar_t *__s = (s);\ size_t __n = wcsnlen(__s, n);\ @@ -33,7 +33,7 @@ * @return Duplicate of `s` */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, _libsimple_assume_aligned_as(wchar_t), __nonnull__, - __warn_unused_result__, __returns_nonnull__))) + __warn_unused_result__))) wchar_t *libsimple_wcsndup(const wchar_t *, size_t); #ifndef wcsndup # define wcsndup libsimple_wcsndup @@ -65,7 +65,7 @@ wchar_t *libsimple_enwcsndup(int, const wchar_t *, size_t); */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, _libsimple_assume_aligned_as(wchar_t), __nonnull__, __warn_unused_result__, __returns_nonnull__))) -static inline wchar_t *libsimple_ewcsndup(const wchar_t *__s, size_t __n) /* TODO test */ +static inline wchar_t *libsimple_ewcsndup(const wchar_t *__s, size_t __n) { return libsimple_enwcsndup(libsimple_default_failure_exit, __s, __n); } #ifndef ewcsndup # define ewcsndup libsimple_ewcsndup diff --git a/libsimple/wmemdup.h b/libsimple/wmemdup.h index 85bfea4..2c1f899 100644 --- a/libsimple/wmemdup.h +++ b/libsimple/wmemdup.h @@ -9,7 +9,7 @@ * @return :wchar_t * Duplicate of `s` with automatic storage */ #if defined(__GNUC__) || defined(__clang__) -# define libsimple_wmemdupa(s, n) /* TODO test */\ +# define libsimple_wmemdupa(s, n)\ ({\ const wchar_t *__s = (s);\ size_t __n = (n);\ @@ -61,7 +61,7 @@ wchar_t *libsimple_enwmemdup(int, const wchar_t *, size_t); */ _LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, _libsimple_assume_aligned_as(wchar_t), __alloc_size__(2), __warn_unused_result__, __returns_nonnull__))) -static inline wchar_t *libsimple_ewmemdup(const wchar_t *__s, size_t __n) /* TODO test */ +static inline wchar_t *libsimple_ewmemdup(const wchar_t *__s, size_t __n) { return libsimple_enwmemdup(libsimple_default_failure_exit, __s, __n); } #ifndef ewmemdup # define ewmemdup libsimple_ewmemdup diff --git a/test.c b/test.c index 01100e8..5297987 100644 --- a/test.c +++ b/test.c @@ -229,11 +229,13 @@ strndup(const char *s, size_t n) } +#if 0 void * memdup(const void *s, size_t size) { return libsimple_memdup(s, size); } +#endif wchar_t * @@ -250,6 +252,7 @@ wcsdup(const wchar_t *s) } +#if 0 wchar_t * wcsndup(const wchar_t *s, size_t n) { @@ -262,6 +265,7 @@ wmemdup(const wchar_t *s, size_t n) { return libsimple_wmemdup(s, n); } +#endif void diff --git a/test.h b/test.h index fe229ef..d8ac2d4 100644 --- a/test.h +++ b/test.h @@ -95,3 +95,42 @@ test_fprintf(FILE *restrict stream, const char *restrict format, ...) return test_vfprintf(stream, format, ap); va_end(ap); } + + + +static size_t +gcd(size_t u, size_t v) +{ + size_t t; + int shift = 0; + /* Not needed because u>0, v>0: if (!(u | v)) return u + v; */ + while (!((u | v) & 1)) u >>= 1, v >>= 1, shift++; + while (!(u & 1)) u >>= 1; + do { + while (!(v & 1)) v >>= 1; + if (u > v) t = u, u = v, v = t; + } while (v -= u); + return u << shift; +} + +static inline size_t +lcm(size_t u, size_t v) +{ + return u / gcd(u, v) * v; +} + +#define ASSERT_ALIGNMENT(INFO, ALIGN)\ + do {\ + assert((INFO)->alignment <= lcm(cacheline, ALIGN));\ + assert(!((INFO)->alignment % (ALIGN)));\ + if ((cacheline - (ALIGN) % cacheline) % cacheline + (INFO)->size % (ALIGN) > cacheline)\ + assert(!((INFO)->alignment % cacheline));\ + } while (0) + +#define DEFINE_PAGESIZE size_t pagesize = (size_t)sysconf(_SC_PAGESIZE) + +#ifdef _SC_LEVEL1_DCACHE_LINESIZ +#define DEFINE_CACHELINE size_t cacheline = (size_t)sysconf(_SC_LEVEL1_DCACHE_LINESIZE) +#else +#define DEFINE_CACHELINE size_t cacheline = 64 +#endif diff --git a/wcsndup.c b/wcsndup.c index 5b8f7cc..5621084 100644 --- a/wcsndup.c +++ b/wcsndup.c @@ -4,15 +4,12 @@ wchar_t * -libsimple_wcsndup(const wchar_t *s, size_t n) /* TODO test */ +libsimple_wcsndup(const wchar_t *s, size_t n) { size_t size; wchar_t *ret; n = wcsnlen(s, n); - if (LIBSIMPLE_UMUL_OVERFLOW_NONZERO(n + 1, sizeof(wchar_t), &size, SIZE_MAX)) { - errno = ENOMEM; - return NULL; - } + size = (n + 1) * sizeof(wchar_t); ret = aligned_alloc(_Alignof(wchar_t), size); if (!ret) return NULL; @@ -28,6 +25,81 @@ libsimple_wcsndup(const wchar_t *s, size_t n) /* TODO test */ int main(void) { + struct allocinfo *info; + const wchar_t *s = L"test"; + wchar_t *p; + + p = libsimple_wcsndup(s, SIZE_MAX); + assert(p); + assert(p != s); + assert(!((uintptr_t)s % _Alignof(wchar_t))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(p))); + assert(info->size == 5 * sizeof(wchar_t)); + assert(info->alignment == _Alignof(wchar_t)); + } + assert(!wmemcmp(p, s, 5)); + wmemset(p, 0, 5); + assert(!wmemcmp(s, L"test", 5)); + free(p); + + p = libsimple_wcsndup(s, 10); + assert(p); + assert(p != s); + assert(!((uintptr_t)s % _Alignof(wchar_t))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(p))); + assert(info->size == 5 * sizeof(wchar_t)); + assert(info->alignment == _Alignof(wchar_t)); + } + assert(!wmemcmp(p, s, 5)); + wmemset(p, 0, 5); + assert(!wmemcmp(s, L"test", 5)); + free(p); + + p = libsimple_wcsndup(s, 5); + assert(p); + assert(p != s); + assert(!((uintptr_t)s % _Alignof(wchar_t))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(p))); + assert(info->size == 5 * sizeof(wchar_t)); + assert(info->alignment == _Alignof(wchar_t)); + } + assert(!wmemcmp(p, s, 5)); + wmemset(p, 0, 5); + assert(!wmemcmp(s, L"test", 5)); + free(p); + + p = libsimple_wcsndup(s, 4); + assert(p); + assert(p != s); + assert(!((uintptr_t)s % _Alignof(wchar_t))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(p))); + assert(info->size == 5 * sizeof(wchar_t)); + assert(info->alignment == _Alignof(wchar_t)); + } + assert(!wmemcmp(p, s, 5)); + wmemset(p, 0, 5); + assert(!wmemcmp(s, L"test", 5)); + free(p); + + p = libsimple_wcsndup(s, 2); + assert(p); + assert(p != s); + assert(!((uintptr_t)s % _Alignof(wchar_t))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(p))); + assert(info->size == 3 * sizeof(wchar_t)); + assert(info->alignment == _Alignof(wchar_t)); + } + assert(!wmemcmp(p, s, 2)); + assert(!p[2]); + wmemset(p, 0, 3); + assert(!wmemcmp(s, L"test", 5)); + free(p); + return 0; } diff --git a/wmemdup.c b/wmemdup.c index 239ae7d..2e9cc1c 100644 --- a/wmemdup.c +++ b/wmemdup.c @@ -4,7 +4,7 @@ wchar_t * -libsimple_wmemdup(const wchar_t *s, size_t n) /* TODO test */ +libsimple_wmemdup(const wchar_t *s, size_t n) { wchar_t *ret; size_t size; @@ -25,6 +25,27 @@ libsimple_wmemdup(const wchar_t *s, size_t n) /* TODO test */ int main(void) { + struct allocinfo *info; + const wchar_t *s = L"test"; + wchar_t *p; + + p = libsimple_wmemdup(s, 5); + assert(p); + assert(p != s); + assert(!((uintptr_t)s % _Alignof(wchar_t))); + if (have_custom_malloc()) { + assert((info = get_allocinfo(p))); + assert(info->size == 5 * sizeof(wchar_t)); + assert(info->alignment == _Alignof(wchar_t)); + } + assert(!wmemcmp(p, s, 5)); + wmemset(p, 0, 5); + assert(!wmemcmp(s, L"test", 5)); + free(p); + + errno = 0; + assert(!libsimple_wmemdup(NULL, SSIZE_MAX) && errno == ENOMEM); + return 0; } -- cgit v1.2.3-70-g09d2