]>
Commit | Line | Data |
---|---|---|
fff5f7d5 VZ |
1 | #!/bin/awk -f |
2 | # scripts/dfn.awk - process a .dfn file | |
3 | # | |
4 | # last changed in libpng version 1.5.14 - February 4, 2013 | |
5 | # | |
6 | # Copyright (c) 2013-2013 Glenn Randers-Pehrson | |
7 | # | |
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 | |
11 | ||
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. | |
16 | ||
17 | BEGIN{ | |
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 | |
22 | array[""]="" | |
23 | } | |
24 | ||
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 | |
30 | } | |
31 | ||
32 | # Output can be sorted; two lines are recognized | |
33 | $1 == "PNG_DFN_START_SORT"{ | |
34 | sort=0+$2 | |
35 | next | |
36 | } | |
37 | ||
38 | $1 ~ /^PNG_DFN_END_SORT/{ | |
39 | # Do a very simple, slow, sort; notice that blank lines won't be | |
40 | # output by this | |
41 | for (entry in array) { | |
42 | while (array[entry] != "") { | |
43 | key = entry | |
44 | value = array[key] | |
45 | array[key] = "" | |
46 | ||
47 | for (alt in array) { | |
48 | if (array[alt] != "" && alt < key) { | |
49 | array[key] = value | |
50 | value = array[alt] | |
51 | key = alt | |
52 | array[alt] = "" | |
53 | } | |
54 | } | |
55 | ||
56 | print value >out | |
57 | } | |
58 | } | |
59 | sort=0 | |
60 | next | |
61 | } | |
62 | ||
63 | /^[^"]*PNG_DFN *".*"[^"]*$/{ | |
64 | # A definition line, apparently correctly formated, 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 | |
68 | # | |
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 '#' because those | |
72 | # are introduced #line directives. | |
73 | orig=$0 | |
74 | line=$0 | |
75 | lineno=FNR | |
76 | if (lineno == "") lineno=NR | |
77 | ||
78 | if (sub(/^[^"]*PNG_DFN *"/,"",line) != 1) { | |
79 | print "line", lineno ": processing failed:" | |
80 | print orig | |
81 | err=1 | |
82 | next | |
83 | } else { | |
84 | ++out_count | |
85 | } | |
86 | ||
87 | # Now examine quotes within the value: | |
88 | # | |
89 | # @" - delete this and any following spaces | |
90 | # "@ - delete this and any preceding spaces | |
91 | # @' - replace this by a double quote | |
92 | # | |
93 | # This allows macro substitution by the C compiler thus: | |
94 | # | |
95 | # #define first_name John | |
96 | # #define last_name Smith | |
97 | # | |
98 | # PNG_DFN"#define name @'@" first_name "@ @" last_name "@@'" | |
99 | # | |
100 | # Might get C preprocessed to: | |
101 | # | |
102 | # PNG_DFN "#define foo @'@" John "@ @" Smith "@@'" | |
103 | # | |
104 | # Which this script reduces to: | |
105 | # | |
106 | # #define name "John Smith" | |
107 | # | |
108 | while (1) { | |
109 | # While there is an @" remove it and the next "@ | |
110 | if (line ~ /@"/) { | |
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 | |
120 | exit 1 | |
121 | } | |
122 | } | |
123 | } | |
124 | ||
125 | # There is no matching "@. Assume a split line | |
126 | else while (1) { | |
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 | |
132 | break | |
133 | } | |
134 | } else { | |
135 | # This is end-of-input - probably a missig "@ on the first line: | |
136 | print "line", lineno ": unbalanced @\" ... \"@ pair" | |
137 | err=1 | |
138 | next | |
139 | } | |
140 | } | |
141 | ||
142 | # Keep going until all the @" have gone | |
143 | continue | |
144 | } | |
145 | ||
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)) | |
149 | break | |
150 | ||
151 | # Read another line | |
152 | while (1) { | |
153 | if (getline nextline) { | |
154 | if (nextline !~ /^#/) { | |
155 | line = line " " nextline | |
156 | # Go back to stripping @" "@ pairs | |
157 | break | |
158 | } | |
159 | } else { | |
160 | print "line", lineno ": unterminated PNG_DFN string" | |
161 | err=1 | |
162 | next | |
163 | } | |
164 | } | |
165 | } | |
166 | ||
167 | # Put any needed double quotes in (at the end, because these would otherwise | |
168 | # interfere with the processing above.) | |
169 | gsub(/@'/,"\"", line) | |
170 | ||
171 | # Remove any trailing spaces (not really required, but for | |
172 | # editorial consistency | |
173 | sub(/ *$/, "", line) | |
174 | ||
175 | # Remove trailing CR | |
176 | sub(/\r$/, "", line) | |
177 | ||
178 | if (sort) { | |
179 | if (split(line, parts) < sort) { | |
180 | print "line", lineno ": missing sort field:", line | |
181 | err=1 | |
182 | } else | |
183 | array[parts[sort]] = line | |
184 | } | |
185 | ||
186 | else | |
187 | print line >out | |
188 | next | |
189 | } | |
190 | ||
191 | /PNG_DFN/{ | |
192 | print "line", NR, "incorrectly formated PNG_DFN line:" | |
193 | print $0 | |
194 | err = 1 | |
195 | } | |
196 | ||
197 | END{ | |
198 | if (out_count > 0 || err > 0) | |
199 | exit err | |
200 | ||
201 | print "no definition lines found" | |
202 | exit 1 | |
203 | } |