dfn.awk 5.5 KB

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