| #!/bin/awk -f |
| # scripts/dfn.awk - process a .dfn file |
| # |
| # last changed in libpng version 1.5.14 - February 4, 2013 |
| # |
| # Copyright (c) 2013-2013 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 formated, 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 |
| orig=$0 |
| |
| if (gsub(/^[^"]*PNG_DFN *"/,"") != 1 || gsub(/"[^"]*$/, "") != 1) { |
| print "line", NR, "processing failed:" |
| print orig |
| print $0 |
| err=1 |
| } else { |
| ++out_count |
| } |
| |
| # Now examine quotes within the value: |
| # |
| # @" - delete this and any following spaces |
| # "@ - delete this and any original 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 (sub(/@" */, "")) { |
| if (!sub(/ *"@/, "")) { |
| print "unbalanced @\" ... \"@ pair" |
| err=1 |
| break |
| } |
| } |
| |
| # Put any needed double quotes in |
| gsub(/@'/,"\"") |
| |
| # Remove any trailing spaces (not really required, but for |
| # editorial consistency |
| sub(/ *$/, "") |
| |
| if (sort) |
| array[$(sort)] = $0 |
| |
| else |
| print $0 >out |
| next |
| } |
| |
| /PNG_DFN/{ |
| print "line", NR, "incorrectly formated PNG_DFN line:" |
| print $0 |
| err = 1 |
| } |
| |
| END{ |
| if (out_count > 0 || err > 0) |
| exit err |
| |
| print "no definition lines found" |
| exit 1 |
| } |