gen-strtab.awk: Work around IRIX 6.2 nawk bug.
[dxcommon.git] / scripts / bake-config.awk
blob56e215180b8664b7063db7f67ba182d62c8cb35a
1 #!/bin/awk -f
3 # Copyright © 2023 Nick Bowler
5 # Usage: bake-config.awk config.h some_header.h
7 # Looks for #define and #undef lines in config.h to identify configuration
8 # macros, then looks for uses of those macros in some_header.h and substitutes
9 # them accordingly. The result is a header file that does not directly depend
10 # on config.h, which can be installed normally.
12 # Presently, two kinds of substitions are made.
14 # - For a #define in config.h, any occurrence of that macro is substituted with
15 # its replacement text.
17 # - For an #undef in config.h, any occurrence of that macro in an #if or #elif
18 # directive is replaced with a literal 0.
20 # Almost no attempt is made to understand C syntax so the replacement is very
21 # simplistic, and won't work well in many cases. Inspect the output!
23 # License WTFPL2: Do What The Fuck You Want To Public License, version 2.
24 # This is free software: you are free to do what the fuck you want to.
25 # There is NO WARRANTY, to the extent permitted by law.
27 BEGIN {
28 filenum = 0;
29 idclass = "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0-9_]";
32 FNR == 1 { filenum++; }
33 filenum == 1 && $1 == "#define" && $2 !~ /[(]/ {
34 key = $2;
35 $1 = $2 = "";
36 sub(/^ */, "", $0);
37 config[key] = $0 " /* " key " */";
40 # Autoconf comments out #undef lines in config.h, so we're looking for
41 # /* #undef FOO */
42 filenum == 1 && $2 == "#undef" {
43 undef[$3] = 0 " /* " $3 " */";
46 filenum == 2 {
47 CHANGED = 0;
48 tok = $0;
50 # Mark identifier boundaries to avoid replacing substrings. Use ` as
51 # it is not valid in C code (outside of string/character literals).
52 gsub(idclass"+", "`&`", tok);
54 # Replace all occurrences of configuration macros normally.
55 tok = do_replace(tok, config);
57 # Replace explicitly undefined configuration macros in #if/#elif
58 if ($0 ~ /^[ \t]*#[ \t]*(el)?if[ \t]/)
59 tok = do_replace(tok, undef);
61 if (CHANGED) {
62 gsub(/`/, "", tok);
63 print tok;
64 } else {
65 print $0;
69 function do_replace(s, config, result, t)
71 while (match(s, "`" idclass "+`")) {
72 t = substr(s, RSTART+1, RLENGTH-2);
73 if (t in config) {
74 result = result substr(s, 1, RSTART - 1) config[t];
75 CHANGED = 1;
76 } else {
77 result = result substr(s, 1, RSTART + RLENGTH - 1);
80 s = substr(s, RSTART + RLENGTH);
83 return result s;