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
< $(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
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@)
* 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. */
--- /dev/null
+#!/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 " };"
+}
+++ /dev/null
-#!/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 <<EOF
-/* This file was automatically generated by $0 $*. */
-struct cdecl_declspec *s, *p;
-EOF
-
-i=0
-while read line
-do
- case "$line" in
- [[:alpha:]_]*)
- :
- ;;
- *)
- printf '%s\n' "$line";
- continue
- ;;
- esac
-
- cat <<EOF
-case $i:
- s = NULL;
-EOF
-
- set $line
- while test $# -gt 0
- do
- token=`printf '%s' "$1" | tr [:lower:] [:upper:] | tr -d _`
- cat <<EOF
- p = s;
- s = malloc_nofail(sizeof *s);
- *s = (struct cdecl_declspec) {
- .type = CDECL_TYPE_$token,
- .next = p,
- };
-EOF
- shift
- done
-
- i=`expr $i + 1`
- cat <<EOF
- return s;
-EOF
-done
-
-cat <<EOF
-default:
- assert(0);
-#define TOTAL_TYPES $i
-EOF