1b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#!/bin/awk -f
2b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# scripts/dfn.awk - process a .dfn file
3b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#
4b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari# last changed in libpng version 1.5.19 - $RDATE%
5b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#
6b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari# Copyright (c) 2013-2014 Glenn Randers-Pehrson
7b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#
8b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# This code is released under the libpng license.
9b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# For conditions of distribution and use, see the disclaimer
10b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# and license in png.h
11b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
12b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# The output of this script is written to the file given by
13b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# the variable 'out', which should be set on the command line.
14b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# Error messages are printed to stdout and if any are printed
15b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# the script will exit with error code 1.
16b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
17b50c217251b086440efcdb273c22f86a06c80cbaChris CraikBEGIN{
18b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   out="/dev/null"       # as a flag
19b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   out_count=0           # count of output lines
20b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   err=0                 # set if an error occured
21b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   sort=0                # sort the output
22b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   array[""]=""
23b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
24b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
25b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# The output file must be specified before any input:
26b50c217251b086440efcdb273c22f86a06c80cbaChris CraikNR==1 && out == "/dev/null" {
27b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   print "out=output.file must be given on the command line"
28b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari   # but continue without setting the error code; this allows the
29b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # script to be checked easily
30b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
31b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
32b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# Output can be sorted; two lines are recognized
33b50c217251b086440efcdb273c22f86a06c80cbaChris Craik$1 == "PNG_DFN_START_SORT"{
34b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   sort=0+$2
35b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   next
36b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
37b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
38b50c217251b086440efcdb273c22f86a06c80cbaChris Craik$1 ~ /^PNG_DFN_END_SORT/{
39b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # Do a very simple, slow, sort; notice that blank lines won't be
40b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # output by this
41b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   for (entry in array) {
42b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      while (array[entry] != "") {
43b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         key = entry
44b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         value = array[key]
45b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         array[key] = ""
46b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
47b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         for (alt in array) {
48b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            if (array[alt] != "" && alt < key) {
49b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               array[key] = value
50b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               value = array[alt]
51b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               key = alt
52b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               array[alt] = ""
53b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            }
54b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         }
55b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
56b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         print value >out
57b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      }
58b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
59b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   sort=0
60b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   next
61b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
62b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
63b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/^[^"]*PNG_DFN *".*"[^"]*$/{
64b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari   # A definition line, apparently correctly formatted; extract the
65b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # definition then replace any doubled "" that remain with a single
66b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # double quote.  Notice that the original doubled double quotes
67b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # may have been split by tokenization
68b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #
69b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari   # Sometimes GCC splits the PNG_DFN lines; we know this has happened
70b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # if the quotes aren't closed and must read another line.  In this
71b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari   # case it is essential to reject lines that start with '#' because those
72b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # are introduced #line directives.
73b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   orig=$0
74b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   line=$0
75b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   lineno=FNR
76b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (lineno == "") lineno=NR
77b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
78b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (sub(/^[^"]*PNG_DFN *"/,"",line) != 1) {
79b50c217251b086440efcdb273c22f86a06c80cbaChris Craik	print "line", lineno ": processing failed:"
80b50c217251b086440efcdb273c22f86a06c80cbaChris Craik	print orig
81b50c217251b086440efcdb273c22f86a06c80cbaChris Craik	err=1
82b50c217251b086440efcdb273c22f86a06c80cbaChris Craik       next
83b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   } else {
84b50c217251b086440efcdb273c22f86a06c80cbaChris Craik	++out_count
85b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
86b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
87b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # Now examine quotes within the value:
88b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #
89b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #   @" - delete this and any following spaces
90b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #   "@ - delete this and any preceding spaces
91b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #   @' - replace this by a double quote
92b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #
93b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # This allows macro substitution by the C compiler thus:
94b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #
95b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #   #define first_name John
96b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #   #define last_name Smith
97b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #
98b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #	PNG_DFN"#define name @'@" first_name "@ @" last_name "@@'"
99b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #
100b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # Might get C preprocessed to:
101b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #
102b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #   PNG_DFN "#define foo @'@" John "@ @" Smith "@@'"
103b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #
104b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # Which this script reduces to:
105b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #
106b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #	#define name "John Smith"
107b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   #
108b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   while (1) {
109b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      # While there is an @" remove it and the next "@
110b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (line ~ /@"/) {
111b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         if (line ~ /@".*"@/) {
112b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            # Do this special case first to avoid swallowing extra spaces
113b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            # before or after the @ stuff:
114b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            if (!sub(/@" *"@/, "", line)) {
115b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               # Ok, do it in pieces - there has to be a non-space between the
116b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               # two.  NOTE: really weird things happen if a leading @" is
117b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               # lost - the code will error out below (I believe).
118b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               if (!sub(/@" */, "", line) || !sub(/ *"@/, "", line)) {
119b50c217251b086440efcdb273c22f86a06c80cbaChris Craik                  print "line", lineno, ": internal error:", orig
120b50c217251b086440efcdb273c22f86a06c80cbaChris Craik                  exit 1
121b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               }
122b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            }
123b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         }
124b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
125b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         # There is no matching "@.  Assume a split line
126b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         else while (1) {
127b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            if (getline nextline) {
128b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               # If the line starts with '#' it is a preprocesor line directive
129b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari               # from cc -E; skip it:
130b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               if (nextline !~ /^#/) {
131b50c217251b086440efcdb273c22f86a06c80cbaChris Craik                  line = line " " nextline
132b50c217251b086440efcdb273c22f86a06c80cbaChris Craik                  break
133b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               }
134b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            } else {
135b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari               # This is end-of-input - probably a missing "@ on the first line:
136b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               print "line", lineno ": unbalanced @\" ... \"@ pair"
137b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               err=1
138b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               next
139b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            }
140b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         }
141b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
142b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         # Keep going until all the @" have gone
143b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         continue
144b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      }
145b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
146b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      # Attempt to remove a trailing " (not preceded by '@') - if this can
147b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari      # be done, stop now; if not assume a split line again
148b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (sub(/"[^"]*$/, "", line))
149b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         break
150b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
151b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      # Read another line
152b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      while (1) {
153b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         if (getline nextline) {
154b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            if (nextline !~ /^#/) {
155b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               line = line " " nextline
156b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               # Go back to stripping @" "@ pairs
157b50c217251b086440efcdb273c22f86a06c80cbaChris Craik               break
158b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            }
159b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         } else {
160b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            print "line", lineno ": unterminated PNG_DFN string"
161b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            err=1
162b50c217251b086440efcdb273c22f86a06c80cbaChris Craik            next
163b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         }
164b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      }
165b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
166b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
167b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # Put any needed double quotes in (at the end, because these would otherwise
168b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # interfere with the processing above.)
169b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   gsub(/@'/,"\"", line)
170b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
171b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # Remove any trailing spaces (not really required, but for
172b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # editorial consistency
173b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   sub(/ *$/, "", line)
174b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
175b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   # Remove trailing CR
176b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   sub(/
177b50c217251b086440efcdb273c22f86a06c80cbaChris Craik$/, "", line)
178b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
179b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (sort) {
180b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      if (split(line, parts) < sort) {
181b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         print "line", lineno ": missing sort field:", line
182b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         err=1
183b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      } else
184b50c217251b086440efcdb273c22f86a06c80cbaChris Craik         array[parts[sort]] = line
185b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   }
186b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
187b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   else
188b50c217251b086440efcdb273c22f86a06c80cbaChris Craik      print line >out
189b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   next
190b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
191b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
192b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari/PNG_DFN/{
193b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   print "line", NR, "incorrectly formatted PNG_DFN line:"
194b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   print $0
195b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   err = 1
196b50c217251b086440efcdb273c22f86a06c80cbaChris Craik}
197b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
198b50c217251b086440efcdb273c22f86a06c80cbaChris CraikEND{
199b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   if (out_count > 0 || err > 0)
200b50c217251b086440efcdb273c22f86a06c80cbaChris Craik	exit err
201b50c217251b086440efcdb273c22f86a06c80cbaChris Craik
202b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   print "no definition lines found"
203b50c217251b086440efcdb273c22f86a06c80cbaChris Craik   exit 1
204}
205