| #!/bin/awk |
| # Check a list of symbols against the master definition |
| # (official) list. Arguments: |
| # |
| # awk -f checksym.awk official-def list-to-check |
| # |
| # Output is a file in the current directory called 'symbols.new', |
| # stdout holds error messages. Error code indicates success or |
| # failure. |
| # |
| # NOTE: this is a pure, old fashioned, awk script. It will |
| # work with any awk |
| |
| BEGIN{ |
| err=0 |
| master="" # master file |
| official[1] = "" # defined symbols from master file |
| symbol[1] = "" # defined symbols from png.h |
| removed[1] = "" # removed symbols from png.h |
| lasto = 0 # last ordinal value from png.h |
| mastero = 0 # highest ordinal in master file |
| symbolo = 0 # highest ordinal in png.h |
| } |
| |
| # Read existing definitions from the master file (the first |
| # file on the command line.) This must be a def file and it |
| # has definition lines (others are ignored) of the form: |
| # |
| # symbol @ordinal |
| # |
| master == "" { |
| master = FILENAME; |
| } |
| FILENAME==master && NF==2 && $2~/^@/ && $1!~/^;/ { |
| o=0+substr($2,2) |
| if (o >0) { |
| if (official[o] == "") { |
| official[o] = $1 |
| if (o > mastero) mastero = o |
| next |
| } else |
| print master ": duplicated symbol:", official[o] ":", $0 |
| } else |
| print master ": bad export line format:", $0 |
| err = 1 |
| } |
| FILENAME==master { |
| next |
| } |
| |
| # Read new definitions, these are free form but the lines must |
| # just be symbol definitions. Lines will be commented out for |
| # 'removed' symbols, introduced in png.h using PNG_REMOVED rather |
| # than PNG_EXPORT. Use checksym.dfn to generate the input file. |
| # |
| # symbol ordinal # two fields, exported symbol |
| # ; symbol ordinal # three fields, removed symbol |
| # ; ordinal # two fields, the last ordinal |
| NF==2 && $1 == ";" && $2 ~ /^[1-9][0-9]*$/ { # last ordinal |
| o = 0+$2 |
| if (lasto == 0 || lasto == o) |
| lasto=o |
| else { |
| print "png.h: duplicated last ordinal:", lasto, o |
| err = 1 |
| } |
| next |
| } |
| NF==3 && $1 == ";" && $3 ~ /^[1-9][0-9]*$/ { # removed symbol |
| o = 0+$3 |
| if (removed[o] == "" || removed[o] == $2) { |
| removed[o] = $2 |
| if (o > symbolo) symbolo = o |
| } else { |
| print "png.h: duplicated removed symbol", |
| o ": '" removed[o] "' != '" $2 "'" |
| err = 1 |
| } |
| next |
| } |
| NF==2 && $2 ~ /^[1-9][0-9]*$/ { # exported symbol |
| o = 0+$2 |
| if (symbol[o] == "" || symbol[o] == $1) { |
| symbol[o] = $1 |
| if (o > symbolo) symbolo = o |
| } else { |
| print "png.h: duplicated symbol", |
| o ": '" symbol[o] "' != '" $1 "'" |
| err = 1 |
| } |
| } |
| { |
| next # skip all other lines |
| } |
| |
| # At the end check for symbols marked as both duplicated and removed |
| END{ |
| if (symbolo > lasto) { |
| print "highest symbol ordinal in png.h,", |
| symbolo ", exceeds last ordinal from png.h", lasto |
| err = 1 |
| } |
| if (mastero > lasto) { |
| print "highest symbol ordinal in", master ",", |
| mastero ", exceeds last ordinal from png.h", lasto |
| err = 1 |
| } |
| missing = 0 |
| for (o=1; o<=lasto; ++o) { |
| stop=0 |
| if (symbol[o] == "" && removed[o] == "") { |
| if (missing == 0) missing = o |
| if (o < lasto) continue |
| stop=1 |
| } |
| if (missing != 0) { |
| if (o-1 > missing) |
| print "png.h: missing symbol definitions:", missing "-" o-1 |
| else |
| print "png.h: missing symbol definition:", missing |
| missing = 0 |
| err = 1 |
| } |
| if (stop == 1) break; # lasto is missing |
| if (symbol[o] != "" && removed[o] != "") { |
| print "png.h: symbol", o, |
| "both exported as '" symbol[o] "' and removed as '" removed[o] "'" |
| err = 1 |
| } else if (symbol[o] != official[o]) { |
| # either master symbol not there or it changed |
| err = 1 |
| if (symbol[o] == "") |
| print "png.h: removed symbol", o, |
| "'" symbol[o] "' exported as '" official[o] "' in", master |
| else if (official[o] == "") |
| print "png.h: exported symbol", o, "'" symbol[o] "' not present in", |
| master |
| else |
| print "png.h: exported symbol", o, |
| "'" symbol[o] "' exists as '" official[o] "' in", master |
| } |
| |
| # Finally generate symbols.new |
| if (symbol[o] != "") |
| print " " symbol[o], "@" o > "symbols.new" |
| } |
| |
| if (err != 0) { |
| print "*** A new list is in symbols.new ***" |
| exit 1 |
| } |
| } |