aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--README192
-rw-r--r--encalloc.c37
-rw-r--r--enmalloc.c37
-rw-r--r--enmemdup.c2
-rw-r--r--enrealloc.c59
-rw-r--r--enstrdup.c2
-rw-r--r--enstrndup.c2
-rw-r--r--envmalloczn.c162
-rw-r--r--envputenvf.c2
-rw-r--r--envreallocn.c2
-rw-r--r--libsimple.c89
-rw-r--r--libsimple.h300
-rw-r--r--test.c6
-rw-r--r--test.h37
-rw-r--r--vweprintf.c2
15 files changed, 693 insertions, 238 deletions
diff --git a/README b/README
index 264cdbe..003313d 100644
--- a/README
+++ b/README
@@ -80,8 +80,12 @@ The following macros are defined, unless already defined:
The following functions are defined (some as inline functions):
+ int libsimple_close(int *)
+ Ensures that errno is not modified when closing an
+ already closed file descriptor.
+
void *libsimple_rawmemchr(const void *, int)
- Memchr without boundary check.
+ memchr without boundary check.
void *libsimple_memrchr(const void *, int, size_t)
Like memchr, except finds the last occurrence.
@@ -108,6 +112,21 @@ The following functions are defined (some as inline functions):
Like memcpy, except returns the byte after the
last written byte.
+ char *libsimple_strdupa(const char *)
+ Like `strdup`, except the returned pointer is stack-allocated.
+ This function is implemented as a macro and is only available
+ when compiling with GCC or clang.
+
+ char *libsimple_strndupa(const char *, size_t)
+ Like `strndup`, except the returned pointer is stack-allocated.
+ This function is implemented as a macro and is only available
+ when compiling with GCC or clang.
+
+ void *libsimple_memdupa(const void *, size_t)
+ Like `memdup`, except the returned pointer is stack-allocated.
+ This function is implemented as a macro and is only available
+ when compiling with GCC or clang.
+
int libsimple_isutf8(const char *s, int allow_modified_nul)
Returns 1 if `s` is valid UTF-8 (Unicode codepoints are not
validated) and 0 otherwise. If `allow_modified_nul` is non-zero,
@@ -119,6 +138,18 @@ The following functions are defined (some as inline functions):
int libsimple_vasprintf(char **, const char *, va_list);
Like vsprintf accept allocated the buffer.
+ char *libsimple_asprintfa(const char *, ...)
+ Like `asprintf` accept the the buffer is stack-allocated and
+ returned instead of stored in a pointer. This function is
+ implemented as a macro and is only available when compiling
+ with GCC or clang.
+
+ char *libsimple_vasprintfa(const char *, va_list)
+ Like `vasprintf` accept the the buffer is stack-allocated and
+ returned instead of stored in a pointer. This function is
+ implemented as a macro and is only available when compiling
+ with GCC or clang.
+
void *libsimple_memmem(const void *s, size_t sn, const void *t, size_t tn)
Finds the first occurrence of `t` in `s`.
Length of `s` is `sn`. Length of `t` is `tn`.
@@ -192,24 +223,58 @@ The following functions are defined (some as inline functions):
int libsimple_strneq(const char *a, const char *b, size_t n)
!strncmp(a, b, n)
- int libsimple_strcaseeq(const char *a, const char *b)
- !strcasecmp(a, b)
-
- int libsimple_strncaseeq(const char *a, const char *b, size_t n)
- !strncasecmp(a, b, n)
-
int libsimple_streqnul(const char *a, const char *b)
!strcmpnul(a, b)
int libsimple_strneqnul(const char *a, const char *b, size_t n)
!strncmpnul(a, b, n)
+ int libsimple_strcaseeq(const char *a, const char *b)
+ !strcasecmp(a, b)
+
+ int libsimple_strncaseeq(const char *a, const char *b, size_t n)
+ !strncasecmp(a, b, n)
+
int libsimple_strcaseeqnul(const char *a, const char *b)
!strcasecmpnul(a, b)
int libsimple_strncaseeqnul(const char *a, const char *b, size_t n)
!strncasecmpnul(a, b, n)
+ void *libsimple_vmalloczn(int, size_t, va_list)
+ Like malloczn accept uses va_list instead of variadic arguments.
+
+ void *libsimple_vmallocn(size_t, va_list)
+ Like mallocn accept uses va_list instead of variadic arguments.
+
+ void *libsimple_vcallocn(size_t, va_list)
+ Like callocn accept uses va_list instead of variadic arguments.
+
+ void *libsimple_vreallocn(void *, size_t, va_list)
+ Like reallocn accept uses va_list instead of variadic arguments.
+
+ void *libsimple_mallocz(int, size_t)
+ Identical to malloc if first argument is zero,
+ Identical to calloc, with 1 as the first argument, if first
+ argument is non-zero.
+
+ void *libsimple_malloczn(int, size_t, ... /*, (size_t)0 */)
+ Identical to mallocn if first argument is zero,
+ Identical to callocn if first argument is non-zero.
+
+ void *libsimple_mallocn(size_t, ... /*, (size_t)0 */)
+ Like malloc, accept uses the product of all argument, until
+ the first 0-argument, the first argument must not be 0.
+
+ void *libsimple_callocn(size_t, ... /*, (size_t)0 */)
+ Like calloc, accept uses the product of all argument, until
+ the first 0-argument, the first argument must not be 0.
+
+ void *libsimple_reallocn(void *, size_t, ... /*, (size_t)0 */)
+ Like realloc, accept uses the product of all argument,
+ not counting the first argument, until the first 0-argument,
+ the second argument must not be 0.
+
char *libsimple_getenv_ne(const char *)
Like getenv, except returns NULL if the value
of the environment variable is the empty string.
@@ -218,12 +283,42 @@ The following functions are defined (some as inline functions):
Like getenv, except returns the empty string if the
value of the environment variable is undefined.
- int libsimple_putenvf(const char *, ...)
+ int libsimple_vputenvf(const char *, va_list)
Format a string and call putenv.
- int libsimple_vputenvf(const char *, va_list)
+ int libsimple_putenvf(const char *, ...)
Format a string and call putenv.
+ void libsimple_vweprintf(const char *, va_list)
+ Identical to libsimple_weprintf, except using va_list.
+
+ void libsimple_weprintf(const char *fmt, ...)
+ Similar to printf, except prints to stderr and:
+ * unless `fmt` starts with "usage: " the `argv` follow by
+ ": " is prepended to the printed string,
+ * if `fmt` ends with ":", " " followed by `strerror(errno)`
+ and "\n" and appended to the printed string, and
+ * if `fmt` does not end with ":" or "\n", "\n" and appended to
+ the printed string.
+
+ libsimple.h defines `extern int libsimple_default_failure_exit`.
+
+ void libsimple_venprintf(int status, const char *, va_list)
+ Like libsimple_vweprintf, but calls exit(stats) afterwards.
+
+ void libsimple_enprintf(int status, const char *, ...)
+ Like libsimple_weprintf, but calls exit(stats) afterwards.
+
+ void libsimple_veprintf(const char *fmt, va_list)
+ Like libsimple_veprintf, but calls exit(libsimple_default_failure_exit)
+ afterwards.
+
+ void libsimple_eprintf(const char *fmt, ...)
+ Like libsimple_weprintf, but calls exit(libsimple_default_failure_exit)
+ afterwards.
+
+ libsimple.h defines `extern int libsimple_default_failure_exit`.
+
int libsimple_sendfd(int sock, int fd)
Send a file descriptor over a socket.
@@ -321,82 +416,45 @@ The following functions are defined (some as inline functions):
such macro already exists) is idential to libsimple_unlist
except `width` is automatically.
- char *libsimple_strdupa(const char *)
- Like `strdup`, except the returned pointer is stack-allocated.
- This function is implemented as a macro and is only available
- when compiling with GCC or clang.
-
- char *libsimple_strndupa(const char *, size_t)
- Like `strndup`, except the returned pointer is stack-allocated.
- This function is implemented as a macro and is only available
- when compiling with GCC or clang.
-
- void *libsimple_memdupa(const void *, size_t)
- Like `memdup`, except the returned pointer is stack-allocated.
- This function is implemented as a macro and is only available
- when compiling with GCC or clang.
-
- char *libsimple_asprintfa(const char *, ...)
- Like `asprintf` accept the the buffer is stack-allocated and
- returned instead of stored in a pointer. This function is
- implemented as a macro and is only available when compiling
- with GCC or clang.
-
- char *libsimple_vasprintfa(const char *, va_list)
- Like `vasprintf` accept the the buffer is stack-allocated and
- returned instead of stored in a pointer. This function is
- implemented as a macro and is only available when compiling
- with GCC or clang.
-
- void libsimple_weprintf(const char *fmt, ...)
- Similar to printf, except prints to stderr and:
- * unless `fmt` starts with "usage: " the `argv` follow by
- ": " is prepended to the printed string,
- * if `fmt` ends with ":", " " followed by `strerror(errno)`
- and "\n" and appended to the printed string, and
- * if `fmt` does not end with ":" or "\n", "\n" and appended to
- the printed string.
-
- void libsimple_vweprintf(const char *, va_list)
- Identical to libsimple_weprintf, except using va_list.
-
- void libsimple_eprintf(const char *fmt, ...)
- Like libsimple_weprintf, but calls exit(libsimple_default_failure_exit)
- afterwards.
-
- libsimple.h defines `extern int libsimple_default_failure_exit`.
-
- void libsimple_veprintf(const char *fmt, va_list)
- Like libsimple_veprintf, but calls exit(libsimple_default_failure_exit)
- afterwards.
-
- libsimple.h defines `extern int libsimple_default_failure_exit`.
-
- void libsimple_enprintf(int status, const char *, ...)
- Like libsimple_weprintf, but calls exit(stats) afterwards.
-
- void libsimple_venprintf(int status, const char *, va_list)
- Like libsimple_vweprintf, but calls exit(stats) afterwards.
The following functions, which call `eprintf` on failure, are also defined:
- void libsimple_eputenvf(const char *, ...)
void libsimple_evputenvf(const char *, va_list)
+ void libsimple_eputenvf(const char *, ...)
+ void *libsimple_emallocz(int, size_t)
void *libsimple_emalloc(size_t)
void *libsimple_ecalloc(size_t, size_t)
void *libsimple_erealloc(void *, size_t)
char *libsimple_estrdup(const char *)
char *libsimple_estrndup(const char *, size_t)
void *libsimple_ememdup(const void *, size_t)
+ void *libsimple_evmallocn(size_t, va_list)
+ void *libsimple_evcallocn(size_t, va_list)
+ void *libsimple_evreallocn(void *, size_t, va_list)
+ void *libsimple_evmalloczn(int, size_t, va_list)
+ void *libsimple_emalloczn(int, size_t, ...)
+ void *libsimple_emallocn(size_t, ...)
+ void *libsimple_ecallocn(size_t, ...)
+ void *libsimple_ereallocn(void *, size_t, ...)
+
The following functions, which call `enprintf` on failure, are also defined,
the first argument is used as the first argument for `enprintf`:
- void libsimple_enputenvf(int, const char *, ...)
void libsimple_envputenvf(int, const char *, va_list)
+ void libsimple_enputenvf(int, const char *, ...)
+ void *libsimple_enmallocz(int, size_t)
void *libsimple_enmalloc(int, size_t)
void *libsimple_encalloc(int, size_t, size_t)
void *libsimple_enrealloc(int, void *, size_t)
char *libsimple_enstrdup(int, const char *)
char *libsimple_enstrndup(int, const char *, size_t)
void *libsimple_enmemdup(int, const void *, size_t)
+ void *libsimple_envmallocn(int, size_t, va_list)
+ void *libsimple_envcallocn(int, size_t, va_list)
+ void *libsimple_envreallocn(int, void *, size_t, va_list)
+ void *libsimple_envmalloczn(int, int, size_t, va_list)
+ void *libsimple_enmalloczn(int, int, size_t, ...)
+ void *libsimple_enmallocn(int, size_t, ...)
+ void *libsimple_encallocn(int, size_t, ...)
+ void *libsimple_enreallocn(int, void *, size_t, ...)
diff --git a/encalloc.c b/encalloc.c
index de5a2c9..f930f82 100644
--- a/encalloc.c
+++ b/encalloc.c
@@ -4,7 +4,7 @@
void *
-libsimple_encalloc(int status, size_t n, size_t m) /* TODO test */
+libsimple_encalloc(int status, size_t n, size_t m)
{
void *ret = calloc(n, m);
if (!ret)
@@ -19,6 +19,41 @@ libsimple_encalloc(int status, size_t n, size_t m) /* TODO test */
int
main(void)
{
+ struct allocinfo *info;
+ void *ptr;
+
+ assert((ptr = libsimple_encalloc(1, 2, 5)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 10);
+ assert(info->zeroed == 10);
+ }
+ free(ptr);
+
+ assert((ptr = libsimple_ecalloc(3, 4)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 12);
+ assert(info->zeroed == 12);
+ }
+ free(ptr);
+
+ if (have_custom_malloc()) {
+ alloc_fail_in = 1;
+ assert_exit_ptr(libsimple_encalloc(5, 1, 1));
+ assert(exit_status == 5);
+ assert_stderr("%s: calloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+
+ libsimple_default_failure_exit = 103;
+ alloc_fail_in = 1;
+ assert_exit_ptr(libsimple_ecalloc(1, 1));
+ assert(exit_status == 103);
+ assert_stderr("%s: calloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+ libsimple_default_failure_exit = 1;
+ }
+
return 0;
}
diff --git a/enmalloc.c b/enmalloc.c
index f981872..edf4b5e 100644
--- a/enmalloc.c
+++ b/enmalloc.c
@@ -4,7 +4,7 @@
void *
-libsimple_enmalloc(int status, size_t n) /* TODO test */
+libsimple_enmalloc(int status, size_t n)
{
void *ret = malloc(n);
if (!ret)
@@ -19,6 +19,41 @@ libsimple_enmalloc(int status, size_t n) /* TODO test */
int
main(void)
{
+ struct allocinfo *info;
+ void *ptr;
+
+ assert((ptr = libsimple_enmalloc(1, 5)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 5);
+ assert(!info->zeroed);
+ }
+ free(ptr);
+
+ assert((ptr = libsimple_emalloc(4)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 4);
+ assert(!info->zeroed);
+ }
+ free(ptr);
+
+ if (have_custom_malloc()) {
+ alloc_fail_in = 1;
+ assert_exit_ptr(libsimple_enmalloc(3, 4));
+ assert(exit_status == 3);
+ assert_stderr("%s: malloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+
+ libsimple_default_failure_exit = 102;
+ alloc_fail_in = 1;
+ assert_exit_ptr(libsimple_emalloc(3));
+ assert(exit_status == 102);
+ assert_stderr("%s: malloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+ libsimple_default_failure_exit = 1;
+ }
+
return 0;
}
diff --git a/enmemdup.c b/enmemdup.c
index 9050efd..b573b7b 100644
--- a/enmemdup.c
+++ b/enmemdup.c
@@ -4,7 +4,7 @@
void *
-libsimple_enmemdup(int status, const void *s, size_t n) /* TODO test */
+libsimple_enmemdup(int status, const void *s, size_t n) /* TODO test (libsimple_ememdup) */
{
void *ret = memdup(s, n);
if (!ret)
diff --git a/enrealloc.c b/enrealloc.c
index 92a50db..59033e7 100644
--- a/enrealloc.c
+++ b/enrealloc.c
@@ -4,7 +4,7 @@
void *
-libsimple_enrealloc(int status, void *ptr, size_t n) /* TODO test */
+libsimple_enrealloc(int status, void *ptr, size_t n)
{
char *ret = realloc(ptr, n);
if (!ret)
@@ -19,6 +19,63 @@ libsimple_enrealloc(int status, void *ptr, size_t n) /* TODO test */
int
main(void)
{
+ struct allocinfo *info;
+ void *ptr, *old;
+
+ assert((ptr = libsimple_enrealloc(1, NULL, 5)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 5);
+ assert(!info->zeroed);
+ info->refcount += 1;
+ }
+ stpcpy(ptr, "test");
+ assert((ptr = libsimple_enrealloc(1, old = ptr, 10)));
+ assert(!strcmp(ptr, "test"));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 10);
+ assert(!info->zeroed);
+ assert(ptr != old);
+ free(old);
+ }
+ free(ptr);
+
+ assert((ptr = libsimple_erealloc(NULL, 5)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 5);
+ assert(!info->zeroed);
+ info->refcount += 1;
+ }
+ stpcpy(ptr, "test");
+ assert((ptr = libsimple_erealloc(old = ptr, 10)));
+ assert(!strcmp(ptr, "test"));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 10);
+ assert(!info->zeroed);
+ assert(ptr != old);
+ free(old);
+ }
+ free(ptr);
+
+ if (have_custom_malloc()) {
+ alloc_fail_in = 1;
+ assert_exit_ptr(libsimple_enrealloc(2, NULL, 1));
+ assert(exit_status == 2);
+ assert_stderr("%s: realloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+
+ libsimple_default_failure_exit = 104;
+ alloc_fail_in = 1;
+ assert_exit_ptr(libsimple_erealloc(NULL, 1));
+ assert(exit_status == 104);
+ assert_stderr("%s: realloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+ libsimple_default_failure_exit = 1;
+ }
+
return 0;
}
diff --git a/enstrdup.c b/enstrdup.c
index d8a8c53..5baeed8 100644
--- a/enstrdup.c
+++ b/enstrdup.c
@@ -4,7 +4,7 @@
char *
-libsimple_enstrdup(int status, const char *s) /* TODO test */
+libsimple_enstrdup(int status, const char *s) /* TODO test (libsimple_estrdup) */
{
char *ret = strdup(s);
if (!ret)
diff --git a/enstrndup.c b/enstrndup.c
index 8803a99..367ab3c 100644
--- a/enstrndup.c
+++ b/enstrndup.c
@@ -4,7 +4,7 @@
char *
-libsimple_enstrndup(int status, const char *s, size_t n) /* TODO test */
+libsimple_enstrndup(int status, const char *s, size_t n) /* TODO test (libsimple_estrndup) */
{
void *ret = strndup(s, n);
if (!ret)
diff --git a/envmalloczn.c b/envmalloczn.c
index 84c0ea7..7531ecf 100644
--- a/envmalloczn.c
+++ b/envmalloczn.c
@@ -4,7 +4,7 @@
void *
-libsimple_envmalloczn(int status, int clear, size_t n, va_list ap) /* TODO test */
+libsimple_envmalloczn(int status, int clear, size_t n, va_list ap)
{
void *ret = libsimple_vmalloczn(clear, n, ap);
if (!ret)
@@ -19,6 +19,166 @@ libsimple_envmalloczn(int status, int clear, size_t n, va_list ap) /* TODO test
int
main(void)
{
+ struct allocinfo *info;
+ void *ptr;
+
+ assert((ptr = libsimple_enmalloczn(1, 0, 5, 3, 0)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 15);
+ assert(!info->zeroed);
+ }
+ free(ptr);
+
+ assert((ptr = libsimple_enmalloczn(1, 1, 5, 4, 0)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 20);
+ assert(info->zeroed == 20);
+ }
+ free(ptr);
+
+ assert((ptr = libsimple_enmallocn(1, 4, 3, 0)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 12);
+ assert(!info->zeroed);
+ }
+ free(ptr);
+
+ assert((ptr = libsimple_encallocn(1, 4, 4, 0)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 16);
+ assert(info->zeroed == 16);
+ }
+ free(ptr);
+
+ if (have_custom_malloc()) {
+ alloc_fail_in = 1;
+ assert_exit_ptr(libsimple_enmalloczn(3, 0, 4, 0));
+ assert(exit_status == 3);
+ stderr_buf[stderr_n] = 0;
+ assert_stderr("%s: malloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+
+ alloc_fail_in = 1;
+ assert_exit_ptr(libsimple_enmalloczn(5, 1, 2, 0));
+ assert(exit_status == 5);
+ assert_stderr("%s: calloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+
+ alloc_fail_in = 1;
+ assert_exit_ptr(libsimple_enmallocn(9, 1, 0));
+ assert(exit_status == 9);
+ assert_stderr("%s: malloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+
+ alloc_fail_in = 1;
+ assert_exit_ptr(libsimple_encallocn(7, 5, 0));
+ assert(exit_status == 7);
+ assert_stderr("%s: calloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+ }
+
+ assert_exit_ptr(libsimple_enmalloczn(13, 0, SIZE_MAX, 2, 0));
+ assert(exit_status == 13);
+ assert_stderr("%s: malloc: %s\n", argv0, strerror(ENOMEM));
+
+ assert_exit_ptr(libsimple_enmalloczn(15, 1, SIZE_MAX, 2, 0));
+ assert(exit_status == 15);
+ assert_stderr("%s: calloc: %s\n", argv0, strerror(ENOMEM));
+
+ assert_exit_ptr(libsimple_enmallocn(19, SIZE_MAX, 2, 0));
+ assert(exit_status == 19);
+ assert_stderr("%s: malloc: %s\n", argv0, strerror(ENOMEM));
+
+ assert_exit_ptr(libsimple_encallocn(17, SIZE_MAX, 2, 0));
+ assert(exit_status == 17);
+ assert_stderr("%s: calloc: %s\n", argv0, strerror(ENOMEM));
+
+ assert((ptr = libsimple_emalloczn(0, 2, 5, 3, 0)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 30);
+ assert(!info->zeroed);
+ }
+ free(ptr);
+
+ assert((ptr = libsimple_emalloczn(1, 2, 5, 4, 0)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 40);
+ assert(info->zeroed == 40);
+ }
+ free(ptr);
+
+ assert((ptr = libsimple_emallocn(2, 4, 3, 0)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 24);
+ assert(!info->zeroed);
+ }
+ free(ptr);
+
+ assert((ptr = libsimple_ecallocn(2, 4, 4, 0)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 32);
+ assert(info->zeroed == 32);
+ }
+ free(ptr);
+
+ if (have_custom_malloc()) {
+ alloc_fail_in = 1;
+ libsimple_default_failure_exit = 23;
+ assert_exit_ptr(libsimple_emalloczn(0, 4, 0));
+ assert(exit_status == 23);
+ assert_stderr("%s: malloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+
+ alloc_fail_in = 1;
+ libsimple_default_failure_exit = 25;
+ assert_exit_ptr(libsimple_emalloczn(1, 2, 0));
+ assert(exit_status == 25);
+ assert_stderr("%s: calloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+
+ alloc_fail_in = 1;
+ libsimple_default_failure_exit = 29;
+ assert_exit_ptr(libsimple_emallocn(1, 0));
+ assert(exit_status == 29);
+ assert_stderr("%s: malloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+
+ alloc_fail_in = 1;
+ libsimple_default_failure_exit = 27;
+ assert_exit_ptr(libsimple_ecallocn(5, 0));
+ assert(exit_status == 27);
+ assert_stderr("%s: calloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+ }
+
+ libsimple_default_failure_exit = 33;
+ assert_exit_ptr(libsimple_emalloczn(0, SIZE_MAX, 2, 0));
+ assert(exit_status == 33);
+ assert_stderr("%s: malloc: %s\n", argv0, strerror(ENOMEM));
+
+ libsimple_default_failure_exit = 35;
+ assert_exit_ptr(libsimple_emalloczn(1, SIZE_MAX, 2, 0));
+ assert(exit_status == 35);
+ assert_stderr("%s: calloc: %s\n", argv0, strerror(ENOMEM));
+
+ libsimple_default_failure_exit = 39;
+ assert_exit_ptr(libsimple_emallocn(SIZE_MAX, 2, 0));
+ assert(exit_status == 39);
+ assert_stderr("%s: malloc: %s\n", argv0, strerror(ENOMEM));
+
+ libsimple_default_failure_exit = 37;
+ assert_exit_ptr(libsimple_ecallocn(SIZE_MAX, 2, 0));
+ assert(exit_status == 37);
+ assert_stderr("%s: calloc: %s\n", argv0, strerror(ENOMEM));
+
return 0;
}
diff --git a/envputenvf.c b/envputenvf.c
index 7bc1f0a..bef9867 100644
--- a/envputenvf.c
+++ b/envputenvf.c
@@ -4,7 +4,7 @@
void
-libsimple_envputenvf(int status, const char *fmt, va_list ap) /* TODO test */
+libsimple_envputenvf(int status, const char *fmt, va_list ap) /* TODO test (enputenvf, evputenvf, eputenvf) */
{
if (libsimple_vputenvf(fmt, ap))
enprintf(status, "putenvf:");
diff --git a/envreallocn.c b/envreallocn.c
index 1956933..b6ef1c1 100644
--- a/envreallocn.c
+++ b/envreallocn.c
@@ -4,7 +4,7 @@
void *
-libsimple_envreallocn(int status, void *ptr, size_t n, va_list ap) /* TODO test */
+libsimple_envreallocn(int status, void *ptr, size_t n, va_list ap) /* TODO test (enreallocn, ereallocn) */
{
void *ret = libsimple_vreallocn(ptr, n, ap);
if (!ret)
diff --git a/libsimple.c b/libsimple.c
index 24c5dd3..9a182c6 100644
--- a/libsimple.c
+++ b/libsimple.c
@@ -75,6 +75,8 @@ test_timeval(double d, time_t sec, long int usec, double rd, const char *s, cons
int
main(void)
{
+ struct allocinfo *info;
+ void *ptr;
struct timespec ts, ts1, ts2;
struct timeval tv1, tv2;
const char *cs;
@@ -82,6 +84,8 @@ main(void)
int intarray[10];
size_t i, n;
+ assert(libsimple_default_failure_exit == 1);
+
assert(MIN(1, 3) == 1);
assert(MIN(1, 1) == 1);
assert(MIN(3, 1) == 1);
@@ -990,12 +994,95 @@ main(void)
tv2.tv_sec = 1, tv2.tv_usec = 0L;
assert(libsimple_cmptimeval(&tv1, &tv2) == -1);
+ assert((ptr = libsimple_mallocz(0, 11)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 11);
+ assert(!info->zeroed);
+ }
+ free(ptr);
+
+ assert((ptr = libsimple_mallocz(1, 12)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 12);
+ assert(info->zeroed == 12);
+ }
+ free(ptr);
+
+ assert((ptr = libsimple_emallocz(0, 13)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 13);
+ assert(!info->zeroed);
+ }
+ free(ptr);
+
+ assert((ptr = libsimple_emallocz(1, 14)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 14);
+ assert(info->zeroed == 14);
+ }
+ free(ptr);
+
+ assert((ptr = libsimple_enmallocz(10, 0, 15)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 15);
+ assert(!info->zeroed);
+ }
+ free(ptr);
+
+ assert((ptr = libsimple_enmallocz(10, 1, 16)));
+ if (have_custom_malloc()) {
+ assert((info = get_allocinfo(ptr)));
+ assert(info->size == 16);
+ assert(info->zeroed == 16);
+ }
+ free(ptr);
+
+ if (have_custom_malloc()) {
+ alloc_fail_in = 1;
+ assert_exit_ptr(libsimple_enmallocz(5, 0, 20));
+ assert(exit_status == 5);
+ assert_stderr("%s: malloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+
+ alloc_fail_in = 1;
+ assert_exit_ptr(libsimple_enmallocz(6, 1, 20));
+ assert(exit_status == 6);
+ assert_stderr("%s: calloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+
+ libsimple_default_failure_exit = 7;
+ alloc_fail_in = 1;
+ assert_exit_ptr(libsimple_emallocz(0, 20));
+ assert(exit_status == 7);
+ assert_stderr("%s: malloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+
+ libsimple_default_failure_exit = 8;
+ alloc_fail_in = 1;
+ assert_exit_ptr(libsimple_emallocz(1, 20));
+ assert(exit_status == 8);
+ assert_stderr("%s: calloc: %s\n", argv0, strerror(ENOMEM));
+ assert(!alloc_fail_in);
+
+ alloc_fail_in = 1;
+ assert(!(ptr = libsimple_mallocz(0, 20)) && errno == ENOMEM);
+ assert(!alloc_fail_in);
+
+ alloc_fail_in = 1;
+ assert(!(ptr = libsimple_mallocz(1, 20)) && errno == ENOMEM);
+ assert(!alloc_fail_in);
+ }
+
if (!have_custom_malloc()) {
stderr_real = 1;
fprintf(stderr, "\nSome tests have not been ran because malloc(3) was not "
"replaced, this is normal if running under valgrind(1).\n\n");
}
-
return 0;
}
diff --git a/libsimple.h b/libsimple.h
index 7f54b8a..24dda8b 100644
--- a/libsimple.h
+++ b/libsimple.h
@@ -500,14 +500,12 @@ void *libsimple_rawmemchr(const void *, int);
# define rawmemchr libsimple_rawmemchr
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
void *libsimple_memrchr(const void *, int, size_t);
#ifndef memrchr
# define memrchr libsimple_memrchr
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
void *libsimple_rawmemrchr(const void *, int, size_t);
#ifndef rawmemrchr
@@ -521,16 +519,16 @@ char *libsimple_strchrnul(const char *, int);
# define strchrnul libsimple_strchrnul
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
-static inline char *libsimple_strend(const char *__s) { return strchr(__s, '\0'); }
+static inline char *libsimple_strend(const char *__s)
+{ return strchr(__s, '\0'); }
#ifndef strend
# define strend libsimple_strend
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
-static inline int libsimple_inchrset(int __c, const char *__s) { return __c && strchr(__s, __c); }
+static inline int libsimple_inchrset(int __c, const char *__s)
+{ return __c && strchr(__s, __c); }
#ifndef inchrset
# define inchrset libsimple_inchrset
#endif
@@ -542,7 +540,6 @@ void *libsimple_memdup(const void *, size_t);
# define memdup libsimple_memdup
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __warn_unused_result__)))
char *libsimple_strndup(const char *, size_t);
#ifndef strndup
@@ -571,7 +568,6 @@ static inline void *libsimple_mempcpy(void *__d, const void *__s, size_t __n)
# endif
#endif
-
#if defined(__GNUC__) || defined(__clang__)
# define libsimple_strndupa(s, n)\
({\
@@ -590,7 +586,6 @@ static inline void *libsimple_mempcpy(void *__d, const void *__s, size_t __n)
# endif
#endif
-
#if defined(__GNUC__) || defined(__clang__)
# define libsimple_memdupa(s, n)\
({\
@@ -625,14 +620,12 @@ int libsimple_asprintf(char **, const char *, ...);
# define asprintf libsimple_asprintf
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1, 2))))
int libsimple_vasprintf(char **, const char *, va_list);
#ifndef vasprintf
# define vasprintf libsimple_vasprintf
#endif
-
#if defined(__GNUC__) && !defined(__clang__)
# define libsimple_asprintfa(__fmt, ...) /* TODO test */\
({\
@@ -650,7 +643,6 @@ int libsimple_vasprintf(char **, const char *, va_list);
# endif
#endif
-
#if defined(__GNUC__) || defined(__clang__)
# define libsimple_vasprintfa(__fmt, __ap) /* TODO test */\
({\
@@ -680,21 +672,18 @@ void *libsimple_memmem(const void *, size_t, const void *, size_t);
# define memmem libsimple_memmem
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
void *libsimple_memrmem(const void *, size_t, const void *, size_t);
#ifndef memrmem
# define memrmem libsimple_memrmem
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
int libsimple_memstarts(const void *, size_t, const void *, size_t);
#ifndef memstarts
# define memstarts libsimple_memstarts
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
int libsimple_memends(const void *, size_t, const void *, size_t);
#ifndef memends
@@ -708,76 +697,66 @@ char *libsimple_strrstr(const char *, const char *);
# define strrstr libsimple_strrstr
#endif
-
-_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
-char *libsimple_strrnstr(const char *, const char *, size_t);
-#ifndef strrnstr
-# define strrnstr libsimple_strrnstr
-#endif
-
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
char *libsimple_strnstr(const char *, const char *, size_t);
#ifndef strnstr
# define strnstr libsimple_strnstr
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
-char *libsimple_strrncasestr(const char *, const char *, size_t);
-#ifndef strrncasestr
-# define strrncasestr libsimple_strrncasestr
-#endif
-
-
-_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
-char *libsimple_strncasestr(const char *, const char *, size_t);
-#ifndef strncasestr
-# define strncasestr libsimple_strncasestr
+char *libsimple_strrnstr(const char *, const char *, size_t);
+#ifndef strrnstr
+# define strrnstr libsimple_strrnstr
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
int libsimple_strstarts(const char *, const char *);
#ifndef strstarts
# define strstarts libsimple_strstarts
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
-static inline int libsimple_strcasestarts(const char *__s, const char *__t) { return !strncasecmp(__s, __t, strlen(__t)); }
+static inline int libsimple_strcasestarts(const char *__s, const char *__t)
+{ return !strncasecmp(__s, __t, strlen(__t)); }
#ifndef strcasestarts
# define strcasestarts libsimple_strcasestarts
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
int libsimple_strends(const char *, const char *);
#ifndef strends
# define strends libsimple_strends
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
int libsimple_strcaseends(const char *, const char *);
#ifndef strcaseends
# define strcaseends libsimple_strcaseends
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
char *libsimple_strcasestr(const char *, const char *);
#ifndef strcasestr
# define strcasestr libsimple_strcasestr
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
char *libsimple_strrcasestr(const char *, const char *);
#ifndef strrcasestr
# define strrcasestr libsimple_strrcasestr
#endif
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
+char *libsimple_strncasestr(const char *, const char *, size_t);
+#ifndef strncasestr
+# define strncasestr libsimple_strncasestr
+#endif
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
+char *libsimple_strrncasestr(const char *, const char *, size_t);
+#ifndef strrncasestr
+# define strrncasestr libsimple_strrncasestr
+#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
static inline int libsimple_strcmpnul(const char *__a, const char *__b)
@@ -786,15 +765,6 @@ static inline int libsimple_strcmpnul(const char *__a, const char *__b)
# define strcmpnul libsimple_strcmpnul
#endif
-
-_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
-static inline int libsimple_strcasecmpnul(const char *__a, const char *__b)
-{ return (!__a || !__b) ? !__b - !__a : strcasecmp(__a, __b); }
-#ifndef strcasecmpnul
-# define strcasecmpnul libsimple_strcasecmpnul
-#endif
-
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
static inline int libsimple_strncmpnul(const char *__a, const char *__b, size_t __n)
{ return (!__a || !__b) ? !__b - !__a : strncmp(__a, __b, __n); }
@@ -802,6 +772,12 @@ static inline int libsimple_strncmpnul(const char *__a, const char *__b, size_t
# define strncmpnul libsimple_strncmpnul
#endif
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
+static inline int libsimple_strcasecmpnul(const char *__a, const char *__b)
+{ return (!__a || !__b) ? !__b - !__a : strcasecmp(__a, __b); }
+#ifndef strcasecmpnul
+# define strcasecmpnul libsimple_strcasecmpnul
+#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
static inline int libsimple_strncasecmpnul(const char *__a, const char *__b, size_t __n)
@@ -810,28 +786,27 @@ static inline int libsimple_strncasecmpnul(const char *__a, const char *__b, siz
# define strncasecmpnul libsimple_strncasecmpnul
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
-static inline int libsimple_streq(const char *__a, const char *__b) { return !strcmp(__a, __b); }
+static inline int libsimple_streq(const char *__a, const char *__b)
+{ return !strcmp(__a, __b); }
#ifndef streq
# define streq libsimple_streq
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
-static inline int libsimple_strneq(const char *__a, const char *__b, size_t __n) { return !strncmp(__a, __b, __n); }
+static inline int libsimple_strneq(const char *__a, const char *__b, size_t __n)
+{ return !strncmp(__a, __b, __n); }
#ifndef strneq
# define strneq libsimple_strneq
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
-static inline int libsimple_streqnul(const char *__a, const char *__b) { return !strcmpnul(__a, __b); }
+static inline int libsimple_streqnul(const char *__a, const char *__b)
+{ return !strcmpnul(__a, __b); }
#ifndef streqnul
# define streqnul libsimple_streqnul
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
static inline int libsimple_strneqnul(const char *__a, const char *__b, size_t __n)
{ return !strncmpnul(__a, __b, __n); }
@@ -839,28 +814,27 @@ static inline int libsimple_strneqnul(const char *__a, const char *__b, size_t _
# define strneqnul libsimple_strneqnul
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
-static inline int libsimple_strcaseeq(const char *__a, const char *__b) { return !strcasecmp(__a, __b); }
+static inline int libsimple_strcaseeq(const char *__a, const char *__b)
+{ return !strcasecmp(__a, __b); }
#ifndef strcaseeq
# define strcaseeq libsimple_strcaseeq
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
-static inline int libsimple_strncaseeq(const char *__a, const char *__b, size_t __n) { return !strncasecmp(__a, __b, __n); }
+static inline int libsimple_strncaseeq(const char *__a, const char *__b, size_t __n)
+{ return !strncasecmp(__a, __b, __n); }
#ifndef strncaseeq
# define strncaseeq libsimple_strncaseeq
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
-static inline int libsimple_strcaseeqnul(const char *__a, const char *__b) { return !strcasecmpnul(__a, __b); }
+static inline int libsimple_strcaseeqnul(const char *__a, const char *__b)
+{ return !strcasecmpnul(__a, __b); }
#ifndef strcaseeqnul
# define strcaseeqnul libsimple_strcaseeqnul
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
static inline int libsimple_strncaseeqnul(const char *__a, const char *__b, size_t __n)
{ return !strncasecmpnul(__a, __b, __n); }
@@ -876,13 +850,15 @@ void *libsimple_vmalloczn(int, size_t, va_list);
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
-static inline void *libsimple_vmallocn(size_t __n, va_list __ap) { return libsimple_vmalloczn(0, __n, __ap); }
+static inline void *libsimple_vmallocn(size_t __n, va_list __ap)
+{ return libsimple_vmalloczn(0, __n, __ap); }
#ifndef vmallocn
# define vmallocn libsimple_vmallocn
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
-static inline void *libsimple_vcallocn(size_t __n, va_list __ap) { return libsimple_vmalloczn(1, __n, __ap); }
+static inline void *libsimple_vcallocn(size_t __n, va_list __ap)
+{ return libsimple_vmalloczn(1, __n, __ap); }
#ifndef vcallocn
# define vcallocn libsimple_vcallocn
#endif
@@ -895,7 +871,15 @@ void *libsimple_vreallocn(void *, size_t, va_list);
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
static inline void *
-libsimple_malloczn(int __clear, size_t __n, ...)
+libsimple_mallocz(int __clear, size_t __n)
+{ return __clear ? calloc(1, __n) : malloc(__n); }
+#ifndef mallocn
+# define mallocn libsimple_mallocn
+#endif
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
+static inline void *
+libsimple_malloczn(int __clear, size_t __n, ... /*, (size_t)0 */)
{
va_list __ap;
va_start(__ap, __n);
@@ -908,7 +892,7 @@ libsimple_malloczn(int __clear, size_t __n, ...)
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
static inline void *
-libsimple_mallocn(size_t __n, ...)
+libsimple_mallocn(size_t __n, ... /*, (size_t)0 */)
{
va_list __ap;
va_start(__ap, __n);
@@ -921,7 +905,7 @@ libsimple_mallocn(size_t __n, ...)
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
static inline void *
-libsimple_callocn(size_t __n, ...)
+libsimple_callocn(size_t __n, ... /*, (size_t)0 */)
{
va_list __ap;
va_start(__ap, __n);
@@ -934,7 +918,7 @@ libsimple_callocn(size_t __n, ...)
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
static inline void *
-libsimple_reallocn(void *__ptr, size_t __n, ...)
+libsimple_reallocn(void *__ptr, size_t __n, ... /*, (size_t)0 */)
{
va_list __ap;
va_start(__ap, __n);
@@ -945,7 +929,6 @@ libsimple_reallocn(void *__ptr, size_t __n, ...)
# define reallocn libsimple_reallocn
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
void *libsimple_enmalloc(int, size_t);
#ifndef enmalloc
@@ -964,6 +947,13 @@ void *libsimple_enrealloc(int, void *, size_t);
# define enrealloc libsimple_enrealloc
#endif
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
+static inline void *libsimple_enmallocz(int __status, int __clear, size_t __n)
+{ return __clear ? libsimple_encalloc(__status, 1, __n) : libsimple_enmalloc(__status, __n); }
+#ifndef enmallocz
+# define enmallocz libsimple_enmallocz
+#endif
+
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __warn_unused_result__, __returns_nonnull__)))
char *libsimple_enstrdup(int, const char *);
#ifndef enstrdup
@@ -989,13 +979,15 @@ void *libsimple_envmalloczn(int, int, size_t, va_list);
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
-static inline void *libsimple_envmallocn(int __st, size_t __n, va_list __ap) { return libsimple_envmalloczn(__st, 0, __n, __ap); } /* TODO test */
+static inline void *libsimple_envmallocn(int __st, size_t __n, va_list __ap)
+{ return libsimple_envmalloczn(__st, 0, __n, __ap); }
#ifndef envmallocn
# define envmallocn libsimple_envmallocn
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
-static inline void *libsimple_envcallocn(int __st, size_t __n, va_list __ap) { return libsimple_envmalloczn(__st, 1, __n, __ap); } /* TODO test */
+static inline void *libsimple_envcallocn(int __st, size_t __n, va_list __ap)
+{ return libsimple_envmalloczn(__st, 1, __n, __ap); }
#ifndef envcallocn
# define envcallocn libsimple_envcallocn
#endif
@@ -1008,7 +1000,7 @@ void *libsimple_envreallocn(int, void *, size_t, va_list);
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
-libsimple_enmalloczn(int __status, int __clear, size_t __n, ...) /* TODO test */
+libsimple_enmalloczn(int __status, int __clear, size_t __n, ... /*, (size_t)0 */)
{
va_list __ap;
va_start(__ap, __n);
@@ -1021,11 +1013,11 @@ libsimple_enmalloczn(int __status, int __clear, size_t __n, ...) /* TODO test */
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
-libsimple_enmallocn(int __status, size_t __n, ...) /* TODO test */
+libsimple_enmallocn(int __status, size_t __n, ... /*, (size_t)0 */)
{
va_list __ap;
va_start(__ap, __n);
- return libsimple_envmalloczn(__status, 0, __n, __ap);
+ return libsimple_envmallocn(__status, __n, __ap);
va_end(__ap);
}
#ifndef enmallocn
@@ -1034,11 +1026,11 @@ libsimple_enmallocn(int __status, size_t __n, ...) /* TODO test */
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
-libsimple_encallocn(int __status, size_t __n, ...) /* TODO test */
+libsimple_encallocn(int __status, size_t __n, ... /*, (size_t)0 */)
{
va_list __ap;
va_start(__ap, __n);
- return libsimple_envmalloczn(__status, 1, __n, __ap);
+ return libsimple_envcallocn(__status, __n, __ap);
va_end(__ap);
}
#ifndef encallocn
@@ -1047,7 +1039,7 @@ libsimple_encallocn(int __status, size_t __n, ...) /* TODO test */
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
-libsimple_enreallocn(int __status, void *__ptr, size_t __n, ...) /* TODO test */
+libsimple_enreallocn(int __status, void *__ptr, size_t __n, ... /*, (size_t)0 */)
{
va_list __ap;
va_start(__ap, __n);
@@ -1058,66 +1050,78 @@ libsimple_enreallocn(int __status, void *__ptr, size_t __n, ...) /* TODO test */
# define enreallocn libsimple_enreallocn
#endif
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
+static inline void *libsimple_emallocz(int __clear, size_t __n)
+{ return libsimple_enmallocz(libsimple_default_failure_exit, __clear, __n); }
+#ifndef emallocz
+# define emallocz libsimple_emallocz
+#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
-static inline void *libsimple_emalloc(size_t __n) { return enmalloc(libsimple_default_failure_exit, __n); } /* TODO test */
+static inline void *libsimple_emalloc(size_t __n)
+{ return libsimple_enmalloc(libsimple_default_failure_exit, __n); }
#ifndef emalloc
# define emalloc libsimple_emalloc
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
-static inline void *libsimple_ecalloc(size_t __n, size_t __m) { return encalloc(libsimple_default_failure_exit, __n, __m); } /* TODO test */
+static inline void *libsimple_ecalloc(size_t __n, size_t __m)
+{ return encalloc(libsimple_default_failure_exit, __n, __m); }
#ifndef ecalloc
# define ecalloc libsimple_ecalloc
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
-static inline void *libsimple_erealloc(void *__ptr, size_t __n) { return enrealloc(libsimple_default_failure_exit, __ptr, __n); } /* TODO test */
+static inline void *libsimple_erealloc(void *__ptr, size_t __n)
+{ return enrealloc(libsimple_default_failure_exit, __ptr, __n); }
#ifndef erealloc
# define erealloc libsimple_erealloc
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, __warn_unused_result__, __returns_nonnull__)))
-static inline char *libsimple_estrdup(const char *__s) { return enstrdup(libsimple_default_failure_exit, __s); } /* TODO test */
+static inline char *libsimple_estrdup(const char *__s)
+{ return enstrdup(libsimple_default_failure_exit, __s); }
#ifndef estrdup
# define estrdup libsimple_estrdup
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, __warn_unused_result__, __returns_nonnull__)))
-static inline char *libsimple_estrndup(const char *__s, size_t __n) { return enstrndup(libsimple_default_failure_exit, __s, __n); } /* TODO test */
+static inline char *libsimple_estrndup(const char *__s, size_t __n)
+{ return enstrndup(libsimple_default_failure_exit, __s, __n); }
#ifndef estrndup
# define estrndup libsimple_estrndup
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
-static inline void *libsimple_ememdup(const void *__s, size_t __n) { return enmemdup(libsimple_default_failure_exit, __s, __n); } /* TODO test */
+static inline void *libsimple_ememdup(const void *__s, size_t __n)
+{ return enmemdup(libsimple_default_failure_exit, __s, __n); }
#ifndef ememdup
# define ememdup libsimple_ememdup
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
-static inline void *libsimple_evmalloczn(int __clear, size_t __n, va_list __ap) /* TODO test */
+static inline void *libsimple_evmalloczn(int __clear, size_t __n, va_list __ap)
{ return libsimple_envmalloczn(libsimple_default_failure_exit, __clear, __n, __ap); }
#ifndef evmalloczn
# define evmalloczn libsimple_evmalloczn
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
-static inline void *libsimple_evmallocn(size_t __n, va_list __ap) /* TODO test */
-{ return libsimple_envcallocn(libsimple_default_failure_exit, __n, __ap); }
+static inline void *libsimple_evmallocn(size_t __n, va_list __ap)
+{ return libsimple_envmallocn(libsimple_default_failure_exit, __n, __ap); }
#ifndef evmallocn
# define evmallocn libsimple_evmallocn
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
-static inline void *libsimple_evcallocn(size_t __n, va_list __ap) /* TODO test */
-{ return libsimple_envmallocn(libsimple_default_failure_exit, __n, __ap); }
+static inline void *libsimple_evcallocn(size_t __n, va_list __ap)
+{ return libsimple_envcallocn(libsimple_default_failure_exit, __n, __ap); }
#ifndef evcallocn
# define evcallocn libsimple_evcallocn
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
-static inline void *libsimple_evreallocn(void *__ptr, size_t __n, va_list __ap) /* TODO test */
+static inline void *libsimple_evreallocn(void *__ptr, size_t __n, va_list __ap)
{ return libsimple_envreallocn(libsimple_default_failure_exit, __ptr, __n, __ap); }
#ifndef evreallocn
# define evreallocn libsimple_evreallocn
@@ -1125,11 +1129,11 @@ static inline void *libsimple_evreallocn(void *__ptr, size_t __n, va_list __ap)
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
-libsimple_emalloczn(int __c, size_t __n, ...) /* TODO test */
+libsimple_emalloczn(int __clear, size_t __n, ... /*, (size_t)0 */)
{
va_list __ap;
va_start(__ap, __n);
- return libsimple_envmalloczn(libsimple_default_failure_exit, __c, __n, __ap);
+ return libsimple_evmalloczn(__clear, __n, __ap);
va_end(__ap);
}
#ifndef emalloczn
@@ -1138,11 +1142,11 @@ libsimple_emalloczn(int __c, size_t __n, ...) /* TODO test */
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
-libsimple_emallocn(size_t __n, ...) /* TODO test */
+libsimple_emallocn(size_t __n, ... /*, (size_t)0 */)
{
va_list __ap;
va_start(__ap, __n);
- return libsimple_envmalloczn(libsimple_default_failure_exit, 0, __n, __ap);
+ return libsimple_evmallocn(__n, __ap);
va_end(__ap);
}
#ifndef emallocn
@@ -1151,11 +1155,11 @@ libsimple_emallocn(size_t __n, ...) /* TODO test */
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
-libsimple_ecallocn(size_t __n, ...) /* TODO test */
+libsimple_ecallocn(size_t __n, ... /*, (size_t)0 */)
{
va_list __ap;
va_start(__ap, __n);
- return libsimple_envmalloczn(libsimple_default_failure_exit, 1, __n, __ap);
+ return libsimple_evcallocn(__n, __ap);
va_end(__ap);
}
#ifndef ecallocn
@@ -1164,11 +1168,11 @@ libsimple_ecallocn(size_t __n, ...) /* TODO test */
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
-libsimple_ereallocn(void *__p, size_t __n, ...) /* TODO test */
+libsimple_ereallocn(void *__ptr, size_t __n, ... /*, (size_t)0 */)
{
va_list __ap;
va_start(__ap, __n);
- return libsimple_envreallocn(libsimple_default_failure_exit, __p, __n, __ap);
+ return libsimple_evreallocn(__ptr, __n, __ap);
va_end(__ap);
}
#ifndef ereallocn
@@ -1216,12 +1220,6 @@ int libsimple_vputenvf(const char *, va_list);
# define vputenvf libsimple_vputenvf
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
-void libsimple_envputenvf(int, const char *, va_list);
-#ifndef envputenvf
-# define envputenvf libsimple_envputenvf
-#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __format__(__printf__, 1, 2))))
static inline int
libsimple_putenvf(const char *__fmt, ...)
@@ -1235,22 +1233,28 @@ libsimple_putenvf(const char *__fmt, ...)
# define putenvf libsimple_putenvf
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __format__(__printf__, 1, 2))))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
+void libsimple_envputenvf(int, const char *, va_list);
+#ifndef envputenvf
+# define envputenvf libsimple_envputenvf
+#endif
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __format__(__printf__, 2, 3))))
static inline void
-libsimple_eputenvf(const char *__fmt, ...) /* TODO test */
+libsimple_enputenvf(int __status, const char *__fmt, ...)
{
va_list __ap;
va_start(__ap, __fmt);
- libsimple_envputenvf(libsimple_default_failure_exit, __fmt, __ap);
+ libsimple_envputenvf(__status, __fmt, __ap);
va_end(__ap);
}
-#ifndef eputenvf
-# define eputenvf libsimple_eputenvf
+#ifndef enputenvf
+# define enputenvf libsimple_enputenvf
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
static inline void
-libsimple_evputenvf(const char *__fmt, va_list __ap) /* TODO test */
+libsimple_evputenvf(const char *__fmt, va_list __ap)
{
libsimple_envputenvf(libsimple_default_failure_exit, __fmt, __ap);
}
@@ -1258,17 +1262,17 @@ libsimple_evputenvf(const char *__fmt, va_list __ap) /* TODO test */
# define evputenvf libsimple_evputenvf
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __format__(__printf__, 2, 3))))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __format__(__printf__, 1, 2))))
static inline void
-libsimple_enputenvf(int __status, const char *__fmt, ...) /* TODO test */
+libsimple_eputenvf(const char *__fmt, ...)
{
va_list __ap;
va_start(__ap, __fmt);
- libsimple_envputenvf(__status, __fmt, __ap);
+ libsimple_evputenvf(__fmt, __ap);
va_end(__ap);
}
-#ifndef enputenvf
-# define enputenvf libsimple_enputenvf
+#ifndef eputenvf
+# define eputenvf libsimple_eputenvf
#endif
@@ -1278,67 +1282,65 @@ void libsimple_vweprintf(const char *, va_list);
# define vweprintf libsimple_vweprintf
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1), __format__(__printf__, 1, 2), __noreturn__)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1), __format__(__printf__, 1, 2))))
static inline void
-libsimple_eprintf(const char *__fmt, ...) /* TODO test */
+libsimple_weprintf(const char *__fmt, ...)
{
va_list __ap;
va_start(__ap, __fmt);
libsimple_vweprintf(__fmt, __ap);
va_end(__ap);
- exit(libsimple_default_failure_exit);
}
-#ifndef eprintf
-# define eprintf libsimple_eprintf
+#ifndef weprintf
+# define weprintf libsimple_weprintf
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1), __noreturn__)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2), __noreturn__)))
static inline void
-libsimple_veprintf(const char *__fmt, va_list __ap) /* TODO test */
+libsimple_venprintf(int __status, const char *__fmt, va_list __ap)
{
libsimple_vweprintf(__fmt, __ap);
- exit(libsimple_default_failure_exit);
+ exit(__status);
}
-#ifndef veprintf
-# define veprintf libsimple_veprintf
+#ifndef venprintf
+# define venprintf libsimple_venprintf
#endif
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2), __format__(__printf__, 2, 3), __noreturn__)))
static inline void
-libsimple_enprintf(int __status, const char *__fmt, ...) /* TODO test */
+libsimple_enprintf(int __status, const char *__fmt, ...)
{
va_list __ap;
va_start(__ap, __fmt);
- libsimple_vweprintf(__fmt, __ap);
+ libsimple_venprintf(__status, __fmt, __ap);
va_end(__ap);
- exit(__status);
}
#ifndef enprintf
# define enprintf libsimple_enprintf
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2), __noreturn__)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1), __noreturn__)))
static inline void
-libsimple_venprintf(int __status, const char *__fmt, va_list __ap) /* TODO test */
+libsimple_veprintf(const char *__fmt, va_list __ap)
{
libsimple_vweprintf(__fmt, __ap);
- exit(__status);
+ exit(libsimple_default_failure_exit);
}
-#ifndef venprintf
-# define venprintf libsimple_venprintf
+#ifndef veprintf
+# define veprintf libsimple_veprintf
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1), __format__(__printf__, 1, 2))))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1), __format__(__printf__, 1, 2), __noreturn__)))
static inline void
-libsimple_weprintf(const char *__fmt, ...) /* TODO test */
+libsimple_eprintf(const char *__fmt, ...)
{
va_list __ap;
va_start(__ap, __fmt);
- libsimple_vweprintf(__fmt, __ap);
+ libsimple_veprintf(__fmt, __ap);
va_end(__ap);
}
-#ifndef weprintf
-# define weprintf libsimple_weprintf
+#ifndef eprintf
+# define eprintf libsimple_eprintf
#endif
@@ -1347,14 +1349,12 @@ int libsimple_sendfd(int, int);
# define sendfd libsimple_sendfd
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
int libsimple_recvfd(int);
#ifndef recvfd
# define recvfd libsimple_recvfd
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
ssize_t libsimple_recvfrom_timestamped(int, void *restrict, size_t, int, struct sockaddr *restrict,
socklen_t, struct timespec *restrict);
@@ -1362,7 +1362,6 @@ ssize_t libsimple_recvfrom_timestamped(int, void *restrict, size_t, int, struct
# define recvfrom_timestamped libsimple_recvfrom_timestamped
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
static inline ssize_t
libsimple_recv_timestamped(int __fd, void *restrict __buf, size_t __n, /* TODO test */
@@ -1381,21 +1380,18 @@ int libsimple_sumtimespec(struct timespec *, const struct timespec *, const stru
# define sumtimespec libsimple_sumtimespec
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
int libsimple_difftimespec(struct timespec *, const struct timespec *, const struct timespec *);
#ifndef difftimespec
# define difftimespec libsimple_difftimespec
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
int libsimple_multimespec(struct timespec *, const struct timespec *, int);
#ifndef multimespec
# define multimespec libsimple_multimespec
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __warn_unused_result__)))
static inline int
libsimple_cmptimespec(const struct timespec *__a, const struct timespec *__b)
@@ -1415,21 +1411,18 @@ int libsimple_sumtimeval(struct timeval *, const struct timeval *, const struct
# define sumtimeval libsimple_sumtimeval
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
int libsimple_difftimeval(struct timeval *, const struct timeval *, const struct timeval *);
#ifndef difftimeval
# define difftimeval libsimple_difftimeval
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
int libsimple_multimeval(struct timeval *, const struct timeval *, int);
#ifndef multimeval
# define multimeval libsimple_multimeval
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __warn_unused_result__)))
static inline int
libsimple_cmptimeval(const struct timeval *__a, const struct timeval *__b)
@@ -1455,42 +1448,36 @@ libsimple_timeval2timespec(struct timespec *restrict __ts, const struct timeval
# define timeval2timespec libsimple_timeval2timespec
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
int libsimple_timespec2timeval(struct timeval *restrict, const struct timespec *restrict);
#ifndef timespec2timeval
# define timespec2timeval libsimple_timespec2timeval
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1, 2))))
int libsimple_strtotimespec(struct timespec *restrict, const char *restrict, char **restrict);
#ifndef strtotimespec
# define strtotimespec libsimple_strtotimespec
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1, 2))))
int libsimple_strtotimeval(struct timeval *restrict, const char *restrict, char **restrict);
#ifndef strtotimeval
# define strtotimeval libsimple_strtotimeval
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2))))
char *libsimple_timespectostr(char *restrict, const struct timespec *restrict);
#ifndef timespectostr
# define timespectostr libsimple_timespectostr
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2))))
char *libsimple_timevaltostr(char *restrict, const struct timeval *restrict);
#ifndef timevaltostr
# define timevaltostr libsimple_timevaltostr
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
static inline double
libsimple_timespectodouble(const struct timespec *__ts)
@@ -1504,7 +1491,6 @@ libsimple_timespectodouble(const struct timespec *__ts)
# define timespectodouble libsimple_timespectodouble
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
static inline double
libsimple_timevaltodouble(const struct timeval *__tv)
@@ -1518,21 +1504,18 @@ libsimple_timevaltodouble(const struct timeval *__tv)
# define timevaltodouble libsimple_timevaltodouble
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
void libsimple_doubletotimespec(struct timespec *, double);
#ifndef doubletotimespec
# define doubletotimespec libsimple_doubletotimespec
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
void libsimple_doubletotimeval(struct timeval *, double);
#ifndef doubletotimeval
# define doubletotimeval libsimple_doubletotimeval
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__returns_nonnull__, __nonnull__)))
char *libsimple_minimise_number_string(char *);
#ifndef minimise_number_string
@@ -1545,7 +1528,6 @@ char *libsimple_minimise_number_string(char *);
# define UNLIST(LIST, I, NP) LIBSIMPLE_UNLIST((LIST), (I), (NP))
#endif
-
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
static inline void
libsimple_unlist(void *__list, size_t __i, size_t *__np, size_t __width)
diff --git a/test.c b/test.c
index edc3d15..4d16ebb 100644
--- a/test.c
+++ b/test.c
@@ -8,6 +8,8 @@
#undef memdup
+char *argv0 = (char []){"<test>"};
+
size_t alloc_fail_in = 0;
int exit_real = 0;
int exit_ok = 0;
@@ -16,6 +18,7 @@ jmp_buf exit_jmp;
char stderr_buf[8 << 10];
size_t stderr_n = 0;
int stderr_real = 0;
+int stderr_ok = 0;
static int custom_malloc = 0;
@@ -274,9 +277,10 @@ vfprintf(FILE *restrict stream, const char *restrict format, va_list ap)
n = (size_t)r;
buf = alloca(n + 1);
n = vsnprintf(buf, n + 1, format, ap);
- if (fileno(stream) != STDERR_FILENO) {
+ if (fileno(stream) != STDERR_FILENO || stderr_real) {
fwrite(buf, 1, n, stream);
} else {
+ assert(stderr_ok);
assert(stderr_n + n <= sizeof(stderr_buf));
memcpy(&stderr_buf[stderr_n], buf, n);
stderr_n += n;
diff --git a/test.h b/test.h
index e68c9c1..dcbf3b8 100644
--- a/test.h
+++ b/test.h
@@ -20,6 +20,40 @@
return 0;\
} while (0)
+#define assert_unreached()\
+ assert(*&(volatile int *){0})
+
+#define assert_exit(EXPR)\
+ do {\
+ volatile int old_stderr_ok__ = stderr_ok;\
+ exit_ok = 1;\
+ stderr_ok = 1;\
+ stderr_n = 0;\
+ if (setjmp(exit_jmp)) {\
+ exit_ok = 0;\
+ stderr_ok = old_stderr_ok__;\
+ break;\
+ }\
+ assert(EXPR);\
+ assert_unreached();\
+ } while (0)
+
+#define assert_exit_ptr(EXPR)\
+ do {\
+ void *volatile ptr__;\
+ assert_exit((ptr__ = (EXPR)));\
+ } while (0)
+
+#define assert_stderr(FMT, ...)\
+ do {\
+ char buf__[1024];\
+ int len__;\
+ len__ = sprintf(buf__, FMT, __VA_ARGS__);\
+ assert(len__ >= 0);\
+ assert((size_t)len__ == stderr_n);\
+ assert(!memcmp(buf__, stderr_buf, stderr_n));\
+ } while (0);
+
struct allocinfo {
void *real_beginning;
@@ -32,6 +66,8 @@ struct allocinfo {
};
+extern char *argv0;
+
extern size_t alloc_fail_in;
extern int exit_real;
extern int exit_ok;
@@ -40,6 +76,7 @@ extern jmp_buf exit_jmp;
extern char stderr_buf[8 << 10];
extern size_t stderr_n;
extern int stderr_real;
+extern int stderr_ok;
size_t get_pagesize(void);
diff --git a/vweprintf.c b/vweprintf.c
index d994c0e..a46363d 100644
--- a/vweprintf.c
+++ b/vweprintf.c
@@ -7,7 +7,7 @@ extern char *argv0;
void
-libsimple_vweprintf(const char *fmt, va_list ap) /* TODO test */
+libsimple_vweprintf(const char *fmt, va_list ap) /* TODO test (weprintf, enprintf, eprintf) */
{
int saved_errno = errno, r;
const char *end = strchr(fmt, '\0');