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