/* * Copyright © 2021 Michael Smith * * 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 #include #include #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