3 # scripts/dfn.awk - process a .dfn file
\r
5 # Copyright (c) 2013-2014 Glenn Randers-Pehrson
\r
7 # This code is released under the libpng license.
\r
8 # For conditions of distribution and use, see the disclaimer
\r
9 # and license in png.h
\r
11 # The output of this script is written to the file given by
\r
12 # the variable 'out', which should be set on the command line.
\r
13 # Error messages are printed to stdout and if any are printed
\r
14 # the script will exit with error code 1.
\r
17 out="/dev/null" # as a flag
\r
18 out_count=0 # count of output lines
\r
19 err=0 # set if an error occurred
\r
20 sort=0 # sort the output
\r
24 # The output file must be specified before any input:
\r
25 NR==1 && out == "/dev/null" {
\r
26 print "out=output.file must be given on the command line"
\r
27 # but continue without setting the error code; this allows the
\r
28 # script to be checked easily
\r
31 # Output can be sorted; two lines are recognized
\r
32 $1 == "PNG_DFN_START_SORT"{
\r
37 $1 ~ /^PNG_DFN_END_SORT/{
\r
38 # Do a very simple, slow, sort; notice that blank lines won't be
\r
40 for (entry in array) {
\r
41 while (array[entry] != "") {
\r
46 for (alt in array) {
\r
47 if (array[alt] != "" && alt < key) {
\r
62 /^[^"]*PNG_DFN *".*"[^"]*$/{
\r
63 # A definition line, apparently correctly formatted; extract the
\r
64 # definition then replace any doubled "" that remain with a single
\r
65 # double quote. Notice that the original doubled double quotes
\r
66 # may have been split by tokenization
\r
68 # Sometimes GCC splits the PNG_DFN lines; we know this has happened
\r
69 # if the quotes aren't closed and must read another line. In this
\r
70 # case it is essential to reject lines that start with '#' because those
\r
71 # are introduced #line directives.
\r
75 if (lineno == "") lineno=NR
\r
77 if (sub(/^[^"]*PNG_DFN *"/,"",line) != 1) {
\r
78 print "line", lineno ": processing failed:"
\r
86 # Now examine quotes within the value:
\r
88 # @" - delete this and any following spaces
\r
89 # "@ - delete this and any preceding spaces
\r
90 # @' - replace this by a double quote
\r
92 # This allows macro substitution by the C compiler thus:
\r
94 # #define first_name John
\r
95 # #define last_name Smith
\r
97 # PNG_DFN"#define name @'@" first_name "@ @" last_name "@@'"
\r
99 # Might get C preprocessed to:
\r
101 # PNG_DFN "#define foo @'@" John "@ @" Smith "@@'"
\r
103 # Which this script reduces to:
\r
105 # #define name "John Smith"
\r
108 # While there is an @" remove it and the next "@
\r
110 if (line ~ /@".*"@/) {
\r
111 # Do this special case first to avoid swallowing extra spaces
\r
112 # before or after the @ stuff:
\r
113 if (!sub(/@" *"@/, "", line)) {
\r
114 # Ok, do it in pieces - there has to be a non-space between the
\r
115 # two. NOTE: really weird things happen if a leading @" is
\r
116 # lost - the code will error out below (I believe).
\r
117 if (!sub(/@" */, "", line) || !sub(/ *"@/, "", line)) {
\r
118 print "line", lineno, ": internal error:", orig
\r
124 # There is no matching "@. Assume a split line
\r
126 if (getline nextline) {
\r
127 # If the line starts with '#' it is a preprocessor line directive
\r
128 # from cc -E; skip it:
\r
129 if (nextline !~ /^#/) {
\r
130 line = line " " nextline
\r
134 # This is end-of-input - probably a missing "@ on the first line:
\r
135 print "line", lineno ": unbalanced @\" ... \"@ pair"
\r
141 # Keep going until all the @" have gone
\r
145 # Attempt to remove a trailing " (not preceded by '@') - if this can
\r
146 # be done, stop now; if not assume a split line again
\r
147 if (sub(/"[^"]*$/, "", line))
\r
150 # Read another line
\r
152 if (getline nextline) {
\r
153 if (nextline !~ /^#/) {
\r
154 line = line " " nextline
\r
155 # Go back to stripping @" "@ pairs
\r
159 print "line", lineno ": unterminated PNG_DFN string"
\r
166 # Put any needed double quotes in (at the end, because these would otherwise
\r
167 # interfere with the processing above.)
\r
168 gsub(/@'/,"\"", line)
\r
170 # Remove any trailing spaces (not really required, but for
\r
171 # editorial consistency
\r
172 sub(/ *$/, "", line)
\r
174 # Remove trailing CR
\r
175 sub(/
\r$/, "", line)
\r
178 if (split(line, parts) < sort) {
\r
179 print "line", lineno ": missing sort field:", line
\r
182 array[parts[sort]] = line
\r
191 print "line", NR, "incorrectly formatted PNG_DFN line:"
\r
197 if (out_count > 0 || err > 0)
\r
200 print "no definition lines found"
\r