diff options
Diffstat (limited to '')
-rw-r--r-- | README | 192 | ||||
-rw-r--r-- | encalloc.c | 37 | ||||
-rw-r--r-- | enmalloc.c | 37 | ||||
-rw-r--r-- | enmemdup.c | 2 | ||||
-rw-r--r-- | enrealloc.c | 59 | ||||
-rw-r--r-- | enstrdup.c | 2 | ||||
-rw-r--r-- | enstrndup.c | 2 | ||||
-rw-r--r-- | envmalloczn.c | 162 | ||||
-rw-r--r-- | envputenvf.c | 2 | ||||
-rw-r--r-- | envreallocn.c | 2 | ||||
-rw-r--r-- | libsimple.c | 89 | ||||
-rw-r--r-- | libsimple.h | 300 | ||||
-rw-r--r-- | test.c | 6 | ||||
-rw-r--r-- | test.h | 37 | ||||
-rw-r--r-- | vweprintf.c | 2 |
15 files changed, 693 insertions, 238 deletions
@@ -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, ...) @@ -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; } @@ -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; } @@ -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; } @@ -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) @@ -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; @@ -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'); |