1 | #!/bin/awk -f |
---|
2 | # Check a list of symbols against the master definition |
---|
3 | # (official) list. Arguments: |
---|
4 | # |
---|
5 | # awk -f checksym.awk official-def list-to-check |
---|
6 | # |
---|
7 | # Output is a file in the current directory called 'symbols.new', |
---|
8 | # stdout holds error messages. Error code indicates success or |
---|
9 | # failure. |
---|
10 | # |
---|
11 | # NOTE: this is a pure, old fashioned, awk script. It will |
---|
12 | # work with any awk |
---|
13 | |
---|
14 | BEGIN{ |
---|
15 | err=0 |
---|
16 | master="" # master file |
---|
17 | official[1] = "" # defined symbols from master file |
---|
18 | symbol[1] = "" # defined symbols from png.h |
---|
19 | removed[1] = "" # removed symbols from png.h |
---|
20 | lasto = 0 # last ordinal value from png.h |
---|
21 | mastero = 0 # highest ordinal in master file |
---|
22 | symbolo = 0 # highest ordinal in png.h |
---|
23 | missing = "error"# log an error on missing symbols |
---|
24 | } |
---|
25 | |
---|
26 | # Read existing definitions from the master file (the first |
---|
27 | # file on the command line.) This must be a def file and it |
---|
28 | # has definition lines (others are ignored) of the form: |
---|
29 | # |
---|
30 | # symbol @ordinal |
---|
31 | # |
---|
32 | master == "" { |
---|
33 | master = FILENAME |
---|
34 | } |
---|
35 | FILENAME==master && NF==2 && $2~/^@/ && $1!~/^;/ { |
---|
36 | o=0+substr($2,2) |
---|
37 | if (o > 0) { |
---|
38 | if (official[o] == "") { |
---|
39 | official[o] = $1 |
---|
40 | if (o > mastero) mastero = o |
---|
41 | next |
---|
42 | } else |
---|
43 | print master ": duplicated symbol:", official[o] ":", $0 |
---|
44 | } else |
---|
45 | print master ": bad export line format:", $0 |
---|
46 | err = 1 |
---|
47 | } |
---|
48 | FILENAME==master && $1==";missing" && NF==2{ |
---|
49 | # This allows the master file to control how missing symbols |
---|
50 | # are handled; symbols that aren't in either the master or |
---|
51 | # the new file. Valid values are 'ignore', 'warning' and |
---|
52 | # 'error' |
---|
53 | missing = $2 |
---|
54 | } |
---|
55 | FILENAME==master { |
---|
56 | next |
---|
57 | } |
---|
58 | |
---|
59 | # Read new definitions, these are free form but the lines must |
---|
60 | # just be symbol definitions. Lines will be commented out for |
---|
61 | # 'removed' symbols, introduced in png.h using PNG_REMOVED rather |
---|
62 | # than PNG_EXPORT. Use symbols.dfn or pngwin.dfn to generate the |
---|
63 | # input file. |
---|
64 | # |
---|
65 | # symbol @ordinal # two fields, exported symbol |
---|
66 | # ; symbol @ordinal # three fields, removed symbol |
---|
67 | # ; @ordinal # two fields, the last ordinal |
---|
68 | NF==2 && $1 == ";" && $2 ~ /^@[1-9][0-9]*$/ { # last ordinal |
---|
69 | o=0+substr($2,2) |
---|
70 | if (lasto == 0 || lasto == o) |
---|
71 | lasto=o |
---|
72 | else { |
---|
73 | print "png.h: duplicated last ordinal:", lasto, o |
---|
74 | err = 1 |
---|
75 | } |
---|
76 | next |
---|
77 | } |
---|
78 | NF==3 && $1 == ";" && $3 ~ /^@[1-9][0-9]*$/ { # removed symbol |
---|
79 | o=0+substr($3,2) |
---|
80 | if (removed[o] == "" || removed[o] == $2) { |
---|
81 | removed[o] = $2 |
---|
82 | if (o > symbolo) symbolo = o |
---|
83 | } else { |
---|
84 | print "png.h: duplicated removed symbol", o ": '" removed[o] "' != '" $2 "'" |
---|
85 | err = 1 |
---|
86 | } |
---|
87 | next |
---|
88 | } |
---|
89 | NF==2 && $2 ~ /^@[1-9][0-9]*$/ { # exported symbol |
---|
90 | o=0+substr($2,2) |
---|
91 | if (symbol[o] == "" || symbol[o] == $1) { |
---|
92 | symbol[o] = $1 |
---|
93 | if (o > symbolo) symbolo = o |
---|
94 | } else { |
---|
95 | print "png.h: duplicated symbol", o ": '" symbol[o] "' != '" $1 "'" |
---|
96 | err = 1 |
---|
97 | } |
---|
98 | } |
---|
99 | { |
---|
100 | next # skip all other lines |
---|
101 | } |
---|
102 | |
---|
103 | # At the end check for symbols marked as both duplicated and removed |
---|
104 | END{ |
---|
105 | if (symbolo > lasto) { |
---|
106 | print "highest symbol ordinal in png.h,", symbolo ", exceeds last ordinal from png.h", lasto |
---|
107 | err = 1 |
---|
108 | } |
---|
109 | if (mastero > lasto) { |
---|
110 | print "highest symbol ordinal in", master ",", mastero ", exceeds last ordinal from png.h", lasto |
---|
111 | err = 1 |
---|
112 | } |
---|
113 | unexported=0 |
---|
114 | for (o=1; o<=lasto; ++o) { |
---|
115 | if (symbol[o] == "" && removed[o] == "") { |
---|
116 | if (unexported == 0) unexported = o |
---|
117 | if (official[o] == "") { |
---|
118 | # missing in export list too, so ok |
---|
119 | if (o < lasto) continue |
---|
120 | } |
---|
121 | } |
---|
122 | if (unexported != 0) { |
---|
123 | # Symbols in the .def but not in the new file are errors, but |
---|
124 | # the 'unexported' symbols aren't in either. By default this |
---|
125 | # is an error too (see the setting of 'missing' at the start), |
---|
126 | # but this can be reset on the command line or by stuff in the |
---|
127 | # file - see the comments above. |
---|
128 | if (missing != "ignore") { |
---|
129 | if (o-1 > unexported) |
---|
130 | print "png.h:", missing ": missing symbols:", unexported "-" o-1 |
---|
131 | else |
---|
132 | print "png.h:", missing ": missing symbol:", unexported |
---|
133 | if (missing != "warning") |
---|
134 | err = 1 |
---|
135 | } |
---|
136 | unexported = 0 |
---|
137 | } |
---|
138 | if (symbol[o] != "" && removed[o] != "") { |
---|
139 | print "png.h: symbol", o, "both exported as '" symbol[o] "' and removed as '" removed[o] "'" |
---|
140 | err = 1 |
---|
141 | } else if (symbol[o] != official[o]) { |
---|
142 | # either the symbol is missing somewhere or it changed |
---|
143 | err = 1 |
---|
144 | if (symbol[o] == "") |
---|
145 | print "png.h: symbol", o, "is exported as '" official[o] "' in", master |
---|
146 | else if (official[o] == "") |
---|
147 | print "png.h: exported symbol", o, "'" symbol[o] "' not present in", master |
---|
148 | else |
---|
149 | print "png.h: exported symbol", o, "'" symbol[o] "' exists as '" official[o] "' in", master |
---|
150 | } |
---|
151 | |
---|
152 | # Finally generate symbols.new |
---|
153 | if (symbol[o] != "") |
---|
154 | print " " symbol[o], "@" o > "symbols.new" |
---|
155 | } |
---|
156 | |
---|
157 | if (err != 0) { |
---|
158 | print "*** A new list is in symbols.new ***" |
---|
159 | exit 1 |
---|
160 | } |
---|
161 | } |
---|