mirror of
				https://git.code.sf.net/p/libpng/code.git
				synced 2025-07-10 18:04:09 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			204 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Awk
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Awk
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/awk -f
 | 
						|
# scripts/dfn.awk - process a .dfn file
 | 
						|
#
 | 
						|
# last changed in libpng version 1.5.19 - August 21, 2014
 | 
						|
#
 | 
						|
# Copyright (c) 2013-2014 Glenn Randers-Pehrson
 | 
						|
#
 | 
						|
# This code is released under the libpng license.
 | 
						|
# For conditions of distribution and use, see the disclaimer
 | 
						|
# and license in png.h
 | 
						|
 | 
						|
# The output of this script is written to the file given by
 | 
						|
# the variable 'out', which should be set on the command line.
 | 
						|
# Error messages are printed to stdout and if any are printed
 | 
						|
# the script will exit with error code 1.
 | 
						|
 | 
						|
BEGIN{
 | 
						|
   out="/dev/null"       # as a flag
 | 
						|
   out_count=0           # count of output lines
 | 
						|
   err=0                 # set if an error occured
 | 
						|
   sort=0                # sort the output
 | 
						|
   array[""]=""
 | 
						|
}
 | 
						|
 | 
						|
# The output file must be specified before any input:
 | 
						|
NR==1 && out == "/dev/null" {
 | 
						|
   print "out=output.file must be given on the command line"
 | 
						|
   # but continue without setting the error code; this allows the
 | 
						|
   # script to be checked easily
 | 
						|
}
 | 
						|
 | 
						|
# Output can be sorted; two lines are recognized
 | 
						|
$1 == "PNG_DFN_START_SORT"{
 | 
						|
   sort=0+$2
 | 
						|
   next
 | 
						|
}
 | 
						|
 | 
						|
$1 ~ /^PNG_DFN_END_SORT/{
 | 
						|
   # Do a very simple, slow, sort; notice that blank lines won't be
 | 
						|
   # output by this
 | 
						|
   for (entry in array) {
 | 
						|
      while (array[entry] != "") {
 | 
						|
         key = entry
 | 
						|
         value = array[key]
 | 
						|
         array[key] = ""
 | 
						|
 | 
						|
         for (alt in array) {
 | 
						|
            if (array[alt] != "" && alt < key) {
 | 
						|
               array[key] = value
 | 
						|
               value = array[alt]
 | 
						|
               key = alt
 | 
						|
               array[alt] = ""
 | 
						|
            }
 | 
						|
         }
 | 
						|
 | 
						|
         print value >out
 | 
						|
      }
 | 
						|
   }
 | 
						|
   sort=0
 | 
						|
   next
 | 
						|
}
 | 
						|
 | 
						|
