#!/usr/bin/awk -f ## # tweakmeta # # First read a PKGMETA file in the current directory, loading its values. # Next read a PKGTWEAK file from standard input. # The PKGTWEAK file tells us how to modify the PKGMETA data. # The modified PKGMETA is printed to standard output. # # Justin Davis BEGIN { PROG = "tweakmeta" if (system("test -r PKGMETA") != 0) { print PROG ": PKGMETA file could not be read." | "cat 1>&2" exit(errcode = 2) } FS = "\n"; RS = "" while (getline<"PKGMETA" > 0) for (i = 2; i <= NF; i++) pushval($1, $i) close("PKGMETA") FS = " "; RS = "\n" } { sub(/#.*/, "") } $1 == "+" { pushval($2, joinfields(3)); next } $1 == "-" { remval($2, $3); next } $1 == "<" { i = findval($2, $3) stack[++stacklen] = pbvars[$2, i] remelem($2, i) next } $1 == ">" { if (stacklen < 1) die("No values on the stack. Make sure you use '<' first.") pushval($2, stack[stacklen--]) next } $1 == "=" { if ($2 == "optdepends") die("cannot use '=' with optdepends.") remall($2) for (i=3; i<=NF; i++) pushval($2, $i) next } # ignore lines of whitespace $1 !~ /^[ \t]*$/ { die("invalid input: " $0) } END { if (errcode) exit(errcode) OFS = "\n" for (name in pbcount) { len = pbcount[name] if (len == 0) continue print name for (i=1; i<=len; i++) print pbvars[name, i] print "" } } function die (msg) { printf "%s: error line %d: %s\n", PROG, FNR, msg | "cat 1>&2" exit(errcode = 1) } function joinfields (start, msg) { msg = $(start++) while (start <= NF) msg = msg " " $(start++) return msg } function remall (field) { pbcount[field] = 0 } function pushval (field, val) { pbvars[field, ++pbcount[field]] = val } function remval (field, prefix) { remelem(field, findval(field, prefix)) } function remelem (field, i, len) { # TODO: error check if "i" is in bounds? len = pbcount[field] for (len = pbcount[field]; i < len; i++) pbvars[field, i] = pbvars[field, i+1] delete pbvars[field, i] pbcount[field]-- } function findval (field, prefix, i, len) { len = pbcount[field] if (len == 0) die(field " is empty!") for (i = 1; i <= len; i++) if (index(pbvars[field,i], prefix) == 1) break if (i > len) die("could not find " prefix " in " field "'s values") return i }