Blame


1 23b7ad13 2024-03-02 benni # awkward make
2 23b7ad13 2024-03-02 benni
3 23b7ad13 2024-03-02 benni function strip(s) {
4 23b7ad13 2024-03-02 benni sub(/^[[:space:]]*/, "", s);
5 23b7ad13 2024-03-02 benni sub(/[[:space:]]*$/, "", s);
6 23b7ad13 2024-03-02 benni return s;
7 23b7ad13 2024-03-02 benni }
8 23b7ad13 2024-03-02 benni
9 23b7ad13 2024-03-02 benni function find(name) {
10 23b7ad13 2024-03-02 benni for (i = 1; i <= length(data);) {
11 23b7ad13 2024-03-02 benni if (data[i] == name)
12 23b7ad13 2024-03-02 benni return i;
13 23b7ad13 2024-03-02 benni i += data[++i] + 1;
14 23b7ad13 2024-03-02 benni i += data[i] + 1;
15 23b7ad13 2024-03-02 benni }
16 23b7ad13 2024-03-02 benni return 0;
17 23b7ad13 2024-03-02 benni }
18 23b7ad13 2024-03-02 benni
19 23b7ad13 2024-03-02 benni function isnewer(a, b) {
20 23b7ad13 2024-03-02 benni cmd = sprintf("ls -1t '%s' '%s' 2>&1", a, b);
21 23b7ad13 2024-03-02 benni cmd | getline file;
22 23b7ad13 2024-03-02 benni close(cmd);
23 23b7ad13 2024-03-02 benni regex = "^" a "\*?$";
24 23b7ad13 2024-03-02 benni return file ~ regex;
25 23b7ad13 2024-03-02 benni }
26 23b7ad13 2024-03-02 benni
27 23b7ad13 2024-03-02 benni function exists(f) {
28 23b7ad13 2024-03-02 benni cmd = sprintf("ls '%s' > /dev/null 2>&1", f);
29 23b7ad13 2024-03-02 benni return system(cmd) == 0;
30 23b7ad13 2024-03-02 benni }
31 23b7ad13 2024-03-02 benni
32 23b7ad13 2024-03-02 benni function expand(s, rulename, i, out, name, ch, chars) {
33 23b7ad13 2024-03-02 benni out = "";
34 23b7ad13 2024-03-02 benni split(s, chars, "");
35 23b7ad13 2024-03-02 benni for (i = 1; i <= length(chars);) {
36 23b7ad13 2024-03-02 benni ch = chars[i++];
37 23b7ad13 2024-03-02 benni if (ch != "$") {
38 23b7ad13 2024-03-02 benni out = out ch;
39 23b7ad13 2024-03-02 benni continue;
40 23b7ad13 2024-03-02 benni }
41 23b7ad13 2024-03-02 benni
42 23b7ad13 2024-03-02 benni ch = chars[i++];
43 23b7ad13 2024-03-02 benni
44 23b7ad13 2024-03-02 benni if (ch == "{") {
45 23b7ad13 2024-03-02 benni name = "";
46 23b7ad13 2024-03-02 benni while (1) {
47 23b7ad13 2024-03-02 benni ch = chars[i++];
48 23b7ad13 2024-03-02 benni if (ch == "}")
49 23b7ad13 2024-03-02 benni break;
50 23b7ad13 2024-03-02 benni name = name ch;
51 23b7ad13 2024-03-02 benni }
52 23b7ad13 2024-03-02 benni
53 23b7ad13 2024-03-02 benni out = out macros[name];
54 23b7ad13 2024-03-02 benni } else if (ch == "$") {
55 23b7ad13 2024-03-02 benni out = out "$";
56 23b7ad13 2024-03-02 benni } else if (ch == "@") {
57 23b7ad13 2024-03-02 benni out = out rulename;
58 23b7ad13 2024-03-02 benni } else {
59 23b7ad13 2024-03-02 benni print "ERROR: invalid replacement";
60 23b7ad13 2024-03-02 benni exit 1;
61 23b7ad13 2024-03-02 benni }
62 23b7ad13 2024-03-02 benni }
63 23b7ad13 2024-03-02 benni return out;
64 23b7ad13 2024-03-02 benni }
65 23b7ad13 2024-03-02 benni
66 23b7ad13 2024-03-02 benni function run(pos, name, updated, num, i, dep, cmd) {
67 23b7ad13 2024-03-02 benni name = data[pos];
68 23b7ad13 2024-03-02 benni num = data[++pos];
69 23b7ad13 2024-03-02 benni ++pos;
70 23b7ad13 2024-03-02 benni
71 23b7ad13 2024-03-02 benni updated = !exists(name);
72 23b7ad13 2024-03-02 benni
73 23b7ad13 2024-03-02 benni for (i = 1; i <= num; ++i) {
74 23b7ad13 2024-03-02 benni dep = data[pos++];
75 23b7ad13 2024-03-02 benni rule = find(dep);
76 23b7ad13 2024-03-02 benni
77 23b7ad13 2024-03-02 benni if (exists(dep)) {
78 23b7ad13 2024-03-02 benni if (isnewer(dep, name))
79 23b7ad13 2024-03-02 benni updated = 1;
80 23b7ad13 2024-03-02 benni }
81 23b7ad13 2024-03-02 benni
82 23b7ad13 2024-03-02 benni if (rule != 0) {
83 23b7ad13 2024-03-02 benni if (run(rule))
84 23b7ad13 2024-03-02 benni updated = 1;
85 23b7ad13 2024-03-02 benni } else if (!exists(dep)) {
86 23b7ad13 2024-03-02 benni print "ERROR: No rule for", dep;
87 23b7ad13 2024-03-02 benni exit 1;
88 23b7ad13 2024-03-02 benni }
89 23b7ad13 2024-03-02 benni }
90 23b7ad13 2024-03-02 benni
91 23b7ad13 2024-03-02 benni if (updated == 0)
92 23b7ad13 2024-03-02 benni return 0;
93 23b7ad13 2024-03-02 benni
94 23b7ad13 2024-03-02 benni num = data[pos++];
95 23b7ad13 2024-03-02 benni for (i = 1; i <= num; ++i) {
96 23b7ad13 2024-03-02 benni cmd = data[pos++];
97 23b7ad13 2024-03-02 benni print cmd;
98 23b7ad13 2024-03-02 benni cmd = expand(cmd, name);
99 23b7ad13 2024-03-02 benni if (system(cmd) != 0) {
100 23b7ad13 2024-03-02 benni print "ERROR: Command failed";
101 23b7ad13 2024-03-02 benni exit 1;
102 23b7ad13 2024-03-02 benni }
103 23b7ad13 2024-03-02 benni }
104 23b7ad13 2024-03-02 benni return 1;
105 23b7ad13 2024-03-02 benni }
106 23b7ad13 2024-03-02 benni
107 23b7ad13 2024-03-02 benni BEGIN {
108 23b7ad13 2024-03-02 benni pos = 1;
109 23b7ad13 2024-03-02 benni saved = -1;
110 23b7ad13 2024-03-02 benni }
111 23b7ad13 2024-03-02 benni
112 23b7ad13 2024-03-02 benni # Empty lines and comments
113 23b7ad13 2024-03-02 benni /^[[:space:]]*(#.*)?$/ { next; }
114 23b7ad13 2024-03-02 benni
115 23b7ad13 2024-03-02 benni # Macro Definitions
116 23b7ad13 2024-03-02 benni /^[a-zA-Z_][a-zA-Z_0-9]*[[:space:]]*=.*$/ {
117 23b7ad13 2024-03-02 benni split($0, x, "=");
118 23b7ad13 2024-03-02 benni macros[strip(x[1])] = strip(x[2]);
119 23b7ad13 2024-03-02 benni next;
120 23b7ad13 2024-03-02 benni }
121 23b7ad13 2024-03-02 benni
122 23b7ad13 2024-03-02 benni # Rule Declarations
123 23b7ad13 2024-03-02 benni /^[^:]+:[^:]*$/ {
124 23b7ad13 2024-03-02 benni split($0, x, ":");
125 23b7ad13 2024-03-02 benni split(strip(x[1]), targets, "[[:space:]]+");
126 23b7ad13 2024-03-02 benni if (length(targets) != 1) {
127 23b7ad13 2024-03-02 benni print "ERROR: no multi-targets supported";
128 23b7ad13 2024-03-02 benni exit 1;
129 23b7ad13 2024-03-02 benni }
130 23b7ad13 2024-03-02 benni target = targets[1];
131 23b7ad13 2024-03-02 benni split(strip(x[2]), deps, "[[:space:]]+");
132 23b7ad13 2024-03-02 benni
133 23b7ad13 2024-03-02 benni if (target ~ /^\..*$/) {
134 23b7ad13 2024-03-02 benni if (target == ".POSIX")
135 23b7ad13 2024-03-02 benni next;
136 23b7ad13 2024-03-02 benni print "ERROR: invalid directive" target;
137 23b7ad13 2024-03-02 benni exit 1;
138 23b7ad13 2024-03-02 benni }
139 23b7ad13 2024-03-02 benni
140 23b7ad13 2024-03-02 benni data[pos++] = target;
141 23b7ad13 2024-03-02 benni data[pos++] = length(deps);
142 23b7ad13 2024-03-02 benni for (i = 1; i <= length(deps); ++i) {
143 23b7ad13 2024-03-02 benni data[pos++] = deps[i];
144 23b7ad13 2024-03-02 benni }
145 23b7ad13 2024-03-02 benni saved = pos++;
146 23b7ad13 2024-03-02 benni data[saved] = 0;
147 23b7ad13 2024-03-02 benni next;
148 23b7ad13 2024-03-02 benni }
149 23b7ad13 2024-03-02 benni
150 23b7ad13 2024-03-02 benni # Rule Commands
151 23b7ad13 2024-03-02 benni /^\t.*$/ {
152 23b7ad13 2024-03-02 benni if (saved == -1) {
153 23b7ad13 2024-03-02 benni print "ERROR: no rule declaration";
154 23b7ad13 2024-03-02 benni exit 1;
155 23b7ad13 2024-03-02 benni }
156 23b7ad13 2024-03-02 benni gsub(/^\t/, "");
157 23b7ad13 2024-03-02 benni data[saved]++;
158 23b7ad13 2024-03-02 benni data[pos++] = $0;
159 23b7ad13 2024-03-02 benni }
160 23b7ad13 2024-03-02 benni
161 23b7ad13 2024-03-02 benni END {
162 23b7ad13 2024-03-02 benni split(args, argv, "[[:space:]]+");
163 23b7ad13 2024-03-02 benni
164 23b7ad13 2024-03-02 benni k = 1;
165 23b7ad13 2024-03-02 benni
166 23b7ad13 2024-03-02 benni for (i = 1; i <= length(argv); ++i) {
167 23b7ad13 2024-03-02 benni arg = argv[i];
168 23b7ad13 2024-03-02 benni if (arg ~ /^[^=]+=.*$/) {
169 23b7ad13 2024-03-02 benni split(arg, m, "=");
170 23b7ad13 2024-03-02 benni macros[m[1]] = m[2];
171 23b7ad13 2024-03-02 benni } else {
172 23b7ad13 2024-03-02 benni rules[k++] = arg;
173 23b7ad13 2024-03-02 benni }
174 23b7ad13 2024-03-02 benni }
175 23b7ad13 2024-03-02 benni
176 23b7ad13 2024-03-02 benni if (length(rules) != 0) {
177 23b7ad13 2024-03-02 benni for (k = 1; k <= length(rules); ++k) {
178 23b7ad13 2024-03-02 benni name = rules[k];
179 23b7ad13 2024-03-02 benni rule = find(name);
180 23b7ad13 2024-03-02 benni if (rule == 0) {
181 23b7ad13 2024-03-02 benni print "No such rule:", name;
182 23b7ad13 2024-03-02 benni exit 1;
183 23b7ad13 2024-03-02 benni }
184 23b7ad13 2024-03-02 benni run(rule);
185 23b7ad13 2024-03-02 benni }
186 23b7ad13 2024-03-02 benni } else {
187 23b7ad13 2024-03-02 benni run(1);
188 23b7ad13 2024-03-02 benni }
189 23b7ad13 2024-03-02 benni }