3 # Copyright © 2021, 2023 Nick Bowler
5 # Generate a function to return the C keyword corresponding to a specifier
6 # type as a string, for internal use by the output routines.
8 # License WTFPL2: Do What The Fuck You Want To Public License, version 2.
9 # This is free software: you are free to do what the fuck you want to.
10 # There is NO WARRANTY, to the extent permitted by law.
15 print " * Automatically generated by gen-specstr.awk from " FILENAME;
17 print " * Automatically generated by gen-specstr.awk";
19 print " * Do not edit.";
24 kinds["TYPE"] = kinds["STOR"] = kinds["QUAL"] = kinds["FUNC"] = 1;
28 # Locate all the relevant identifiers in cdecl.h. We assume everything
29 # is in numerically increasing order within the various enums.
31 sub(/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ_].*/, "", $1);
33 split($1, parts, "_");
34 if (parts[2] == "SPEC") {
41 print "cannot create skip table";
45 skiptab[x] = parts[3];
48 if (parts[2] in kinds) {
49 kind_counts[parts[2]]++;
50 specs[count++] = parts[3];
52 if (length(parts[3]) > maxwidth)
53 maxwidth = length(parts[3]);
58 # Create the token table. The first 5 entries key off of bits 9 through 11,
59 # which is sufficient to distinguish the different specifier kinds and is
60 # used to partition the rest of the token table.
67 skip_pos = ++skip_count;
68 for (i = 0; i < skip_count; i++) {
69 offset_table = offset_table skip_pos ", ";
70 skip_pos += kind_counts[skiptab[i]];
72 sub(/ $/, "\n\t\t", offset_table);
74 for (i = 0; i < count; i++) {
79 if (specs[i] == "IDENT")
82 s = "T_" substr(specs[i] " ", 1, maxwidth) " & 0xff";
83 offset_table = offset_table s suffix;
86 print "static const char *spec_string(unsigned type)"
88 print "\tstatic const uint_least8_t idx[] = {";
89 print "\t\t" offset_table;
92 print "\tunsigned x = (type & 0xff) + idx[type >> 9];";
93 print "\tassert(x < sizeof idx);";
94 print "\tif (!(x = idx[x]))";
95 print "\t\treturn \"\";";
96 print "\tif (T_" specs[0] " >= 256)";
97 print "\t\tx += 256;";
98 print "\treturn cdecl__token_name(x);";