aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile9
-rw-r--r--README4
-rw-r--r--aligned_wcsndup.c4
-rw-r--r--aligned_wmemdup.c2
-rw-r--r--allocn.c12
-rw-r--r--enaligned_realloc.c25
-rw-r--r--enaligned_reallocarray.c25
-rw-r--r--enrealloc.c2
-rw-r--r--enreallocarray.c25
-rw-r--r--envaligned_reallocn.c25
-rw-r--r--enwcsndup.c2
-rw-r--r--enwmemdup.c2
-rw-r--r--libsimple-arg.h30
-rw-r--r--libsimple.h97
-rw-r--r--libsimple/aligned_realloc.h655
-rw-r--r--libsimple/aligned_strdup.h8
-rw-r--r--libsimple/aligned_strndup.h8
-rw-r--r--libsimple/aligned_wcsdup.h8
-rw-r--r--libsimple/aligned_wcsndup.h8
-rw-r--r--libsimple/aligned_wmemdup.h14
-rw-r--r--libsimple/realloc.h260
-rw-r--r--libsimple/wcsdup.h12
-rw-r--r--libsimple/wcsndup.h17
-rw-r--r--libsimple/wmemdup.h16
-rw-r--r--man0/libsimple.h.0245
l---------man3/aligned_realloc.3libsimple1
l---------man3/aligned_reallocarray.3libsimple1
l---------man3/aligned_reallocarrayf.3libsimple1
l---------man3/aligned_reallocf.3libsimple1
l---------man3/aligned_reallocfn.3libsimple1
l---------man3/aligned_reallocn.3libsimple1
l---------man3/aligned_strdup.3libsimple1
l---------man3/aligned_strdupa.3libsimple1
l---------man3/aligned_strndup.3libsimple1
l---------man3/aligned_strndupa.3libsimple1
l---------man3/aligned_wcsdup.3libsimple1
l---------man3/aligned_wcsdupa.3libsimple1
l---------man3/aligned_wcsndup.3libsimple1
l---------man3/aligned_wcsndupa.3libsimple1
l---------man3/aligned_wmemdup.3libsimple1
l---------man3/aligned_wmemdupa.3libsimple1
l---------man3/ealigned_realloc.3libsimple1
l---------man3/ealigned_reallocarray.3libsimple1
l---------man3/ealigned_reallocn.3libsimple1
l---------man3/ealigned_strdup.3libsimple1
l---------man3/ealigned_strndup.3libsimple1
l---------man3/ealigned_wcsdup.3libsimple1
l---------man3/ealigned_wcsndup.3libsimple1
l---------man3/ealigned_wmemdup.3libsimple1
l---------man3/enaligned_realloc.3libsimple1
l---------man3/enaligned_reallocarray.3libsimple1
l---------man3/enaligned_reallocn.3libsimple1
l---------man3/enaligned_strdup.3libsimple1
l---------man3/enaligned_strndup.3libsimple1
l---------man3/enaligned_wcsdup.3libsimple1
l---------man3/enaligned_wcsndup.3libsimple1
l---------man3/enaligned_wmemdup.3libsimple1
l---------man3/enreallocarray.3libsimple1
l---------man3/envaligned_reallocn.3libsimple1
l---------man3/enwcsdup.3libsimple1
l---------man3/enwcsndup.3libsimple1
l---------man3/enwmemdup.3libsimple1
l---------man3/ereallocarray.3libsimple1
l---------man3/evaligned_reallocn.3libsimple1
l---------man3/ewcsdup.3libsimple1
l---------man3/ewcsndup.3libsimple1
l---------man3/ewmemdup.3libsimple1
-rw-r--r--man3/libsimple_aligned_allocz.310
-rw-r--r--man3/libsimple_aligned_memdup.311
-rw-r--r--man3/libsimple_aligned_realloc.3200
-rw-r--r--man3/libsimple_aligned_reallocarray.3202
-rw-r--r--man3/libsimple_aligned_reallocarrayf.3154
-rw-r--r--man3/libsimple_aligned_reallocf.3152
l---------man3/libsimple_aligned_reallocfn.31
l---------man3/libsimple_aligned_reallocn.31
-rw-r--r--man3/libsimple_aligned_strdup.3151
l---------man3/libsimple_aligned_strdupa.31
-rw-r--r--man3/libsimple_aligned_strndup.3154
l---------man3/libsimple_aligned_strndupa.31
-rw-r--r--man3/libsimple_aligned_wcsdup.3151
l---------man3/libsimple_aligned_wcsdupa.31
-rw-r--r--man3/libsimple_aligned_wcsndup.3156
l---------man3/libsimple_aligned_wcsndupa.31
-rw-r--r--man3/libsimple_aligned_wmemdup.3155
l---------man3/libsimple_aligned_wmemdupa.31
l---------man3/libsimple_ealigned_realloc.31
l---------man3/libsimple_ealigned_reallocarray.31
l---------man3/libsimple_ealigned_reallocn.31
l---------man3/libsimple_ealigned_strdup.31
l---------man3/libsimple_ealigned_strndup.31
l---------man3/libsimple_ealigned_wcsdup.31
l---------man3/libsimple_ealigned_wcsndup.31
l---------man3/libsimple_ealigned_wmemdup.31
-rw-r--r--man3/libsimple_enaligned_alloc.310
l---------man3/libsimple_enaligned_realloc.31
l---------man3/libsimple_enaligned_reallocarray.31
l---------man3/libsimple_enaligned_reallocn.31
l---------man3/libsimple_enaligned_strdup.31
l---------man3/libsimple_enaligned_strndup.31
l---------man3/libsimple_enaligned_wcsdup.31
l---------man3/libsimple_enaligned_wcsndup.31
l---------man3/libsimple_enaligned_wmemdup.31
-rw-r--r--man3/libsimple_encalloc.310
-rw-r--r--man3/libsimple_enmalloc.310
-rw-r--r--man3/libsimple_enposix_memalign.310
-rw-r--r--man3/libsimple_enrealloc.310
l---------man3/libsimple_enreallocarray.31
-rw-r--r--man3/libsimple_enstrdup.38
-rw-r--r--man3/libsimple_enstrndup.38
l---------man3/libsimple_envaligned_reallocn.31
-rw-r--r--man3/libsimple_enwcsdup.3124
l---------man3/libsimple_enwcsndup.31
l---------man3/libsimple_enwmemdup.31
l---------man3/libsimple_ereallocarray.31
l---------man3/libsimple_evaligned_reallocn.31
l---------man3/libsimple_ewcsdup.31
l---------man3/libsimple_ewcsndup.31
l---------man3/libsimple_ewmemdup.31
-rw-r--r--man3/libsimple_mallocz.310
-rw-r--r--man3/libsimple_memalign.310
-rw-r--r--man3/libsimple_memalignz.310
-rw-r--r--man3/libsimple_memdup.310
-rw-r--r--man3/libsimple_posix_memalignz.310
-rw-r--r--man3/libsimple_pvalloc.310
-rw-r--r--man3/libsimple_pvallocz.310
-rw-r--r--man3/libsimple_reallocarray.3191
-rw-r--r--man3/libsimple_reallocarrayf.3143
-rw-r--r--man3/libsimple_reallocf.3141
l---------man3/libsimple_reallocfn.31
-rw-r--r--man3/libsimple_valigned_allocn.310
-rw-r--r--man3/libsimple_valigned_alloczn.310
-rw-r--r--man3/libsimple_valigned_reallocfn.3177
-rw-r--r--man3/libsimple_valigned_reallocn.3267
-rw-r--r--man3/libsimple_valloc.310
-rw-r--r--man3/libsimple_vallocz.310
-rw-r--r--man3/libsimple_varrayalloc.310
-rw-r--r--man3/libsimple_vcallocn.310
-rw-r--r--man3/libsimple_vmallocn.310
-rw-r--r--man3/libsimple_vmalloczn.310
-rw-r--r--man3/libsimple_vmemalignn.310
-rw-r--r--man3/libsimple_vmemalignzn.310
-rw-r--r--man3/libsimple_vmemalloc.310
-rw-r--r--man3/libsimple_vposix_memalignn.310
-rw-r--r--man3/libsimple_vposix_memalignzn.310
-rw-r--r--man3/libsimple_vpvallocn.310
-rw-r--r--man3/libsimple_vpvalloczn.310
-rw-r--r--man3/libsimple_vreallocfn.3166
-rw-r--r--man3/libsimple_vreallocn.317
-rw-r--r--man3/libsimple_vvallocn.310
-rw-r--r--man3/libsimple_vvalloczn.310
l---------man3/libsimple_wcsdupa.31
-rw-r--r--man3/libsimple_wcsndup.3155
l---------man3/libsimple_wcsndupa.31
-rw-r--r--man3/libsimple_wmemdup.3155
l---------man3/libsimple_wmemdupa.31
l---------man3/reallocarray.3libsimple1
l---------man3/reallocarrayf.3libsimple1
l---------man3/reallocf.3libsimple1
l---------man3/reallocfn.3libsimple1
l---------man3/valigned_reallocfn.3libsimple1
l---------man3/valigned_reallocn.3libsimple1
l---------man3/vreallocfn.3libsimple1
l---------man3/wcsdupa.3libsimple1
l---------man3/wcsndup.3libsimple1
l---------man3/wcsndupa.3libsimple1
l---------man3/wmemdup.3libsimple1
l---------man3/wmemdupa.3libsimple1
-rw-r--r--wcsndup.c7
168 files changed, 4861 insertions, 89 deletions
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 <strings.h>, the naming scheme of these functions is:
= wcsn for wide-character strings that may not be NUL-terminated
= wmem for wide-character arrays
- <str> = str if <base> is str, wsc, strn, or wscn
+ <str> = str if <base> is str, wcs, strn, or wcsn
= mem if <base> is mem or wmem
- <scan> = chrnul if <base> is str, wsc, strn, or wscn
+ <scan> = chrnul if <base> is str, wcs, strn, or wcsn
= scan if <base> 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 <wctype.h>
+
#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 <malloc.h>
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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 <libsimple.h>
+
+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;