aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libsimple.h50
-rw-r--r--libsimple/aligned_alloc.h151
-rw-r--r--libsimple/aligned_allocz.h179
-rw-r--r--libsimple/definitions.h83
-rw-r--r--libsimple/memalign.h169
-rw-r--r--libsimple/memalignz.h178
-rw-r--r--libsimple/posix_memalign.h181
-rw-r--r--libsimple/posix_memalignz.h209
-rw-r--r--libsimple/printf.h181
-rw-r--r--libsimple/pvalloc.h191
-rw-r--r--libsimple/pvallocz.h202
-rw-r--r--libsimple/valloc.h154
-rw-r--r--libsimple/vallocz.h165
-rw-r--r--man/libsimple_aligned_memdup.34
-rw-r--r--man/libsimple_enstrdup.34
-rw-r--r--man/libsimple_enstrndup.34
-rw-r--r--man/libsimple_memdup.34
-rw-r--r--vweprintf.c4
18 files changed, 2068 insertions, 45 deletions
diff --git a/libsimple.h b/libsimple.h
index 96cd73c..8020926 100644
--- a/libsimple.h
+++ b/libsimple.h
@@ -47,6 +47,11 @@
#endif
+/**
+ * Exit value for `libsimple_eprintf`
+ *
+ * Default value is 1
+ */
extern int libsimple_default_failure_exit;
@@ -82,6 +87,17 @@ extern int libsimple_default_failure_exit;
#define CLOSE(FD) libsimple_close(&(FD))
+
+/**
+ * Wrapper for close(3) that only calls close(3)
+ * if the file descriptor number is non-negative,
+ * and that will set it to -1 after closing
+ *
+ * @param fdp Pointer to file descriptor number, will
+ * be update to -1 if it is non-negative
+ * @return Return value of close(3) (0 on success,
+ * -1 on error), 0 if `*fdp < 0`
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
static inline int
libsimple_close(int *__fdp)
@@ -94,6 +110,15 @@ libsimple_close(int *__fdp)
return __ret;
}
+
+/**
+ * Check whether a byte is in a string of bytes
+ *
+ * @param c The byte to look for, will not be found if it is the NUL byte
+ * @param s The string to look in
+ * @return 1 if the byte `c` is not the NUL byte and can be found in `s`,
+ * 0 otherwise
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
static inline int libsimple_inchrset(int __c, const char *__s)
{ return __c && strchr(__s, __c); }
@@ -101,11 +126,13 @@ static inline int libsimple_inchrset(int __c, const char *__s)
# define inchrset libsimple_inchrset
#endif
+
/**
* Check whether a NUL-terminated string is encoded in UTF-8
*
* @param string The string
- * @param allow_modified_nul Whether Modified UTF-8 is allowed, which allows a two-byte encoding for NUL
+ * @param allow_modified_nul Whether Modified UTF-8 is allowed, which
+ * allows a two-byte encoding for NUL
* @return 1 if good, 0 on encoding error
*/
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
@@ -114,11 +141,32 @@ int libsimple_isutf8(const char *, int);
# define isutf8 libsimple_isutf8
#endif
+
+/**
+ * Remove an item from a list, keeping the list ordered
+ *
+ * `list` must be non-void pointer to a complete type,
+ * the type of the pointer will be used to infer the
+ * width of the items in the list
+ *
+ * @param list:non-void pointer The list
+ * @param i:size_t The index of the item to remove
+ * @param n:size_t Pointer to the number of items in the list, will be updated
+ */
#define LIBSIMPLE_UNLIST(LIST, I, NP) libsimple_unlist((LIST), (I), (NP), sizeof(*(LIST)))
#ifndef UNLIST
# define UNLIST(LIST, I, NP) LIBSIMPLE_UNLIST((LIST), (I), (NP))
#endif
+
+/**
+ * Remove an item from a list, keeping the list ordered
+ *
+ * @param list The list
+ * @param i The index of the item to remove
+ * @param n Pointer to the number of items in the list, will be updated
+ * @param width The width, in bytes, of each item in the list
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
static inline void
libsimple_unlist(void *__list, size_t __i, size_t *__np, size_t __width)
diff --git a/libsimple/aligned_alloc.h b/libsimple/aligned_alloc.h
index 6155c7d..b2a60f1 100644
--- a/libsimple/aligned_alloc.h
+++ b/libsimple/aligned_alloc.h
@@ -1,10 +1,24 @@
/* See LICENSE file for copyright and license details. */
-/*
- * Alignment must be a power of 2.
- * Allocation size must be a mutiple of the alignment.
- */
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `alignment`,
+ * up to the first 0, will be used as the number of
+ * bytes to allocated
+ *
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0 or `alignment` is not a power of 2
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(1), __warn_unused_result__)))
static inline void *libsimple_valigned_allocn(size_t __alignment, size_t __n, va_list __ap)
{ return libsimple_valigned_alloczn(0, __alignment, __n, __ap); }
@@ -12,6 +26,18 @@ static inline void *libsimple_valigned_allocn(size_t __alignment, size_t __n, va
# define valigned_allocn libsimple_valigned_allocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * @param alignment The alignment, must be a power of 2
+ * @param n The number of bytes to allocate
+ * @return A unique pointer with at least the specified size
+ * and alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0 or `alignment` is not a power of 2
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(1), __warn_unused_result__)))
static inline void *
libsimple_aligned_allocn(size_t __alignment, size_t __n, ... /*, (size_t)0 */)
@@ -25,6 +51,22 @@ libsimple_aligned_allocn(size_t __alignment, size_t __n, ... /*, (size_t)0 */)
# define aligned_allocn libsimple_aligned_allocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param alignment The alignment, must be a power of 2
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __alloc_size__(3), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_enaligned_alloc(int __status, size_t __alignment, size_t __n)
{ return libsimple_enaligned_allocz(__status, 0, __alignment, __n); }
@@ -32,6 +74,28 @@ static inline void *libsimple_enaligned_alloc(int __status, size_t __alignment,
# define enaligned_alloc libsimple_enaligned_alloc
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `status` and
+ * `alignment`, up to the first 0, will be used as the
+ * number of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_envaligned_allocn(int __status, size_t __alignment, size_t __n, va_list __ap)
{ return libsimple_envaligned_alloczn(__status, 0, __alignment, __n, __ap); }
@@ -39,6 +103,28 @@ static inline void *libsimple_envaligned_allocn(int __status, size_t __alignment
# define envaligned_allocn libsimple_envaligned_allocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `status` and
+ * `alignment`, up to the first 0, will be used as the
+ * number of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_enaligned_allocn(int __status, size_t __alignment, size_t __n, ... /*, (size_t)0 */)
@@ -52,6 +138,21 @@ libsimple_enaligned_allocn(int __status, size_t __alignment, size_t __n, ... /*,
# define enaligned_allocn libsimple_enaligned_allocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param alignment The alignment, must be a power of 2
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(1), __alloc_size__(2), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_ealigned_alloc(size_t __alignment, size_t __n)
{ return libsimple_enaligned_alloc(libsimple_default_failure_exit, __alignment, __n); }
@@ -59,6 +160,27 @@ static inline void *libsimple_ealigned_alloc(size_t __alignment, size_t __n)
# define ealigned_alloc libsimple_ealigned_alloc
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `alignment`,
+ * up to the first 0, will be used as the number of
+ * bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(1), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_evaligned_allocn(size_t __alignment, size_t __n, va_list __ap)
{ return libsimple_envaligned_allocn(libsimple_default_failure_exit, __alignment, __n, __ap); }
@@ -66,6 +188,27 @@ static inline void *libsimple_evaligned_allocn(size_t __alignment, size_t __n, v
# define evaligned_allocn libsimple_evaligned_allocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `alignment`,
+ * up to the first 0, will be used as the number of
+ * bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(1), __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_ealigned_allocn(size_t __alignment, size_t __n, ... /*, (size_t)0 */)
diff --git a/libsimple/aligned_allocz.h b/libsimple/aligned_allocz.h
index 1c81697..9380a50 100644
--- a/libsimple/aligned_allocz.h
+++ b/libsimple/aligned_allocz.h
@@ -1,16 +1,45 @@
/* See LICENSE file for copyright and license details. */
-/*
- * Alignment must be a power of 2.
- * Allocation size must be a mutiple of the alignment.
- */
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `clear` and
+ * `alignment`, up to the first 0, will be used as
+ * the number of bytes to allocated
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0 or `alignment` is not a power of 2
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __warn_unused_result__)))
void *libsimple_valigned_alloczn(int, size_t, size_t, va_list);
#ifndef valigned_alloczn
# define valigned_alloczn libsimple_valigned_alloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size
+ * and alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0 or `alignment` is not a power of 2
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __alloc_size__(3), __warn_unused_result__)))
static inline void *
libsimple_aligned_allocz(int __clear, size_t __alignment, size_t __n)
@@ -24,6 +53,26 @@ libsimple_aligned_allocz(int __clear, size_t __alignment, size_t __n)
# define aligned_allocz libsimple_aligned_allocz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `clear` and
+ * `alignment`, up to the first 0, will be used as
+ * the number of bytes to allocated
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0 or `alignment` is not a power of 2
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __warn_unused_result__)))
static inline void *
libsimple_aligned_alloczn(int __clear, size_t __alignment, size_t __n, ... /*, (size_t)0 */)
@@ -37,18 +86,81 @@ libsimple_aligned_alloczn(int __clear, size_t __alignment, size_t __n, ... /*, (
# define aligned_alloczn libsimple_aligned_alloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(3), __alloc_size__(4), __warn_unused_result__, __returns_nonnull__)))
void *libsimple_enaligned_allocz(int, int, size_t, size_t);
#ifndef enaligned_allocz
# define enaligned_allocz libsimple_enaligned_allocz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `status`,
+ * `clear`, and `alignment`, up to the first 0,
+ * will be used as the number of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(3), __warn_unused_result__, __returns_nonnull__)))
void *libsimple_envaligned_alloczn(int, int, size_t, size_t, va_list);
#ifndef envaligned_alloczn
# define envaligned_alloczn libsimple_envaligned_alloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `status`,
+ * `clear`, and `alignment`, up to the first 0,
+ * will be used as the number of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(3), __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_enaligned_alloczn(int __status, int __clear, size_t __alignment, size_t __n, ... /*, (size_t)0 */)
@@ -62,6 +174,21 @@ libsimple_enaligned_alloczn(int __status, int __clear, size_t __alignment, size_
# define enaligned_alloczn libsimple_enaligned_alloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param alignment The alignment, must be a power of 2
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __alloc_size__(3), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_ealigned_allocz(int __clear, size_t __alignment, size_t __n)
{ return libsimple_enaligned_allocz(libsimple_default_failure_exit, __clear, __alignment, __n); }
@@ -69,6 +196,28 @@ static inline void *libsimple_ealigned_allocz(int __clear, size_t __alignment, s
# define ealigned_allocz libsimple_ealigned_allocz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `clear` and
+ * `alignment`, up to the first 0, will be used as
+ * the number of bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_evaligned_alloczn(int __clear, size_t __alignment, size_t __n, va_list __ap)
{ return libsimple_envaligned_alloczn(libsimple_default_failure_exit, __clear, __alignment, __n, __ap); }
@@ -76,6 +225,28 @@ static inline void *libsimple_evaligned_alloczn(int __clear, size_t __alignment,
# define evaligned_alloczn libsimple_evaligned_alloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `clear` and
+ * `alignment`, up to the first 0, will be used as
+ * the number of bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_ealigned_alloczn(int __clear, size_t __alignment, size_t __n, ... /*, (size_t)0 */)
diff --git a/libsimple/definitions.h b/libsimple/definitions.h
index 9bbc649..0ff2677 100644
--- a/libsimple/definitions.h
+++ b/libsimple/definitions.h
@@ -108,45 +108,126 @@
#endif
+/**
+ * Get the smallest of two numerical values
+ *
+ * @param A One of the values
+ * @param B The other value
+ * @return The smallest of `A` and `B`
+ */
#ifndef MIN
# define MIN(A, B) ((A) < (B) ? (A) : (B))
#endif
+
+/**
+ * Get the largest of two numerical values
+ *
+ * @param A One of the values
+ * @param B The other value
+ * @return The largest of `A` and `B`
+ */
#ifndef MAX
# define MAX(A, B) ((A) > (B) ? (A) : (B))
#endif
+
+/**
+ * Get the smallest of three numerical values
+ *
+ * @param A One of the values
+ * @param B Another one of the values
+ * @param C The last value
+ * @return The smallest of `A`, `B`, and `C`
+ */
#ifndef MIN3
# define MIN3(A, B, C) MIN(MIN((A), (B)), (C))
#endif
+
+/**
+ * Get the largest of three numerical values
+ *
+ * @param A One of the values
+ * @param B Another one of the values
+ * @param C The last value
+ * @return The largest of `A`, `B`, and `C`
+ */
#ifndef MAX3
# define MAX3(A, B, C) MAX(MAX((A), (B)), (C))
#endif
+/**
+ * Get the number of elements in an array
+ *
+ * @param ARR The array, must not be a pointer
+ * @return :size_t The number of elements in `ARR` (constant
+ * expression, unless its size is dynamic)
+ */
#ifndef ELEMSOF
# define ELEMSOF(ARR) (sizeof(ARR) / (sizeof(*(ARR))))
#endif
+
+/**
+ * Get the length of a string literal
+ *
+ * This macro does not support the wide-character strings
+ *
+ * @param STR:const char [] The string, must be a literal
+ * @return :size_t The value of `strlen(STR)` as a constant expression
+ */
#ifndef STRLEN
# define STRLEN(STR) (sizeof(STR) - 1)
#endif
+
+/**
+ * Get an approximation for the longest string an
+ * integer of the specific integer type can be
+ * converted to assuming it will not having an
+ * explicit '+' sign or any leading zeroes or
+ * other superfluous characters
+ *
+ * The calculated approximation will not be less
+ * than the real limit
+ *
+ * @param TYPE:integer type The type, must be an integer type, may be signed or unsigned
+ * @return :size_t A value close to, but not less than, the longest string a
+ * value of the type `TYPE` can be converted to without any
+ * superfluous characters (such as explitict '+' or leading zeroes')
+ * (constant expression)
+ */
#ifndef INTSTRLEN
# define INTSTRLEN(TYPE) ((sizeof(TYPE) == 1 ? 3 : 5 * (sizeof(TYPE) / 2)) + ((TYPE)-1 < 0))
#endif
+/**
+ * Get the maximum value for an integer type
+ *
+ * @param TYPE:integer type The type, must be an integer type, may be signed or unsigned
+ * @return :TYPE The largest value that can be stored in `TYPE` (constant expression)
+ */
#ifndef TYPE_MAX
# define TYPE_MAX(TYPE) ((TYPE)(((1ULL << (8 * sizeof(TYPE) - 1)) - 1) << ((TYPE)-1 > 0) | 1))
#endif
+
+/**
+ * Get the minimum value for an integer type
+ *
+ * @param TYPE:integer type The type, must be an integer type, may be signed or unsigned
+ * @return :TYPE The smallest value that can be stored in `TYPE` (constant expression)
+ */
#ifndef TYPE_MIN
# define TYPE_MIN(TYPE) ((TYPE)((TYPE)-1 > 0 ? 0 : (TYPE)~0 < (TYPE)-1 ? (TYPE)~0 : (TYPE)(1ULL << (8 * sizeof(TYPE) - 1))))
#endif
+/* --- Maximum values --- */
+
#ifndef BLKCNT64_MAX
# define BLKCNT64_MAX TYPE_MAX(blkcnt64_t)
#endif
@@ -284,6 +365,8 @@
#endif
+/* --- Minimum values --- */
+
#ifndef BLKCNT64_MIN
# define BLKCNT64_MIN TYPE_MIN(blkcnt64_t)
#endif
diff --git a/libsimple/memalign.h b/libsimple/memalign.h
index 466de3e..169ec57 100644
--- a/libsimple/memalign.h
+++ b/libsimple/memalign.h
@@ -1,9 +1,24 @@
/* See LICENSE file for copyright and license details. */
-/*
- * Alignment must be a power of 2.
- */
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `alignment`,
+ * up to the first 0, will be used as the number of
+ * bytes to allocated
+ *
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0 or `alignment` is not a power of 2
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(1), __warn_unused_result__)))
static inline void *libsimple_vmemalignn(size_t __alignment, size_t __n, va_list __ap)
{ return libsimple_vmemalignzn(0, __alignment, __n, __ap); }
@@ -11,6 +26,18 @@ static inline void *libsimple_vmemalignn(size_t __alignment, size_t __n, va_list
# define vmemalignn libsimple_vmemalignn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * @param alignment The alignment, must be a power of 2
+ * @param n The number of bytes to allocate
+ * @return A unique pointer with at least the specified size
+ * and alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0 or `alignment` is not a power of 2
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(1), __alloc_size__(2), __warn_unused_result__)))
static inline void *libsimple_memalign(size_t __alignment, size_t __n)
{ return libsimple_memalignz(0, __alignment, __n); }
@@ -18,6 +45,25 @@ static inline void *libsimple_memalign(size_t __alignment, size_t __n)
# define memalign libsimple_memalign
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `alignment`,
+ * up to the first 0, will be used as the number of
+ * bytes to allocated
+ *
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0 or `alignment` is not a power of 2
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(1), __warn_unused_result__)))
static inline void *
libsimple_memalignn(size_t __alignment, size_t __n, ... /*, (size_t)0 */)
@@ -31,6 +77,22 @@ libsimple_memalignn(size_t __alignment, size_t __n, ... /*, (size_t)0 */)
# define memalignn libsimple_memalignn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param alignment The alignment, must be a power of 2
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __alloc_size__(3), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_enmemalign(int __status, size_t __alignment, size_t __n)
{ return libsimple_enmemalignz(__status, 0, __alignment, __n); }
@@ -38,6 +100,28 @@ static inline void *libsimple_enmemalign(int __status, size_t __alignment, size_
# define enmemalign libsimple_enmemalign
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `status` and
+ * `alignment`, up to the first 0, will be used as the
+ * number of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_envmemalignn(int __status, size_t __alignment, size_t __n, va_list __ap)
{ return libsimple_envmemalignzn(__status, 0, __alignment, __n, __ap); }
@@ -45,6 +129,28 @@ static inline void *libsimple_envmemalignn(int __status, size_t __alignment, siz
# define envmemalignn libsimple_envmemalignn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `status` and
+ * `alignment`, up to the first 0, will be used as the
+ * number of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_enmemalignn(int __status, size_t __alignment, size_t __n, ... /*, (size_t)0 */)
@@ -58,6 +164,21 @@ libsimple_enmemalignn(int __status, size_t __alignment, size_t __n, ... /*, (siz
# define enmemalignn libsimple_enmemalignn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param alignment The alignment, must be a power of 2
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(1), __alloc_size__(2), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_ememalign(size_t __alignment, size_t __n)
{ return libsimple_enmemalign(libsimple_default_failure_exit, __alignment, __n); }
@@ -65,6 +186,27 @@ static inline void *libsimple_ememalign(size_t __alignment, size_t __n)
# define ememalign libsimple_ememalign
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `alignment`,
+ * up to the first 0, will be used as the number of
+ * bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(1), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_evmemalignn(size_t __alignment, size_t __n, va_list __ap)
{ return libsimple_envmemalignn(libsimple_default_failure_exit, __alignment, __n, __ap); }
@@ -72,6 +214,27 @@ static inline void *libsimple_evmemalignn(size_t __alignment, size_t __n, va_lis
# define evmemalignn libsimple_evmemalignn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `alignment`,
+ * up to the first 0, will be used as the number of
+ * bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(1), __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_ememalignn(size_t __alignment, size_t __n, ... /*, (size_t)0 */)
diff --git a/libsimple/memalignz.h b/libsimple/memalignz.h
index 4b47d0e..224443b 100644
--- a/libsimple/memalignz.h
+++ b/libsimple/memalignz.h
@@ -1,9 +1,25 @@
/* See LICENSE file for copyright and license details. */
-/*
- * Alignment must be a power of 2.
- */
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `clear` and
+ * `alignment`, up to the first 0, will be used as
+ * the number of bytes to allocated
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0 or `alignment` is not a power of 2
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __warn_unused_result__)))
static inline void *
libsimple_vmemalignzn(int __clear, size_t __alignment, size_t __n, va_list __ap) /* TODO test ([v]memalign[z]n) */
@@ -21,6 +37,19 @@ libsimple_vmemalignzn(int __clear, size_t __alignment, size_t __n, va_list __ap)
# define vmemalignzn libsimple_vmemalignzn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @param n The number of bytes to allocate
+ * @return A unique pointer with at least the specified size
+ * and alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0 or `alignment` is not a power of 2
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __alloc_size__(3), __warn_unused_result__)))
static inline void *
libsimple_memalignz(int __clear, size_t __alignment, size_t __n) /* TODO test (memalign[z]) */
@@ -38,6 +67,26 @@ libsimple_memalignz(int __clear, size_t __alignment, size_t __n) /* TODO test (m
# define memalignz libsimple_memalignz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `clear` and
+ * `alignment`, up to the first 0, will be used as
+ * the number of bytes to allocated
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0 or `alignment` is not a power of 2
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __warn_unused_result__)))
static inline void *
libsimple_memalignzn(int __clear, size_t __alignment, size_t __n, ... /*, (size_t)0 */)
@@ -51,6 +100,23 @@ libsimple_memalignzn(int __clear, size_t __alignment, size_t __n, ... /*, (size_
# define memalignzn libsimple_memalignzn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(3), __alloc_size__(4), __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_enmemalignz(int __status, int __clear, size_t __alignment, size_t __n) /* TODO test (e[n]memalign[z]) */
@@ -68,6 +134,29 @@ libsimple_enmemalignz(int __status, int __clear, size_t __alignment, size_t __n)
# define enmemalignz libsimple_enmemalignz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `status`,
+ * `clear`, and `alignment`, up to the first 0,
+ * will be used as the number of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(3), __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_envmemalignzn(int __status, int __clear, size_t __alignment, size_t __n, va_list __ap) /* TODO test (e[n][v]memalign[z]n) */
@@ -86,6 +175,29 @@ libsimple_envmemalignzn(int __status, int __clear, size_t __alignment, size_t __
# define envmemalignzn libsimple_envmemalignzn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `status`,
+ * `clear`, and `alignment`, up to the first 0,
+ * will be used as the number of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(3), __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_enmemalignzn(int __status, int __clear, size_t __alignment, size_t __n, ... /*, (size_t)0 */)
@@ -99,6 +211,22 @@ libsimple_enmemalignzn(int __status, int __clear, size_t __alignment, size_t __n
# define enmemalignzn libsimple_enmemalignzn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __alloc_size__(3), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_ememalignz(int __clear, size_t __alignment, size_t __n)
{ return libsimple_enmemalignz(libsimple_default_failure_exit, __alignment, __clear, __n); }
@@ -106,6 +234,28 @@ static inline void *libsimple_ememalignz(int __clear, size_t __alignment, size_t
# define ememalignz libsimple_ememalignz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `clear` and
+ * `alignment`, up to the first 0, will be used as
+ * the number of bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_evmemalignzn(int __clear, size_t __alignment, size_t __n, va_list __ap)
{ return libsimple_envmemalignzn(libsimple_default_failure_exit, __alignment, __clear, __n, __ap); }
@@ -113,6 +263,28 @@ static inline void *libsimple_evmemalignzn(int __clear, size_t __alignment, size
# define evmemalignzn libsimple_evmemalignzn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `clear` and
+ * `alignment`, up to the first 0, will be used as
+ * the number of bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2
+ * @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 A unique pointer with at least the specified size
+ * and alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_align__(2), __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_ememalignzn(int __clear, size_t __alignment, size_t __n, ... /*, (size_t)0 */)
diff --git a/libsimple/posix_memalign.h b/libsimple/posix_memalign.h
index 5443418..f656ea8 100644
--- a/libsimple/posix_memalign.h
+++ b/libsimple/posix_memalign.h
@@ -1,9 +1,30 @@
/* See LICENSE file for copyright and license details. */
-/*
- * Alignment must be a power of 2 and a multiple of `sizeof(void *)`.
- */
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `memptr` and
+ * `alignment`, up to the first 0, will be used as the
+ * number of bytes to allocated
+ *
+ * @param memptr Output parameter for the new allocation, which
+ * will on successful completion be set to a unique
+ * pointer with at least the specified size and
+ * alignment
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @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 0 on success, the error code on failure (errno is
+ * not set)
+ * @throws EINVAL `n` is 0, `alignment` is not a power of 2, or
+ * `alignment` is not a multiple of `sizeof(void *)`
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1))))
static inline int libsimple_vposix_memalignn(void **__memptr, size_t __alignment, size_t __n, va_list __ap)
{ return libsimple_vposix_memalignzn(__memptr, 0, __alignment, __n, __ap); }
@@ -11,6 +32,31 @@ static inline int libsimple_vposix_memalignn(void **__memptr, size_t __alignment
# define vposix_memalignn libsimple_vposix_memalignn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `memptr` and
+ * `alignment`, up to the first 0, will be used as the
+ * number of bytes to allocated
+ *
+ * @param memptr Output parameter for the new allocation, which
+ * will on successful completion be set to a unique
+ * pointer with at least the specified size and
+ * alignment
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @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 0 on success, the error code on failure (errno is
+ * not set)
+ * @throws EINVAL `n` is 0, `alignment` is not a power of 2, or
+ * `alignment` is not a multiple of `sizeof(void *)`
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1))))
static inline int
libsimple_posix_memalignn(void **__memptr, size_t __alignment, size_t __n, ... /*, (size_t)0 */)
@@ -24,6 +70,24 @@ libsimple_posix_memalignn(void **__memptr, size_t __alignment, size_t __n, ... /
# define posix_memalignn libsimple_posix_memalignn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param memptr Output parameter for the new allocation, which
+ * will be set to a unique pointer with at least the
+ * specified size and alignment
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2))))
static inline void libsimple_enposix_memalign(int __status, void **__memptr, size_t __alignment, size_t __n)
{ libsimple_enposix_memalignz(__status, __memptr, 0, __alignment, __n); }
@@ -31,6 +95,30 @@ static inline void libsimple_enposix_memalign(int __status, void **__memptr, siz
# define enposix_memalign libsimple_enposix_memalign
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `status`, `memptr`,
+ * and `alignment`, up to the first 0, will be used as
+ * the number of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param memptr Output parameter for the new allocation, which
+ * will be set to a unique pointer with at least the
+ * specified size and alignment
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @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)
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2))))
static inline void libsimple_envposix_memalignn(int __status, void **__memptr, size_t __alignment, size_t __n, va_list __ap)
{ libsimple_envposix_memalignzn(__status, __memptr, 0, __alignment, __n, __ap); }
@@ -38,6 +126,30 @@ static inline void libsimple_envposix_memalignn(int __status, void **__memptr, s
# define envposix_memalignn libsimple_envposix_memalignn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `status`, `memptr`,
+ * and `alignment`, up to the first 0, will be used as
+ * the number of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param memptr Output parameter for the new allocation, which
+ * will be set to a unique pointer with at least the
+ * specified size and alignment
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @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)
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2))))
static inline void
libsimple_enposix_memalignn(int __status, void **__memptr, size_t __alignment, size_t __n, ... /*, (size_t)0 */)
@@ -51,6 +163,23 @@ libsimple_enposix_memalignn(int __status, void **__memptr, size_t __alignment, s
# define enposix_memalignn libsimple_enposix_memalignn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param memptr Output parameter for the new allocation, which
+ * will be set to a unique pointer with at least the
+ * specified size and alignment
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1))))
static inline void libsimple_eposix_memalign(void **__memptr, size_t __alignment, size_t __n)
{ libsimple_enposix_memalign(libsimple_default_failure_exit, __memptr, __alignment, __n); }
@@ -58,6 +187,29 @@ static inline void libsimple_eposix_memalign(void **__memptr, size_t __alignment
# define eposix_memalign libsimple_eposix_memalign
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `memptr` and
+ * `alignment`, up to the first 0, will be used as the
+ * number of bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param memptr Output parameter for the new allocation, which
+ * will be set to a unique pointer with at least the
+ * specified size and alignment
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @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)
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1))))
static inline void libsimple_evposix_memalignn(void **__memptr, size_t __alignment, size_t __n, va_list __ap)
{ libsimple_envposix_memalignn(libsimple_default_failure_exit, __memptr, __alignment, __n, __ap); }
@@ -65,6 +217,29 @@ static inline void libsimple_evposix_memalignn(void **__memptr, size_t __alignme
# define evposix_memalignn libsimple_evposix_memalignn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with custom alignment
+ *
+ * The product of all arguments except `memptr` and
+ * `alignment`, up to the first 0, will be used as the
+ * number of bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param memptr Output parameter for the new allocation, which
+ * will be set to a unique pointer with at least the
+ * specified size and alignment
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @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)
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1))))
static inline void
libsimple_eposix_memalignn(void **__memptr, size_t __alignment, size_t __n, ... /*, (size_t)0 */)
diff --git a/libsimple/posix_memalignz.h b/libsimple/posix_memalignz.h
index 2bbd310..323863d 100644
--- a/libsimple/posix_memalignz.h
+++ b/libsimple/posix_memalignz.h
@@ -1,15 +1,57 @@
/* See LICENSE file for copyright and license details. */
-/*
- * Alignment must be a power of 2 and a multiple of `sizeof(void *)`.
- */
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `memptr`, `clear`
+ * and `alignment`, up to the first 0, will be used as
+ * the number of bytes to allocated
+ *
+ * @param memptr Output parameter for the new allocation, which
+ * will on successful completion be set to a unique
+ * pointer with at least the specified size and
+ * alignment
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @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 0 on success, the error code on failure (errno is
+ * not set)
+ * @throws EINVAL `n` is 0, `alignment` is not a power of 2, or
+ * `alignment` is not a multiple of `sizeof(void *)`
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1))))
int libsimple_vposix_memalignzn(void **, int, size_t, size_t, va_list);
#ifndef vposix_memalignzn
# define vposix_memalignzn libsimple_vposix_memalignzn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * @param memptr Output parameter for the new allocation, which
+ * will on successful completion be set to a unique
+ * pointer with at least the specified size and
+ * alignment
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return 0 on success, the error code on failure (errno is
+ * not set)
+ * @throws EINVAL `n` is 0, `alignment` is not a power of 2, or
+ * `alignment` is not a multiple of `sizeof(void *)`
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1))))
static inline int
libsimple_posix_memalignz(void **__memptr, int __clear, size_t __alignment, size_t __n)
@@ -23,6 +65,32 @@ libsimple_posix_memalignz(void **__memptr, int __clear, size_t __alignment, size
# define posix_memalignz libsimple_posix_memalignz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `memptr`, `clear`
+ * and `alignment`, up to the first 0, will be used as
+ * the number of bytes to allocated
+ *
+ * @param memptr Output parameter for the new allocation, which
+ * will on successful completion be set to a unique
+ * pointer with at least the specified size and
+ * alignment
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @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 0 on success, the error code on failure (errno is
+ * not set)
+ * @throws EINVAL `n` is 0, `alignment` is not a power of 2, or
+ * `alignment` is not a multiple of `sizeof(void *)`
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1))))
static inline int
libsimple_posix_memalignzn(void **__memptr, int __clear, size_t __alignment, size_t __n, ... /*, (size_t)0 */)
@@ -36,18 +104,87 @@ libsimple_posix_memalignzn(void **__memptr, int __clear, size_t __alignment, siz
# define posix_memalignzn libsimple_posix_memalignzn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param memptr Output parameter for the new allocation, which
+ * will be set to a unique pointer with at least the
+ * specified size and alignment
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2))))
void libsimple_enposix_memalignz(int, void **, int, size_t, size_t);
#ifndef enposix_memalignz
# define enposix_memalignz libsimple_enposix_memalignz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `status`, `memptr`,
+ * `clear`, and `alignment`, up to the first 0, will be
+ * used as the number of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param memptr Output parameter for the new allocation, which
+ * will be set to a unique pointer with at least the
+ * specified size and alignment
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @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)
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2))))
void libsimple_envposix_memalignzn(int, void **, int, size_t, size_t, va_list);
#ifndef envposix_memalignzn
# define envposix_memalignzn libsimple_envposix_memalignzn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `status`, `memptr`,
+ * `clear`, and `alignment`, up to the first 0, will be
+ * used as the number of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param memptr Output parameter for the new allocation, which
+ * will be set to a unique pointer with at least the
+ * specified size and alignment
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @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)
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2))))
static inline void
libsimple_enposix_memalignzn(int __status, void **__memptr, int __clear, size_t __alignment, size_t __n, ... /*, (size_t)0 */)
@@ -61,6 +198,24 @@ libsimple_enposix_memalignzn(int __status, void **__memptr, int __clear, size_t
# define enposix_memalignzn libsimple_enposix_memalignzn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param memptr Output parameter for the new allocation, which
+ * will be set to a unique pointer with at least the
+ * specified size and alignment
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1))))
static inline void libsimple_eposix_memalignz(void **__memptr, int __clear, size_t __alignment, size_t __n)
{ libsimple_enposix_memalignz(libsimple_default_failure_exit, __memptr, __clear, __alignment, __n); }
@@ -68,6 +223,30 @@ static inline void libsimple_eposix_memalignz(void **__memptr, int __clear, size
# define eposix_memalignz libsimple_eposix_memalignz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `memptr`, `clear`
+ * and `alignment`, up to the first 0, will be used as
+ * the number of bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param memptr Output parameter for the new allocation, which
+ * will be set to a unique pointer with at least the
+ * specified size and alignment
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @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)
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1))))
static inline void libsimple_evposix_memalignzn(void **__memptr, int __clear, size_t __alignment, size_t __n, va_list __ap)
{ libsimple_envposix_memalignzn(libsimple_default_failure_exit, __memptr, __clear, __alignment, __n, __ap); }
@@ -75,6 +254,30 @@ static inline void libsimple_evposix_memalignzn(void **__memptr, int __clear, si
# define evposix_memalignzn libsimple_evposix_memalignzn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with custom alignment
+ *
+ * The product of all arguments except `memptr`, `clear`
+ * and `alignment`, up to the first 0, will be used as
+ * the number of bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param memptr Output parameter for the new allocation, which
+ * will be set to a unique pointer with at least the
+ * specified size and alignment
+ * @param clear Non-zero if the memory should be initialised
+ * @param alignment The alignment, must be a power of 2 and a multiple
+ * of `sizeof(void *)`
+ * @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)
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1))))
static inline void
libsimple_eposix_memalignzn(void **__memptr, int __clear, size_t __alignment, size_t __n, ... /*, (size_t)0 */)
diff --git a/libsimple/printf.h b/libsimple/printf.h
index f1e0b0d..9b6253c 100644
--- a/libsimple/printf.h
+++ b/libsimple/printf.h
@@ -1,17 +1,65 @@
/* See LICENSE file for copyright and license details. */
+
+/**
+ * Version of `printf` that allocates, on the heap, a
+ * sufficiently large string and writes the output to it
+ *
+ * @param strp Output pointer for string, will be set to `NULL`
+ * on failure, however portable applications should
+ * assume that it may also be unmodified or a recently
+ * freed pointer if `asprintf` is used rather than
+ * `libsimple_asprintf` explicitly
+ * @param fmt The format string
+ * @param ... The format argument
+ * @return The length of the output on success, -1 on error
+ * @throws EMFILE {FOPEN_MAX} streams are currently open in the calling process
+ * @throws ENOMEM Could not allocate enough memory
+ * @throws Any error specified for `fprintf`
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1, 2), __format__(__printf__, 2, 3))))
int libsimple_asprintf(char **, const char *, ...);
#ifndef asprintf
# define asprintf libsimple_asprintf
#endif
+
+/**
+ * Version of `vprintf` that allocates, on the heap, a
+ * sufficiently large string and writes the output to it
+ *
+ * @param strp Output pointer for string, will be set to `NULL`
+ * on failure, however portable applications should
+ * assume that it may also be unmodified or a recently
+ * freed pointer if `asprintf` is used rather than
+ * `libsimple_asprintf` explicitly
+ * @param fmt The format string
+ * @param ap The format argument
+ * @return The length of the output on success, -1 on error
+ * @throws EMFILE {FOPEN_MAX} streams are currently open in the calling process
+ * @throws ENOMEM Could not allocate enough memory
+ * @throws Any error specified for `fprintf`
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1, 2))))
int libsimple_vasprintf(char **, const char *, va_list);
#ifndef vasprintf
# define vasprintf libsimple_vasprintf
#endif
+
+/**
+ * Version of `printf` that allocates, on the stack, a
+ * sufficiently large string and writes the output to it
+ *
+ * This macro does not check whether it can allocate
+ * enough memory, if it cannot, the kernel may kill the
+ * thread, and possibly the process, with a SIGSEGV signal
+ *
+ * @param fmt The format string
+ * @param ... The format argument
+ * @return The formatted string, `NULL` on error
+ * @throws Any error specified for `snprintf`
+ */
#if defined(__GNUC__) || defined(__clang__)
# define libsimple_asprintfa(__fmt, ...)\
({\
@@ -29,6 +77,20 @@ int libsimple_vasprintf(char **, const char *, va_list);
# endif
#endif
+
+/**
+ * Version of `vprintf` that allocates, on the stack, a
+ * sufficiently large string and writes the output to it
+ *
+ * This macro does not check whether it can allocate
+ * enough memory, if it cannot, the kernel may kill the
+ * thread, and possibly the process, with a SIGSEGV signal
+ *
+ * @param fmt The format string
+ * @param ap The format argument
+ * @return The formatted string, `NULL` on error
+ * @throws Any error specified for `snprintf`
+ */
#if defined(__GNUC__) || defined(__clang__)
# define libsimple_vasprintfa(__fmt, __ap)\
({\
@@ -54,12 +116,47 @@ int libsimple_vasprintf(char **, const char *, va_list);
#endif
+/**
+ * Version of `vprintf` for printing error message;
+ * it prints to standard error (rather than standard
+ * output) and, unless `fmt` starts with "usage: "
+ * and unless `argv0` (global `char *`), prefixes
+ * the output with `"%s: ", argv0`; additionally, if
+ * `fmt` ends with ':', the output is suffixed with
+ * `" %s\n", strerror(errno)`, if `fmt` ends with
+ * neither ':' nor '\n', the outpt is suffixed with
+ * `\n`
+ *
+ * NB! This function uses `strerror` which is not
+ * thread-safe
+ *
+ * @param fmt The format string
+ * @param ap The format argument
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1))))
void libsimple_vweprintf(const char *, va_list);
#ifndef vweprintf
# define vweprintf libsimple_vweprintf
#endif
+
+/**
+ * Version of `vprintf` for printing error message;
+ * it prints to standard error (rather than standard
+ * output) and, unless `fmt` starts with "usage: "
+ * and unless `argv0` (global `char *`), prefixes
+ * the output with `"%s: ", argv0`; additionally, if
+ * `fmt` ends with ':', the output is suffixed with
+ * `" %s\n", strerror(errno)`, if `fmt` ends with
+ * neither ':' nor '\n', the outpt is suffixed with
+ * `\n`
+ *
+ * NB! This function uses `strerror` which is not
+ * thread-safe
+ *
+ * @param fmt The format string
+ * @param ... The format argument
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1), __format__(__printf__, 1, 2))))
static inline void
libsimple_weprintf(const char *__fmt, ...)
@@ -73,6 +170,27 @@ libsimple_weprintf(const char *__fmt, ...)
# define weprintf libsimple_weprintf
#endif
+
+/**
+ * Version of `vprintf` for printing error message;
+ * it prints to standard error (rather than standard
+ * output) and, unless `fmt` starts with "usage: "
+ * and unless `argv0` (global `char *`), prefixes
+ * the output with `"%s: ", argv0`; additionally, if
+ * `fmt` ends with ':', the output is suffixed with
+ * `" %s\n", strerror(errno)`, if `fmt` ends with
+ * neither ':' nor '\n', the outpt is suffixed with
+ * `\n`
+ *
+ * This function will exit the process
+ *
+ * NB! This function uses `strerror` which is not
+ * thread-safe
+ *
+ * @param status Exit value for the process
+ * @param fmt The format string
+ * @param ap The format argument
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2), __noreturn__)))
static inline void
libsimple_venprintf(int __status, const char *__fmt, va_list __ap)
@@ -84,6 +202,27 @@ libsimple_venprintf(int __status, const char *__fmt, va_list __ap)
# define venprintf libsimple_venprintf
#endif
+
+/**
+ * Version of `vprintf` for printing error message;
+ * it prints to standard error (rather than standard
+ * output) and, unless `fmt` starts with "usage: "
+ * and unless `argv0` (global `char *`), prefixes
+ * the output with `"%s: ", argv0`; additionally, if
+ * `fmt` ends with ':', the output is suffixed with
+ * `" %s\n", strerror(errno)`, if `fmt` ends with
+ * neither ':' nor '\n', the outpt is suffixed with
+ * `\n`
+ *
+ * This function will exit the process
+ *
+ * NB! This function uses `strerror` which is not
+ * thread-safe
+ *
+ * @param status Exit value for the process
+ * @param fmt The format string
+ * @param ... The format argument
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2), __format__(__printf__, 2, 3), __noreturn__)))
static inline void
libsimple_enprintf(int __status, const char *__fmt, ...)
@@ -97,6 +236,27 @@ libsimple_enprintf(int __status, const char *__fmt, ...)
# define enprintf libsimple_enprintf
#endif
+
+/**
+ * Version of `vprintf` for printing error message;
+ * it prints to standard error (rather than standard
+ * output) and, unless `fmt` starts with "usage: "
+ * and unless `argv0` (global `char *`), prefixes
+ * the output with `"%s: ", argv0`; additionally, if
+ * `fmt` ends with ':', the output is suffixed with
+ * `" %s\n", strerror(errno)`, if `fmt` ends with
+ * neither ':' nor '\n', the outpt is suffixed with
+ * `\n`
+ *
+ * This function will exit the process with the
+ * value `libsimple_default_failure_exit`
+ *
+ * NB! This function uses `strerror` which is not
+ * thread-safe
+ *
+ * @param fmt The format string
+ * @param ap The format argument
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1), __noreturn__)))
static inline void
libsimple_veprintf(const char *__fmt, va_list __ap)
@@ -108,6 +268,27 @@ libsimple_veprintf(const char *__fmt, va_list __ap)
# define veprintf libsimple_veprintf
#endif
+
+/**
+ * Version of `vprintf` for printing error message;
+ * it prints to standard error (rather than standard
+ * output) and, unless `fmt` starts with "usage: "
+ * and unless `argv0` (global `char *`), prefixes
+ * the output with `"%s: ", argv0`; additionally, if
+ * `fmt` ends with ':', the output is suffixed with
+ * `" %s\n", strerror(errno)`, if `fmt` ends with
+ * neither ':' nor '\n', the outpt is suffixed with
+ * `\n`
+ *
+ * This function will exit the process with the
+ * value `libsimple_default_failure_exit`
+ *
+ * NB! This function uses `strerror` which is not
+ * thread-safe
+ *
+ * @param fmt The format string
+ * @param ... The format argument
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1), __format__(__printf__, 1, 2), __noreturn__)))
static inline void
libsimple_eprintf(const char *__fmt, ...)
diff --git a/libsimple/pvalloc.h b/libsimple/pvalloc.h
index dfd7b31..78deb1a 100644
--- a/libsimple/pvalloc.h
+++ b/libsimple/pvalloc.h
@@ -1,10 +1,26 @@
/* See LICENSE file for copyright and license details. */
-/*
- * The alignment will be the page size.
- * The allocation size is rounded up to the next multiple of the alignment.
- */
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The product of all arguments, up to the first 0,
+ * will be used as the number of bytes to allocated
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * @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 A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__)))
static inline void *libsimple_vpvallocn(size_t __n, va_list __ap)
{ return libsimple_vpvalloczn(0, __n, __ap); }
@@ -12,6 +28,21 @@ static inline void *libsimple_vpvallocn(size_t __n, va_list __ap)
# define vpvallocn libsimple_vpvallocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * @param n The number of bytes to allocate
+ * @return A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__)))
static inline void *libsimple_pvalloc(size_t __n)
{ return libsimple_pvallocz(0, __n); }
@@ -19,6 +50,27 @@ static inline void *libsimple_pvalloc(size_t __n)
# define pvalloc libsimple_pvalloc
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The product of all arguments, up to the first 0,
+ * will be used as the number of bytes to allocated
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * @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 A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__)))
static inline void *
libsimple_pvallocn(size_t __n, ... /*, (size_t)0 */)
@@ -32,6 +84,25 @@ libsimple_pvallocn(size_t __n, ... /*, (size_t)0 */)
# define pvallocn libsimple_pvallocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_enpvalloc(int __status, size_t __n)
{ return libsimple_enpvallocz(__status, 0, __n); }
@@ -39,6 +110,30 @@ static inline void *libsimple_enpvalloc(int __status, size_t __n)
# define enpvalloc libsimple_enpvalloc
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The product of all arguments except `status`, up to the
+ * first 0, will be used as the number of bytes to allocated
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @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 A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_envpvallocn(int __status, size_t __n, va_list __ap)
{ return libsimple_envpvalloczn(__status, 0, __n, __ap); }
@@ -46,6 +141,30 @@ static inline void *libsimple_envpvallocn(int __status, size_t __n, va_list __ap
# define envpvallocn libsimple_envpvallocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The product of all arguments except `status`, up to the
+ * first 0, will be used as the number of bytes to allocated
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @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 A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_enpvallocn(int __status, size_t __n, ... /*, (size_t)0 */)
@@ -59,6 +178,24 @@ libsimple_enpvallocn(int __status, size_t __n, ... /*, (size_t)0 */)
# define enpvallocn libsimple_enpvallocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_epvalloc(size_t __n)
{ return libsimple_enpvalloc(libsimple_default_failure_exit, __n); }
@@ -66,6 +203,29 @@ static inline void *libsimple_epvalloc(size_t __n)
# define epvalloc libsimple_epvalloc
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The product of all arguments, up to the first 0,
+ * will be used as the number of bytes to allocated
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @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 A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_evpvallocn(size_t __n, va_list __ap)
{ return libsimple_envpvallocn(libsimple_default_failure_exit, __n, __ap); }
@@ -73,6 +233,29 @@ static inline void *libsimple_evpvallocn(size_t __n, va_list __ap)
# define evpvallocn libsimple_evpvallocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The product of all arguments, up to the first 0,
+ * will be used as the number of bytes to allocated
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @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 A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_epvallocn(size_t __n, ... /*, (size_t)0 */)
diff --git a/libsimple/pvallocz.h b/libsimple/pvallocz.h
index 2fc628d..7821991 100644
--- a/libsimple/pvallocz.h
+++ b/libsimple/pvallocz.h
@@ -1,10 +1,27 @@
/* See LICENSE file for copyright and license details. */
-/*
- * The alignment will be the page size.
- * The allocation size is rounded up to the next multiple of the alignment.
- */
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The product of all arguments except `clear`, up to the
+ * first 0, will be used as the number of bytes to allocated
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @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 A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__)))
static inline void *
libsimple_vpvalloczn(int __clear, size_t __n, va_list __ap) /* TODO test ([v]pvalloc[z]n) */
@@ -19,6 +36,22 @@ libsimple_vpvalloczn(int __clear, size_t __n, va_list __ap) /* TODO test ([v]pva
# define vpvalloczn libsimple_vpvalloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param n The number of bytes to allocate
+ * @return A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_size__(2), __warn_unused_result__)))
static inline void *
libsimple_pvallocz(int __clear, size_t __n) /* TODO test (pvalloc[z]) */
@@ -33,6 +66,28 @@ libsimple_pvallocz(int __clear, size_t __n) /* TODO test (pvalloc[z]) */
# define pvallocz libsimple_pvallocz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The product of all arguments except `clear`, up to the
+ * first 0, will be used as the number of bytes to allocated
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @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 A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__)))
static inline void *
libsimple_pvalloczn(int __clear, size_t __n, ... /*, (size_t)0 */)
@@ -46,6 +101,26 @@ libsimple_pvalloczn(int __clear, size_t __n, ... /*, (size_t)0 */)
# define pvalloczn libsimple_pvalloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param clear Non-zero if the memory should be initialised
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_size__(3), __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_enpvallocz(int __status, int __clear, size_t __n) /* TODO test (e[n]pvalloc[z]) */
@@ -60,6 +135,32 @@ libsimple_enpvallocz(int __status, int __clear, size_t __n) /* TODO test (e[n]pv
# define enpvallocz libsimple_enpvallocz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The product of all arguments except `status` and
+ * `clear`, up to the first 0, will be used as the number
+ * of bytes to allocated
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param clear Non-zero if the memory should be initialised
+ * @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 A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_envpvalloczn(int __status, int __clear, size_t __n, va_list __ap) /* TODO test (e[n][v]pvalloc[z]n) */
@@ -75,6 +176,32 @@ libsimple_envpvalloczn(int __status, int __clear, size_t __n, va_list __ap) /* T
# define envpvalloczn libsimple_envpvalloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The product of all arguments except `status` and
+ * `clear`, up to the first 0, will be used as the number
+ * of bytes to allocated
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param clear Non-zero if the memory should be initialised
+ * @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 A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_enpvalloczn(int __status, int __clear, size_t __n, ... /*, (size_t)0 */)
@@ -88,6 +215,25 @@ libsimple_enpvalloczn(int __status, int __clear, size_t __n, ... /*, (size_t)0 *
# define enpvalloczn libsimple_enpvalloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_size__(2), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_epvallocz(int __clear, size_t __n)
{ return libsimple_enpvallocz(libsimple_default_failure_exit, __clear, __n); }
@@ -95,6 +241,30 @@ static inline void *libsimple_epvallocz(int __clear, size_t __n)
# define epvallocz libsimple_epvallocz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The product of all arguments except `clear`, up to the
+ * first 0, will be used as the number of bytes to allocated
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @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 A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_evpvalloczn(int __clear, size_t __n, va_list __ap)
{ return libsimple_envpvalloczn(libsimple_default_failure_exit, __clear, __n, __ap); }
@@ -102,6 +272,30 @@ static inline void *libsimple_evpvalloczn(int __clear, size_t __n, va_list __ap)
# define evpvalloczn libsimple_evpvalloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The product of all arguments except `clear`, up to the
+ * first 0, will be used as the number of bytes to allocated
+ *
+ * The allocation size is rounded up to the next multiple
+ * of the page size (the alignment)
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @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 A unique pointer with at least the specified size,
+ * rounded up to the next multiple of the page size,
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_epvalloczn(int __clear, size_t __n, ... /*, (size_t)0 */)
diff --git a/libsimple/valloc.h b/libsimple/valloc.h
index 6f9d57b..c0fcd03 100644
--- a/libsimple/valloc.h
+++ b/libsimple/valloc.h
@@ -1,9 +1,22 @@
/* See LICENSE file for copyright and license details. */
-/*
- * The alignment will be the page size.
- */
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The product of all arguments, up to the first 0,
+ * will be used as the number of bytes to allocated
+ *
+ * @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 A unique pointer with at least the specified size
+ * and with page size alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__)))
static inline void *libsimple_vvallocn(size_t __n, va_list __ap)
{ return libsimple_vvalloczn(0, __n, __ap); }
@@ -11,6 +24,17 @@ static inline void *libsimple_vvallocn(size_t __n, va_list __ap)
# define vvallocn libsimple_vvallocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * @param n The number of bytes to allocate
+ * @return A unique pointer with at least the specified size
+ * and with page size alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_size__(1), __warn_unused_result__)))
static inline void *libsimple_valloc(size_t __n)
{ return libsimple_vallocz(0, __n); }
@@ -18,6 +42,23 @@ static inline void *libsimple_valloc(size_t __n)
# define valloc libsimple_valloc
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The product of all arguments, up to the first 0,
+ * will be used as the number of bytes to allocated
+ *
+ * @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 A unique pointer with at least the specified size
+ * and with page size alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__)))
static inline void *
libsimple_vallocn(size_t __n, ... /*, (size_t)0 */)
@@ -31,6 +72,21 @@ libsimple_vallocn(size_t __n, ... /*, (size_t)0 */)
# define vallocn libsimple_vallocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_size__(2), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_envalloc(int __status, size_t __n)
{ return libsimple_envallocz(__status, 0, __n); }
@@ -38,6 +94,26 @@ static inline void *libsimple_envalloc(int __status, size_t __n)
# define envalloc libsimple_envalloc
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The product of all arguments except `status`, up to the
+ * first 0, will be used as the number of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @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 A unique pointer with at least the specified size
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_envvallocn(int __status, size_t __n, va_list __ap)
{ return libsimple_envvalloczn(__status, 0, __n, __ap); }
@@ -45,6 +121,26 @@ static inline void *libsimple_envvallocn(int __status, size_t __n, va_list __ap)
# define envvallocn libsimple_envvallocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The product of all arguments except `status`, up to the
+ * first 0, will be used as the number of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @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 A unique pointer with at least the specified size
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_envallocn(int __status, size_t __n, ... /*, (size_t)0 */)
@@ -58,6 +154,20 @@ libsimple_envallocn(int __status, size_t __n, ... /*, (size_t)0 */)
# define envallocn libsimple_envallocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_size__(1), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_evalloc(size_t __n)
{ return libsimple_envalloc(libsimple_default_failure_exit, __n); }
@@ -65,6 +175,25 @@ static inline void *libsimple_evalloc(size_t __n)
# define evalloc libsimple_evalloc
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The product of all arguments, up to the first 0,
+ * will be used as the number of bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @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 A unique pointer with at least the specified size
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_evvallocn(size_t __n, va_list __ap)
{ return libsimple_envvallocn(libsimple_default_failure_exit, __n, __ap); }
@@ -72,6 +201,25 @@ static inline void *libsimple_evvallocn(size_t __n, va_list __ap)
# define evvallocn libsimple_evvallocn
#endif
+
+/**
+ * Dynamically allocates heap allocated, uninitialised,
+ * memory with page size alignment
+ *
+ * The product of all arguments, up to the first 0,
+ * will be used as the number of bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @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 A unique pointer with at least the specified size
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_evallocn(size_t __n, ... /*, (size_t)0 */)
diff --git a/libsimple/vallocz.h b/libsimple/vallocz.h
index 2831cf8..a4765c5 100644
--- a/libsimple/vallocz.h
+++ b/libsimple/vallocz.h
@@ -1,9 +1,23 @@
/* See LICENSE file for copyright and license details. */
-/*
- * The alignment will be the page size.
- */
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The product of all arguments except `clear`, up to the
+ * first 0, will be used as the number of bytes to allocated
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @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 A unique pointer with at least the specified size
+ * and with page size alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__)))
static inline void *
libsimple_vvalloczn(int __clear, size_t __n, va_list __ap) /* TODO test ([v]valloc[z]n) */
@@ -17,6 +31,18 @@ libsimple_vvalloczn(int __clear, size_t __n, va_list __ap) /* TODO test ([v]vall
# define vvalloczn libsimple_vvalloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param n The number of bytes to allocate
+ * @return A unique pointer with at least the specified size
+ * and with page size alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_size__(2), __warn_unused_result__)))
static inline void *
libsimple_vallocz(int __clear, size_t __n) /* TODO test (valloc[z]) */
@@ -30,6 +56,24 @@ libsimple_vallocz(int __clear, size_t __n) /* TODO test (valloc[z]) */
# define vallocz libsimple_vallocz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The product of all arguments except `clear`, up to the
+ * first 0, will be used as the number of bytes to allocated
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @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 A unique pointer with at least the specified size
+ * and with page size alignment; `NULL` on failure
+ * @throws EINVAL `n` is 0
+ * @throws ENOMEM Could not allocated enough memory
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__)))
static inline void *
libsimple_valloczn(int __clear, size_t __n, ... /*, (size_t)0 */)
@@ -43,6 +87,22 @@ libsimple_valloczn(int __clear, size_t __n, ... /*, (size_t)0 */)
# define valloczn libsimple_valloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param clear Non-zero if the memory should be initialised
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_size__(3), __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_envallocz(int __status, int __clear, size_t __n) /* TODO test (e[n]valloc[z]) */
@@ -56,6 +116,28 @@ libsimple_envallocz(int __status, int __clear, size_t __n) /* TODO test (e[n]val
# define envallocz libsimple_envallocz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The product of all arguments except `status` and
+ * `clear`, up to the first 0, will be used as the number
+ * of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param clear Non-zero if the memory should be initialised
+ * @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 A unique pointer with at least the specified size
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_envvalloczn(int __status, int __clear, size_t __n, va_list __ap) /* TODO test (e[n][v]valloc[z]n, e[n]vallocn) */
@@ -70,6 +152,28 @@ libsimple_envvalloczn(int __status, int __clear, size_t __n, va_list __ap) /* TO
# define envvalloczn libsimple_envvalloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The product of all arguments except `status` and
+ * `clear`, up to the first 0, will be used as the number
+ * of bytes to allocated
+ *
+ * On failure, the `libsimple_enprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_enprintf` for more information
+ *
+ * @param status The exit value for the process in case of failure
+ * @param clear Non-zero if the memory should be initialised
+ * @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 A unique pointer with at least the specified size
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_envalloczn(int __status, int __clear, size_t __n, ... /*, (size_t)0 */)
@@ -83,6 +187,21 @@ libsimple_envalloczn(int __status, int __clear, size_t __n, ... /*, (size_t)0 */
# define envalloczn libsimple_envalloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @param n The number of bytes to allocate, the behaviour of
+ * this function is unspecified for the value 0
+ * @return A unique pointer with at least the specified size
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __alloc_size__(2), __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_evallocz(int __clear, size_t __n)
{ return libsimple_envallocz(libsimple_default_failure_exit, __clear, __n); }
@@ -90,6 +209,26 @@ static inline void *libsimple_evallocz(int __clear, size_t __n)
# define evallocz libsimple_evallocz
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The product of all arguments except `clear`, up to the
+ * first 0, will be used as the number of bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @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 A unique pointer with at least the specified size
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_evvalloczn(int __clear, size_t __n, va_list __ap)
{ return libsimple_envvalloczn(libsimple_default_failure_exit, __clear, __n, __ap); }
@@ -97,6 +236,26 @@ static inline void *libsimple_evvalloczn(int __clear, size_t __n, va_list __ap)
# define evvalloczn libsimple_evvalloczn
#endif
+
+/**
+ * Dynamically allocates heap allocated, optionally
+ * initialised, memory with page size alignment
+ *
+ * The product of all arguments except `clear`, up to the
+ * first 0, will be used as the number of bytes to allocated
+ *
+ * On failure, the `libsimple_eprintf` function is called,
+ * cause the program to print an error message and exit,
+ * see `libsimple_eprintf` for more information
+ *
+ * @param clear Non-zero if the memory should be initialised
+ * @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 A unique pointer with at least the specified size
+ * and with page size alignment
+ */
_LIBSIMPLE_GCC_ONLY(__attribute__((__malloc__, __warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_evalloczn(int __clear, size_t __n, ... /*, (size_t)0 */)
diff --git a/man/libsimple_aligned_memdup.3 b/man/libsimple_aligned_memdup.3
index 17132ff..6cd287a 100644
--- a/man/libsimple_aligned_memdup.3
+++ b/man/libsimple_aligned_memdup.3
@@ -77,10 +77,10 @@ to indicate the error, and the
.BR libsimple_enaligned_memdup (),
and
.BR libsimple_ealigned_memdup ()
-functions exit the process group. The
+functions exit the process. The
.BR libsimple_aligned_memdupa ()
function cannot fail, however the kernel
-can kill the process with a
+can kill the thread, and possibly the process, with a
.B SIGSEGV
signal if the memory cannot be allocated.
.PP
diff --git a/man/libsimple_enstrdup.3 b/man/libsimple_enstrdup.3
index 512da34..4a2aa4f 100644
--- a/man/libsimple_enstrdup.3
+++ b/man/libsimple_enstrdup.3
@@ -55,10 +55,10 @@ functions return a non-null pointer, on failure the
.BR libsimple_enstrdup (),
and
.BR libsimple_estrdup ()
-functions exit the process group. The
+functions exit the process. The
.BR libsimple_strdupa ()
function cannot fail, however the kernel
-can kill the process with a
+can kill the thread, and possibly the process, with a
.B SIGSEGV
signal if the memory cannot be allocated.
.PP
diff --git a/man/libsimple_enstrndup.3 b/man/libsimple_enstrndup.3
index c761c1c..66272b0 100644
--- a/man/libsimple_enstrndup.3
+++ b/man/libsimple_enstrndup.3
@@ -55,10 +55,10 @@ functions return a non-null pointer, on failure the
.BR libsimple_enstrndup (),
and
.BR libsimple_estrndup ()
-functions exit the process group. The
+functions exit the process. The
.BR libsimple_strndupa ()
function cannot fail, however the kernel
-can kill the process with a
+can kill the thread, and possibly the process, with a
.B SIGSEGV
signal if the memory cannot be allocated.
.PP
diff --git a/man/libsimple_memdup.3 b/man/libsimple_memdup.3
index d9e6d32..e111574 100644
--- a/man/libsimple_memdup.3
+++ b/man/libsimple_memdup.3
@@ -74,10 +74,10 @@ to indicate the error, and the
.BR libsimple_enmemdup (),
and
.BR libsimple_ememdup ()
-functions exit the process group. The
+functions exit the process. The
.BR libsimple_memdupa ()
function cannot fail, however the kernel
-can kill the process with a
+can kill the thread, and possibly the process, with a
.B SIGSEGV
signal if the memory cannot be allocated.
.PP
diff --git a/vweprintf.c b/vweprintf.c
index 491763b..96a82a7 100644
--- a/vweprintf.c
+++ b/vweprintf.c
@@ -20,13 +20,13 @@ libsimple_vweprintf(const char *fmt, va_list ap)
va_list ap1;
va_list ap2;
- if (!argv0 || !strncmp(fmt, "usage: ", strlen("usage: ")))
+ if (!argv0 || !strncmp(fmt, "usage: ", sizeof("usage: ") - 1))
prefix1 = prefix2 = "";
va_copy(ap1, ap);
va_copy(ap2, ap);
r = vsnprintf(NULL, 0, fmt, ap1);
- if (0 <= r && (size_t)r < SIZE_MAX) {
+ if (0 <= r && r < 8096) {
message = alloca((size_t)r + 1);
vsprintf(message, fmt, ap2);
}