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