parselist.awk revision 1.13 1 1.13 thorpej # $NetBSD: parselist.awk,v 1.13 2002/09/15 16:15:40 thorpej Exp $
2 1.1 lukem #
3 1.1 lukem # Copyright (c) 2002 The NetBSD Foundation, Inc.
4 1.1 lukem # All rights reserved.
5 1.1 lukem #
6 1.1 lukem # This code is derived from software contributed to The NetBSD Foundation
7 1.1 lukem # by Luke Mewburn of Wasabi Systems.
8 1.1 lukem #
9 1.1 lukem # Redistribution and use in source and binary forms, with or without
10 1.1 lukem # modification, are permitted provided that the following conditions
11 1.1 lukem # are met:
12 1.1 lukem # 1. Redistributions of source code must retain the above copyright
13 1.1 lukem # notice, this list of conditions and the following disclaimer.
14 1.1 lukem # 2. Redistributions in binary form must reproduce the above copyright
15 1.1 lukem # notice, this list of conditions and the following disclaimer in the
16 1.1 lukem # documentation and/or other materials provided with the distribution.
17 1.1 lukem # 3. All advertising materials mentioning features or use of this software
18 1.1 lukem # must display the following acknowledgement:
19 1.1 lukem # This product includes software developed by the NetBSD
20 1.1 lukem # Foundation, Inc. and its contributors.
21 1.1 lukem # 4. Neither the name of The NetBSD Foundation nor the names of its
22 1.1 lukem # contributors may be used to endorse or promote products derived
23 1.1 lukem # from this software without specific prior written permission.
24 1.1 lukem #
25 1.1 lukem # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
26 1.1 lukem # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 1.1 lukem # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 1.1 lukem # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
29 1.1 lukem # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 1.1 lukem # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 1.1 lukem # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 1.1 lukem # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 1.1 lukem # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 1.1 lukem # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 1.1 lukem # POSSIBILITY OF SUCH DAMAGE.
36 1.1 lukem #
37 1.3 lukem
38 1.3 lukem #
39 1.3 lukem # awk -f parselist.awk -v mode=MODE [var=val ...] file1 [...]
40 1.1 lukem #
41 1.1 lukem # Parse list files file1 [...], generating different output,
42 1.7 lukem # depending upon the value of MODE:
43 1.9 lukem #
44 1.1 lukem # crunch crunchgen(1) config
45 1.9 lukem #
46 1.12 lukem # install make(1) Makefile to install commands into ${TARGETDIR},
47 1.12 lukem # with an `install' target.
48 1.12 lukem # The following environment variables need to be set:
49 1.12 lukem # TARGETDIR Directory to populate
50 1.12 lukem #
51 1.1 lukem # mtree mtree(8) specfile
52 1.9 lukem #
53 1.9 lukem # populate sh(1) commands to populate ${TARGETDIR} from ${CURDIR}
54 1.9 lukem # The following environment variables need to be set:
55 1.9 lukem # CURDIR Source directory; make(1)'s ${.CURDIR}
56 1.9 lukem # TARGETDIR Directory to populate
57 1.9 lukem #
58 1.12 lukem # The following environment variables need to be set for all modes:
59 1.12 lukem # CRUNCHBIN Name of crunchgen(1) target binary
60 1.12 lukem # OBJDIR Object directory; make(1)'s ${.OBJDIR}
61 1.1 lukem #
62 1.1 lukem # Each line of the input is either a comment (starts with `#'),
63 1.1 lukem # or contains one of the following keywords and arguments.
64 1.1 lukem #
65 1.9 lukem # Before each line is parsed for a keyword, words surrounded by
66 1.9 lukem # "${" and "}", and containing only letters, numbers, and `_'
67 1.9 lukem # will be replaced by the value of the environment variable of
68 1.9 lukem # the same name. I.e., "${MACHINE_ARCH}" will be replaced with the
69 1.9 lukem # value of ENVIRON["MACHINE_ARCH"].
70 1.3 lukem #
71 1.1 lukem # mode key operation
72 1.1 lukem # -------- ---------
73 1.1 lukem # C crunch
74 1.12 lukem # I install
75 1.1 lukem # M mtree
76 1.1 lukem # P populate
77 1.1 lukem #
78 1.1 lukem # mode keyword arg1 [...] description
79 1.1 lukem # ---- ------------------ -----------
80 1.1 lukem #
81 1.1 lukem # C ARGVLN prog link as per crunchgen(1) `ln'
82 1.1 lukem #
83 1.1 lukem # P CMD arg1 [...] run CMD as a shell command
84 1.1 lukem #
85 1.12 lukem # IMP COPY src dest [perm] copy src to dest. perm defaults to 0444
86 1.4 lukem #
87 1.12 lukem # IMP COPYDIR src dest recursively copy files under src to
88 1.10 lukem # dest. for M, dest is listed first,
89 1.10 lukem # followed by the subdirectories in src.
90 1.11 lukem # copied directories have mode 0755.
91 1.11 lukem # copied files have mode 0444.
92 1.1 lukem #
93 1.1 lukem # C LIBS libspec ... as per crunchgen(1) `libs'
94 1.1 lukem #
95 1.12 lukem # IMP LINK src d1 [d2 ...] hard link src to d1, d2, ...
96 1.1 lukem #
97 1.6 lukem # M MTREE arg1 [...] output arguments `as-is' to specfile
98 1.6 lukem #
99 1.12 lukem # CIMP PROG prog [links...] program(s) to crunch/mtree/populate.
100 1.12 lukem # for I, M & P, the first prog listed
101 1.1 lukem # is copied from ${OBJDIR}/${CRUNCHBIN}
102 1.1 lukem # and then used as the name to link
103 1.1 lukem # all other PROG entries to.
104 1.1 lukem #
105 1.1 lukem # C SPECIAL prog cmd ... as per crunchgen(1) `special'
106 1.1 lukem #
107 1.1 lukem # C SRCDIRS dirname ... as per crunchgen(1) `srcdirs'
108 1.1 lukem #
109 1.12 lukem # IMP SYMLINK src dest [...] symlink src to dest, [...]
110 1.1 lukem #
111 1.1 lukem
112 1.1 lukem BEGIN \
113 1.1 lukem {
114 1.1 lukem crunchprog = "";
115 1.1 lukem
116 1.12 lukem if (mode != "crunch" && mode != "install" &&
117 1.12 lukem mode != "mtree" && mode != "populate")
118 1.9 lukem errx("Unknown parselist mode '" mode "'");
119 1.9 lukem
120 1.12 lukem needvars["CRUNCHBIN"]++
121 1.12 lukem needvars["OBJDIR"]++
122 1.12 lukem if (mode == "install") {
123 1.12 lukem needvars["TARGETDIR"]++
124 1.12 lukem }
125 1.12 lukem else if (mode == "populate") {
126 1.12 lukem needvars["CURDIR"]++
127 1.12 lukem }
128 1.12 lukem for (nv in needvars) {
129 1.12 lukem if (! (nv in ENVIRON))
130 1.12 lukem errx("Environment variable " nv " not defined");
131 1.9 lukem }
132 1.9 lukem
133 1.1 lukem print "#";
134 1.1 lukem print "# This file is automatically generated by";
135 1.1 lukem print "#\tparselist mode=" mode;
136 1.1 lukem print "#";
137 1.1 lukem print "";
138 1.12 lukem if (mode == "install") {
139 1.12 lukem print ".include <bsd.own.mk>"
140 1.12 lukem print "install:"
141 1.1 lukem } else if (mode == "mtree") {
142 1.2 lukem print "/unset\tall";
143 1.1 lukem print "/set\ttype=file uname=root gname=wheel";
144 1.1 lukem print;
145 1.12 lukem } else if (mode == "populate") {
146 1.12 lukem print "cd " ENVIRON["CURDIR"];
147 1.12 lukem print;
148 1.1 lukem }
149 1.1 lukem }
150 1.1 lukem
151 1.1 lukem /^$/ || /^#/ \
152 1.1 lukem {
153 1.1 lukem print;
154 1.1 lukem next;
155 1.1 lukem }
156 1.1 lukem
157 1.9 lukem # replace ${FOO} with ENVIRON["FOO"]
158 1.9 lukem #
159 1.13 thorpej /\$\{[A-Za-z0-9_]+\}/ \
160 1.3 lukem {
161 1.13 thorpej while (match($0, /\$\{[A-Za-z0-9_]+\}/) > 0) {
162 1.9 lukem v = substr($0, RSTART + 2, RLENGTH - 3);
163 1.9 lukem if (! (v in ENVIRON))
164 1.9 lukem err("Variable " v " is not in the environment");
165 1.9 lukem else
166 1.13 thorpej sub(/\$\{[A-Za-z0-9_]+\}/, ENVIRON[v]);
167 1.9 lukem }
168 1.3 lukem }
169 1.3 lukem
170 1.1 lukem $1 == "COPY" \
171 1.1 lukem {
172 1.3 lukem if (NF < 3 || NF > 4)
173 1.11 lukem err("Usage: COPY src dest [perm]");
174 1.12 lukem if (mode == "install" || mode == "mtree" || mode == "populate")
175 1.3 lukem copy($2, $3, $4);
176 1.1 lukem next;
177 1.1 lukem }
178 1.1 lukem
179 1.4 lukem $1 == "COPYDIR" \
180 1.4 lukem {
181 1.4 lukem if (NF != 3)
182 1.4 lukem err("Usage: COPYDIR src dest");
183 1.5 lukem srcdir=$2;
184 1.5 lukem destdir=$3;
185 1.4 lukem if (mode == "mtree") {
186 1.5 lukem printf("./%s type=dir mode=755\n", destdir);
187 1.8 lukem command="cd " srcdir " && find . -type d -print"
188 1.4 lukem while (command | getline dir) {
189 1.4 lukem gsub(/^\.\//, "", dir);
190 1.5 lukem if (dir == ".")
191 1.5 lukem continue;
192 1.5 lukem printf("./%s/%s type=dir mode=755\n", destdir, dir);
193 1.4 lukem }
194 1.4 lukem close(command);
195 1.4 lukem }
196 1.12 lukem if (mode == "install" || mode == "mtree" || mode == "populate") {
197 1.8 lukem command="cd " srcdir " && find . -type f -print"
198 1.4 lukem while (command | getline srcfile) {
199 1.4 lukem gsub(/^\.\//, "", srcfile);
200 1.4 lukem copy(srcdir "/" srcfile, destdir "/" srcfile, "");
201 1.4 lukem }
202 1.4 lukem close(command);
203 1.4 lukem }
204 1.4 lukem next;
205 1.4 lukem }
206 1.4 lukem
207 1.1 lukem $1 == "LIBS" || $1 == "SPECIAL" || $1 == "SRCDIRS" \
208 1.1 lukem {
209 1.3 lukem if (NF < 2)
210 1.3 lukem err("Usage: " $1 " args...");
211 1.1 lukem if (mode == "crunch") {
212 1.1 lukem $1 = tolower($1);
213 1.1 lukem print;
214 1.1 lukem }
215 1.1 lukem next;
216 1.1 lukem }
217 1.1 lukem
218 1.1 lukem $1 == "PROG" \
219 1.1 lukem {
220 1.3 lukem if (NF < 2)
221 1.3 lukem err("Usage: PROG prog [link ...]");
222 1.1 lukem if (mode == "crunch") {
223 1.1 lukem prog = basename($2);
224 1.1 lukem print "progs " prog;
225 1.1 lukem for (i = 3; i <= NF; i++)
226 1.1 lukem print "ln " prog " " basename($i);
227 1.1 lukem } else {
228 1.1 lukem for (i = 2; i <= NF; i++) {
229 1.1 lukem if (crunchprog == "") {
230 1.1 lukem crunchprog = $i;
231 1.9 lukem copy(ENVIRON["OBJDIR"] "/" ENVIRON["CRUNCHBIN"],
232 1.11 lukem crunchprog, 555);
233 1.1 lukem continue;
234 1.1 lukem }
235 1.1 lukem link(crunchprog, $i);
236 1.1 lukem }
237 1.1 lukem }
238 1.1 lukem next;
239 1.1 lukem }
240 1.1 lukem
241 1.1 lukem $1 == "ARGVLN" \
242 1.1 lukem {
243 1.3 lukem if (NF != 3)
244 1.3 lukem err("Usage: ARGVLN prog link");
245 1.1 lukem if (mode == "crunch") {
246 1.1 lukem $1 = "ln";
247 1.1 lukem print;
248 1.1 lukem }
249 1.1 lukem next;
250 1.1 lukem }
251 1.1 lukem
252 1.1 lukem $1 == "LINK" \
253 1.1 lukem {
254 1.3 lukem if (NF < 3)
255 1.3 lukem err("Usage: LINK prog link [...]");
256 1.12 lukem if (mode == "install" || mode == "mtree" || mode == "populate") {
257 1.1 lukem for (i = 3; i <= NF; i++)
258 1.1 lukem link($2, $i);
259 1.1 lukem }
260 1.1 lukem next;
261 1.1 lukem }
262 1.1 lukem
263 1.1 lukem $1 == "SYMLINK" \
264 1.1 lukem {
265 1.3 lukem if (NF < 3)
266 1.3 lukem err("Usage: SYMLINK prog link [...]");
267 1.12 lukem if (mode == "install" || mode == "mtree" || mode == "populate") {
268 1.1 lukem for (i = 3; i <= NF; i++)
269 1.1 lukem symlink($2, $i);
270 1.1 lukem }
271 1.1 lukem next;
272 1.1 lukem }
273 1.1 lukem
274 1.1 lukem $1 == "CMD" \
275 1.1 lukem {
276 1.3 lukem if (NF < 2)
277 1.3 lukem err("Usage: CMD ...");
278 1.1 lukem if (mode == "populate") {
279 1.9 lukem printf("(cd %s;", ENVIRON["TARGETDIR"]);
280 1.1 lukem for (i = 2; i <= NF; i++)
281 1.1 lukem printf(" %s", $i);
282 1.11 lukem print ") || exit 1";
283 1.1 lukem }
284 1.1 lukem next;
285 1.1 lukem }
286 1.6 lukem
287 1.6 lukem $1 == "MTREE" \
288 1.6 lukem {
289 1.6 lukem if (NF < 2)
290 1.6 lukem err("Usage: MTREE ...");
291 1.6 lukem if (mode == "mtree") {
292 1.6 lukem sub(/^[^ \t]+[ \t]+/, ""); # strip first word ("MTREE")
293 1.6 lukem print;
294 1.6 lukem }
295 1.6 lukem next;
296 1.6 lukem }
297 1.6 lukem
298 1.1 lukem
299 1.1 lukem {
300 1.3 lukem err("Unknown keyword '" $1 "'");
301 1.1 lukem }
302 1.1 lukem
303 1.1 lukem
304 1.1 lukem function basename (file) \
305 1.1 lukem {
306 1.1 lukem gsub(/[^\/]+\//, "", file);
307 1.1 lukem return file;
308 1.1 lukem }
309 1.1 lukem
310 1.3 lukem function copy (src, dest, perm) \
311 1.1 lukem {
312 1.11 lukem if (perm == "")
313 1.11 lukem perm = 444;
314 1.12 lukem if (mode == "install") {
315 1.12 lukem printf("\t\${INSTALL_FILE} -o \${BINOWN} -g \${BINGRP} -m %s %s %s/%s\n",
316 1.12 lukem perm, src, ENVIRON["TARGETDIR"], dest)
317 1.12 lukem } else if (mode == "mtree") {
318 1.11 lukem printf("./%s mode=%s\n", dest, perm);
319 1.1 lukem } else {
320 1.9 lukem printf("rm -rf %s/%s\n", ENVIRON["TARGETDIR"], dest);
321 1.9 lukem printf("cp %s %s/%s\n", src, ENVIRON["TARGETDIR"], dest);
322 1.11 lukem printf("chmod %s %s/%s\n", perm, ENVIRON["TARGETDIR"], dest);
323 1.1 lukem }
324 1.1 lukem }
325 1.1 lukem
326 1.1 lukem function link (src, dest) \
327 1.1 lukem {
328 1.12 lukem if (mode == "install") {
329 1.12 lukem printf("\t\${INSTALL_LINK} %s/%s %s/%s\n",
330 1.12 lukem ENVIRON["TARGETDIR"], src, ENVIRON["TARGETDIR"], dest)
331 1.12 lukem } else if (mode == "mtree") {
332 1.1 lukem printf("./%s\n", dest);
333 1.1 lukem } else {
334 1.9 lukem printf("rm -rf %s/%s\n", ENVIRON["TARGETDIR"], dest);
335 1.11 lukem printf("(cd %s; ln %s %s) || exit 1\n",
336 1.11 lukem ENVIRON["TARGETDIR"], src, dest);
337 1.1 lukem }
338 1.1 lukem }
339 1.1 lukem
340 1.1 lukem function symlink (src, dest) \
341 1.1 lukem {
342 1.12 lukem if (mode == "install") {
343 1.12 lukem printf("\t\${INSTALL_SYMLINK} %s/%s %s/%s\n",
344 1.12 lukem ENVIRON["TARGETDIR"], src, ENVIRON["TARGETDIR"], dest)
345 1.12 lukem } else if (mode == "mtree") {
346 1.1 lukem printf("./%s type=link link=%s\n", dest, src);
347 1.1 lukem } else {
348 1.9 lukem printf("rm -rf %s/%s\n", ENVIRON["TARGETDIR"], dest);
349 1.11 lukem printf("(cd %s; ln -s %s %s) || exit 1\n",
350 1.11 lukem ENVIRON["TARGETDIR"], src, dest);
351 1.1 lukem }
352 1.3 lukem }
353 1.3 lukem
354 1.3 lukem function err(msg) \
355 1.3 lukem {
356 1.9 lukem printf("parselist: %s at line %d of input.\n", msg, NR) >"/dev/stderr";
357 1.9 lukem exit 1;
358 1.9 lukem }
359 1.9 lukem
360 1.9 lukem function errx(msg) \
361 1.9 lukem {
362 1.9 lukem printf("parselist: %s.\n", msg) >"/dev/stderr";
363 1.3 lukem exit 1;
364 1.1 lukem }
365