From: Nick Bowler Date: Wed, 10 Mar 2021 07:31:59 +0000 (-0500) Subject: Replace typegen.sh with a new and improved script. X-Git-Tag: v1.1~7 X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/commitdiff_plain/02413704070c34bec00184120c4728854671d2d5 Replace typegen.sh with a new and improved script. The old typegen.sh has a bunch of portability problems; let's write a new script in awk which is a better tool for this sort of code generation task anyway. --- diff --git a/Makefile.am b/Makefile.am index 44b4601..82a6c0d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,12 +24,12 @@ MAINTAINERCLEANFILES = src/scan.c src/scan.h src/scan.stamp \ DISTCLEANFILES = CLEANFILES = src/validtypes.h src/namespecs.h src/ordspecs.h \ - test/typegen.h $(EXTRA_LTLIBRARIES) + $(EXTRA_LTLIBRARIES) EXTRA_DIST = bootstrap $(DX_BASEDIR)/scripts/fix-gnulib.pl m4/gnulib-cache.m4 \ src/types.lst src/validtypes.sed src/specs.lst src/namespecs.sed \ - src/ordspecs.sed test/typegen.sh src/parse.y src/parse.stamp \ - src/scan.l src/scan.stamp COPYING.WTFPL2 README.md INSTALL + src/ordspecs.sed src/parse.y src/parse.stamp src/scan.l \ + src/scan.stamp COPYING.WTFPL2 README.md INSTALL dist_man_MANS = doc/cdecl99.1 doc/libcdecl.3 @@ -106,11 +106,6 @@ src/ordspecs.h: $(srcdir)/src/specs.lst $(srcdir)/src/ordspecs.sed < $(srcdir)/src/specs.lst > $@.tmp $(AM_V_at) mv -f $@.tmp $@ -test/typegen.h: $(srcdir)/src/types.lst $(srcdir)/test/typegen.sh - $(AM_V_GEN) $(SHELL) $(srcdir)/test/typegen.sh \ - < $(srcdir)/src/types.lst > $@.tmp - $(AM_V_at)mv -f $@.tmp $@ - # Supporting rules for gettext. include $(top_srcdir)/common/snippet/gettext.mk @@ -219,6 +214,13 @@ src/cmdlist.h: src/gen-cmdlist.awk src/execute.c DISTCLEANFILES += src/cmdlist.h EXTRA_DIST += src/gen-cmdlist.awk +test/typegen.h: test/gen-typegen.awk src/types.lst + $(AM_V_GEN) $(AWK) -f $(srcdir)/test/gen-typegen.awk \ + $(srcdir)/src/types.lst >$@.tmp + $(AM_V_at) mv -f $@.tmp $@ +DISTCLEANFILES += test/typegen.h +EXTRA_DIST += test/gen-typegen.awk + # Supporting rules for bison/flex. BISON_V = $(BISON_V_@AM_V@) diff --git a/test/declgen.c b/test/declgen.c index 4fb39cb..c02613a 100644 --- a/test/declgen.c +++ b/test/declgen.c @@ -150,21 +150,15 @@ struct cdecl_declspec *gen_storspecs(struct gen_rng *rng, bool registeronly) * Generate random type specifiers. There is a short list of valid * combinations, from which we can select one uniformly at random. */ -static const unsigned long total_types; -static struct cdecl_declspec *gen_raw_typespecs(struct gen_rng *rng) -{ - switch (gsl_rng_uniform_int(rng->rng, total_types)) { -# include "typegen.h" - } -} -static const unsigned long total_types = TOTAL_TYPES; +#include "typegen.h" struct cdecl_declspec *gen_typespecs(struct gen_rng *rng, bool voidtype) { struct cdecl_declspec *specs; retry: - specs = gen_raw_typespecs(rng); + specs = gen_raw_typespecs(gsl_rng_uniform_int(rng->rng, + GEN_TOTAL_TYPES)); switch (specs->type) { /* void is not always valid, so we might need to pick again. */ diff --git a/test/gen-typegen.awk b/test/gen-typegen.awk new file mode 100755 index 0000000..0ae20f5 --- /dev/null +++ b/test/gen-typegen.awk @@ -0,0 +1,61 @@ +#!/bin/awk -f +# +# Copyright © 2021 Nick Bowler +# +# Generate a mapping from a (random) integer to a list of type specifiers +# represented by struct cdecl_declspec. Used internally by declgen to +# produce random valid declarations. +# +# License WTFPL2: Do What The Fuck You Want To Public License, version 2. +# This is free software: you are free to do what the fuck you want to. +# There is NO WARRANTY, to the extent permitted by law. + +END { + print "/*" + if (FILENAME) { + print " * Automatically generated by gen-typegen.awk from " FILENAME + } else { + print " * Automatically generated by gen-typegen.awk" + } + print " * Do not edit." + print " */" +} + +BEGIN { + count = 0 +} + +$0 ~ /^[abcdefghijklmnopqrstuvwxyz_]/ { + for (i = 1; i <= NF; i++) { + sub(/_/, "", $i) + $i = "CDECL_TYPE_" toupper($i) + } + specs[count++] = $0 +} + +END { + print "static inline struct cdecl_declspec *" + print "gen_raw_typespec_(unsigned type, struct cdecl_declspec *next)\n{" + print "\tstruct cdecl_declspec *s = malloc_nofail(sizeof *s);" + print "\t*s = (struct cdecl_declspec) { .next = next, .type = type };" + print "\treturn s;\n}\n" + + print "static inline struct cdecl_declspec *" + print "gen_raw_typespecs(unsigned rngval)\n{" + print "\tswitch (rngval) {" + + for (i = 0; i < count; i++) { + print "\tcase " i ":" + $0 = specs[i] + + for (j = 1; j <= NF; j++) { + prefix = j == 1 ? "return" : ""; + + printf "\t\t%6s gen_raw_typespec_(%s,\n", prefix, $j + } + printf "\t\t%25sNULL%.*s;\n", "", NF, "))))))))" + } + print "\tdefault:\n\t\tassert(0);\n\t}" + print "}\n" + print "enum { GEN_TOTAL_TYPES = " count " };" +} diff --git a/test/typegen.sh b/test/typegen.sh deleted file mode 100755 index 1658d5d..0000000 --- a/test/typegen.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/sh -# -# Copyright © 2011 Nick Bowler -# -# License WTFPL2: Do What The Fuck You Want To Public License, version 2. -# This is free software: you are free to do what the fuck you want to. -# There is NO WARRANTY, to the extent permitted by law. - -cat <