aboutsummaryrefslogtreecommitdiffstats
path: root/libsimple.h
diff options
context:
space:
mode:
Diffstat (limited to 'libsimple.h')
-rw-r--r--libsimple.h576
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