diff options
Diffstat (limited to 'libsimple.h')
-rw-r--r-- | libsimple.h | 576 |
1 files changed, 576 insertions, 0 deletions
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 |