1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
#!/usr/bin/awk -f
##
# tweakmeta
#
# First read a PKGDATA 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 PKGDATA data.
# The modified PKGDATA is printed to standard output.
#
# Justin Davis <jrcd83@gmail.com>
BEGIN {
PROG = "tweakmeta"
if (system("test -r PKGDATA") != 0) {
print PROG ": PKGDATA file could not be read." | "cat 1>&2"
exit(errcode = 2)
}
FS = "\n"; RS = ""
while (getline<"PKGDATA" > 0)
for (i = 2; i <= NF; i++) pushval($1, $i)
close("PKGDATA")
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
}
|