From c0d4714cb304394f19cac5b71d704aa6b2c27dd5 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Sun, 20 Mar 2022 20:05:42 +0000 Subject: Support deferring cvar registration This allows stuff to be registered conditionally. Unfortunately cmeta is now truly the worst thing of all time, but cleaning it up isn't a huge priority. On the plus side, codegen actually got simpler. --- src/build/cmeta.c | 31 ++++++++++++++++++++++++----- src/build/cmeta.h | 2 +- src/build/codegen.c | 57 ++++++++++++++++++++++++++--------------------------- 3 files changed, 55 insertions(+), 35 deletions(-) (limited to 'src/build') diff --git a/src/build/cmeta.c b/src/build/cmeta.c index 7b7a767..4e1eb4a 100644 --- a/src/build/cmeta.c +++ b/src/build/cmeta.c @@ -204,16 +204,37 @@ void cmeta_includes(const struct cmeta *cm, // AGAIN, NOTE: this doesn't *perfectly* match top level decls only in the event // that someone writes something weird, but we just don't really care because // we're not writing something weird. Don't write something weird! -void cmeta_conmacros(const struct cmeta *cm, void (*cb)(const char *, bool)) { +void cmeta_conmacros(const struct cmeta *cm, + void (*cb)(const char *, bool, bool)) { Token *tp = (Token *)cm; if (!tp || !tp->next || !tp->next->next) return; // DEF_xyz, (, name while (tp) { bool isplusminus = false, isvar = false; - if (equal(tp, "DEF_CCMD_PLUSMINUS")) isplusminus = true; + bool unreg = false; + // this is like the worst thing ever, but oh well it's just build time + // XXX: tidy this up some day, though, probably + if (equal(tp, "DEF_CCMD_PLUSMINUS")) { + isplusminus = true; + } + else if (equal(tp, "DEF_CCMD_PLUSMINUS_UNREG")) { + isplusminus = true; + unreg = true; + } else if (equal(tp, "DEF_CVAR") || equal(tp, "DEF_CVAR_MIN") || equal(tp, "DEF_CVAR_MAX") || equal(tp, "DEF_CVAR_MINMAX")) { isvar = true; } + else if (equal(tp, "DEF_CVAR_UNREG") || + equal(tp, "DEF_CVAR_MIN_UNREG") || + equal(tp, "DEF_CVAR_MAX_UNREG") || + equal(tp, "DEF_CVAR_MINMAX_UNREG")) { + isvar = true; + unreg = true; + } + else if (equal(tp, "DEF_CCMD_UNREG") || + equal(tp, "DEF_CCMD_HERE_UNREG")) { + unreg = true; + } else if (!equal(tp, "DEF_CCMD") && !equal(tp, "DEF_CCMD_HERE")) { tp = tp->next; continue; } @@ -226,20 +247,20 @@ void cmeta_conmacros(const struct cmeta *cm, void (*cb)(const char *, bool)) { memcpy(plusname, "PLUS_", 5); memcpy(plusname + sizeof("PLUS_") - 1, tp->loc, tp->len); plusname[sizeof("PLUS_") - 1 + tp->len] = '\0'; - cb(plusname, false); + cb(plusname, false, unreg); char *minusname = malloc(sizeof("MINUS_") + tp->len); if (!minusname) die1("couldn't allocate memory"); memcpy(minusname, "MINUS_", 5); memcpy(minusname + sizeof("MINUS_") - 1, tp->loc, tp->len); minusname[sizeof("MINUS_") - 1 + tp->len] = '\0'; - cb(minusname, false); + cb(minusname, false, unreg); } else { char *name = malloc(tp->len + 1); if (!name) die1("couldn't allocate memory"); memcpy(name, tp->loc, tp->len); name[tp->len] = '\0'; - cb(name, isvar); + cb(name, isvar, unreg); } tp = tp->next; } diff --git a/src/build/cmeta.h b/src/build/cmeta.h index 3319e3a..18ff62c 100644 --- a/src/build/cmeta.h +++ b/src/build/cmeta.h @@ -37,7 +37,7 @@ void cmeta_includes(const struct cmeta *cm, * con_.h, passing each one in turn to the callback cb. */ void cmeta_conmacros(const struct cmeta *cm, - void (*cb)(const char *name, bool isvar)); + void (*cb)(const char *name, bool isvar, bool unreg)); #endif diff --git a/src/build/codegen.c b/src/build/codegen.c index c9be0ef..38645e5 100644 --- a/src/build/codegen.c +++ b/src/build/codegen.c @@ -21,26 +21,30 @@ #include "../os.h" #include "cmeta.h" -static const char *cmdnames[4096]; // arbitrary limit! -static int ncmdnames = 0; -static const char *varnames[4096]; // arbitrary limit! -static int nvarnames = 0; +#define MAXENT 65536 // arbitrary limit! +static struct ent { + const char *name; + bool unreg; + bool isvar; // false for cmd +} ents[MAXENT]; +static int nents; static void die(const char *s) { fprintf(stderr, "codegen: %s\n", s); exit(100); } -#define PUT(array, ent) do { \ - if (n##array == sizeof(array) / sizeof(*array)) { \ - fprintf(stderr, "codegen: out of space; make " #array " bigger!\n"); \ +#define PUT(name_, isvar_, unreg_) do { \ + if (nents == sizeof(ents) / sizeof(*ents)) { \ + fprintf(stderr, "codegen: out of space; make ents bigger!\n"); \ exit(1); \ } \ - array[n##array++] = ent; \ + ents[nents].name = name_; \ + ents[nents].isvar = isvar_; ents[nents++].unreg = unreg_; \ } while (0) -static void oncondef(const char *name, bool isvar) { - if (isvar) PUT(varnames, name); else PUT(cmdnames, name); +static void oncondef(const char *name, bool isvar, bool unreg) { + PUT(name, isvar, unreg); } #define _(x) \ @@ -60,31 +64,26 @@ int OS_MAIN(int argc, os_char *argv[]) { FILE *out = fopen(".build/include/cmdinit.gen.h", "wb"); if (!out) die("couldn't open cmdinit.gen.h"); H(); - for (const char *const *pp = cmdnames; - pp - cmdnames < ncmdnames; ++pp) { -F( "extern struct con_cmd *%s;", *pp) - } - for (const char *const *pp = varnames; - pp - varnames < nvarnames; ++pp) { -F( "extern struct con_var *%s;", *pp) + for (const struct ent *p = ents; p - ents < nents; ++p) { +F( "extern struct con_%s *%s;", p->isvar ? "var" : "cmd", p->name) } _( "") -_( "static void regcmds(void (*VCALLCONV f)(void *, void *)) {") - for (const char *const *pp = cmdnames; - pp - cmdnames < ncmdnames; ++pp) { -F( " f(_con_iface, %s);", *pp) - } - for (const char *const *pp = varnames; - pp - varnames < nvarnames; ++pp) { -F( " initval(%s);", *pp) -F( " f(_con_iface, %s);", *pp) +_( "static void regcmds(void) {") + for (const struct ent *p = ents; p - ents < nents; ++p) { + if (p->isvar) { +F( " initval(%s);", p->name) + } + if (!p->unreg) { +F( " con_reg(%s);", p->name) + } } _( "}") _( "") _( "static void freevars(void) {") - for (const char *const *pp = varnames; - pp - varnames < nvarnames; ++pp) { -F( " extfree(%s->strval);", *pp) + for (const struct ent *p = ents; p - ents < nents; ++p) { + if (p->isvar) { +F( " extfree(%s->strval);", p->name); + } } _( "}") if (fflush(out) == EOF) die("couldn't fully write cmdinit.gen.h"); -- cgit v1.2.3