/^[^"]*PNG_DFN *".*"[^"]*$/{
 | 
						|
   # A definition line, apparently correctly formatted; extract the
 | 
						|
   # definition then replace any doubled "" that remain with a single
 | 
						|
   # double quote.  Notice that the original doubled double quotes
 | 
						|
   # may have been split by tokenization
 | 
						|
   #
 | 
						|
   # Sometimes GCC splits the PNG_DFN lines; we know this has happened
 | 
						|
   # if the quotes aren't closed and must read another line.  In this
 | 
						|
   # case it is essential to reject lines that start with '#' because those
 | 
						|
   # are introduced #line directives.
 | 
						|
   orig=$0
 | 
						|
   line=$0
 | 
						|
   lineno=FNR
 | 
						|
   if (lineno == "") lineno=NR
 | 
						|
 | 
						|
   if (sub(/^[^"]*PNG_DFN *"/,"",line) != 1) {
 | 
						|
	print "line", lineno ": processing failed:"
 | 
						|
	print orig
 | 
						|
	err=1
 | 
						|
       next
 | 
						|
   } else {
 | 
						|
	++out_count
 | 
						|
   }
 | 
						|
 | 
						|
   # Now examine quotes within the value:
 | 
						|
   #
 | 
						|
   #   @" - delete this and any following spaces
 | 
						|
   #   "@ - delete this and any preceding spaces
 | 
						|
   #   @' - replace this by a double quote
 | 
						|
   #
 | 
						|
   # This allows macro substitution by the C compiler thus:
 | 
						|
   #
 | 
						|
   #   #define first_name John
 | 
						|
   #   #define last_name Smith
 | 
						|
   #
 | 
						|
   #	PNG_DFN"#define name @'@" first_name "@ @" last_name "@@'"
 | 
						|
   #
 | 
						|
   # Might get C preprocessed to:
 | 
						|
   #
 | 
						|
   #   PNG_DFN "#define foo @'@" John "@ @" Smith "@@'"
 | 
						|
   #
 | 
						|
   # Which this script reduces to:
 | 
						|
   #
 | 
						|
   #	#define name "John Smith"
 | 
						|
   #
 | 
						|
   while (1) {
 | 
						|
      # While there is an @" remove it and the next "@
 | 
						|
      if (line ~ /@"/) {
 | 
						|
         if (line ~ /@".*"@/) {
 | 
						|
            # Do this special case first to avoid swallowing extra spaces
 | 
						|
            # before or after the @ stuff:
 | 
						|
            if (!sub(/@" *"@/, "", line)) {
 | 
						|
               # Ok, do it in pieces - there has to be a non-space between the
 | 
						|
               # two.  NOTE: really weird things happen if a leading @" is
 | 
						|
               # lost - the code will error out below (I believe).
 | 
						|
               if (!sub(/@" */, "", line) || !sub(/ *"@/, "", line)) {
 | 
						|
                  print "line", lineno, ": internal error:", orig
 | 
						|
                  exit 1
 | 
						|
               }
 | 
						|
            }
 | 
						|
         }
 | 
						|
 | 
						|
         # There is no matching "@.  Assume a split line
 | 
						|
         else while (1) {
 | 
						|
            if (getline nextline) {
 | 
						|
               # If the line starts with '#' it is a preprocesor line directive
 | 
						|
               # from cc -E; skip it:
 | 
						|
               if (nextline !~ /^#/) {
 | 
						|
                  line = line " " nextline
 | 
						|
                  break
 | 
						|
               }
 | 
						|
            } else {
 | 
						|
               # This is end-of-input - probably a missing "@ on the first line:
 | 
						|
               print "line", lineno ": unbalanced @\" ... \"@ pair"
 | 
						|
               err=1
 | 
						|
               next
 | 
						|
            }
 | 
						|
         }
 | 
						|
 | 
						|
         # Keep going until all the @" have gone
 | 
						|
         continue
 | 
						|
      }
 | 
						|
 | 
						|
      # Attempt to remove a trailing " (not preceded by '@') - if this can
 | 
						|
      # be done, stop now; if not assume a split line again
 | 
						|
      if (sub(/"[^"]*$/, "", line))
 | 
						|
         break
 | 
						|
 | 
						|
      # Read another line
 | 
						|
      while (1) {
 | 
						|
         if (getline nextline) {
 | 
						|
            if (nextline !~ /^#/) {
 | 
						|
               line = line " " nextline
 | 
						|
               # Go back to stripping @" "@ pairs
 | 
						|
               break
 | 
						|
            }
 | 
						|
         } else {
 | 
						|
            print "line", lineno ": unterminated PNG_DFN string"
 | 
						|
            err=1
 | 
						|
            next
 | 
						|
         }
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   # Put any needed double quotes in (at the end, because these would otherwise
 | 
						|
   # interfere with the processing above.)
 | 
						|
   gsub(/@'/,"\"", line)
 | 
						|
 | 
						|
   # Remove any trailing spaces (not really required, but for
 | 
						|
   # editorial consistency
 | 
						|
   sub(/ *$/, "", line)
 | 
						|
 | 
						|
   # Remove trailing CR
 | 
						|
   sub(/
 | 
						|
$/, "", line)
 | 
						|
 | 
						|
   if (sort) {
 | 
						|
      if (split(line, parts) < sort) {
 | 
						|
         print "line", lineno ": missing sort field:", line
 | 
						|
         err=1
 | 
						|
      } else
 | 
						|
         array[parts[sort]] = line
 | 
						|
   }
 | 
						|
 | 
						|
   else
 | 
						|
      print line >out
 | 
						|
   next
 | 
						|
}
 | 
						|
 | 
						|
/PNG_DFN/{
 | 
						|
   print "line", NR, "incorrectly formatted PNG_DFN line:"
 | 
						|
   print $0
 | 
						|
   err = 1
 | 
						|
}
 | 
						|
 | 
						|
END{
 | 
						|
   if (out_count > 0 || err > 0)
 | 
						|
	exit err
 | 
						|
 | 
						|
   print "no definition lines found"
 | 
						|
   exit 1
 | 
						|
}
 |