aboutsummaryrefslogtreecommitdiff
path: root/include/fwd/mod.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/fwd/mod.h')
-rw-r--r--include/fwd/mod.h111
1 files changed, 111 insertions, 0 deletions
diff --git a/include/fwd/mod.h b/include/fwd/mod.h
new file mode 100644
index 0000000..6031c92
--- /dev/null
+++ b/include/fwd/mod.h
@@ -0,0 +1,111 @@
+#ifndef FWD_MOD_H
+#define FWD_MOD_H
+
+#include <stddef.h>
+#include <assert.h>
+#include <stdlib.h>
+
+typedef enum fwd_type {
+ FWD_VOID,
+ FWD_I8,
+ FWD_I16,
+ FWD_I32,
+ FWD_I64,
+ FWD_U8,
+ FWD_U16,
+ FWD_U32,
+ FWD_U64,
+ FWD_PTR,
+ /** @todo others */
+ FWD_END /* end of types, IDs above this are custom types I guess? */
+} fwd_type_t;
+
+typedef struct fwd_arg {
+ fwd_type_t t;
+ union {
+ int64_t i64;
+ void *p;
+ };
+} fwd_arg_t;
+
+/** @todo I hate this name */
+typedef struct fwd_extern_args {
+ size_t argc;
+ struct fwd_arg *args;
+} fwd_extern_args_t;
+
+typedef struct fwd_state fwd_state_t;
+typedef long (*fwd_extern_t)(fwd_extern_args_t args);
+typedef long (*fwd_open_t)(fwd_state_t *state);
+
+extern int fwd_register(struct fwd_state *state, const char *name, fwd_extern_t func, fwd_type_t rtype, ...);
+
+#define FWD_REGISTER(state, func, rtype, ...) \
+ fwd_register(state, #func, func, rtype __VA_OPT__(,) __VA_ARGS__, FWD_END)
+
+static inline void *fwd_arg(fwd_extern_args_t args, size_t idx, fwd_type_t id)
+{
+ assert(idx < args.argc);
+ assert(args.args[idx + 1].t == id);
+ switch (id) {
+ case FWD_I64: return &args.args[idx + 1].i64;
+ default:
+ }
+
+ return NULL;
+}
+
+#define FWD_ARG(args, idx, type, id) \
+ *(type *)fwd_arg(args, idx, id)
+
+#define FWD_ARG_T(args, idx, type) \
+ FWD_ARG(args, idx, type, FWD_T(type))
+
+static inline fwd_type_t fwd_t_signed(size_t s)
+{
+ switch (s) {
+ case 1: return FWD_I8;
+ case 2: return FWD_I16;
+ case 4: return FWD_I32;
+ case 8: return FWD_I64;
+ }
+
+ abort();
+ return FWD_END;
+}
+
+static inline fwd_type_t fwd_t_unsigned(size_t s)
+{
+ switch (s) {
+ case 1: return FWD_U8;
+ case 2: return FWD_U16;
+ case 4: return FWD_U32;
+ case 8: return FWD_U64;
+ }
+
+ abort();
+ return FWD_END;
+}
+
+static inline fwd_type_t fwd_t_ptr(size_t s)
+{
+ (void)s;
+ return FWD_PTR;
+}
+
+#define FWD_T(type) \
+ _Generic((type)(0),\
+ signed char : fwd_t_signed, \
+ signed short : fwd_t_signed, \
+ signed int : fwd_t_signed, \
+ signed long : fwd_t_signed, \
+ signed long long : fwd_t_signed, \
+ unsigned char : fwd_t_unsigned, \
+ unsigned short : fwd_t_unsigned, \
+ unsigned int : fwd_t_unsigned, \
+ unsigned long : fwd_t_unsigned, \
+ unsigned long long : fwd_t_signed, \
+ default: fwd_t_ptr)(sizeof(type))
+
+
+#endif /* FWD_MOD_H */