diff options
author | Michael Smith <mikesmiffy128@gmail.com> | 2021-11-20 03:10:50 +0000 |
---|---|---|
committer | Michael Smith <mikesmiffy128@gmail.com> | 2021-11-20 03:18:08 +0000 |
commit | da6f343032cb01597dc7866e66f091adf3243a62 (patch) | |
tree | 870f8cb8e82bb42202ab92bea03fc6ab35ada7ca /src/build/codegen.c |
Initial public snapshot
With code from Bill. Thanks Bill!
Diffstat (limited to 'src/build/codegen.c')
-rw-r--r-- | src/build/codegen.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/build/codegen.c b/src/build/codegen.c new file mode 100644 index 0000000..c9be0ef --- /dev/null +++ b/src/build/codegen.c @@ -0,0 +1,95 @@ +/* + * Copyright © 2021 Michael Smith <mikesmiffy128@gmail.com> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#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; + +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"); \ + exit(1); \ + } \ + array[n##array++] = ent; \ +} while (0) + +static void oncondef(const char *name, bool isvar) { + if (isvar) PUT(varnames, name); else PUT(cmdnames, name); +} + +#define _(x) \ + if (fprintf(out, "%s\n", x) < 0) die("couldn't write to file"); +#define F(f, ...) \ + if (fprintf(out, f "\n", __VA_ARGS__) < 0) die("couldn't write to file"); +#define H() \ +_( "/* This file is autogenerated by src/build/codegen.c. DO NOT EDIT! */") \ +_( "") + +int OS_MAIN(int argc, os_char *argv[]) { + for (++argv; *argv; ++argv) { + const struct cmeta *cm = cmeta_loadfile(*argv); + cmeta_conmacros(cm, &oncondef); + } + + 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) + } +_( "") +_( "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 freevars(void) {") + for (const char *const *pp = varnames; + pp - varnames < nvarnames; ++pp) { +F( " extfree(%s->strval);", *pp) + } +_( "}") + if (fflush(out) == EOF) die("couldn't fully write cmdinit.gen.h"); + + return 0; +} + +// vi: sw=4 ts=4 noet tw=80 cc=80 |