diff options
Diffstat (limited to 'libpng/scripts/dfn.awk')
-rwxr-xr-x | libpng/scripts/dfn.awk | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/libpng/scripts/dfn.awk b/libpng/scripts/dfn.awk new file mode 100755 index 00000000..346b9db7 --- /dev/null +++ b/libpng/scripts/dfn.awk @@ -0,0 +1,203 @@ +#!/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 occurred + 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 +} |