fukasawa e60969
#!/bin/awk -f
fukasawa e60969
# Check a list of symbols against the master definition
fukasawa e60969
# (official) list.  Arguments:
fukasawa e60969
#
fukasawa e60969
# awk -f checksym.awk official-def list-to-check
fukasawa e60969
#
fukasawa e60969
# Output is a file in the current directory called 'symbols.new',
fukasawa e60969
# the value of the awk variable "of" (which can be changed on the
fukasawa e60969
# command line if required.)  stdout holds error messages.  Error
fukasawa e60969
# code indicates success or failure.
fukasawa e60969
#
fukasawa e60969
# NOTE: this is a pure, old fashioned, awk script.  It will
fukasawa e60969
# work with any awk
fukasawa e60969
fukasawa e60969
BEGIN{
fukasawa e60969
   err=0
fukasawa e60969
   master=""        # master file
fukasawa e60969
   official[1] = "" # defined symbols from master file
fukasawa e60969
   symbol[1] = ""   # defined symbols from png.h
fukasawa e60969
   removed[1] = ""  # removed symbols from png.h
fukasawa e60969
   lasto = 0        # last ordinal value from png.h
fukasawa e60969
   mastero = 0      # highest ordinal in master file
fukasawa e60969
   symbolo = 0      # highest ordinal in png.h
fukasawa e60969
   missing = "error"# log an error on missing symbols
fukasawa e60969
   of="symbols.new" # default to a fixed name
fukasawa e60969
}
fukasawa e60969
fukasawa e60969
# Read existing definitions from the master file (the first
fukasawa e60969
# file on the command line.)  This must be a def file and it
fukasawa e60969
# has definition lines (others are ignored) of the form:
fukasawa e60969
#
fukasawa e60969
#   symbol @ordinal
fukasawa e60969
#
fukasawa e60969
master == "" {
fukasawa e60969
   master = FILENAME
fukasawa e60969
}
fukasawa e60969
FILENAME==master && NF==2 && $2~/^@/ && $1!~/^;/ {
fukasawa e60969
   o=0+substr($2,2)
fukasawa e60969
   if (o > 0) {
fukasawa e60969
      if (official[o] == "") {
fukasawa e60969
         official[o] = $1
fukasawa e60969
         if (o > mastero) mastero = o
fukasawa e60969
         next
fukasawa e60969
      } else
fukasawa e60969
         print master ": duplicated symbol:", official[o] ":", $0
fukasawa e60969
   } else
fukasawa e60969
      print master ": bad export line format:", $0
fukasawa e60969
   err = 1
fukasawa e60969
}
fukasawa e60969
FILENAME==master && $1==";missing" && NF==2{
fukasawa e60969
   # This allows the master file to control how missing symbols
fukasawa e60969
   # are handled; symbols that aren't in either the master or
fukasawa e60969
   # the new file.  Valid values are 'ignore', 'warning' and
fukasawa e60969
   # 'error'
fukasawa e60969
   missing = $2
fukasawa e60969
}
fukasawa e60969
FILENAME==master {
fukasawa e60969
   next
fukasawa e60969
}
fukasawa e60969
fukasawa e60969
# Read new definitions, these are free form but the lines must
fukasawa e60969
# just be symbol definitions.  Lines will be commented out for
fukasawa e60969
# 'removed' symbols, introduced in png.h using PNG_REMOVED rather
fukasawa e60969
# than PNG_EXPORT.  Use symbols.dfn or pngwin.dfn to generate the
fukasawa e60969
# input file.
fukasawa e60969
#
fukasawa e60969
#  symbol @ordinal   # two fields, exported symbol
fukasawa e60969
#  ; symbol @ordinal # three fields, removed symbol
fukasawa e60969
#  ; @ordinal        # two fields, the last ordinal
fukasawa e60969
NF==2 && $1 == ";" && $2 ~ /^@[1-9][0-9]*$/ { # last ordinal
fukasawa e60969
   o=0+substr($2,2)
fukasawa e60969
   if (lasto == 0 || lasto == o)
fukasawa e60969
      lasto=o
fukasawa e60969
   else {
fukasawa e60969
      print "png.h: duplicated last ordinal:", lasto, o
fukasawa e60969
      err = 1
fukasawa e60969
   }
fukasawa e60969
   next
fukasawa e60969
}
fukasawa e60969
NF==3 && $1 == ";" && $3 ~ /^@[1-9][0-9]*$/ { # removed symbol
fukasawa e60969
   o=0+substr($3,2)
fukasawa e60969
   if (removed[o] == "" || removed[o] == $2) {
fukasawa e60969
      removed[o] = $2
fukasawa e60969
      if (o > symbolo) symbolo = o
fukasawa e60969
   } else {
fukasawa e60969
      print "png.h: duplicated removed symbol", o ": '" removed[o] "' != '" $2 "'"
fukasawa e60969
      err = 1
fukasawa e60969
   }
fukasawa e60969
   next
fukasawa e60969
}
fukasawa e60969
NF==2 && $2 ~ /^@[1-9][0-9]*$/ { # exported symbol
fukasawa e60969
   o=0+substr($2,2)
fukasawa e60969
   if (symbol[o] == "" || symbol[o] == $1) {
fukasawa e60969
      symbol[o] = $1
fukasawa e60969
      if (o > symbolo) symbolo = o
fukasawa e60969
   } else {
fukasawa e60969
      print "png.h: duplicated symbol", o ": '" symbol[o] "' != '" $1 "'"
fukasawa e60969
      err = 1
fukasawa e60969
   }
fukasawa e60969
}
fukasawa e60969
{
fukasawa e60969
   next # skip all other lines
fukasawa e60969
}
fukasawa e60969
fukasawa e60969
# At the end check for symbols marked as both duplicated and removed
fukasawa e60969
END{
fukasawa e60969
   if (symbolo > lasto) {
fukasawa e60969
      print "highest symbol ordinal in png.h,", symbolo ", exceeds last ordinal from png.h", lasto
fukasawa e60969
      err = 1
fukasawa e60969
   }
fukasawa e60969
   if (mastero > lasto) {
fukasawa e60969
      print "highest symbol ordinal in", master ",", mastero ", exceeds last ordinal from png.h", lasto
fukasawa e60969
      err = 1
fukasawa e60969
   }
fukasawa e60969
   unexported=0
fukasawa e60969
   # Add a standard header to symbols.new:
fukasawa e60969
   print ";Version INSERT-VERSION-HERE" >of
fukasawa e60969
   print ";--------------------------------------------------------------" >of
fukasawa e60969
   print "; LIBPNG symbol list as a Win32 DEF file" >of
fukasawa e60969
   print "; Contains all the symbols that can be exported from libpng" >of
fukasawa e60969
   print ";--------------------------------------------------------------" >of
fukasawa e60969
   print "LIBRARY" >of
fukasawa e60969
   print "" >of
fukasawa e60969
   print "EXPORTS" >of
fukasawa e60969
fukasawa e60969
   for (o=1; o<=lasto; ++o) {
fukasawa e60969
      if (symbol[o] == "" && removed[o] == "") {
fukasawa e60969
         if (unexported == 0) unexported = o
fukasawa e60969
         if (official[o] == "") {
fukasawa e60969
            # missing in export list too, so ok
fukasawa e60969
            if (o < lasto) continue
fukasawa e60969
         }
fukasawa e60969
      }
fukasawa e60969
      if (unexported != 0) {
fukasawa e60969
         # Symbols in the .def but not in the new file are errors, but
fukasawa e60969
         # the 'unexported' symbols aren't in either.  By default this
fukasawa e60969
         # is an error too (see the setting of 'missing' at the start),
fukasawa e60969
         # but this can be reset on the command line or by stuff in the
fukasawa e60969
         # file - see the comments above.
fukasawa e60969
         if (missing != "ignore") {
fukasawa e60969
            if (o-1 > unexported)
fukasawa e60969
               print "png.h:", missing ": missing symbols:", unexported "-" o-1
fukasawa e60969
            else
fukasawa e60969
               print "png.h:", missing ": missing symbol:", unexported
fukasawa e60969
            if (missing != "warning")
fukasawa e60969
               err = 1
fukasawa e60969
         }
fukasawa e60969
         unexported = 0
fukasawa e60969
      }
fukasawa e60969
      if (symbol[o] != "" && removed[o] != "") {
fukasawa e60969
         print "png.h: symbol", o, "both exported as '" symbol[o] "' and removed as '" removed[o] "'"
fukasawa e60969
         err = 1
fukasawa e60969
      } else if (symbol[o] != official[o]) {
fukasawa e60969
         # either the symbol is missing somewhere or it changed
fukasawa e60969
         err = 1
fukasawa e60969
         if (symbol[o] == "")
fukasawa e60969
            print "png.h: symbol", o, "is exported as '" official[o] "' in", master
fukasawa e60969
         else if (official[o] == "")
fukasawa e60969
            print "png.h: exported symbol", o, "'" symbol[o] "' not present in", master
fukasawa e60969
         else
fukasawa e60969
            print "png.h: exported symbol", o, "'" symbol[o] "' exists as '" official[o] "' in", master
fukasawa e60969
      }
fukasawa e60969
fukasawa e60969
      # Finally generate symbols.new
fukasawa e60969
      if (symbol[o] != "")
fukasawa e60969
         print " " symbol[o], "@" o > of
fukasawa e60969
   }
fukasawa e60969
fukasawa e60969
   if (err != 0) {
fukasawa e60969
      print "*** A new list is in", of, "***"
fukasawa e60969
      exit 1
fukasawa e60969
   }
fukasawa e60969
}