From b594c53771a1d6bae2548d06b86f91c504811785 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 21 Sep 2021 16:53:07 +0930 Subject: [PATCH] common/autodata: autodata replacement which uses __attribute__((constructor)) This is a GCC extension, but avoids much other messiness. Signed-off-by: Rusty Russell --- common/Makefile | 1 + common/autodata.c | 40 ++++++++++++++++++++++++++++++++++++++++ common/autodata.h | 26 ++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 common/autodata.c create mode 100644 common/autodata.h diff --git a/common/Makefile b/common/Makefile index f0e68d2e6..44d02c1c2 100644 --- a/common/Makefile +++ b/common/Makefile @@ -1,6 +1,7 @@ COMMON_SRC_NOGEN := \ common/addr.c \ common/amount.c \ + common/autodata.c \ common/base32.c \ common/base64.c \ common/bech32.c \ diff --git a/common/autodata.c b/common/autodata.c new file mode 100644 index 000000000..4273a9b0b --- /dev/null +++ b/common/autodata.c @@ -0,0 +1,40 @@ +#include "config.h" +#include +#include +#include + +struct typereg { + size_t num; + const void **ptrs; +}; + +static STRMAP(struct typereg *) typemap; + +void autodata_register_(const char *typename, const void *ptr) +{ + struct typereg *t; + assert(ptr); + + t = strmap_get(&typemap, typename); + if (!t) { + t = malloc(sizeof(struct typereg)); + t->num = 0; + t->ptrs = NULL; + strmap_add(&typemap, typename, t); + } + + t->ptrs = realloc(t->ptrs, (t->num + 1) * sizeof(*t->ptrs)); + t->ptrs[t->num] = ptr; + t->num++; +} + +void *autodata_get_(const char *typename, size_t *nump) +{ + struct typereg *t = strmap_get(&typemap, typename); + if (!t) { + *nump = 0; + return NULL; + } + *nump = t->num; + return t->ptrs; +} diff --git a/common/autodata.h b/common/autodata.h new file mode 100644 index 000000000..7d05217b4 --- /dev/null +++ b/common/autodata.h @@ -0,0 +1,26 @@ +#ifndef LIGHTNING_COMMON_AUTODATA_H +#define LIGHTNING_COMMON_AUTODATA_H +#include "config.h" +#include +#include + +#define AUTODATA_TYPE(name, type) \ + static inline void register_autotype_##name(const type *t) { \ + autodata_register_(#name, t); \ + } \ + typedef type autodata_##name##_ + +/* This uses GCC's constructor attribute */ +#define AUTODATA(name, ptr) \ + static __attribute__((constructor)) NEEDED \ + void CPPMAGIC_GLUE2(register_one_##name,__COUNTER__)(void) { \ + register_autotype_##name(ptr); \ + } + +#define autodata_get(name, nump) \ + ((autodata_##name##_ **)autodata_get_(#name, (nump))) + +void autodata_register_(const char *typename, const void *ptr); +void *autodata_get_(const char *typename, size_t *nump); + +#endif /* LIGHTNING_COMMON_AUTODATA_H */