aboutsummaryrefslogtreecommitdiffstats
path: root/libabort.h
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-02-28 19:17:45 +0100
committerMattias Andrée <m@maandree.se>2026-02-28 19:17:45 +0100
commit7c545b4b9c31dbfb2e8430aded030654a92e967a (patch)
treecd79fb055bfcca79dee8b1b35c0ed59ea3a0c85a /libabort.h
downloadlibabort-1.0.tar.gz
libabort-1.0.tar.bz2
libabort-1.0.tar.xz
First commitHEAD1.0master
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'libabort.h')
-rw-r--r--libabort.h233
1 files changed, 233 insertions, 0 deletions
diff --git a/libabort.h b/libabort.h
new file mode 100644
index 0000000..333edb3
--- /dev/null
+++ b/libabort.h
@@ -0,0 +1,233 @@
+/* See LICENSE file for copyright and license details. */
+#ifndef LIBABORT_H
+#define LIBABORT_H
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#if defined(__GNUC__)
+# if defined(__clang__)
+# define LIBABORT_PRINTF__(FMT, ARGS) __attribute__((__format__(__printf__, FMT, ARGS)))
+# else
+# define LIBABORT_PRINTF__(FMT, ARGS) __attribute__((__format__(__gnu_printf__, FMT, ARGS)))
+# endif
+# define LIBABORT_NONNULL__(INDEX) __attribute__((__nonnull__(INDEX)))
+# define LIBABORT_ALL_NONNULL__ __attribute__((__nonnull__))
+# define LIBABORT_PURE__ __attribute__((__pure__))
+#else
+# define LIBABORT_PRINTF__(FMT, ARGS)
+# define LIBABORT_NONNULL__(INDEX)
+# define LIBABORT_ALL_NONNULL__
+# define LIBABORT_PURE__
+#endif
+
+
+#ifndef LIBABORT_NO_SHORTHANDS
+# ifndef stracpy
+# define stracpy libabort_stracpy
+# endif
+# ifndef saprintf
+# define saprintf libabort_saprintf
+# endif
+# ifndef vsaprintf
+# define vsaprintf libabort_vsaprintf
+# endif
+# ifndef stpacpy
+# define stpacpy libabort_stpacpy
+# endif
+# ifndef stracat
+# define stracat libabort_stracat
+# endif
+# ifndef stralen
+# define stralen libabort_stralen
+# endif
+# ifndef stpacat
+# define stpacat libabort_stpacat
+# endif
+#endif
+
+
+/**
+ * libabort_stracpy
+ *
+ * Copy a string like strncpy(3), but abort if truncation would occur
+ *
+ * @param dst The destination buffer
+ * @param src The source string
+ * @param size The size of `dst`, in bytes
+ * @return `dst`
+ */
+LIBABORT_ALL_NONNULL__
+inline char *
+libabort_stracpy(char *dst, const char *src, size_t size)
+{
+ size_t i;
+ for (i = 0; i < size; i++)
+ if ((dst[i] = src[i]) == '\0')
+ return dst;
+ abort();
+}
+
+
+/**
+ * libabort_stpacpy
+ *
+ * Copy a string like stpcpy(3), but abort if truncation would occur.
+ *
+ * @param dst The destination buffer
+ * @param src The source string
+ * @param size The size of `dst`, in bytes
+ * @return A pointer to the terminating NUL byte in `dst`
+ */
+LIBABORT_ALL_NONNULL__
+inline char *
+libabort_stpacpy(char *dst, const char *src, size_t size)
+{
+ size_t i;
+ for (i = 0; i < size; i++)
+ if ((dst[i] = src[i]) == '\0')
+ return &dst[i];
+ abort();
+}
+
+
+/**
+ * libabort_stracat
+ *
+ * Concatenate strings like strcat(3), but abort if truncation would occur.
+ *
+ * @param dst The destination buffer (must contain a NUL-terminated string)
+ * @param src The source string
+ * @param size The size of `dst`, in bytes
+ * @return `dst`
+ */
+LIBABORT_ALL_NONNULL__
+inline char *
+libabort_stracat(char *dst, const char *src, size_t size)
+{
+ size_t i, j;
+ for (i = 0; i < size; i++)
+ if (dst[i] == '\0')
+ break;
+ if (i == size)
+ abort();
+ for (j = 0; i < size; i++, j++)
+ if ((dst[i] = src[j]) == '\0')
+ return dst;
+ abort();
+}
+
+
+/**
+ * libabort_stralen
+ *
+ * Get the length of a string like strlen(3), but abort if no NUL byte is found
+ * within `size` bytes.
+ *
+ * @param str The string
+ * @param size The maximum number of bytes to examine
+ * @return The length of the string, excluding the terminating NUL byte
+ */
+LIBABORT_PURE__
+LIBABORT_ALL_NONNULL__
+inline size_t
+libabort_stralen(const char *str, size_t size)
+{
+ size_t i;
+ for (i = 0; i < size; i++)
+ if (!str[i])
+ return i;
+ abort();
+}
+
+
+/**
+ * libabort_stpacat
+ *
+ * Concatenate strings like stpcat(3) would (non-standard), but abort if
+ * truncation would occur.
+ *
+ * @param dst The destination buffer (must contain a NUL-terminated string)
+ * @param src The source string
+ * @param size The size of `dst`, in bytes
+ * @return A pointer to the terminating NUL byte in `dst`
+ */
+LIBABORT_ALL_NONNULL__
+inline char *
+libabort_stpacat(char *dst, const char *src, size_t size)
+{
+ size_t i, j;
+ for (i = 0; i < size; i++)
+ if (dst[i] == '\0')
+ break;
+ if (i == size)
+ abort();
+ for (j = 0; i < size; i++, j++)
+ if ((dst[i] = src[j]) == '\0')
+ return &dst[i];
+ abort();
+}
+
+
+/**
+ * libabort_vsaprintf
+ *
+ * Format a string like vsnprintf(3), but abort if truncation would occur
+ *
+ * @param buf The output buffer
+ * @param size The size of `buf`, in bytes
+ * @param fmt The format string
+ * @param ap The format arguments
+ * @return The number of bytes written excluding the terminating NUL byte
+ *
+ * NB! This function aborts if `size` is 0, use vsnprintf(3) get the size required for `buf`
+ */
+LIBABORT_NONNULL__(1)
+LIBABORT_NONNULL__(3)
+LIBABORT_PRINTF__(3, 0)
+inline int
+libabort_vsaprintf(char *buf, size_t size, const char *fmt, va_list ap)
+{
+ int n = vsnprintf(buf, size, fmt, ap);
+ if (n < 0 || (size_t)n >= size)
+ abort();
+ return n;
+}
+
+
+/**
+ * libabort_saprintf
+ *
+ * Format a string like snprintf(3), but abort if truncation would occur
+ *
+ * @param buf The output buffer
+ * @param size The size of `buf`, in bytes
+ * @param fmt The format string
+ * @return The number of bytes written excluding the terminating NUL byte
+ *
+ * NB! This function aborts if `size` is 0, use snprintf(3) get the size required for `buf`
+ */
+LIBABORT_NONNULL__(1)
+LIBABORT_NONNULL__(3)
+LIBABORT_PRINTF__(3, 4)
+inline int
+libabort_saprintf(char *buf, size_t size, const char *fmt, ...)
+{
+ va_list ap;
+ int r;
+ va_start(ap, fmt);
+ r = libabort_vsaprintf(buf, size, fmt, ap);
+ va_end(ap);
+ return r;
+}
+
+
+#undef LIBABORT_PRINTF__
+#undef LIBABORT_NONNULL__
+#undef LIBABORT_ALL_NONNULL__
+
+#endif