You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
5.5 KiB
203 lines
5.5 KiB
#!/bin/awk -f |
|
# scripts/dfn.awk - process a .dfn file |
|
# |
|
# last changed in libpng version 1.5.19 - August 21, 2014 |
|
# |
|
# Copyright (c) 2013-2014 Glenn Randers-Pehrson |
|
# |
|
# This code is released under the libpng license. |
|
# For conditions of distribution and use, see the disclaimer |
|
# and license in png.h |
|
|
|
# The output of this script is written to the file given by |
|
# the variable 'out', which should be set on the command line. |
|
# Error messages are printed to stdout and if any are printed |
|
# the script will exit with error code 1. |
|
|
|
BEGIN{ |
|
out="/dev/null" # as a flag |
|
out_count=0 # count of output lines |
|
err=0 # set if an error occurred |
|
sort=0 # sort the output |
|
array[""]="" |
|
} |
|
|
|
# The output file must be specified before any input: |
|
NR==1 && out == "/dev/null" { |
|
print "out=output.file must be given on the command line" |
|
# but continue without setting the error code; this allows the |
|
# script to be checked easily |
|
} |
|
|
|
# Output can be sorted; two lines are recognized |
|
$1 == "PNG_DFN_START_SORT"{ |
|
sort=0+$2 |
|
next |
|
} |
|
|
|
$1 ~ /^PNG_DFN_END_SORT/{ |
|
# Do a very simple, slow, sort; notice that blank lines won't be |
|
# output by this |
|
for (entry in array) { |
|
while (array[entry] != "") { |
|
key = entry |
|
value = array[key] |
|
array[key] = "" |
|
|
|
for (alt in array) { |
|
if (array[alt] != "" && alt < key) { |
|
array[key] = value |
|
value = array[alt] |
|
key = alt |
|
array[alt] = "" |
|
} |
|
} |
|
|
|
print value >out |
|
} |
|
} |
|
sort=0 |
|
next |
|
} |
|
|
|
/^[^"]*PNG_DFN *".*"[^"]*$/{ |
|
# A definition line, apparently correctly formatted; extract the |
|
# definition then replace any doubled "" that remain with a single |
|
# double quote. Notice that the original doubled double quotes |
|
# may have been split by tokenization |
|
# |
|
# Sometimes GCC splits the PNG_DFN lines; we know this has happened |
|
# if the quotes aren't closed and must read another line. In this |
|
# case it is essential to reject lines that start with '#' because those |
|
# are introduced #line directives. |
|
orig=$0 |
|
line=$0 |
|
lineno=FNR |
|
if (lineno == "") lineno=NR |
|
|
|
if (sub(/^[^"]*PNG_DFN *"/,"",line) != 1) { |
|
print "line", lineno ": processing failed:" |
|
print orig |
|
err=1 |
|
next |
|
} else { |
|
++out_count |
|
} |
|
|
|
# Now examine quotes within the value: |
|
# |
|
# @" - delete this and any following spaces |
|
# "@ - delete this and any preceding spaces |
|
# @' - replace this by a double quote |
|
# |
|
# This allows macro substitution by the C compiler thus: |
|
# |
|
# #define first_name John |
|
# #define last_name Smith |
|
# |
|
# PNG_DFN"#define name @'@" first_name "@ @" last_name "@@'" |
|
# |
|
# Might get C preprocessed to: |
|
# |
|
# PNG_DFN "#define foo @'@" John "@ @" Smith "@@'" |
|
# |
|
# Which this script reduces to: |
|
# |
|
# #define name "John Smith" |
|
# |
|
while (1) { |
|
# While there is an @" remove it and the next "@ |
|
if (line ~ /@"/) { |
|
if (line ~ /@".*"@/) { |
|
# Do this special case first to avoid swallowing extra spaces |
|
# before or after the @ stuff: |
|
if (!sub(/@" *"@/, "", line)) { |
|
# Ok, do it in pieces - there has to be a non-space between the |
|
# two. NOTE: really weird things happen if a leading @" is |
|
# lost - the code will error out below (I believe). |
|
if (!sub(/@" */, "", line) || !sub(/ *"@/, "", line)) { |
|
print "line", lineno, ": internal error:", orig |
|
exit 1 |
|
} |
|
} |
|
} |
|
|
|
# There is no matching "@. Assume a split line |
|
else while (1) { |
|
if (getline nextline) { |
|
# If the line starts with '#' it is a preprocesor line directive |
|
# from cc -E; skip it: |
|
if (nextline !~ /^#/) { |
|
line = line " " nextline |
|
break |
|
} |
|
} else { |
|
# This is end-of-input - probably a missing "@ on the first line: |
|
print "line", lineno ": unbalanced @\" ... \"@ pair" |
|
err=1 |
|
next |
|
} |
|
} |
|
|
|
# Keep going until all the @" have gone |
|
continue |
|
} |
|
|
|
# Attempt to remove a trailing " (not preceded by '@') - if this can |
|
# be done, stop now; if not assume a split line again |
|
if (sub(/"[^"]*$/, "", line)) |
|
break |
|
|
|
# Read another line |
|
while (1) { |
|
if (getline nextline) { |
|
if (nextline !~ /^#/) { |
|
line = line " " nextline |
|
# Go back to stripping @" "@ pairs |
|
break |
|
} |
|
} else { |
|
print "line", lineno ": unterminated PNG_DFN string" |
|
err=1 |
|
next |
|
} |
|
} |
|
} |
|
|
|
# Put any needed double quotes in (at the end, because these would otherwise |
|
# interfere with the processing above.) |
|
gsub(/@'/,"\"", line) |
|
|
|
# Remove any trailing spaces (not really required, but for |
|
# editorial consistency |
|
sub(/ *$/, "", line) |
|
|
|
# Remove trailing CR |
|
sub(/ |
|
$/, "", line) |
|
|
|
if (sort) { |
|
if (split(line, parts) < sort) { |
|
print "line", lineno ": missing sort field:", line |
|
err=1 |
|
} else |
|
array[parts[sort]] = line |
|
} |
|
|
|
else |
|
print line >out |
|
next |
|
} |
|
|
|
/PNG_DFN/{ |
|
print "line", NR, "incorrectly formatted PNG_DFN line:" |
|
print $0 |
|
err = 1 |
|
} |
|
|
|
END{ |
|
if (out_count > 0 || err > 0) |
|
exit err |
|
|
|
print "no definition lines found" |
|
exit 1
}
|
|
|