]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libpng/lib/dist/scripts/options.awk
update
[l4.git] / l4 / pkg / libpng / lib / dist / scripts / options.awk
1 #!/bin/awk -f
2 # scripts/options.awk - library build configuration control
3 #
4 # last changed in libpng version 1.5.7 - December 15, 2011
5 #
6 # Copyright (c) 1998-2011 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'.  The script is run twice, once with
14 # an intermediate output file, 'options.tmp' then again on
15 # that file to produce the final output:
16 #
17 #  awk -f scripts/options.awk out=options.tmp scripts/options.dfa 1>&2
18 #  awk -f scripts/options.awk out=options.dfn options.tmp 1>&2
19 #
20 # Some options may be specified on the command line:
21 #
22 #  deb=1            Causes debugging to be output
23 #  logunsupported=1 Causes all options to be recorded in the output
24 #  everything=off   Causes all options to be disabled by default
25 #  everything=on    Causes all options to be enabled by default
26 #
27 # If awk fails on your platform, try nawk instead.
28 #
29 # These options may also be specified in the original input file (and
30 # are copied to the preprocessed file).
31
32 BEGIN{
33    out="/dev/null"              # intermediate, preprocessed, file
34    pre=-1                       # preprocess (first line)
35    version="libpng version unknown" # version information
36    version_file=""              # where to find the version
37    err=0                        # in-line exit sets this
38    start="PNG_DEFN_MAGIC-"      # Arbitrary start
39    end="-PNG_DEFN_END"          # Arbitrary end
40    ct="PNG_JOIN"                # Join two tokens
41    cx= "/" ct "*"               # Open C comment for output file
42    comment=start cx             # Comment start
43    cend="*/" end                # Comment end
44    def=start "#define PNG_" ct  # Arbitrary define
45    sup=ct "_SUPPORTED 1" end    # end supported option
46    und=comment "#undef PNG_" ct # Unsupported option
47    une=ct "_SUPPORTED" cend     # end unsupported option
48    error=start "ERROR:"         # error message
49
50    # Variables
51    deb=0                        # debug - set on command line
52    everything=""                # do not override defaults
53    logunsupported=0             # write unsupported options too
54
55    # Precreate arrays
56    option[""] = ""    # list of all options: default enabled/disabled
57    done[""] = 1       # marks option as having been output
58    requires[""] = ""  # requires by option
59    iffs[""] = ""      # if by option
60    enabledby[""] = "" # options that enable it by option
61    setting[""] = ""   # requires by setting
62    defaults[""] = ""  # used for a defaulted value
63    doneset[""] = 1    # marks setting as having been output
64    r[""] = ""         # Temporary array
65
66    # For decorating the output file
67    protect = ""
68 }
69
70 # The output file must be specified before any input:
71 out == "/dev/null" {
72    print "out=output.file must be given on the command line"
73    err = 1
74    exit 1
75 }
76
77 # The very first line indicates whether we are reading pre-processed
78 # input or not, this must come *first* because 'PREPROCESSED' needs
79 # to be the very first line in the temporary file.
80 pre == -1{
81    if ($0 == "PREPROCESSED") {
82       pre = 0
83       next
84    } else {
85       pre = 1
86       print "PREPROCESSED" >out
87       # And fall through to continue processing
88    }
89 }
90
91 # While pre-processing if version is set to "search" look for a version string
92 # in the following file.
93 pre && version == "search" && version_file == ""{
94    version_file = FILENAME
95 }
96
97 pre && version == "search" && version_file != FILENAME{
98    print "version string not found in", version_file
99    err = 1
100    exit 1
101 }
102
103 pre && version == "search" && $0 ~ /^ \* libpng version/{
104    version = substr($0, 4)
105    print "version =", version >out
106    next
107 }
108
109 pre && FILENAME == version_file{
110    next
111 }
112
113 # variable=value
114 #   Sets the given variable to the given value (the syntax is fairly
115 #   free form, except for deb (you are expected to understand how to
116 #   set the debug variable...)
117 #
118 #   This happens before the check on 'pre' below skips most of the
119 #   rest of the actions, so the variable settings happen during
120 #   preprocessing but are recorded in the END action too.  This
121 #   allows them to be set on the command line too.
122 $0 ~ /^[        ]*version[      ]*=/{
123    sub(/^[  ]*version[  ]*=[  ]*/, "")
124    version = $0
125    next
126 }
127 $0 ~ /^[        ]*everything[   =]*off[         ]*$/{
128    everything = "off"
129    next
130 }
131 $0 ~ /^[        ]*everything[   =]*on[  ]*$/{
132    everything = "on"
133    next
134 }
135 $0 ~ /^[        ]*logunsupported[       =]*0[   ]*$/{
136    logunsupported = 0
137    next
138 }
139 $0 ~ /^[        ]*logunsupported[       =]*1[   ]*$/{
140    logunsupported = 1
141    next
142 }
143 $1 == "deb" && $2 == "=" && NF == 3{
144    deb = $3
145    next
146 }
147
148 # Preprocessing - this just copies the input file with lines
149 # that need preprocessing (just chunk at present) expanded
150 # The bare "pre" instead of "pre != 0" crashes under Sunos awk
151 pre && $1 != "chunk"{
152    print >out
153    next
154 }
155
156 # The first characters of the line determine how it is processed,
157 # leading spaces are ignored.  In general tokens that are not
158 # keywords are the names of options.  An option 'name' is
159 # controlled by the definition of the corresponding macros:
160 #
161 #   PNG_name_SUPPORTED    The option is turned on
162 #   PNG_NO_name
163 #   PNG_NO_name_SUPPORTED If the first macro is not defined
164 #                         either of these will turn the option off
165 #
166 # If none of these macros are defined the option is turned on, unless
167 # the keyword 'off' is given in a line relating to the option.  The
168 # keyword 'on' can also be given, but it will be ignored (since it is
169 # the default.)
170 #
171 # In the syntax below a 'name' is indicated by "NAME", other macro
172 # values are indicated by "MACRO", as with "NAME" the leading "PNG_"
173 # is omitted, but in this case the "NO_" prefix and the "_SUPPORTED"
174 # suffix are never used.
175 #
176 # Each line is introduced by a keyword - the first non-space characters
177 # on the line.  A line starting with a '#' is a comment - it is totally
178 # ignored.  Keywords are as follows, a NAME, is simply a macro name
179 # without the leading PNG_, PNG_NO_ or the trailing _SUPPORTED.
180
181 $1 ~ /^#/ || $0 ~ /^[   ]*$/{
182    next
183 }
184
185 # com <comment>
186 #   The whole line is placed in the output file as a comment with
187 #   the preceding 'com' removed
188 $1 == "com"{
189    if (NF > 1) {
190       # sub(/^[         ]*com[  ]*/, "")
191       $1 = ""
192       print comment, $0, cend >out
193    } else
194       print start end >out
195    next
196 }
197
198 # version
199 #   Inserts a version comment
200 $1 == "version" && NF == 1{
201    if (version == "") {
202       print "ERROR: no version string set"
203       err = 1 # prevent END{} running
204       exit 1
205    }
206
207    print comment, version, cend >out
208    next
209 }
210
211 # file output input protect
212 #   Informational: the official name of the input file (without
213 #   make generated local directories), the official name of the
214 #   output file and, if required, a name to use in a protection
215 #   macro for the contents.
216 $1 == "file" && NF >= 2{
217    print comment, $2, cend >out
218    print comment, "Machine generated file: DO NOT EDIT", cend >out
219    if (NF >= 3)
220       print comment, "Derived from:", $3, cend >out
221    protect = $4
222    if (protect != "") {
223       print start "#ifndef", protect end >out
224       print start "#define", protect end >out
225    }
226    next
227 }
228
229 # option NAME ( (requires|enables|if) NAME* | on | off | disabled )*
230 #   Declares an option 'NAME' and describes its default setting (disabled)
231 #   and its relationship to other options.  The option is disabled
232 #   unless *all* the options listed after 'requires' are set and at
233 #   least one of the options listed after 'if' is set.  If the
234 #   option is set then it turns on all the options listed after 'enables'.
235 #
236 #   Note that "enables" takes priority over the required/if/disabled/off
237 #   setting of the target option.
238 #
239 #   The definition file may list an option as 'disabled': off by default,
240 #   otherwise the option is enabled: on by default.  A later (and it must
241 #   be later) entry may turn an option on or off explicitly.
242
243 $1 == "option" && NF >= 2{
244    onoff = option[$2]  # records current (and the default is "", enabled)
245    key = ""
246    for (i=3; i<=NF; ++i) {
247       if ($(i) == "on" || $(i) == "off" || $(i) == "disabled") {
248          key = ""
249          if (onoff != $(i)) {
250             # on or off can zap disabled or enabled:
251             if (onoff == "" || (onoff == "disabled" || onoff == "enabled") && ($(i) == "on" || $(i) == "off")) {
252                # It's easy to mis-spell the option when turning it
253                # on or off, so warn about it here:
254                if (onoff == "" && ($(i) == "on" || $(i) == "off")) {
255                   print $2 ": ERROR: turning unrecognized option", $(i)
256                   # For the moment error out - it is safer
257                   err = 1 # prevent END{} running
258                   exit 1
259                }
260                onoff = $(i)
261             } else {
262                # Print a message, otherwise the error
263                # below is incomprehensible
264                print $2 ": currently", onoff ": attempt to turn", $(i)
265                break
266             }
267          }
268       } else if ($(i) == "requires" || $(i) == "if" || $(i) == "enables") {
269          key = $(i)
270       } else if (key == "requires") {
271          requires[$2] = requires[$2] " " $(i)
272       } else if (key == "if") {
273          iffs[$2] = iffs[$2] " " $(i)
274       } else if (key == "enables") {
275          enabledby[$(i)] = enabledby[$(i)] " " $2
276       } else
277          break # bad line format
278    }
279
280    if (i > NF) {
281       # Set the option, defaulting to 'enabled'
282       if (onoff == "") onoff = "enabled"
283       option[$2] = onoff
284       next
285    }
286    # Else fall through to the error handler
287 }
288
289 # chunk NAME [requires OPT] [on|off|disabled]
290 #   Expands to the 'option' settings appropriate to the reading and
291 #   writing of an ancilliary PNG chunk 'NAME':
292 #
293 #   option READ_NAME requires READ_ANCILLARY_CHUNKS [READ_OPT]
294 #   option READ_NAME enables NAME
295 #   [option READ_NAME off]
296 #   option WRITE_NAME requires WRITE_ANCILLARY_CHUNKS [WRITE_OPT]
297 #   option WRITE_NAME enables NAME
298 #   [option WRITE_NAME off]
299
300 pre != 0 && $1 == "chunk" && NF >= 2{
301    # 'chunk' is handled on the first pass by writing appropriate
302    # 'option' lines into the intermediate file.
303    onoff = ""
304    reqread = ""
305    reqwrite = ""
306    i = 3 # indicates format error
307    if (NF > 2) {
308       # read the keywords/additional OPTS
309       req = 0
310       for (i=3; i<=NF; ++i) {
311          if ($(i) == "on" || $(i) == "off" || $(i) == "disabled") {
312             if (onoff != $(i)) {
313                if (onoff == "")
314                   onoff = $(i)
315                else
316                   break # on/off conflict
317             }
318          } else if ($(i) == "requires")
319             req = 1
320          else if (req != 1)
321             break # bad line: handled below
322          else {
323             reqread = reqread " READ_" $(i)
324             reqwrite = reqwrite " WRITE_" $(i)
325          }
326       }
327    }
328
329    if (i > NF) {
330       # Output new 'option' lines to the intermediate file (out)
331       print "option READ_" $2, "requires READ_ANCILLARY_CHUNKS" reqread, "enables", $2, onoff >out
332       print "option WRITE_" $2, "requires WRITE_ANCILLARY_CHUNKS" reqwrite, "enables", $2, onoff >out
333       next
334    }
335    # Else hit the error handler below - bad line format!
336 }
337
338 # setting MACRO ( requires MACRO* )* [ default VALUE ]
339 #   Behaves in a similar way to 'option' without looking for NO_ or
340 #   _SUPPORTED; the macro is enabled if it is defined so long as all
341 #   the 'requires' macros are also defined.  The definitions may be
342 #   empty, an error will be issued if the 'requires' macros are
343 #   *not* defined.  If given the 'default' value is used if the
344 #   macro is not defined.  The default value will be re-tokenised.
345 #   (BTW: this is somewhat restrictive, it mainly exists for the
346 #   support of non-standard configurations and numeric parameters,
347 #   see the uses in scripts/options.dat
348
349 $1 == "setting" && (NF == 2 || NF >= 3 && ($3 == "requires" || $3 == "default")){
350    reqs = ""
351    deflt = ""
352    isdef = 0
353    key = ""
354    for (i=3; i<=NF; ++i)
355       if ($(i) == "requires" || $(i) == "default") {
356          key = $(i)
357          if (key == "default") isdef = 1
358       } else if (key == "requires")
359          reqs = reqs " " $(i)
360       else if (key == "default")
361          deflt = deflt " " $(i)
362       else
363          break # Format error, handled below
364
365    setting[$2] = reqs
366    # NOTE: this overwrites a previous value silently
367    if (isdef && deflt == "")
368       deflt = " " # as a flag to force output
369    defaults[$2] = deflt
370    next
371 }
372
373 # The order of the dependency lines (option, chunk, setting) is irrelevant
374 # - the 'enables', 'requires' and 'if' settings will be used to determine
375 # the correct order in the output and the final values in pnglibconf.h are
376 # not order dependent.  'requires' and 'if' entries take precedence over
377 # 'enables' from other options; if an option requires another option it
378 # won't be set regardless of any options that enable it unless the other
379 # option is also enabled.
380 #
381 # Similarly 'enables' trumps a NO_ definition in CFLAGS or pngusr.h
382 #
383 # For simplicity cycles in the definitions are regarded as errors,
384 # even if they are not ambiguous.
385 # A given NAME can be specified in as many 'option' lines as required, the
386 # definitions are additive.
387
388 # For backwards compatibility equivalent macros may be listed thus:
389 #
390 # = [NO_]NAME MACRO
391 #   Makes -DMACRO equivalent to -DPNG_NO_NAME or -DPNG_NAME_SUPPORTED
392 #   as appropriate.
393 #
394 # The definition is injected into the C compiler input when encountered
395 # in the second pass (so all these definitions appear *after* the @
396 # lines!)
397 #
398 # 'NAME' is as above, but 'MACRO' is the full text of the equivalent
399 # old, deprecated, macro.
400
401 $1 == "=" && NF == 3{
402    print "#ifdef PNG_" $3 >out
403    if ($2 ~ /^NO_/)
404       print "#   define PNG_" $2 >out
405    else
406       print "#   define PNG_" $2 "_SUPPORTED" >out
407    print "#endif" >out
408    next
409 }
410
411 # Lines may be injected into the C compiler input by preceding them
412 # with an "@" character.  The line is copied with just the leading
413 # @ removed.
414
415 $1 ~ /^@/{
416    # sub(/^[    ]*@/, "")
417    $1 = substr($1, 2)
418    print >out
419    next
420 }
421
422 # Check for unreognized lines, because of the preprocessing chunk
423 # format errors will be detected on the first pass independent of
424 # any other format errors.
425 {
426    print "options.awk: bad line (" NR "):", $0
427    err = 1 # prevent END{} running
428    exit 1
429 }
430
431 # For checking purposes names that start with "ok_" or "fail_" are
432 # not output to pnglibconf.h and must be either enabled or disabled
433 # respectively for the build to succeed.  This allows interdependencies
434 # between options of the form "at least one of" or "at most one of"
435 # to be checked.  For example:
436 #
437 # option FLOATING_POINT enables ok_math
438 # option FIXED_POINT enables ok_math
439 #   This ensures that at least one of FLOATING_POINT and FIXED_POINT
440 #   must be set for the build to succeed.
441 #
442 # option fail_math requires FLOATING_POINT FIXED_POINT
443 #   This means the build will fail if *both* FLOATING_POINT and
444 #   FIXED_POINT are set (this is an example; in fact both are allowed.)
445 #
446 # If all these options were given the build would require exactly one
447 # of the names to be enabled.
448
449 END{
450    # END{} gets run on an exit (a traditional awk feature)
451    if (err) exit 1
452
453    if (pre) {
454       # Record the final value of the variables
455       print "deb =", deb >out
456       if (everything != "") {
457          print "everything =", everything >out
458       }
459       print "logunsupported =", logunsupported >out
460       exit 0
461    }
462
463    # Do the 'setting' values first, the algorithm the standard
464    # tree walk (O(1)) done in an O(2) while/for loop; interations
465    # settings x depth, outputing the deepest required macros
466    # first.
467    print "" >out
468    print "/* SETTINGS */" >out
469    print comment, "settings", cend >out
470    finished = 0
471    while (!finished) {
472       finished = 1
473       movement = 0 # done nothing
474       for (i in setting) if (!doneset[i]) {
475          nreqs = split(setting[i], r)
476          if (nreqs > 0) {
477             for (j=1; j<=nreqs; ++j) if (!doneset[r[j]]) {
478                break
479             }
480             if (j<=nreqs) {
481                finished = 0
482                continue # try a different setting
483             }
484          }
485
486          # All the requirements have been processed, output
487          # this setting.
488          if (deb) print "setting", i
489          print "" >out
490          print "/* setting: ", i >out
491          print " *   requires:" setting[i] >out
492          print " *   default: ", defaults[i], "*/" >out
493          if (defaults[i] == "") { # no default, only check if defined
494             print "#ifdef PNG_" i >out
495          }
496          for (j=1; j<=nreqs; ++j) {
497             print "# ifndef PNG_" r[j] >out
498             print error, i, "requires", r[j] end >out
499             print "# endif" >out
500          }
501          if (defaults[i] != "") { # default handling
502             print "#ifdef PNG_" i >out
503          }
504          print def i, "PNG_" i end >out
505          if (defaults[i] != "") {
506             print "#else /*default*/" >out
507             # And add the default definition for the benefit
508             # of later settings an options test:
509             print "# define PNG_" i defaults[i] >out
510             print def i defaults[i] end >out
511          }
512          print "#endif" >out
513
514          doneset[i] = 1
515          ++movement
516       }
517
518       if (!finished && !movement) {
519          print "setting: loop or missing setting in 'requires', cannot process:"
520          for (i in setting) if (!doneset[i]) {
521             print "  setting", i, "requires" setting[i]
522          }
523          exit 1
524       }
525    }
526    print comment, "end of settings", cend >out
527
528    # Now do the options - somewhat more complex.  The dependency
529    # tree is thus:
530    #
531    #   name     >     name
532    #   name requires  name
533    #   name if        name
534    #   name enabledby name
535    #
536    # First build a list 'tree' by option of all the things on which
537    # it depends.
538    print "" >out
539    print "/* OPTIONS */" >out
540    print comment, "options", cend >out
541    for (opt in enabledby) tree[opt] = 1  # may not be explicit options
542    for (opt in option) if (opt != "") {
543       o = option[opt]
544       # option should always be one of the following values
545       if (o != "on" && o != "off" && o != "disabled" && o != "enabled") {
546          print "internal option error (" o ")"
547          exit 1
548       }
549       tree[opt] = ""   # so unlisted options marked
550    }
551    for (opt in tree) if (opt != "") {
552       if (tree[opt] == 1) {
553          tree[opt] = ""
554          if (option[opt] != "") {
555             print "internal error (1)"
556             exit 1
557          }
558          # Macros only listed in 'enables' remain off unless
559          # one of the enabling macros is on.
560          option[opt] = "disabled"
561       }
562
563       split("", list) # clear 'list'
564       # Now add every requires, iffs or enabledby entry to 'list'
565       # so that we can add a unique list of requirements to tree[i]
566       split(requires[opt] iffs[opt] enabledby[opt], r)
567       for (i in r) list[r[i]] = 1
568       for (i in list) tree[opt] = tree[opt] " " i
569    }
570
571    # print the tree for extreme debugging
572    if (deb > 2) for (i in tree) if (i != "") print i, "depends-on" tree[i]
573
574    # Ok, now check all options marked explicitly 'on' or 'off':
575    #
576    # If an option[opt] is 'on' then turn on all requires[opt]
577    # If an option[opt] is 'off' then turn off all enabledby[opt]
578    #
579    # Error out if we have to turn 'on' an 'off' option or vice versa.
580    npending = 0
581    for (opt in option) if (opt != "") {
582       if (option[opt] == "on" || option[opt] == "off") {
583          pending[++npending] = opt
584       }
585    }
586
587    err = 0 # set on error
588    while (npending > 0) {
589       opt = pending[npending--]
590       if (option[opt] == "on") {
591          nreqs = split(requires[opt], r)
592          for (j=1; j<=nreqs; ++j) {
593             if (option[r[j]] == "off") {
594                print "option", opt, "turned on, but requirement", r[j], "is turned off"
595                err = 1
596             } else if (option[r[j]] != "on") {
597                option[r[j]] = "on"
598                pending[++npending] = r[j]
599             }
600          }
601       } else {
602          if (option[opt] != "off") {
603             print "internal error (2)"
604             exit 1
605          }
606          nreqs = split(enabledby[opt], r)
607          for (j=1; j<=nreqs; ++j) {
608             if (option[r[j]] == "on") {
609                print "option", opt, "turned off, but enabled by", r[j], "which is turned on"
610                err = 1
611             } else if (option[r[j]] != "off") {
612                option[r[j]] = "off"
613                pending[++npending] = r[j]
614             }
615          }
616       }
617    }
618    if (err) exit 1
619
620    # option[i] is now the complete list of all the tokens we may
621    # need to output, go through it as above, depth first.
622    finished = 0
623    while (!finished) {
624       finished = 1
625       movement = 0 # done nothing
626       for (i in option) if (!done[i]) {
627          nreqs = split(tree[i], r)
628          if (nreqs > 0) {
629             for (j=1; j<=nreqs; ++j) if (!done[r[j]]) {
630                break
631             }
632             if (j<=nreqs) {
633                finished = 0
634                continue  # next option
635             }
636          }
637
638          # All the requirements have been processed, output
639          # this option.  An option is _SUPPORTED if:
640          #
641          # all 'requires' are _SUPPORTED AND
642          # at least one of the 'if' options are _SUPPORTED AND
643          # EITHER:
644          #   The name is _SUPPORTED (on the command line)
645          # OR:
646          #   an 'enabledby' is _SUPPORTED
647          # OR:
648          #   NO_name is not defined AND
649          #   the option is not disabled; an option is disabled if:
650          #    option == off
651          #    option == disabled && everything != on
652          #    option == "" && everything == off
653          if (deb) print "option", i
654          print "" >out
655          print "/* option:", i, option[i] >out
656          print " *   requires:  " requires[i] >out
657          print " *   if:      " iffs[i] >out
658          print " *   enabled-by:" enabledby[i], "*/" >out
659          print "#undef PNG_on" >out
660          print "#define PNG_on 1" >out
661
662          # requires
663          nreqs = split(requires[i], r)
664          for (j=1; j<=nreqs; ++j) {
665             print "#ifndef PNG_" r[j] "_SUPPORTED" >out
666             print "#   undef PNG_on /*!" r[j] "*/" >out
667             # this error appears in the final output if something
668             # was switched 'on' but the processing above to force
669             # the requires did not work
670             if (option[i] == "on") {
671                print error, i, "requires", r[j] end >out
672             }
673             print "#endif" >out
674          }
675
676          # if
677          nreqs = split(iffs[i], r)
678          print "#undef PNG_no_if" >out
679          if (nreqs > 0) {
680             print "/* if" iffs[i], "*/" >out
681             print "#define PNG_no_if 1" >out
682             for (j=1; j<=nreqs; ++j) {
683                print "#ifdef PNG_" r[j] "_SUPPORTED" >out
684                print "#   undef PNG_no_if /*" r[j] "*/" >out
685                print "#endif" >out
686             }
687             print "#ifdef PNG_no_if /*missing if*/" >out
688             print "#   undef PNG_on" >out
689             # There is no checking above for this, because we
690             # don't know which 'if' to choose, so whine about
691             # it here:
692             if (option[i] == "on") {
693                print error, i, "needs one of:", iffs[i] end >out
694             }
695             print "#endif" >out
696          }
697
698          print "#ifdef PNG_on /*requires, if*/" >out
699          # enables
700          print "#   undef PNG_not_enabled" >out
701          print "#   define PNG_not_enabled 1" >out
702          print "   /* enabled by" enabledby[i], "*/" >out
703          nreqs = split(enabledby[i], r)
704          for (j=1; j<=nreqs; ++j) {
705             print "#ifdef PNG_" r[j] "_SUPPORTED" >out
706             print "#   undef PNG_not_enabled /*" r[j] "*/" >out
707             # Oops, probably not intended (should be factored
708             # out by the checks above).
709             if (option[i] == "off") {
710                print error, i, "enabled by:", r[j] end >out
711             }
712             print "#endif" >out
713          }
714
715          print "#   ifndef PNG_" i "_SUPPORTED /*!command line*/" >out
716          print "#    ifdef PNG_not_enabled /*!enabled*/" >out
717          if (option[i] == "off" || option[i] == "disabled" && everything != "on" || option[i] == "enabled" && everything == "off") {
718             print "#      undef PNG_on /*default off*/" >out
719          } else {
720             print "#      ifdef PNG_NO_" i >out
721             print "#       undef PNG_on /*turned off*/" >out
722             print "#      endif" >out
723             print "#      ifdef PNG_NO_" i "_SUPPORTED" >out
724             print "#       undef PNG_on /*turned off*/" >out
725             print "#      endif" >out
726          }
727          print "#    endif /*!enabled*/" >out
728          print "#    ifdef PNG_on" >out
729          # The _SUPPORTED macro must be defined so that dependent
730          # options output later work.
731          print "#      define PNG_" i "_SUPPORTED" >out
732          print "#    endif" >out
733          print "#   endif /*!command line*/" >out
734          # If PNG_on is still set the option should be defined in
735          # pnglibconf.h
736          print "#   ifdef PNG_on" >out
737          if (i ~ /^fail_/) {
738             print error, i, "is on: enabled by:" iffs[i] enabledby[i] ", requires" requires[i] end >out
739          } else if (i !~ /^ok_/) {
740             print def i sup >out
741          }
742          print "#   endif /* definition */" >out
743          print "#endif /*requires, if*/" >out
744          if (logunsupported || i ~ /^ok_/) {
745             print "#ifndef  PNG_on" >out
746             if (logunsupported) {
747                print und i une >out
748             }
749             if (i ~ /^ok_/) {
750                print error, i, "not enabled: requires:" requires[i] ", enabled by:" iffs[i] enabledby[i] end >out
751             }
752             print "#endif" >out
753          }
754
755          done[i] = 1
756          ++movement
757       }
758
759       if (!finished && !movement) {
760          print "option: loop or missing option in dependency tree, cannot process:"
761          for (i in option) if (!done[i]) {
762             print "  option", i, "depends on" tree[i], "needs:"
763             nreqs = split(tree[i], r)
764             if (nreqs > 0) for (j=1; j<=nreqs; ++j) if (!done[r[j]]) {
765                print "   " r[j]
766             }
767          }
768          exit 1
769       }
770    }
771    print comment, "end of options", cend >out
772
773    # Regular end - everything looks ok
774    if (protect != "") {
775       print start "#endif", cx, protect, "*/" end >out
776    }
777 }