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