diff options
-rw-r--r-- | libsimple.c | 462 | ||||
-rw-r--r-- | libsimple.h | 576 |
2 files changed, 1038 insertions, 0 deletions
diff --git a/libsimple.c b/libsimple.c new file mode 100644 index 0000000..9a58ba1 --- /dev/null +++ b/libsimple.c @@ -0,0 +1,462 @@ +/* See LICENSE file for copyright and license details. */ +#include "libsimple.h" + + +extern char *argv0; + + +int libsimple_default_failure_exit = 1; + + +void * +libsimple_rawmemchr(const void *s_, int c) +{ + char *s = *(char **)(void *)&s_; + while ((int)*s++ != c); + return &s[-1]; +} + + +void * +libsimple_memrchr(const void *s_, int c, size_t n_) +{ + char *s = *(char **)(void *)&s_; + ssize_t n = n_; + while (n-- && (int)s[n] != c); + return n < 0 ? NULL : &s[n]; +} + + +void * +libsimple_rawmemrchr(const void *s_, int c, size_t n) +{ + char *s = *(char **)(void *)&s_; + while ((int)s[--n] != c); + return &s[n]; +} + + +char * +libsimple_strchrnul(const char *s_, int c) +{ + char *s = *(char **)(void *)&s_; + for (; *s && (int)*s != c; s++) + return s; +} + + +void * +libsimple_memdup(const void *s, size_t n) +{ + void *ret = malloc(n); + if (!ret) + return NULL; + return memcpy(ret, s, n); +} + + +char * +libsimple_strndup(const char *s, size_t n) +{ + void *ret; + if (n == SIZE_MAX) { + errno = ENOMEM; + return NULL; + } + if (!(ret = malloc(n + 1))) + return NULL; + memcpy(ret, s, n); + ((char *)ret)[n] = '\0'; + return ret; +} + + +int +libsimple_isutf8(const char *string, int allow_modified_nul) +{ + static long BYTES_TO_MIN_BITS[] = {0, 0, 8, 12, 17, 22, 37}; + static long BYTES_TO_MAX_BITS[] = {0, 7, 11, 16, 21, 26, 31}; + long int bytes = 0, read_bytes = 0, bits = 0, c, character; + + /* min bits max bits + 0....... 0 7 + 110..... 10...... 8 11 + 1110.... 10...... 10...... 12 16 + 11110... 10...... 10...... 10...... 17 21 + 111110.. 10...... 10...... 10...... 10...... 22 26 + 1111110. 10...... 10...... 10...... 10...... 10...... 27 31 + */ + + while ((c = (long int)(*string++))) { + if (!read_bytes) { + /* First byte of the character. */ + + if (!(c & 0x80)) + /* Single-byte character. */ + continue; + + if ((c & 0xC0) == 0x80) + /* Single-byte character marked as multibyte, or + a non-first byte in a multibyte character. */ + return -1; + + /* Multibyte character. */ + while ((c & 0x80)) + bytes++, c <<= 1; + read_bytes = 1; + character = c & 0x7F; + if (bytes > 6) + /* 31-bit characters can be encoded with 6-bytes, + and UTF-8 does not cover higher code points. */ + return -1; + } else { + /* Not first byte of the character. */ + + if ((c & 0xC0) != 0x80) + /* Beginning of new character before a + multibyte character has ended. */ + return -1; + + character = (character << 6) | (c & 0x7F); + + if (++read_bytes < bytes) + /* Not at last byte yet. */ + continue; + + /* Check that the character is not unnecessarily long. */ + while (character) + character >>= 1, bits++; + bits = (!bits && bytes == 2 && allow_modified_nul) ? 8 : bits; + if (bits < BYTES_TO_MIN_BITS[bytes] || BYTES_TO_MAX_BITS[bytes] < bits) + return -1; + + read_bytes = bytes = bits = 0; + } + } + + /* Make sure we did not stop at the middle of a multibyte character. */ + return !read_bytes; +} + + +int +libsimple_asprintf(char **strp, const char *fmt, ...) +{ + va_list ap; + int r; + va_start(ap, fmt); + r = libsimple_vasprintf(strp, fmt, ap); + va_end(ap); + return r; +} + + +int +libsimple_vasprintf(char **strp, const char *fmt, va_list ap) +{ + FILE *fp; + size_t siz = 0; + int ret; + *strp = NULL; + fp = open_memstream(strp, &siz); + if (!fp) + goto fail; + ret = vfprintf(fp, fmt, ap); + if (ret < 0) + goto fail; + if (fputc(0, fp)) + goto fail; + fclose(fp); + return ret; +fail: + free(*strp); + *strp = NULL; + return -1; +} + + +void * +libsimple_memmem(const void *hay_, size_t hayn, const void *sub_, size_t subn) +{ + char *hay = *(char **)(void *)&hay_, *end; + const char *sub = sub_; + + if (!subn) + return hay; + if (hayn < subn) + return NULL; + if (subn == 1) + return memchr(hay, *sub, hayn); + + for (end = &hay[hayn - subn + 1]; hay != end; hay++) + if (*hay == *sub && !memcmp(hay, sub, subn)) + return hay; + + return NULL; +} + + +char * +libsimple_strcasestr(const char *h_, const char *n) +{ + char *h = *(char **)(void *)&h_; + size_t hn = strlen(h); + size_t nn = strlen(n); + if (hn < nn) + return NULL; + for (hn -= nn; hn--; h++) + if (!strcasecmp(h, n)) + return h; + return NULL; +} + + +int +libsimple_memstarts(const void *s_, size_t n, const void *t_, size_t m) +{ + const char *s = s_, *t = t_; + size_t i = 0; + if (n < m) + return 0; + while (i < m && s[i] == t[i]) i++; + return i == m; +} + + +int +libsimple_memends(const void *s_, size_t n, const void *t_, size_t m) +{ + const char *s = s_, *t = t_; + if (n < m) + return 0; + while (n--, m--) + if (s[n] != t[m]) + return 0; + return 1; +} + + +int +libsimple_strstarts(const char *s, const char *t) +{ + for (; *t && *s == *t; s++, t++); + return !*t; +} + + +int +libsimple_strends(const char *s, const char *t) +{ + return memends(s, strlen(s), t, strlen(t)); +} + + +static inline size_t +alloc_size_product(size_t n, va_list ap) +{ + size_t prod = n; + if (!n) { + errno = EINVAL; + return 0; + } + for (;;) { + n = va_arg(ap, size_t); + if (!n) + break; + if (n >= SIZE_MAX / prod) { + errno = ENOMEM; + return 0; + } + prod *= n; + } + return prod; +} + +void * +libsimple_vmalloczn(int clear, size_t n, va_list ap) +{ + n = alloc_size_product(n, ap); + return !n ? NULL : clear ? calloc(1, n) : malloc(n); +} + +void * +libsimple_vreallocn(void *ptr, size_t n, va_list ap) +{ + n = alloc_size_product(n, ap); + return !n ? NULL : realloc(ptr, n); +} + + +void * +enmalloc(int status, size_t n) +{ + void *ret = malloc(n); + if (!ret) { + fprintf(stderr, "%s: malloc: %s\n", argv0, strerror(errno)); + exit(status); + } + return ret; +} + + +void * +encalloc(int status, size_t n, size_t m) +{ + void *ret = calloc(n, m); + if (!ret) { + fprintf(stderr, "%s: calloc: %s\n", argv0, strerror(errno)); + exit(status); + } + return ret; +} + + +void * +enrealloc(int status, void *ptr, size_t n) +{ + char *ret = realloc(ptr, n); + if (!ret) { + fprintf(stderr, "%s: realloc: %s\n", argv0, strerror(errno)); + exit(status); + } + return ret; +} + + +char * +enstrdup(int status, const char *s) +{ + char *ret = strdup(s); + if (!ret) { + fprintf(stderr, "%s: strdup: %s\n", argv0, strerror(errno)); + exit(status); + } + return ret; +} + + +char * +enstrndup(int status, const char *s, size_t n) +{ + void *ret = strndup(s, n); + if (!ret) { + fprintf(stderr, "%s: strndup: %s\n", argv0, strerror(errno)); + exit(status); + } + return ret; +} + + +void * +enmemdup(int status, const void *s, size_t n) +{ + void *ret = memdup(s, n); + if (!ret) { + fprintf(stderr, "%s: memdup: %s\n", argv0, strerror(errno)); + exit(status); + } + return ret; +} + + +void * +libsimple_envmalloczn(int status, int clear, size_t n, va_list ap) +{ + void *ret = libsimple_vmalloczn(clear, n, ap); + if (!ret) { + fprintf(stderr, "%s: %s: %s\n", argv0, clear ? "calloc" : "malloc", strerror(errno)); + exit(status); + } + return ret; +} + + +void * +libsimple_envreallocn(int status, void *ptr, size_t n, va_list ap) +{ + void *ret = libsimple_vreallocn(ptr, n, ap); + if (!ret) { + fprintf(stderr, "%s: realloc: %s\n", argv0, strerror(errno)); + exit(status); + } + return ret; +} + + +int +vputenvf(const char *fmt, va_list ap) +{ + va_list ap2; + int n; + char *s; + va_copy(ap2, ap); + n = vsnprintf(NULL, 0, fmt, ap2); + va_end(ap2); + if (n < 0) + return -1; + if ((size_t)n == SIZE_MAX) { + errno = ENOMEM; + return -1; + } + s = alloca((size_t)n + 1); + vsprintf(s, fmt, ap); + return putenv(s); +} + + +void +envputenvf(int status, const char *fmt, va_list ap) +{ + if (vputenvf(fmt, ap)) { + fprintf(stderr, "%s: putenvf: %s\n", argv0, strerror(errno)); + exit(status); + } +} + + +void +vweprintf(const char *fmt, va_list ap) +{ + int saved_errno = errno, r; + const char *end = strchr(fmt, '\0'); + const char *prefix1 = argv0; + const char *prefix2 = ": "; + const char *suffix1 = ""; + const char *suffix2 = ""; + const char *suffix3 = ""; + char *message = NULL; + va_list ap1; + va_list ap2; + + if (!argv0 || !strncmp(fmt, "usage: ", strlen("usage: "))) + prefix1 = prefix2 = ""; + + va_copy(ap1, ap); + va_copy(ap2, ap); + r = vsnprintf(NULL, 0, fmt, ap1); + if (0 <= r && (size_t)r < SIZE_MAX) { + message = alloca((size_t)r + 1); + vsprintf(message, fmt, ap2); + } + va_end(ap2); + va_end(ap1); + + if (*end == ':') { + suffix1 = " "; + suffix2 = strerror(saved_errno); + suffix3 = "\n"; + } else if (*end != '\n') { + suffix1 = "\n"; + } + + if (message) { + /* This is to avoid mangling when multiple processes are writting. */ + fprintf(stderr, "%s%s%s%s%s%s", prefix1, prefix2, message, suffix1, suffix2, suffix3); + } else { + fprintf(stderr, "%s%s", prefix1, prefix2); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "%s%s%s", suffix1, suffix2, suffix3); + } + + errno = saved_errno; +} diff --git a/libsimple.h b/libsimple.h new file mode 100644 index 0000000..02fc912 --- /dev/null +++ b/libsimple.h @@ -0,0 +1,576 @@ +/* See LICENSE file for copyright and license details. */ +#ifndef LIBSIMPLE_H +#define LIBSIMPLE_H + + +#include <alloca.h> +#include <errno.h> +#include <fcntl.h> +#include <inttypes.h> +#include <limits.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> + + +#if defined(__GNUC__) && !defined(__clang__) +# define _LIBSIMPLE_GCC_ONLY(x) x +#else +# define _LIBSIMPLE_GCC_ONLY(x) +#endif + + +extern int libsimple_default_failure_exit; + + +_LIBSIMPLE_GCC_ONLY(__attribute__((pure, nonnull, warn_unused_result))) +void *libsimple_rawmemchr(const void *, int); +#ifndef rawmemchr +# 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 +# define rawmemrchr libsimple_rawmemrchr +#endif + + +_LIBSIMPLE_GCC_ONLY(__attribute__((pure, nonnull, warn_unused_result))) +char *libsimple_strchrnul(const char *, int); +#ifndef strchrnul +# 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'); } +#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); } +#ifndef inchrset +# define inchrset libsimple_inchrset +#endif + + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, warn_unused_result))) +void *libsimple_memdup(const void *, size_t); +#ifndef memdup +# define memdup libsimple_memdup +#endif + + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, warn_unused_result))) +char *libsimple_strndup(const char *, size_t); +#ifndef strndup +# define strndup libsimple_strndup +#endif + + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result))) +static inline void *libsimple_mempcpy(void *__d, const void *__s, size_t __n) +{ return &((char *)memcpy(__d, __s, __n))[__n]; } +#ifndef mempcpy +# define mempcpy libsimple_mempcpy +#endif + + +#ifndef strdupa +# if defined(__GNUC__) || defined(__clang__) +# define strdupa(s)\ + ({\ + const char *__s = (s);\ + size_t __n = strlen(__s) + 1;\ + char *__r = alloca(__n);\ + memcpy(__r, __s, __n);\ + }) +# endif +#endif + + +#ifndef strdupa +# if defined(__GNUC__) || defined(__clang__) +# define strndupa(s, n)\ + ({\ + const char *__s = (s);\ + size_t __n = (n);\ + size_t __m = strlen(__s);\ + char *__r;\ + __n = __n < __m ? __n : __m;\ + __r = alloca(__n + 1);\ + memcpy(__r, __s, __n);\ + __r[n] = '\0';\ + __r;\ + }) +# endif +#endif + + +#ifndef strdupa +# if defined(__GNUC__) || defined(__clang__) +# define memdupa(s, n)\ + ({\ + const char *__s = (s);\ + size_t __n = (n);\ + char *__r = alloca(__n);\ + memcpy(__r, __s, __n);\ + }) +# endif +#endif + + +/** + * Check whether a NUL-terminated string is encoded in UTF-8 + * + * @param string The string + * @param allow_modified_nul Whether Modified UTF-8 is allowed, which allows a two-byte encoding for NUL + * @return 1 if good, 0 on encoding error + */ +_LIBSIMPLE_GCC_ONLY(__attribute__((pure, nonnull, warn_unused_result))) +int libsimple_isutf8(const char *, int); +#ifndef isutf8 +# define isutf8 libsimple_isutf8 +#endif + + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(1, 2), format(printf, 2, 3)))) +int libsimple_asprintf(char **, const char *, ...); +#ifndef asprintf +# 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 + + +#ifndef asprintfa +# if defined(__GNUC__) && !defined(__clang__) +# define asprintfa(__fmt, ...)\ + ({\ + const char *__f = (__fmt);\ + char *__ret = NULL;\ + int __r = snprintf(NULL, 0, __f, __VA_ARGS__);\ + if (__r < 0) {\ + __ret;\ + } else if ((size_t)__r == SIZE_MAX) {\ + errno = ENOMEM;\ + __ret;\ + } else {\ + __ret = alloca((size_t)__r + 1);\ + sprintf(__ret, __f, __VA_ARGS__);\ + __ret;\ + }\ + }) +# endif +#endif + + +#ifndef vasprintfa +# if defined(__GNUC__) || defined(__clang__) +# define vasprintfa(__fmt, __ap)\ + ({\ + const char *__f = (__fmt);\ + va_list __a = (__ap);\ + va_list __a2;\ + char *__ret = NULL;\ + int __r;\ + va_copy(__a2, __a);\ + __r = vsnprintf(NULL, 0, __f, __a);\ + if (__r < 0);\ + else if ((size_t)__r == SIZE_MAX) {\ + errno = ENOMEM;\ + } else {\ + __ret = alloca((size_t)__r + 1);\ + vsprintf(__ret, __f, __a2);\ + }\ + va_end(__a2);\ + __ret;\ + }) +# endif +#endif + + +_LIBSIMPLE_GCC_ONLY(__attribute__((pure, warn_unused_result))) +void *libsimple_memmem(const void *, size_t, const void *, size_t); +#ifndef memmem +# define memmem libsimple_memmem +#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 +# define memends libsimple_memends +#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))) +int libsimple_strends(const char *, const char *); +#ifndef strends +# define strends libsimple_strends +#endif + + +_LIBSIMPLE_GCC_ONLY(__attribute__((pure, nonnull, warn_unused_result))) +char *libsimple_strcasestr(const char *, const char *); +#ifndef strcasestr +# define strcasestr libsimple_strcasestr +#endif + + +#define malloczn(CLEAR, ...) _libsimple_malloczn((CLEAR), __VA_ARGS__, (size_t)0) +#define mallocn(...) malloczn(0, __VA_ARGS__) +#define callocn(...) malloczn(1, __VA_ARGS__) + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result))) +void *libsimple_vmalloczn(int, size_t, va_list); + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result))) +static inline void *libsimple_vmallocn(size_t __n, va_list __ap) { return libsimple_vmalloczn(0, __n, __ap); } + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result))) +static inline void *libsimple_vcallocn(size_t __n, va_list __ap) { return libsimple_vmalloczn(1, __n, __ap); } + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result))) +static inline void * +libsimple_malloczn(int __clear, size_t __n, ...) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_vmalloczn(__clear, __n, __ap); + va_end(__ap); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result))) +static inline void * +libsimple_mallocn(size_t __n, ...) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_vmalloczn(0, __n, __ap); + va_end(__ap); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result))) +static inline void * +libsimple_callocn(size_t __n, ...) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_vmalloczn(1, __n, __ap); + va_end(__ap); +} + + +#define reallocn(PTR, ...) _libsimple_reallocn((PTR), __VA_ARGS__, (size_t)0) +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result))) +void *libsimple_vreallocn(void *, size_t, va_list); + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result))) +static inline void * +libsimple_reallocn(void *__ptr, size_t __n, ...) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_vreallocn(__ptr, __n, __ap); + va_end(__ap); +} + + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +void *enmalloc(int, size_t); + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +void *encalloc(int, size_t, size_t); + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +void *enrealloc(int, void *, size_t); + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, warn_unused_result, returns_nonnull))) +char *enstrdup(int, const char *); + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, warn_unused_result, returns_nonnull))) +char *enstrndup(int, const char *, size_t); + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +void *enmemdup(int, const void *, size_t); + +#define enmalloczn(STATUS, CLEAR, ...) _libsimple_enmalloczn((STATUS), (CLEAR), __VA_ARGS__, (size_t)0) +#define enmallocn(STATUS, ...) _libsimple_enmallocn((STATUS), (CLEAR), __VA_ARGS__, (size_t)0) +#define encallocn(STATUS, ...) _libsimple_encallocn((STATUS), (CLEAR), __VA_ARGS__, (size_t)0) +#define enreallocn(STATUS, PTR, ...) _libsimple_enreallocn((STATUS), (PTR), __VA_ARGS__, (size_t)0) + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +void *libsimple_envmalloczn(int, int, size_t, va_list); + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +void *libsimple_envreallocn(int, void *, size_t, va_list); + +_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); } + +_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); } + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void * +libsimple_enmalloczn(int __status, int __clear, size_t __n, ...) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_envmalloczn(__status, __clear, __n, __ap); + va_end(__ap); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void * +libsimple_enmallocn(int __status, size_t __n, ...) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_envmalloczn(__status, 0, __n, __ap); + va_end(__ap); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void * +libsimple_encallocn(int __status, size_t __n, ...) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_envmalloczn(__status, 1, __n, __ap); + va_end(__ap); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void * +libsimple_enreallocn(int __status, void *__ptr, size_t __n, ...) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_envreallocn(__status, __ptr, __n, __ap); + va_end(__ap); +} + + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void *emalloc(size_t __n) { return enmalloc(libsimple_default_failure_exit, __n); } + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void *ecalloc(size_t __n, size_t __m) { return encalloc(libsimple_default_failure_exit, __n, __m); } + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void *erealloc(void *__ptr, size_t __n) { return enrealloc(libsimple_default_failure_exit, __ptr, __n); } + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, warn_unused_result, returns_nonnull))) +static inline char *estrdup(const char *__s) { return enstrdup(libsimple_default_failure_exit, __s); } + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, warn_unused_result, returns_nonnull))) +static inline char *estrndup(const char *__s, size_t __n) { return enstrndup(libsimple_default_failure_exit, __s, __n); } + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void *ememdup(const void *__s, size_t __n) { return enmemdup(libsimple_default_failure_exit, __s, __n); } + +#define emalloczn(CLEAR, ...) enmalloczn(libsimple_default_failure_exit, (CLEAR), __VA_ARGS__) +#define emallocn(...) enmallocn(libsimple_default_failure_exit, __VA_ARGS__) +#define ecallocn(...) encallocn(libsimple_default_failure_exit, __VA_ARGS__) +#define ereallocn(PTR, ...) enreallocn(libsimple_default_failure_exit, (PTR), __VA_ARGS__) + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void *libsimple_evmalloczn(int __clear, size_t __n, va_list __ap) +{ return libsimple_envmalloczn(libsimple_default_failure_exit, __clear, __n, __ap); } + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void *libsimple_evmallocn(size_t __n, va_list __ap) +{ return libsimple_envcallocn(libsimple_default_failure_exit, __n, __ap); } + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void *libsimple_evcallocn(size_t __n, va_list __ap) +{ return libsimple_envmallocn(libsimple_default_failure_exit, __n, __ap); } + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void *libsimple_evreallocn(void *__ptr, size_t __n, va_list __ap) +{ return libsimple_envreallocn(libsimple_default_failure_exit, __ptr, __n, __ap); } + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void * +libsimple_emalloczn(int __c, size_t __n, ...) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_envmalloczn(libsimple_default_failure_exit, __c, __n, __ap); + va_end(__ap); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void * +libsimple_emallocn(size_t __n, ...) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_envmalloczn(libsimple_default_failure_exit, 0, __n, __ap); + va_end(__ap); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void * +libsimple_ecallocn(size_t __n, ...) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_envmalloczn(libsimple_default_failure_exit, 1, __n, __ap); + va_end(__ap); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull))) +static inline void * +libsimple_ereallocn(void *__p, size_t __n, ...) +{ + va_list __ap; + va_start(__ap, __n); + return libsimple_envreallocn(libsimple_default_failure_exit, __p, __n, __ap); + va_end(__ap); +} + + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull))) +static inline char * +getenv_ne(const char *__name) +{ + char *__env = getenv(__name); + return (__env && *__env) ? __env : NULL; +} + + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull))) +int vputenvf(const char *, va_list); + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull))) +void envputenvf(int, const char *, va_list); + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, format(printf, 1, 2)))) +static inline int +putenvf(const char *__fmt, ...) +{ + va_list __ap; + va_start(__ap, __fmt); + return vputenvf(__fmt, __ap); + va_end(__ap); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, format(printf, 1, 2)))) +static inline void +eputenvf(const char *__fmt, ...) +{ + va_list __ap; + va_start(__ap, __fmt); + envputenvf(1, __fmt, __ap); + va_end(__ap); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull))) +static inline void +evputenvf(const char *__fmt, va_list __ap) +{ + envputenvf(libsimple_default_failure_exit, __fmt, __ap); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, format(printf, 2, 3)))) +static inline void +enputenvf(int __status, const char *__fmt, ...) +{ + va_list __ap; + va_start(__ap, __fmt); + envputenvf(__status, __fmt, __ap); + va_end(__ap); +} + + + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(1)))) +void vweprintf(const char *, va_list); + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(1), format(printf, 1, 2), noreturn))) +static inline void +eprintf(const char *__fmt, ...) +{ + va_list __ap; + va_start(__ap, __fmt); + vweprintf(__fmt, __ap); + va_end(__ap); + exit(libsimple_default_failure_exit); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(1), noreturn))) +static inline void +veprintf(const char *__fmt, va_list __ap) +{ + vweprintf(__fmt, __ap); + exit(libsimple_default_failure_exit); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(2), format(printf, 2, 3), noreturn))) +static inline void +enprintf(int __status, const char *__fmt, ...) +{ + va_list __ap; + va_start(__ap, __fmt); + vweprintf(__fmt, __ap); + va_end(__ap); + exit(__status); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(2), noreturn))) +static inline void +venprintf(int __status, const char *__fmt, va_list __ap) +{ + vweprintf(__fmt, __ap); + exit(__status); +} + +_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(1), format(printf, 1, 2)))) +static inline void +weprintf(const char *__fmt, ...) +{ + va_list __ap; + va_start(__ap, __fmt); + vweprintf(__fmt, __ap); + va_end(__ap); +} + + +#endif |