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