summaryrefslogtreecommitdiffstats
path: root/common.h
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2025-02-09 15:04:27 +0100
committerMattias Andrée <m@maandree.se>2025-02-09 15:04:27 +0100
commited004cba0e8d1d383def76f795b1e63ba0aaa89a (patch)
treeb12e5f23329f631b66c19b932551e4dff5aa477f /common.h
downloadliblog-ed004cba0e8d1d383def76f795b1e63ba0aaa89a.tar.gz
liblog-ed004cba0e8d1d383def76f795b1e63ba0aaa89a.tar.bz2
liblog-ed004cba0e8d1d383def76f795b1e63ba0aaa89a.tar.xz
First commit (everything was written 2024)
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'common.h')
-rw-r--r--common.h316
1 files changed, 316 insertions, 0 deletions
diff --git a/common.h b/common.h
new file mode 100644
index 0000000..277c3d5
--- /dev/null
+++ b/common.h
@@ -0,0 +1,316 @@
+/* See LICENSE file for copyright and license details. */
+#include "liblog.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+
+#define DEFAULT_PREFIXFMT "%[argv0] [%[pid]] [%{utime:%F %T%}.%[milli]Z] [%level]: %[file]:%[line] (%[function]): "
+
+
+#if defined(__GNUC__)
+# define WEAK_LINKING __attribute__((__weak__))
+#else
+# define WEAK_LINKING
+# define WEAK_LINKING_FAILED
+#endif
+
+
+#define MIN(A, B) ((A) < (B) ? (A) : (B))
+#define MAX(A, B) ((A) > (B) ? (A) : (B))
+#define NEXT_LOGLEVEL(LVL) ((enum liblog_level)(LVL) + (enum liblog_level)100)
+
+#define XLOG_NOT_INLINE 0x0100
+
+
+struct messagebuf {
+ char *prefix; /* TODO for each output channel; also get arguments for each channel */
+ char *text;
+ size_t len;
+ size_t size;
+};
+
+#define MESSAGEBUF_INIT ((struct messagebuf){NULL, NULL, 0, 0})
+
+struct liblog_context_internal_state {
+ struct messagebuf msg;
+};
+
+
+extern const char *argv0;
+
+
+int liblog_flush__(struct liblog_context *ctx, const struct messagebuf *msg);
+WEAK_LINKING int liblog_trace__(char **textp, size_t *offsetp, size_t *allocsizep, size_t skip, void *saved_trace);
+WEAK_LINKING int liblog_whence__(char **file_out, off_t *line_out, char **function_out, size_t skip, void **trace_savep);
+
+
+#ifdef TEST
+# if defined(__GNUC__)
+# if defined(__clang__)
+# pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
+# endif
+# define main __attribute__((__const__)) main
+# endif
+#endif
+
+
+
+
+#ifdef TEST
+# define TESTED_ELSEWHERE LIBEXEC_CONST__ int main(void) { return 0; }
+
+enum assert_type {
+ ASSERT_ENUM,
+ ASSERT_UINT,
+ ASSERT_INT,
+ ASSERT_NULL,
+ ASSERT_PTR,
+ ASSERT_STR,
+ ASSERT_STR_REV
+};
+
+enum assert_how {
+ ASSERT_EQ,
+ ASSERT_NE,
+ ASSERT_LT,
+ ASSERT_LE,
+ ASSERT_GT,
+ ASSERT_GE,
+ ASSERT_CONTAINS_ALL,
+ ASSERT_CONTAINS_ANY,
+ ASSERT_CONTAINS_NOT_ALL,
+ ASSERT_CONTAINS_NOT_ANY,
+ ASSERT_IS_IN,
+ ASSERT_NOT_IN,
+ ASSERT_NOT_LT,
+ ASSERT_NOT_LE,
+ ASSERT_NOT_GT,
+ ASSERT_NOT_GE
+};
+
+void test_assert(const char *file, int line, enum assert_type type, enum assert_how how,
+ const char *have_string, const char *expect_string, const void *have, const void *expect);
+
+#define ASSERT_EQ_ENUM(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_ENUM, ASSERT_EQ, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_NE_ENUM(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_ENUM, ASSERT_NE, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_LT_ENUM(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_ENUM, ASSERT_LT, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_GT_ENUM(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_ENUM, ASSERT_GT, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_LE_ENUM(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_ENUM, ASSERT_LE, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_GE_ENUM(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_ENUM, ASSERT_GE, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_CONTAINS_ALL_OF_ENUM(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_ENUM, ASSERT_CONTAINS_ALL, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_CONTAINS_SOME_OF_ENUM(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_ENUM, ASSERT_CONTAINS_ANY, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_CONTAINS_NONE_OF_ENUM(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_ENUM, ASSERT_CONTAINS_NOT_ANY, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_CONTAINS_NOT_ALL_OF_ENUM(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_ENUM, ASSERT_CONTAINS_NOT_ALL, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_IS_IN_ENUM(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_ENUM, ASSERT_IS_IN, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_NOT_IN_ENUM(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_ENUM, ASSERT_NOT_IN, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_EQ_UINT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_UINT, ASSERT_EQ, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_NE_UINT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_UINT, ASSERT_NE, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_LT_UINT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_UINT, ASSERT_LT, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_GT_UINT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_UINT, ASSERT_GT, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_LE_UINT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_UINT, ASSERT_LE, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_GE_UINT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_UINT, ASSERT_GE, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_CONTAINS_ALL_OF_UINT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_UINT, ASSERT_CONTAINS_ALL, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_CONTAINS_SOME_OF_UINT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_UINT, ASSERT_CONTAINS_ANY, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_CONTAINS_NONE_OF_UINT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_UINT, ASSERT_CONTAINS_NOT_ANY, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_CONTAINS_NOT_ALL_OF_UINT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_UINT, ASSERT_CONTAINS_NOT_ALL, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_IS_IN_UINT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_UINT, ASSERT_IS_IN, #HAVE, #EXPECT,\
+ &(uintmax_t){(uintmax_t)(HAVE)}, &(uintmax_t){(uintmax_t)(EXPECT)})
+
+#define ASSERT_EQ_INT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_INT, ASSERT_EQ, #HAVE, #EXPECT,\
+ &(intmax_t){(intmax_t)(HAVE)}, &(intmax_t){(intmax_t)(EXPECT)})
+
+#define ASSERT_NE_INT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_INT, ASSERT_NE, #HAVE, #EXPECT,\
+ &(intmax_t){(intmax_t)(HAVE)}, &(intmax_t){(intmax_t)(EXPECT)})
+
+#define ASSERT_LT_INT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_INT, ASSERT_LT, #HAVE, #EXPECT,\
+ &(intmax_t){(intmax_t)(HAVE)}, &(intmax_t){(intmax_t)(EXPECT)})
+
+#define ASSERT_GT_INT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_INT, ASSERT_GT, #HAVE, #EXPECT,\
+ &(intmax_t){(intmax_t)(HAVE)}, &(intmax_t){(intmax_t)(EXPECT)})
+
+#define ASSERT_LE_INT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_INT, ASSERT_LE, #HAVE, #EXPECT,\
+ &(intmax_t){(intmax_t)(HAVE)}, &(intmax_t){(intmax_t)(EXPECT)})
+
+#define ASSERT_GE_INT(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_INT, ASSERT_GE, #HAVE, #EXPECT,\
+ &(intmax_t){(intmax_t)(HAVE)}, &(intmax_t){(intmax_t)(EXPECT)})
+
+#define ASSERT_EQ_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR, ASSERT_EQ, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_NE_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR, ASSERT_NE, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_STARTS_WITH_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR, ASSERT_GE, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_EXTENDS_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR, ASSERT_GT, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_TRUNCATES_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR, ASSERT_LT, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_BEGINNING_BOUNDED_TO_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR, ASSERT_LE, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_ENDS_WITH_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR_REV, ASSERT_GE, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_EXTENDS_END_OF_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR_REV, ASSERT_GT, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_TRUNCATES_END_OF_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR_REV, ASSERT_LT, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_ENDING_BOUNDED_TO_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR_REV, ASSERT_LE, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_DOES_NOT_STARTS_WITH_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR, ASSERT_NOT_GE, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_DOES_NOT_EXTENDS_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR, ASSERT_NOT_GT, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_DOES_NOT_TRUNCATES_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR, ASSERT_NOT_LT, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_BEGINNING_NOT_BOUNDED_TO_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR, ASSERT_NOT_LE, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_DOES_NOT_ENDS_WITH_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR_REV, ASSERT_NOT_GE, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_DOES_NOT_EXTENDS_END_OF_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR_REV, ASSERT_NOT_GT, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_DOES_NOT_TRUNCATES_END_OF_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR_REV, ASSERT_NOT_LT, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_ENDING_NOT_BOUNDED_TO_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR_REV, ASSERT_NOT_LE, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_CONTAINS_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR, ASSERT_CONTAINS_ALL, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_DOES_NOT_CONTAIN_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR, ASSERT_CONTAINS_NOT_ALL, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_IS_IN_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR, ASSERT_IS_IN, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_NOT_IN_STR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_STR, ASSERT_NOT_IN, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_IS_PTR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_PTR, ASSERT_EQ, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_NOT_PTR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_PTR, ASSERT_NE, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_BEFORE_PTR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_PTR, ASSERT_LT, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_AFTER_PTR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_PTR, ASSERT_GT, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_BEFORE_OR_IS_PTR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_PTR, ASSERT_LE, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_AFTER_OR_IS_PTR(HAVE, EXPECT)\
+ test_assert(__FILE__, __LINE__, ASSERT_PTR, ASSERT_GE, #HAVE, #EXPECT, (HAVE), (EXPECT))
+
+#define ASSERT_IS_NULL(HAVE)\
+ test_assert(__FILE__, __LINE__, ASSERT_NULL, ASSERT_EQ, #HAVE, "NULL", (HAVE), NULL)
+
+#define ASSERT_NOT_NULL(HAVE)\
+ test_assert(__FILE__, __LINE__, ASSERT_NULL, ASSERT_NE, #HAVE, "NULL", (HAVE), NULL)
+
+#define ASSERT_IS_TRUE(HAVE)\
+ ASSERT_NE_INT(HAVE, 0)
+
+#define ASSERT_IS_FALSE(HAVE)\
+ ASSERT_EQ_INT(HAVE, 0)
+
+#define ASSERT_ZERO(HAVE)\
+ ASSERT_EQ_INT(HAVE, 0)
+
+#endif