2 # scripts/dfn.awk - process a .dfn file
4 # last changed in libpng version 1.5.19 - August 21, 2014
6 # Copyright (c) 2013-2014 Glenn Randers-Pehrson
8 # This code is released under the libpng license.
9 # For conditions of distribution and use, see the disclaimer
10 # and license in png.h
12 # The output of this script is written to the file given by
13 # the variable 'out', which should be set on the command line.
14 # Error messages are printed to stdout and if any are printed
15 # the script will exit with error code 1.
18 out=
"/dev/null" # as a flag
19 out_count=
0 # count of output lines
20 err=
0 # set if an error occured
21 sort=
0 # sort the output
25 # The output file must be specified before any input:
26 NR==
1 && out ==
"/dev/null" {
27 print "out=output.file must be given on the command line"
28 # but continue without setting the error code; this allows the
29 # script to be checked easily
32 # Output can be sorted; two lines are recognized
33 $
1 ==
"PNG_DFN_START_SORT"{
38 $
1 ~
/^PNG_DFN_END_SORT
/{
39 # Do a very simple, slow, sort; notice that blank lines won't be
41 for (entry in array
) {
42 while (array
[entry
] != "") {
48 if (array
[alt
] != "" && alt
< key
) {
63 /^
[^
"]*PNG_DFN *".
*"[^"]*$
/{
64 # A definition line, apparently correctly formatted; extract the
65 # definition then replace any doubled "" that remain with a single
66 # double quote. Notice that the original doubled double quotes
67 # may have been split by tokenization
69 # Sometimes GCC splits the PNG_DFN lines; we know this has happened
70 # if the quotes aren't closed and must read another line. In this
71 # case it is essential to reject lines that start with '#' because those
72 # are introduced #line directives.
76 if (lineno ==
"") lineno=
NR
78 if (sub(/^
[^
"]*PNG_DFN *"/,"",line
) != 1) {
79 print "line", lineno
": processing failed:"
87 # Now examine quotes within the value:
89 # @" - delete this and any following spaces
90 # "@ - delete this and any preceding spaces
91 # @' - replace this by a double quote
93 # This allows macro substitution by the C compiler thus:
95 # #define first_name John
96 # #define last_name Smith
98 # PNG_DFN"#define name @'@" first_name "@ @" last_name "@@'"
100 # Might get C preprocessed to:
102 # PNG_DFN "#define foo @'@" John "@ @" Smith "@@'"
104 # Which this script reduces to:
106 # #define name "John Smith"
109 # While there is an @" remove it and the next "@
111 if (line ~ /@".
*"@/) {
112 # Do this special case first to avoid swallowing extra spaces
113 # before or after the @ stuff:
114 if (!sub(/@" *"@/, "", line)) {
115 # Ok, do it in pieces - there has to be a non-space between the
116 # two. NOTE: really weird things happen if a leading @" is
117 # lost - the code will error out below (I believe).
118 if (!
sub(/@
" */, "", line) || !sub(/ *"@
/, "", line
)) {
119 print "line", lineno
, ": internal error:", orig
125 # There is no matching "@. Assume a split line
127 if (getline nextline
) {
128 # If the line starts with '#' it is a preprocesor line directive
129 # from cc -E; skip it:
130 if (nextline !~
/^
#/) {
131 line = line
" " nextline
135 # This is end-of-input - probably a missing "@ on the first line:
136 print "line", lineno
": unbalanced @\" ... \"@ pair"
142 # Keep going until all the @" have gone
146 # Attempt to remove a trailing " (not preceded by '@') - if this can
147 # be done, stop now; if not assume a split line again
148 if (sub(/"[^"]*$
/, "", line
))
153 if (getline nextline
) {
154 if (nextline !~
/^
#/) {
155 line = line
" " nextline
156 # Go back to stripping @" "@ pairs
160 print "line", lineno
": unterminated PNG_DFN string"
167 # Put any needed double quotes in (at the end, because these would otherwise
168 # interfere with the processing above.)
169 gsub(/@
'/,"\"", line)
171 # Remove any trailing spaces (not really required, but for
172 # editorial consistency
179 if (split(line, parts) < sort) {
180 print "line", lineno ": missing sort field:", line
183 array[parts[sort]] = line
192 print "line", NR, "incorrectly formatted PNG_DFN line:"
198 if (out_count > 0 || err > 0)
201 print "no definition lines found"