diff options
Diffstat (limited to 'src/base.h')
| -rw-r--r-- | src/base.h | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/base.h b/src/base.h new file mode 100644 index 0000000..83d086c --- /dev/null +++ b/src/base.h @@ -0,0 +1,118 @@ +#pragma once + +#include <stdio.h> +#include <stdint.h> +#include <stdbool.h> +#include <sysexits.h> +#include <errno.h> +#include <string.h> +#include <err.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <ctype.h> + +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; +typedef int64_t s64; +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; +typedef float f32; +typedef double f64; +typedef int fd; +typedef int jid_t; + +#define ArrayCount(x) (sizeof(x) / sizeof(*(x))) + +#define PARENS () + +#define EVAL3(...) EVAL2(EVAL2(EVAL2(EVAL2(__VA_ARGS__)))) +#define EVAL2(...) EVAL1(EVAL1(EVAL1(EVAL1(__VA_ARGS__)))) +#define EVAL1(...) EVAL0(EVAL0(EVAL0(EVAL0(__VA_ARGS__)))) +#define EVAL0(...) __VA_ARGS__ + +#define FOR_EACH(f, ...) __VA_OPT__(EVAL3(FOR_EACH_STEP(f, __VA_ARGS__))) +#define FOR_EACH_STEP(f, x, ...) f(x) __VA_OPT__(FOR_EACH_AGAIN PARENS(f, __VA_ARGS__)) +#define FOR_EACH_AGAIN() FOR_EACH_STEP + +#define FOR_EACH_1(f, s, ...) __VA_OPT__(EVAL3(FOR_EACH_1_STEP(f, s __VA_ARGS__))) +#define FOR_EACH_1_STEP(f, s, x, ...) f(s, x) __VA_OPT__(FOR_EACH_1_AGAIN PARENS(f, s, __VA_ARGS__)) +#define FOR_EACH_1_AGAIN() FOR_EACH_1_STEP + +#define DO_PRAGMA(x) _Pragma(#x) +#define WARNINGS_RESTORE DO_PRAGMA(clang diagnostic pop) +#define WARNINGS_IGNORE_STEP(x) DO_PRAGMA(clang diagnostic ignored x) +#define WARNINGS_IGNORE(...) \ + DO_PRAGMA(clang diagnostic push) \ + FOR_EACH(WARNINGS_IGNORE_STEP, __VA_ARGS__) + +#define UNUSED(...) (void)sizeof(__VA_ARGS__ __VA_OPT__(, ) 0) // NOLINT(bugprone-sizeof-expression) + +#define OffsetOf(x, y) __builtin_offsetof(x, y) +#define ContainerOf(Member, type, member) (type *)(void *)((u8 *)(Member)-OffsetOf(type, member)) + +WARNINGS_IGNORE("-Wdocumentation") +#include <ucl.h> +WARNINGS_RESTORE + +#define UCL_CHECK_HELPER_INT "an integer" +#define UCL_CHECK_HELPER_STRING "a string" +#define UCL_CHECK_HELPER_OBJECT "an object" +#define UCL_CHECK_HELPER_ARRAY "an array" +#define UCL_CHECK_HELPER_BOOLEAN "a boolean" +#define UCL_CHECK_HELPER_(x) UCL_CHECK_HELPER_##x +#define UCL_CHECK_HELPER(x) UCL_CHECK_HELPER_(x) +#define UCL_CHECK_ROOT(type_) \ + do { \ + if(root == NULL || root->type != UCL_##type_) \ + { \ + if(*Position == '\0') Position = "."; \ + asprintf(&Error, "%s is not " UCL_CHECK_HELPER(type_), Position); \ + goto error; \ + } \ + } while(0) +#define UCL_CHECK(x, type_) \ + do { \ + if(x == NULL || x->type != UCL_##type_) \ + { \ + asprintf(&Error, "%s." #x " is not " UCL_CHECK_HELPER(type_), Position); \ + goto error; \ + } \ + } while(0) +#define UCL_CHECK_OPTIONAL(x, type_) \ + do { \ + if(x != NULL && x->type != UCL_##type_) \ + { \ + asprintf(&Error, "%s." #x " is not " UCL_CHECK_HELPER(type_), Position); \ + goto error; \ + } \ + } while(0) + +#define CONCAT_ENUM_NAMES(a, b) a##_##b, +#define STRING_(...) #__VA_ARGS__ +#define STRING(...) STRING_(__VA_ARGS__) +#define LISTIFY(...) __VA_ARGS__, +#define STRING_LISTIFY(...) LISTIFY(STRING(__VA_ARGS__)) +#define REQUIRE_SEMICOLON_(x) struct dummy_struct_##x +#define REQUIRE_SEMICOLON(x) REQUIRE_SEMICOLON_(x) +#define NAMED_ENUM(x, ...) \ + enum \ + { \ + FOR_EACH_1(CONCAT_ENUM_NAMES, x, __VA_OPT__(, ) __VA_ARGS__) x##_COUNT \ + } typedef x; \ + WARNINGS_IGNORE("-Wunused-variable") \ + static char const *x##_Names[] = { FOR_EACH(STRING_LISTIFY __VA_OPT__(, ) __VA_ARGS__) }; \ + WARNINGS_RESTORE \ + REQUIRE_SEMICOLON(x) + +static inline bool +isprints(char const *String) +{ + for(char const *At = String; *At; ++At) + if(isprint(*At) == false) return false; + return true; +} |
