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