Remove unused error/function codes.
[openssl.git] / Configure
1 #! /usr/bin/env perl
2 # -*- mode: perl; -*-
3 # Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
4 #
5 # Licensed under the OpenSSL license (the "License").  You may not use
6 # this file except in compliance with the License.  You can obtain a copy
7 # in the file LICENSE in the source distribution or at
8 # https://www.openssl.org/source/license.html
9
10 ##  Configure -- OpenSSL source tree configuration script
11
12 require 5.10.0;
13 use strict;
14 use File::Basename;
15 use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
16 use File::Path qw/mkpath/;
17 use IPC::Cmd qw/can_run/;
18
19 # see INSTALL for instructions.
20
21 my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
22
23 # Options:
24 #
25 # --config      add the given configuration file, which will be read after
26 #               any "Configurations*" files that are found in the same
27 #               directory as this script.
28 # --prefix      prefix for the OpenSSL installation, which includes the
29 #               directories bin, lib, include, share/man, share/doc/openssl
30 #               This becomes the value of INSTALLTOP in Makefile
31 #               (Default: /usr/local)
32 # --openssldir  OpenSSL data area, such as openssl.cnf, certificates and keys.
33 #               If it's a relative directory, it will be added on the directory
34 #               given with --prefix.
35 #               This becomes the value of OPENSSLDIR in Makefile and in C.
36 #               (Default: PREFIX/ssl)
37 #
38 # --cross-compile-prefix Add specified prefix to binutils components.
39 #
40 # --api         One of 0.9.8, 1.0.0 or 1.1.0.  Do not compile support for
41 #               interfaces deprecated as of the specified OpenSSL version.
42 #
43 # no-hw-xxx     do not compile support for specific crypto hardware.
44 #               Generic OpenSSL-style methods relating to this support
45 #               are always compiled but return NULL if the hardware
46 #               support isn't compiled.
47 # no-hw         do not compile support for any crypto hardware.
48 # [no-]threads  [don't] try to create a library that is suitable for
49 #               multithreaded applications (default is "threads" if we
50 #               know how to do it)
51 # [no-]shared   [don't] try to create shared libraries when supported.
52 # [no-]pic      [don't] try to build position independent code when supported.
53 #               If disabled, it also disables shared and dynamic-engine.
54 # no-asm        do not use assembler
55 # no-dso        do not compile in any native shared-library methods. This
56 #               will ensure that all methods just return NULL.
57 # no-egd        do not compile support for the entropy-gathering daemon APIs
58 # [no-]zlib     [don't] compile support for zlib compression.
59 # zlib-dynamic  Like "zlib", but the zlib library is expected to be a shared
60 #               library and will be loaded in run-time by the OpenSSL library.
61 # sctp          include SCTP support
62 # 386           generate 80386 code
63 # enable-weak-ssl-ciphers
64 #               Enable weak ciphers that are disabled by default. This currently
65 #               only includes RC4 based ciphers.
66 # no-sse2       disables IA-32 SSE2 code, above option implies no-sse2
67 # no-<cipher>   build without specified algorithm (rsa, idea, rc5, ...)
68 # -<xxx> +<xxx> compiler options are passed through
69 #
70 # DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
71 #               provided to stack calls. Generates unique stack functions for
72 #               each possible stack type.
73 # BN_LLONG      use the type 'long long' in crypto/bn/bn.h
74 # RC4_CHAR      use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
75 # Following are set automatically by this script
76 #
77 # MD5_ASM       use some extra md5 assembler,
78 # SHA1_ASM      use some extra sha1 assembler, must define L_ENDIAN for x86
79 # RMD160_ASM    use some extra ripemd160 assembler,
80 # SHA256_ASM    sha256_block is implemented in assembler
81 # SHA512_ASM    sha512_block is implemented in assembler
82 # AES_ASM       ASE_[en|de]crypt is implemented in assembler
83
84 # Minimum warning options... any contributions to OpenSSL should at least get
85 # past these.
86
87 # DEBUG_UNUSED enables __owur (warn unused result) checks.
88 my $gcc_devteam_warn = "-DDEBUG_UNUSED"
89         # -DPEDANTIC complements -pedantic and is meant to mask code that
90         # is not strictly standard-compliant and/or implementation-specifc,
91         # e.g. inline assembly, disregards to alignment requirements, such
92         # that -pedantic would complain about. Incidentally -DPEDANTIC has
93         # to be used even in sanitized builds, because sanitizer too is
94         # supposed to and does take notice of non-standard behaviour. Then
95         # -pedantic with pre-C9x compiler would also complain about 'long
96         # long' not being supported. As 64-bit algorithms are common now,
97         # it grew impossible to resolve this without sizeable additional
98         # code, so we just tell compiler to be pedantic about everything
99         # but 'long long' type.
100         . " -DPEDANTIC -pedantic -Wno-long-long"
101         . " -Wall"
102         . " -Wsign-compare"
103         . " -Wmissing-prototypes"
104         . " -Wshadow"
105         . " -Wformat"
106         . " -Wtype-limits"
107         . " -Werror"
108         ;
109
110 # These are used in addition to $gcc_devteam_warn when the compiler is clang.
111 # TODO(openssl-team): fix problems and investigate if (at least) the
112 # following warnings can also be enabled:
113 #       -Wswitch-enum
114 #       -Wcast-align
115 #       -Wunreachable-code
116 #       -Wlanguage-extension-token -- no, we use asm()
117 #       -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
118 #       -Wextended-offsetof -- no, needed in CMS ASN1 code
119 my $clang_devteam_warn = ""
120         . " -Qunused-arguments"
121         . " -Wextra"
122         . " -Wno-unused-parameter"
123         . " -Wno-missing-field-initializers"
124         . " -Wno-language-extension-token"
125         . " -Wno-extended-offsetof"
126         . " -Wconditional-uninitialized"
127         . " -Wincompatible-pointer-types-discards-qualifiers"
128         . " -Wmissing-variable-declarations"
129         ;
130
131 # This adds backtrace information to the memory leak info.  Is only used
132 # when crypto-mdebug-backtrace is enabled.
133 my $memleak_devteam_backtrace = "-rdynamic";
134
135 my $strict_warnings = 0;
136
137 # As for $BSDthreads. Idea is to maintain "collective" set of flags,
138 # which would cover all BSD flavors. -pthread applies to them all,
139 # but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
140 # -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
141 # which has to be accompanied by explicit -D_THREAD_SAFE and
142 # sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
143 # seems to be sufficient?
144 our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
145
146 #
147 # API compability name to version number mapping.
148 #
149 my $maxapi = "1.1.0";           # API for "no-deprecated" builds
150 my $apitable = {
151     "1.1.0" => "0x10100000L",
152     "1.0.0" => "0x10000000L",
153     "0.9.8" => "0x00908000L",
154 };
155
156 our %table = ();
157 our %config = ();
158 our %withargs = ();
159
160 # Forward declarations ###############################################
161
162 # read_config(filename)
163 #
164 # Reads a configuration file and populates %table with the contents
165 # (which the configuration file places in %targets).
166 sub read_config;
167
168 # resolve_config(target)
169 #
170 # Resolves all the late evaluations, inheritances and so on for the
171 # chosen target and any target it inherits from.
172 sub resolve_config;
173
174
175 # Information collection #############################################
176
177 # Unified build supports separate build dir
178 my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax
179 my $blddir = catdir(absolutedir("."));         # catdir ensures local syntax
180 my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
181
182 my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
183
184 $config{sourcedir} = abs2rel($srcdir);
185 $config{builddir} = abs2rel($blddir);
186
187 # Collect version numbers
188 $config{version} = "unknown";
189 $config{version_num} = "unknown";
190 $config{shlib_version_number} = "unknown";
191 $config{shlib_version_history} = "unknown";
192
193 collect_information(
194     collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')),
195     qr/OPENSSL.VERSION.TEXT.*OpenSSL (\S+) / => sub { $config{version} = $1; },
196     qr/OPENSSL.VERSION.NUMBER.*(0x\S+)/      => sub { $config{version_num}=$1 },
197     qr/SHLIB_VERSION_NUMBER *"([^"]+)"/      => sub { $config{shlib_version_number}=$1 },
198     qr/SHLIB_VERSION_HISTORY *"([^"]*)"/     => sub { $config{shlib_version_history}=$1 }
199     );
200 if ($config{shlib_version_history} ne "") { $config{shlib_version_history} .= ":"; }
201
202 ($config{major}, $config{minor})
203     = ($config{version} =~ /^([0-9]+)\.([0-9\.]+)/);
204 ($config{shlib_major}, $config{shlib_minor})
205     = ($config{shlib_version_number} =~ /^([0-9]+)\.([0-9\.]+)/);
206 die "erroneous version information in opensslv.h: ",
207     "$config{major}, $config{minor}, $config{shlib_major}, $config{shlib_minor}\n"
208     if ($config{major} eq "" || $config{minor} eq ""
209         || $config{shlib_major} eq "" ||  $config{shlib_minor} eq "");
210
211 # Collect target configurations
212
213 my $pattern = catfile(dirname($0), "Configurations", "*.conf");
214 foreach (sort glob($pattern) ) {
215     &read_config($_);
216 }
217
218 if (defined $ENV{$local_config_envname}) {
219     if ($^O eq 'VMS') {
220         # VMS environment variables are logical names,
221         # which can be used as is
222         $pattern = $local_config_envname . ':' . '*.conf';
223     } else {
224         $pattern = catfile($ENV{$local_config_envname}, '*.conf');
225     }
226
227     foreach (sort glob($pattern) ) {
228         &read_config($_);
229     }
230 }
231
232
233 print "Configuring OpenSSL version $config{version} (0x$config{version_num})\n";
234
235 $config{prefix}="";
236 $config{openssldir}="";
237 $config{processor}="";
238 $config{libdir}="";
239 $config{cross_compile_prefix}="";
240 $config{fipslibdir}="/usr/local/ssl/fips-2.0/lib/";
241 my $nofipscanistercheck=0;
242 $config{baseaddr}="0xFB00000";
243 my $auto_threads=1;    # enable threads automatically? true by default
244 my $default_ranlib;
245 $config{fips}=0;
246
247 # Top level directories to build
248 $config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "tools" ];
249 # crypto/ subdirectories to build
250 $config{sdirs} = [
251     "objects",
252     "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2",
253     "des", "aes", "rc2", "rc4", "rc5", "idea", "bf", "cast", "camellia", "seed", "chacha", "modes",
254     "bn", "ec", "rsa", "dsa", "dh", "dso", "engine",
255     "buffer", "bio", "stack", "lhash", "rand", "err",
256     "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui",
257     "cms", "ts", "srp", "cmac", "ct", "async", "kdf"
258     ];
259
260 # Known TLS and DTLS protocols
261 my @tls = qw(ssl3 tls1 tls1_1 tls1_2);
262 my @dtls = qw(dtls1 dtls1_2);
263
264 # Explicitly known options that are possible to disable.  They can
265 # be regexps, and will be used like this: /^no-${option}$/
266 # For developers: keep it sorted alphabetically
267
268 my @disablables = (
269     "afalgeng",
270     "asan",
271     "asm",
272     "async",
273     "autoalginit",
274     "autoerrinit",
275     "bf",
276     "blake2",
277     "camellia",
278     "capieng",
279     "cast",
280     "chacha",
281     "cmac",
282     "cms",
283     "comp",
284     "crypto-mdebug",
285     "crypto-mdebug-backtrace",
286     "ct",
287     "deprecated",
288     "des",
289     "dgram",
290     "dh",
291     "dsa",
292     "dso",
293     "dtls",
294     "dynamic-engine",
295     "ec",
296     "ec2m",
297     "ecdh",
298     "ecdsa",
299     "ec_nistp_64_gcc_128",
300     "egd",
301     "engine",
302     "err",
303     "filenames",
304     "fuzz",
305     "gost",
306     "heartbeats",
307     "hw(-.+)?",
308     "idea",
309     "makedepend",
310     "md2",
311     "md4",
312     "mdc2",
313     "multiblock",
314     "nextprotoneg",
315     "ocb",
316     "ocsp",
317     "pic",
318     "poly1305",
319     "posix-io",
320     "psk",
321     "rc2",
322     "rc4",
323     "rc5",
324     "rdrand",
325     "rfc3779",
326     "ripemd",
327     "rmd160",
328     "scrypt",
329     "sctp",
330     "seed",
331     "shared",
332     "sock",
333     "srp",
334     "srtp",
335     "sse2",
336     "ssl",
337     "ssl-trace",
338     "static-engine",
339     "stdio",
340     "threads",
341     "tls",
342     "ts",
343     "ubsan",
344     "ui",
345     "unit-test",
346     "whirlpool",
347     "weak-ssl-ciphers",
348     "zlib",
349     "zlib-dynamic",
350     );
351 foreach my $proto ((@tls, @dtls))
352         {
353         push(@disablables, $proto);
354         push(@disablables, "$proto-method");
355         }
356
357 my @deprecated_disablables = (
358     "ssl2",
359     );
360
361 # All of the following is disabled by default (RC5 was enabled before 0.9.8):
362
363 our %disabled = ( # "what"         => "comment"
364                   "asan"                => "default",
365                   "ec_nistp_64_gcc_128" => "default",
366                   "egd"                 => "default",
367                   "fuzz"                => "default",
368                   "md2"                 => "default",
369                   "rc5"                 => "default",
370                   "sctp"                => "default",
371                   "ssl-trace"           => "default",
372                   "ssl3"                => "default",
373                   "ssl3-method"         => "default",
374                   "ubsan"               => "default",
375                   "unit-test"           => "default",
376                   "weak-ssl-ciphers"    => "default",
377                   "zlib"                => "default",
378                   "zlib-dynamic"        => "default",
379                   "crypto-mdebug"       => "default",
380                   "heartbeats"          => "default",
381                 );
382
383 # Note: => pair form used for aesthetics, not to truly make a hash table
384 my @disable_cascades = (
385     # "what"            => [ "cascade", ... ]
386     sub { $config{processor} eq "386" }
387                         => [ "sse2" ],
388     "ssl"               => [ "ssl3" ],
389     "ssl3-method"       => [ "ssl3" ],
390     "zlib"              => [ "zlib-dynamic" ],
391     "des"               => [ "mdc2" ],
392     "ec"                => [ "ecdsa", "ecdh" ],
393
394     "dgram"             => [ "dtls", "sctp" ],
395     "sock"              => [ "dgram" ],
396     "dtls"              => [ @dtls ],
397
398     # SSL 3.0, (D)TLS 1.0 and TLS 1.1 require MD5 and SHA
399     "md5"               => [ "ssl", "tls1", "tls1_1", "dtls1" ],
400     "sha"               => [ "ssl", "tls1", "tls1_1", "dtls1" ],
401
402     # Additionally, SSL 3.0 requires either RSA or DSA+DH
403     sub { $disabled{rsa}
404           && ($disabled{dsa} || $disabled{dh}); }
405                         => [ "ssl" ],
406
407     # (D)TLS 1.0 and TLS 1.1 also require either RSA or DSA+DH
408     # or ECDSA + ECDH.  (D)TLS 1.2 has this requirement as well.
409     # (XXX: We don't support PSK-only builds).
410     sub { $disabled{rsa}
411           && ($disabled{dsa} || $disabled{dh})
412           && ($disabled{ecdsa} || $disabled{ecdh}); }
413                         => [ "tls1", "tls1_1", "tls1_2",
414                              "dtls1", "dtls1_2" ],
415
416     "tls"               => [ @tls ],
417
418     # SRP and HEARTBEATS require TLSEXT
419     "tlsext"            => [ "srp", "heartbeats" ],
420
421     "crypto-mdebug"     => [ "crypto-mdebug-backtrace" ],
422
423     # Without DSO, we can't load dynamic engines, so don't build them dynamic
424     "dso"               => [ "dynamic-engine" ],
425
426     # Without position independent code, there can be no shared libraries or DSOs
427     "pic"               => [ "shared" ],
428     "shared"            => [ "dynamic-engine" ],
429     "engine"            => [ "afalgeng" ],
430
431     # no-autoalginit is only useful when building non-shared
432     "autoalginit"       => [ "shared", "apps" ],
433
434     "stdio"             => [ "apps" ],
435     "apps"              => [ "tests" ],
436     "comp"              => [ "zlib" ],
437     sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
438     );
439
440 # Avoid protocol support holes.  Also disable all versions below N, if version
441 # N is disabled while N+1 is enabled.
442 #
443 my @list = (reverse @tls);
444 while ((my $first, my $second) = (shift @list, shift @list)) {
445     last unless @list;
446     push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
447                               => [ @list ] );
448     unshift @list, $second;
449 }
450 my @list = (reverse @dtls);
451 while ((my $first, my $second) = (shift @list, shift @list)) {
452     last unless @list;
453     push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
454                               => [ @list ] );
455     unshift @list, $second;
456 }
457
458 # Explicit "no-..." options will be collected in %disabled along with the defaults.
459 # To remove something from %disabled, use "enable-foo".
460 # For symmetry, "disable-foo" is a synonym for "no-foo".
461
462 my @generated_headers = (
463     "include/openssl/opensslconf.h",
464     "crypto/include/internal/bn_conf.h",
465     "crypto/include/internal/dso_conf.h"
466     );
467
468 my @generated_by_make_headers = (
469     "crypto/buildinf.h"
470     );
471
472
473 my $no_sse2=0;
474
475 &usage if ($#ARGV < 0);
476
477 my $user_cflags="";
478 my @user_defines=();
479 $config{openssl_api_defines}=[];
480 $config{openssl_algorithm_defines}=[];
481 $config{openssl_thread_defines}=[];
482 $config{openssl_sys_defines}=[];
483 $config{openssl_other_defines}=[];
484 my $libs="";
485 my $target="";
486 $config{options}="";
487 $config{build_type} = "release";
488
489 my @argvcopy=@ARGV;
490
491 if (grep /^reconf(igure)?$/, @argvcopy) {
492     if (-f "./configdata.pm") {
493         my $file = "./configdata.pm";
494         unless (my $return = do $file) {
495             die "couldn't parse $file: $@" if $@;
496             die "couldn't do $file: $!"    unless defined $return;
497             die "couldn't run $file"       unless $return;
498         }
499
500         @argvcopy = defined($configdata::config{perlargv}) ?
501             @{$configdata::config{perlargv}} : ();
502         die "Incorrect data to reconfigure, please do a normal configuration\n"
503             if (grep(/^reconf/,@argvcopy));
504         $ENV{CROSS_COMPILE} = $configdata::config{cross_compile_prefix}
505             if defined($configdata::config{cross_compile_prefix});
506         $ENV{CROSS_COMPILE} = $configdata::config{cc}
507             if defined($configdata::config{cc});
508
509         print "Reconfiguring with: ", join(" ",@argvcopy), "\n";
510         print "    CROSS_COMPILE = ",$ENV{CROSS_COMPILE},"\n"
511             if $ENV{CROSS_COMPILE};
512         print "    CC = ",$ENV{CC},"\n" if $ENV{CC};
513     } elsif (open IN, "<Makefile") {
514         #
515         # THIS SECTION IS TEMPORARY, it helps transitioning from Makefile
516         # centered information gathering the reading configdata.pm
517         #
518         while (<IN>) {
519             s|\R$||;
520             if (/^CONFIGURE_ARGS=\s*(.*)\s*/) {
521                 # Older form, we split the string and hope for the best
522                 @argvcopy = split /\s+/, $_;
523                 die "Incorrect data to reconfigure, please do a normal configuration\n"
524                     if (grep(/^reconf/,@argvcopy));
525             } elsif (/^CROSS_COMPILE=\s*(.*)/) {
526                 $ENV{CROSS_COMPILE}=$1;
527             } elsif (/^CC=\s*(?:\$\(CROSS_COMPILE\))?(.*?)$/) {
528                 $ENV{CC}=$1;
529             }
530         }
531         #
532         # END OF TEMPORARY SECTION
533         #
534     } else {
535         die "Insufficient data to reconfigure, please do a normal configuration\n";
536     }
537 }
538
539 $config{perlargv} = [ @argvcopy ];
540
541 my %unsupported_options = ();
542 my %deprecated_options = ();
543 foreach (@argvcopy)
544         {
545         # VMS is a case insensitive environment, and depending on settings
546         # out of our control, we may receive options uppercased.  Let's
547         # downcase at least the part before any equal sign.
548         if ($^O eq "VMS")
549                 {
550                 s/^([^=]*)/lc($1)/e;
551                 }
552         s /^-no-/no-/; # some people just can't read the instructions
553
554         # rewrite some options in "enable-..." form
555         s /^-?-?shared$/enable-shared/;
556         s /^sctp$/enable-sctp/;
557         s /^threads$/enable-threads/;
558         s /^zlib$/enable-zlib/;
559         s /^zlib-dynamic$/enable-zlib-dynamic/;
560
561         if (/^(no|disable|enable)-(.+)$/)
562                 {
563                 my $word = $2;
564                 if (grep { $word =~ /^${_}$/ } @deprecated_disablables)
565                         {
566                         $deprecated_options{$_} = 1;
567                         next;
568                         }
569                 elsif (!grep { $word =~ /^${_}$/ } @disablables)
570                         {
571                         $unsupported_options{$_} = 1;
572                         next;
573                         }
574                 }
575         if (/^no-(.+)$/ || /^disable-(.+)$/)
576                 {
577                 foreach my $proto ((@tls, @dtls))
578                         {
579                         if ($1 eq "$proto-method")
580                                 {
581                                 $disabled{"$proto"} = "option($proto-method)";
582                                 last;
583                                 }
584                         }
585                 if ($1 eq "dtls")
586                         {
587                         foreach my $proto (@dtls)
588                                 {
589                                 $disabled{$proto} = "option(dtls)";
590                                 }
591                         $disabled{"dtls"} = "option(dtls)";
592                         }
593                 elsif ($1 eq "ssl")
594                         {
595                         # Last one of its kind
596                         $disabled{"ssl3"} = "option(ssl)";
597                         }
598                 elsif ($1 eq "tls")
599                         {
600                         # XXX: Tests will fail if all SSL/TLS
601                         # protocols are disabled.
602                         foreach my $proto (@tls)
603                                 {
604                                 $disabled{$proto} = "option(tls)";
605                                 }
606                         }
607                 elsif ($1 eq "static-engine")
608                         {
609                         delete $disabled{"dynamic-engine"};
610                         }
611                 elsif ($1 eq "dynamic-engine")
612                         {
613                         $disabled{"dynamic-engine"} = "option";
614                         }
615                 else
616                         {
617                         $disabled{$1} = "option";
618                         }
619                 # No longer an automatic choice
620                 $auto_threads = 0 if ($1 eq "threads");
621                 }
622         elsif (/^enable-(.+)$/)
623                 {
624                 if ($1 eq "static-engine")
625                         {
626                         $disabled{"dynamic-engine"} = "option";
627                         }
628                 elsif ($1 eq "dynamic-engine")
629                         {
630                         delete $disabled{"dynamic-engine"};
631                         }
632                 elsif ($1 eq "zlib-dynamic")
633                         {
634                         delete $disabled{"zlib"};
635                         }
636                 my $algo = $1;
637                 delete $disabled{$algo};
638
639                 # No longer an automatic choice
640                 $auto_threads = 0 if ($1 eq "threads");
641                 }
642         elsif (/^--strict-warnings$/)
643                 {
644                 $strict_warnings = 1;
645                 }
646         elsif (/^--debug$/)
647                 {
648                 $config{build_type} = "debug";
649                 }
650         elsif (/^--release$/)
651                 {
652                 $config{build_type} = "release";
653                 }
654         elsif (/^386$/)
655                 { $config{processor}=386; }
656         elsif (/^fips$/)
657                 {
658                 $config{fips}=1;
659                 }
660         elsif (/^rsaref$/)
661                 {
662                 # No RSAref support any more since it's not needed.
663                 # The check for the option is there so scripts aren't
664                 # broken
665                 }
666         elsif (/^nofipscanistercheck$/)
667                 {
668                 $config{fips} = 1;
669                 $nofipscanistercheck = 1;
670                 }
671         elsif (/^[-+]/)
672                 {
673                 if (/^--prefix=(.*)$/)
674                         {
675                         $config{prefix}=$1;
676                         die "Directory given with --prefix MUST be absolute\n"
677                                 unless file_name_is_absolute($config{prefix});
678                         }
679                 elsif (/^--api=(.*)$/)
680                         {
681                         $config{api}=$1;
682                         }
683                 elsif (/^--libdir=(.*)$/)
684                         {
685                         $config{libdir}=$1;
686                         }
687                 elsif (/^--openssldir=(.*)$/)
688                         {
689                         $config{openssldir}=$1;
690                         }
691                 elsif (/^--with-zlib-lib=(.*)$/)
692                         {
693                         $withargs{zlib_lib}=$1;
694                         }
695                 elsif (/^--with-zlib-include=(.*)$/)
696                         {
697                         $withargs{zlib_include}=$1;
698                         }
699                 elsif (/^--with-fipslibdir=(.*)$/)
700                         {
701                         $config{fipslibdir}="$1/";
702                         }
703                 elsif (/^--with-baseaddr=(.*)$/)
704                         {
705                         $config{baseaddr}="$1";
706                         }
707                 elsif (/^--cross-compile-prefix=(.*)$/)
708                         {
709                         $config{cross_compile_prefix}=$1;
710                         }
711                 elsif (/^--config=(.*)$/)
712                         {
713                         read_config $1;
714                         }
715                 elsif (/^-[lL](.*)$/ or /^-Wl,/)
716                         {
717                         $libs.=$_." ";
718                         }
719                 elsif (/^-D(.*)$/)
720                         {
721                         push @user_defines, $1;
722                         }
723                 else    # common if (/^[-+]/), just pass down...
724                         {
725                         $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
726                         $user_cflags.=" ".$_;
727                         }
728                 }
729         else
730                 {
731                 die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
732                 $target=$_;
733                 }
734         unless ($_ eq $target || /^no-/ || /^disable-/)
735                 {
736                 # "no-..." follows later after implied disactivations
737                 # have been derived.  (Don't take this too seriously,
738                 # we really only write OPTIONS to the Makefile out of
739                 # nostalgia.)
740
741                 if ($config{options} eq "")
742                         { $config{options} = $_; }
743                 else
744                         { $config{options} .= " ".$_; }
745                 }
746
747         if (defined($config{api}) && !exists $apitable->{$config{api}}) {
748                 die "***** Unsupported api compatibility level: $config{api}\n",
749         }
750
751         if (keys %deprecated_options)
752                 {
753                 warn "***** Deprecated options: ",
754                         join(", ", keys %deprecated_options), "\n";
755                 }
756         if (keys %unsupported_options)
757                 {
758                 die "***** Unsupported options: ",
759                         join(", ", keys %unsupported_options), "\n";
760                 }
761         }
762
763 if ($config{fips})
764         {
765         delete $disabled{"shared"} if ($disabled{"shared"} =~ /^default/);
766         }
767 else
768         {
769         @{$config{dirs}} = grep !/^fips$/, @{$config{dirs}};
770         }
771
772 my @tocheckfor = (keys %disabled);
773 while (@tocheckfor) {
774     my %new_tocheckfor = ();
775     my @cascade_copy = (@disable_cascades);
776     while (@cascade_copy) {
777         my ($test, $descendents) = (shift @cascade_copy, shift @cascade_copy);
778         if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
779             foreach(grep { !defined($disabled{$_}) } @$descendents) {
780                 $new_tocheckfor{$_} = 1; $disabled{$_} = "forced";
781             }
782         }
783     }
784     @tocheckfor = (keys %new_tocheckfor);
785 }
786
787 if ($target eq "TABLE") {
788     foreach (sort keys %table) {
789         print_table_entry($_, "TABLE");
790     }
791     exit 0;
792 }
793
794 if ($target eq "LIST") {
795     foreach (sort keys %table) {
796         print $_,"\n" unless $table{$_}->{template};
797     }
798     exit 0;
799 }
800
801 if ($target eq "HASH") {
802     print "%table = (\n";
803     foreach (sort keys %table) {
804         print_table_entry($_, "HASH");
805     }
806     exit 0;
807 }
808
809 # Backward compatibility?
810 if ($target =~ m/^CygWin32(-.*)$/) {
811     $target = "Cygwin".$1;
812 }
813
814 foreach (sort (keys %disabled))
815         {
816         $config{options} .= " no-$_";
817
818         printf "    no-%-12s %-10s", $_, "[$disabled{$_}]";
819
820         if (/^dso$/)
821                 { }
822         elsif (/^threads$/)
823                 { }
824         elsif (/^shared$/)
825                 { }
826         elsif (/^pic$/)
827                 { }
828         elsif (/^zlib$/)
829                 { }
830         elsif (/^dynamic-engine$/)
831                 { }
832         elsif (/^makedepend$/)
833                 { }
834         elsif (/^zlib-dynamic$/)
835                 { }
836         elsif (/^sse2$/)
837                 { $no_sse2 = 1; }
838         elsif (/^engine$/)
839                 {
840                 @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
841                 @{$config{sdirs}} = grep !/^engine$/, @{$config{sdirs}};
842                 push @{$config{openssl_other_defines}}, "OPENSSL_NO_ENGINE";
843                 }
844         else
845                 {
846                 my ($ALGO, $algo);
847                 ($ALGO = $algo = $_) =~ tr/[\-a-z]/[_A-Z]/;
848
849                 if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/ || /^async$/
850                                 || /^autoalginit/ || /^autoerrinit/)
851                         {
852                         push @{$config{openssl_other_defines}}, "OPENSSL_NO_$ALGO";
853                         print " OPENSSL_NO_$ALGO";
854
855                         if (/^err$/)    { push @user_defines, "OPENSSL_NO_ERR"; }
856                         }
857                 else
858                         {
859                         ($ALGO,$algo) = ("RMD160","rmd160") if ($algo eq "ripemd");
860
861                         push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$ALGO";
862                         print " OPENSSL_NO_$ALGO";
863
864                         # fix-up crypto/directory name(s)
865                         $algo="whrlpool" if $algo eq "whirlpool";
866                         $algo="ripemd" if $algo eq "rmd160";
867                         @{$config{sdirs}} = grep { $_ ne $algo} @{$config{sdirs}};
868
869                         print " (skip dir)";
870                         }
871                 }
872
873         print "\n";
874         }
875
876 print "Configuring for $target\n";
877
878 # Support for legacy targets having a name starting with 'debug-'
879 my ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
880 if ($d) {
881     $config{build_type} = "debug";
882
883     # If we do not find debug-foo in the table, the target is set to foo.
884     if (!$table{$target}) {
885         $target = $t;
886     }
887 }
888 $config{target} = $target;
889 my %target = resolve_config($target);
890
891 &usage if (!%target || $target{template});
892
893 %target = ( %{$table{DEFAULTS}}, %target );
894
895 $target{exe_extension}="";
896 $target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
897                                   || $config{target} =~ /^(?:Cygwin|mingw)/);
898 $target{exe_extension}=".pm"  if ($config{target} =~ /vos/);
899
900 ($target{shared_extension_simple}=$target{shared_extension})
901     =~ s|\.\$\(SHLIB_MAJOR\)\.\$\(SHLIB_MINOR\)||;
902 $target{dso_extension}=$target{shared_extension_simple};
903 ($target{shared_import_extension}=$target{shared_extension_simple}.".a")
904     if ($config{target} =~ /^(?:Cygwin|mingw)/);
905
906
907 $config{cross_compile_prefix} = $ENV{'CROSS_COMPILE'}
908     if $config{cross_compile_prefix} eq "";
909
910 # Allow overriding the names of some tools.  USE WITH CARE
911 $config{perl} =    $ENV{'PERL'}    || ($^O ne "VMS" ? $^X : "perl");
912 $target{cc} =      $ENV{'CC'}      || $target{cc}      || "cc";
913 $target{ranlib} =  $ENV{'RANLIB'}  || $target{ranlib}  ||
914                    (scalar can_run("$config{cross_compile_prefix}ranlib") ?
915                           "\$(CROSS_COMPILE)ranlib" : "true");
916 $target{ar} =      $ENV{'AR'}      || $target{ar}      || "ar";
917 $target{nm} =      $ENV{'NM'}      || $target{nm}      || "nm";
918 $target{rc} =
919     $ENV{'RC'}  || $ENV{'WINDRES'} || $target{rc}      || "windres";
920
921 # For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_
922 # or release_ attributes.
923 # Do it in such a way that no spurious space is appended (hence the grep).
924 $config{defines} = [];
925 $config{cflags} = "";
926 $config{ex_libs} = "";
927 $config{shared_ldflag} = "";
928
929 # Make sure build_scheme is consistent.
930 $target{build_scheme} = [ $target{build_scheme} ]
931     if ref($target{build_scheme}) ne "ARRAY";
932
933 my ($builder, $builder_platform, @builder_opts) =
934     @{$target{build_scheme}};
935
936 push @{$config{defines}}, "NDEBUG"    if $config{build_type} eq "release";
937
938 if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
939         {
940         $config{cflags} .= " -mno-cygwin";
941         $config{shared_ldflag} .= " -mno-cygwin";
942         }
943
944 if ($target =~ /linux.*-mips/ && !$disabled{asm} && $user_cflags !~ /-m(ips|arch=)/) {
945         # minimally required architecture flags for assembly modules
946         $config{cflags}="-mips2 $config{cflags}" if ($target =~ /mips32/);
947         $config{cflags}="-mips3 $config{cflags}" if ($target =~ /mips64/);
948 }
949
950 my $no_shared_warn=0;
951 my $no_user_cflags=0;
952 my $no_user_defines=0;
953
954 # The DSO code currently always implements all functions so that no
955 # applications will have to worry about that from a compilation point
956 # of view. However, the "method"s may return zero unless that platform
957 # has support compiled in for them. Currently each method is enabled
958 # by a define "DSO_<name>" ... we translate the "dso_scheme" config
959 # string entry into using the following logic;
960 if (!$disabled{dso} && $target{dso_scheme} ne "")
961         {
962         $target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
963         if ($target{dso_scheme} eq "DLFCN")
964                 {
965                 unshift @{$config{defines}}, "DSO_DLFCN", "HAVE_DLFCN_H";
966                 }
967         elsif ($target{dso_scheme} eq "DLFCN_NO_H")
968                 {
969                 unshift @{$config{defines}}, "DSO_DLFCN";
970                 }
971         else
972                 {
973                 unshift @{$config{defines}}, "DSO_$target{dso_scheme}";
974                 }
975         }
976
977 $config{ex_libs}="$libs$config{ex_libs}" if ($libs ne "");
978
979 if ($disabled{asm})
980         {
981         if ($config{fips})
982                 {
983                 @{$config{defines}} = grep !/^[BL]_ENDIAN$/, @{$config{defines}};
984                 @{$target{defines}} = grep !/^[BL]_ENDIAN$/, @{$target{defines}};
985                 }
986         }
987
988 # If threads aren't disabled, check how possible they are
989 unless ($disabled{threads}) {
990     if ($auto_threads) {
991         # Enabled by default, disable it forcibly if unavailable
992         if ($target{thread_scheme} eq "(unknown)") {
993             $disabled{threads} = "unavailable";
994         }
995     } else {
996         # The user chose to enable threads explicitly, let's see
997         # if there's a chance that's possible
998         if ($target{thread_scheme} eq "(unknown)") {
999             # If the user asked for "threads" and we don't have internal
1000             # knowledge how to do it, [s]he is expected to provide any
1001             # system-dependent compiler options that are necessary.  We
1002             # can't truly check that the given options are correct, but
1003             # we expect the user to know what [s]He is doing.
1004             if ($no_user_cflags && $no_user_defines) {
1005                 die "You asked for multi-threading support, but didn't\n"
1006                     ,"provide any system-specific compiler options\n";
1007             }
1008         }
1009     }
1010 }
1011
1012 # If threads still aren't disabled, add a C macro to ensure the source
1013 # code knows about it.  Any other flag is taken care of by the configs.
1014 unless($disabled{threads}) {
1015     foreach (("defines", "openssl_thread_defines")) {
1016         push @{$config{$_}}, "OPENSSL_THREADS";
1017     }
1018 }
1019
1020 # With "deprecated" disable all deprecated features.
1021 if (defined($disabled{"deprecated"})) {
1022         $config{api} = $maxapi;
1023 }
1024
1025 if ($target{shared_target} eq "")
1026         {
1027         $no_shared_warn = 1
1028             if ((!$disabled{shared} || !$disabled{"dynamic-engine"})
1029                 && !$config{fips});
1030         $disabled{shared} = "no-shared-target";
1031         $disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} =
1032             "no-shared-target";
1033         }
1034
1035 if ($disabled{"dynamic-engine"}) {
1036         push @{$config{defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1037         $config{dynamic_engines} = 0;
1038 } else {
1039         push @{$config{defines}}, "OPENSSL_NO_STATIC_ENGINE";
1040         $config{dynamic_engines} = 1;
1041 }
1042
1043 unless ($disabled{fuzz}) {
1044     push @{$config{dirs}}, "fuzz";
1045     $config{cflags} .= "-fsanitize-coverage=edge,indirect-calls ";
1046 }
1047
1048 unless ($disabled{asan}) {
1049     $config{cflags} .= "-fsanitize=address ";
1050 }
1051
1052 unless ($disabled{ubsan}) {
1053     # -DPEDANTIC or -fnosanitize=aligmnent may also be required on some
1054     # platforms.
1055     $config{cflags} .= "-fsanitize=undefined -fno-sanitize-recover=all ";
1056 }
1057
1058 unless ($disabled{fuzz} && $disabled{asan} && $disabled{ubsan}) {
1059     $config{cflags} .= "-fno-omit-frame-pointer -g ";
1060 }
1061 #
1062 # Platform fix-ups
1063 #
1064
1065 # This saves the build files from having to check
1066 if ($disabled{pic})
1067         {
1068         $target{shared_cflag} = $target{shared_ldflag} =
1069                 $target{shared_rcflag} = "";
1070         }
1071 else
1072         {
1073         push @{$config{defines}}, "OPENSSL_PIC";
1074         }
1075
1076 if ($target{sys_id} ne "")
1077         {
1078         push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
1079         }
1080
1081 unless ($disabled{asm}) {
1082     $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386");
1083     $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
1084
1085     # bn-586 is the only one implementing bn_*_part_words
1086     push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
1087     push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/);
1088
1089     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
1090     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
1091     push @{$config{defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
1092
1093     if ($config{fips}) {
1094         push @{$config{openssl_other_defines}}, "OPENSSL_FIPS";
1095     }
1096
1097     if ($target{sha1_asm_src}) {
1098         push @{$config{defines}}, "SHA1_ASM"   if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
1099         push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
1100         push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
1101     }
1102     if ($target{md5_asm_src}) {
1103         push @{$config{defines}}, "MD5_ASM";
1104     }
1105     $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC
1106     if ($target{rmd160_asm_src}) {
1107         push @{$config{defines}}, "RMD160_ASM";
1108     }
1109     if ($target{aes_asm_src}) {
1110         push @{$config{defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
1111         # aes-ctr.fake is not a real file, only indication that assembler
1112         # module implements AES_ctr32_encrypt...
1113         push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
1114         # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
1115         push @{$config{defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
1116         $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2);
1117         push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
1118         push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
1119     }
1120     if ($target{wp_asm_src} =~ /mmx/) {
1121         if ($config{processor} eq "386") {
1122             $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src};
1123         } elsif (!$disabled{"whirlpool"}) {
1124             push @{$config{defines}}, "WHIRLPOOL_ASM";
1125         }
1126     }
1127     if ($target{modes_asm_src} =~ /ghash-/) {
1128         push @{$config{defines}}, "GHASH_ASM";
1129     }
1130     if ($target{ec_asm_src} =~ /ecp_nistz256/) {
1131         push @{$config{defines}}, "ECP_NISTZ256_ASM";
1132     }
1133     if ($target{poly1305_asm_src} ne "") {
1134         push @{$config{defines}}, "POLY1305_ASM";
1135     }
1136 }
1137
1138 my $ecc = $target{cc};
1139 if ($^O ne "VMS" && !$disabled{makedepend}) {
1140     # Is the compiler gcc or clang?  $ecc is used below to see if
1141     # error-checking can be turned on.
1142     my $ccpcc = "$config{cross_compile_prefix}$target{cc}";
1143     open(PIPE, "$ccpcc --version 2>&1 |");
1144     my $lines = 2;
1145     while ( <PIPE> ) {
1146         # Find the version number and save the major.
1147         m|(?:.*)\b(\d+)\.\d+\.\d+\b(?:.*)|;
1148         my $compiler_major = $1;
1149         # We know that GNU C version 3 and up as well as all clang
1150         # versions support dependency generation
1151         $config{makedepprog} = $ccpcc
1152             if (/clang/ || (/gcc/ && $compiler_major > 3));
1153         $ecc = "clang" if /clang/;
1154         $ecc = "gcc" if /gcc/;
1155         last if ($config{makedepprog} || !$lines--);
1156     }
1157     close(PIPE);
1158
1159     $config{makedepprog} = scalar can_run('makedepend') unless $config{makedepprog};
1160     $disabled{makedepend} = "unavailable" unless $config{makedepprog};
1161 }
1162
1163
1164
1165 # Deal with bn_ops ###################################################
1166
1167 $config{bn_ll}                  =0;
1168 $config{export_var_as_fn}       =0;
1169 my $def_int="unsigned int";
1170 $config{rc4_int}                =$def_int;
1171 ($config{b64l},$config{b64},$config{b32})=(0,0,1);
1172
1173 my $count = 0;
1174 foreach (sort split(/\s+/,$target{bn_ops})) {
1175     $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1176     $config{export_var_as_fn}=1                 if $_ eq 'EXPORT_VAR_AS_FN';
1177     $config{bn_ll}=1                            if $_ eq 'BN_LLONG';
1178     $config{rc4_int}="unsigned char"            if $_ eq 'RC4_CHAR';
1179     ($config{b64l},$config{b64},$config{b32})
1180         =(0,1,0)                                if $_ eq 'SIXTY_FOUR_BIT';
1181     ($config{b64l},$config{b64},$config{b32})
1182         =(1,0,0)                                if $_ eq 'SIXTY_FOUR_BIT_LONG';
1183     ($config{b64l},$config{b64},$config{b32})
1184         =(0,0,1)                                if $_ eq 'THIRTY_TWO_BIT';
1185 }
1186 die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1187     if $count > 1;
1188
1189
1190 # Hack cflags for better warnings (dev option) #######################
1191
1192 # "Stringify" the C flags string.  This permits it to be made part of a string
1193 # and works as well on command lines.
1194 $config{cflags} =~ s/([\\\"])/\\$1/g;
1195
1196 if (defined($config{api})) {
1197     $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
1198     my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
1199     push @{$config{defines}}, $apiflag;
1200 }
1201
1202 if ($strict_warnings)
1203         {
1204         my $wopt;
1205         die "ERROR --strict-warnings requires gcc or clang"
1206             unless $ecc eq 'gcc' || $ecc eq 'clang';
1207         foreach $wopt (split /\s+/, $gcc_devteam_warn)
1208                 {
1209                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1210                 }
1211         if ($ecc eq "clang")
1212                 {
1213                 foreach $wopt (split /\s+/, $clang_devteam_warn)
1214                         {
1215                         $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1216                         }
1217                 }
1218         }
1219
1220 unless ($disabled{"crypto-mdebug-backtrace"})
1221         {
1222         foreach my $wopt (split /\s+/, $memleak_devteam_backtrace)
1223                 {
1224                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1225                 }
1226         if ($target =~ /^BSD-/)
1227                 {
1228                 $config{ex_libs} .= " -lexecinfo";
1229                 }
1230         }
1231
1232 if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; }
1233 else                    { $no_user_cflags=1;  }
1234 if (@user_defines) { $config{defines}=[ @{$config{defines}}, @user_defines ]; }
1235 else               { $no_user_defines=1;    }
1236
1237 # ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
1238
1239 unless ($disabled{afalgeng}) {
1240     $config{afalgeng}="";
1241     if ($target =~ m/^linux/) {
1242         my $minver = 4*10000 + 1*100 + 0;
1243         if ($config{cross_compile_prefix} eq "") {
1244             my $verstr = `uname -r`;
1245             my ($ma, $mi1, $mi2) = split("\\.", $verstr);
1246             ($mi2) = $mi2 =~ /(\d+)/;
1247             my $ver = $ma*10000 + $mi1*100 + $mi2;
1248             if ($ver < $minver) {
1249                 $disabled{afalgeng} = "too-old-kernel";
1250             } else {
1251                 push @{$config{engdirs}}, "afalg";
1252             }
1253         } else {
1254             $disabled{afalgeng} = "cross-compiling";
1255         }
1256     } else {
1257         $disabled{afalgeng}  = "not-linux";
1258     }
1259 }
1260
1261 push @{$config{openssl_other_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng});
1262
1263 # If we use the unified build, collect information from build.info files
1264 my %unified_info = ();
1265
1266 my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
1267 if ($builder eq "unified") {
1268     # Store the name of the template file we will build the build file from
1269     # in %config.  This may be useful for the build file itself.
1270     my $build_file_template;
1271
1272     for my $filename (( $builder_platform."-".$target{build_file}.".tmpl",
1273                         $target{build_file}.".tmpl" )) {
1274         if (defined $ENV{$local_config_envname}) {
1275             if ($^O eq 'VMS') {
1276                 # VMS environment variables are logical names,
1277                 # which can be used as is
1278                 $build_file_template = $local_config_envname . ':' . $filename;
1279             } else {
1280                 $build_file_template = catfile($ENV{$local_config_envname},
1281                                                $filename);
1282             }
1283         }
1284
1285         last if -f $build_file_template;
1286
1287         $build_file_template = catfile($srcdir, "Configurations", $filename);
1288
1289         last if -f $build_file_template;
1290     }
1291     $config{build_file_template} = $build_file_template;
1292
1293     use lib catdir(dirname(__FILE__),"util");
1294     use with_fallback qw(Text::Template);
1295
1296     sub cleandir {
1297         my $base = shift;
1298         my $dir = shift;
1299         my $relativeto = shift || ".";
1300
1301         $dir = catdir($base,$dir) unless isabsolute($dir);
1302
1303         # Make sure the directories we're building in exists
1304         mkpath($dir);
1305
1306         my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
1307         #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1308         return $res;
1309     }
1310
1311     sub cleanfile {
1312         my $base = shift;
1313         my $file = shift;
1314         my $relativeto = shift || ".";
1315
1316         $file = catfile($base,$file) unless isabsolute($file);
1317
1318         my $d = dirname($file);
1319         my $f = basename($file);
1320
1321         # Make sure the directories we're building in exists
1322         mkpath($d);
1323
1324         my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
1325         #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1326         return $res;
1327     }
1328
1329     my @build_infos = ( [ ".", "build.info" ] );
1330     foreach (@{$config{dirs}}) {
1331         push @build_infos, [ $_, "build.info" ]
1332             if (-f catfile($srcdir, $_, "build.info"));
1333     }
1334     foreach (@{$config{sdirs}}) {
1335         push @build_infos, [ catdir("crypto", $_), "build.info" ]
1336             if (-f catfile($srcdir, "crypto", $_, "build.info"));
1337     }
1338     foreach (@{$config{engdirs}}) {
1339         push @build_infos, [ catdir("engines", $_), "build.info" ]
1340             if (-f catfile($srcdir, "engines", $_, "build.info"));
1341     }
1342
1343     $config{build_infos} = [ ];
1344
1345     foreach (@build_infos) {
1346         my $sourced = catdir($srcdir, $_->[0]);
1347         my $buildd = catdir($blddir, $_->[0]);
1348
1349         mkpath($buildd);
1350
1351         my $f = $_->[1];
1352         # The basic things we're trying to build
1353         my @programs = ();
1354         my @libraries = ();
1355         my @engines = ();
1356         my @scripts = ();
1357         my @extra = ();
1358         my @overrides = ();
1359         my @intermediates = ();
1360         my @rawlines = ();
1361
1362         my %ordinals = ();
1363         my %sources = ();
1364         my %shared_sources = ();
1365         my %includes = ();
1366         my %depends = ();
1367         my %renames = ();
1368         my %sharednames = ();
1369         my %generate = ();
1370
1371         push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
1372         my $template = Text::Template->new(TYPE => 'FILE',
1373                                            SOURCE => catfile($sourced, $f));
1374         die "Something went wrong with $sourced/$f: $!\n" unless $template;
1375         my @text =
1376             split /^/m,
1377             $template->fill_in(HASH => { config => \%config,
1378                                          target => \%target,
1379                                          disabled => \%disabled,
1380                                          builddir => abs2rel($buildd, $blddir),
1381                                          sourcedir => abs2rel($sourced, $blddir),
1382                                          buildtop => abs2rel($blddir, $blddir),
1383                                          sourcetop => abs2rel($srcdir, $blddir) },
1384                                DELIMITERS => [ "{-", "-}" ]);
1385
1386         # The top item of this stack has the following values
1387         # -2 positive already run and we found ELSE (following ELSIF should fail)
1388         # -1 positive already run (skip until ENDIF)
1389         # 0 negatives so far (if we're at a condition, check it)
1390         # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1391         # 2 positive ELSE (following ELSIF should fail)
1392         my @skip = ();
1393         collect_information(
1394             collect_from_array([ @text ],
1395                                qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1396                                                 $l1 =~ s/\\$//; $l1.$l2 }),
1397             # Info we're looking for
1398             qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
1399             => sub {
1400                 if (! @skip || $skip[$#skip] > 0) {
1401                     push @skip, !! $1;
1402                 } else {
1403                     push @skip, -1;
1404                 }
1405             },
1406             qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1407             => sub { die "ELSIF out of scope" if ! @skip;
1408                      die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1409                      $skip[$#skip] = -1 if $skip[$#skip] != 0;
1410                      $skip[$#skip] = !! $1
1411                          if $skip[$#skip] == 0; },
1412             qr/^\s*ELSE\s*$/
1413             => sub { die "ELSE out of scope" if ! @skip;
1414                      $skip[$#skip] = -2 if $skip[$#skip] != 0;
1415                      $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1416             qr/^\s*ENDIF\s*$/
1417             => sub { die "ENDIF out of scope" if ! @skip;
1418                      pop @skip; },
1419             qr/^\s*PROGRAMS\s*=\s*(.*)\s*$/
1420             => sub { push @programs, split(/\s+/, $1)
1421                          if !@skip || $skip[$#skip] > 0 },
1422             qr/^\s*LIBS\s*=\s*(.*)\s*$/
1423             => sub { push @libraries, split(/\s+/, $1)
1424                          if !@skip || $skip[$#skip] > 0 },
1425             qr/^\s*ENGINES\s*=\s*(.*)\s*$/
1426             => sub { push @engines, split(/\s+/, $1)
1427                          if !@skip || $skip[$#skip] > 0 },
1428             qr/^\s*SCRIPTS\s*=\s*(.*)\s*$/
1429             => sub { push @scripts, split(/\s+/, $1)
1430                          if !@skip || $skip[$#skip] > 0 },
1431             qr/^\s*EXTRA\s*=\s*(.*)\s*$/
1432             => sub { push @extra, split(/\s+/, $1)
1433                          if !@skip || $skip[$#skip] > 0 },
1434             qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/
1435             => sub { push @overrides, split(/\s+/, $1)
1436                          if !@skip || $skip[$#skip] > 0 },
1437
1438             qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
1439             => sub { push @{$ordinals{$1}}, split(/\s+/, $2)
1440                          if !@skip || $skip[$#skip] > 0 },
1441             qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1442             => sub { push @{$sources{$1}}, split(/\s+/, $2)
1443                          if !@skip || $skip[$#skip] > 0 },
1444             qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1445             => sub { push @{$shared_sources{$1}}, split(/\s+/, $2)
1446                          if !@skip || $skip[$#skip] > 0 },
1447             qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1448             => sub { push @{$includes{$1}}, split(/\s+/, $2)
1449                          if !@skip || $skip[$#skip] > 0 },
1450             qr/^\s*DEPEND\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1451             => sub { push @{$depends{$1}}, split(/\s+/, $2)
1452                          if !@skip || $skip[$#skip] > 0 },
1453             qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1454             => sub { push @{$generate{$1}}, $2
1455                          if !@skip || $skip[$#skip] > 0 },
1456             qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1457             => sub { push @{$renames{$1}}, split(/\s+/, $2)
1458                          if !@skip || $skip[$#skip] > 0 },
1459             qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1460             => sub { push @{$sharednames{$1}}, split(/\s+/, $2)
1461                          if !@skip || $skip[$#skip] > 0 },
1462             qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1463             => sub {
1464                 my $lineiterator = shift;
1465                 my $target_kind = $1;
1466                 while (defined $lineiterator->()) {
1467                     s|\R$||;
1468                     if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1469                         die "ENDRAW doesn't match BEGINRAW"
1470                             if $1 ne $target_kind;
1471                         last;
1472                     }
1473                     next if @skip && $skip[$#skip] <= 0;
1474                     push @rawlines,  $_
1475                         if ($target_kind eq $target{build_file}
1476                             || $target_kind eq $target{build_file}."(".$builder_platform.")");
1477                 }
1478             },
1479             qr/^(?:#.*|\s*)$/ => sub { },
1480             "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
1481             "BEFORE" => sub {
1482                 if ($buildinfo_debug) {
1483                     print STDERR "DEBUG: Parsing ",join(" ", @_),"\n";
1484                     print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1485                 }
1486             },
1487             "AFTER" => sub {
1488                 if ($buildinfo_debug) {
1489                     print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1490                 }
1491             },
1492             );
1493         die "runaway IF?" if (@skip);
1494
1495         foreach (keys %renames) {
1496             die "$_ renamed to more than one thing: "
1497                 ,join(" ", @{$renames{$_}}),"\n"
1498                 if scalar @{$renames{$_}} > 1;
1499             my $dest = cleanfile($buildd, $_, $blddir);
1500             my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
1501             die "$dest renamed to more than one thing: "
1502                 ,$unified_info{rename}->{$dest}, $to
1503                 unless !defined($unified_info{rename}->{$dest})
1504                 or $unified_info{rename}->{$dest} eq $to;
1505             $unified_info{rename}->{$dest} = $to;
1506         }
1507
1508         foreach (@programs) {
1509             my $program = cleanfile($buildd, $_, $blddir);
1510             if ($unified_info{rename}->{$program}) {
1511                 $program = $unified_info{rename}->{$program};
1512             }
1513             $unified_info{programs}->{$program} = 1;
1514         }
1515
1516         foreach (@libraries) {
1517             my $library = cleanfile($buildd, $_, $blddir);
1518             if ($unified_info{rename}->{$library}) {
1519                 $library = $unified_info{rename}->{$library};
1520             }
1521             $unified_info{libraries}->{$library} = 1;
1522         }
1523
1524         die <<"EOF" if scalar @engines and !$config{dynamic_engines};
1525 ENGINES can only be used if configured with 'dynamic-engine'.
1526 This is usually a fault in a build.info file.
1527 EOF
1528         foreach (@engines) {
1529             my $library = cleanfile($buildd, $_, $blddir);
1530             if ($unified_info{rename}->{$library}) {
1531                 $library = $unified_info{rename}->{$library};
1532             }
1533             $unified_info{engines}->{$library} = 1;
1534         }
1535
1536         foreach (@scripts) {
1537             my $script = cleanfile($buildd, $_, $blddir);
1538             if ($unified_info{rename}->{$script}) {
1539                 $script = $unified_info{rename}->{$script};
1540             }
1541             $unified_info{scripts}->{$script} = 1;
1542         }
1543
1544         foreach (@extra) {
1545             my $extra = cleanfile($buildd, $_, $blddir);
1546             $unified_info{extra}->{$extra} = 1;
1547         }
1548
1549         foreach (@overrides) {
1550             my $override = cleanfile($buildd, $_, $blddir);
1551             $unified_info{overrides}->{$override} = 1;
1552         }
1553
1554         push @{$unified_info{rawlines}}, @rawlines;
1555
1556         unless ($disabled{shared}) {
1557             # Check sharednames.
1558             foreach (keys %sharednames) {
1559                 my $dest = cleanfile($buildd, $_, $blddir);
1560                 if ($unified_info{rename}->{$dest}) {
1561                     $dest = $unified_info{rename}->{$dest};
1562                 }
1563                 die "shared_name for $dest with multiple values: "
1564                     ,join(" ", @{$sharednames{$_}}),"\n"
1565                     if scalar @{$sharednames{$_}} > 1;
1566                 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
1567                 die "shared_name found for a library $dest that isn't defined\n"
1568                     unless $unified_info{libraries}->{$dest};
1569                 die "shared_name for $dest with multiple values: "
1570                     ,$unified_info{sharednames}->{$dest}, ", ", $to
1571                     unless !defined($unified_info{sharednames}->{$dest})
1572                     or $unified_info{sharednames}->{$dest} eq $to;
1573                 $unified_info{sharednames}->{$dest} = $to;
1574             }
1575
1576             # Additionally, we set up sharednames for libraries that don't
1577             # have any, as themselves.
1578             foreach (keys %{$unified_info{libraries}}) {
1579                 if (!defined $unified_info{sharednames}->{$_}) {
1580                     $unified_info{sharednames}->{$_} = $_
1581                 }
1582             }
1583         }
1584
1585         foreach (keys %ordinals) {
1586             my $dest = $_;
1587             my $ddest = cleanfile($buildd, $_, $blddir);
1588             if ($unified_info{rename}->{$ddest}) {
1589                 $ddest = $unified_info{rename}->{$ddest};
1590             }
1591             foreach (@{$ordinals{$dest}}) {
1592                 my %known_ordinals =
1593                     (
1594                      crypto =>
1595                      cleanfile($sourced, catfile("util", "libcrypto.num"), $blddir),
1596                      ssl =>
1597                      cleanfile($sourced, catfile("util", "libssl.num"), $blddir)
1598                     );
1599                 my $o = $known_ordinals{$_};
1600                 die "Ordinals for $ddest defined more than once\n"
1601                     if $unified_info{ordinals}->{$ddest};
1602                 $unified_info{ordinals}->{$ddest} = [ $_, $o ];
1603             }
1604         }
1605
1606         foreach (keys %sources) {
1607             my $dest = $_;
1608             my $ddest = cleanfile($buildd, $_, $blddir);
1609             if ($unified_info{rename}->{$ddest}) {
1610                 $ddest = $unified_info{rename}->{$ddest};
1611             }
1612             foreach (@{$sources{$dest}}) {
1613                 my $s = cleanfile($sourced, $_, $blddir);
1614
1615                 # If it isn't in the source tree, we assume it's generated
1616                 # in the build tree
1617                 if (! -f $s) {
1618                     $s = cleanfile($buildd, $_, $blddir);
1619                 }
1620                 # We recognise C and asm files
1621                 if ($s =~ /\.[csS]\b$/) {
1622                     (my $o = $_) =~ s/\.[csS]\b$/.o/;
1623                     $o = cleanfile($buildd, $o, $blddir);
1624                     $unified_info{sources}->{$ddest}->{$o} = 1;
1625                     $unified_info{sources}->{$o}->{$s} = 1;
1626                 } else {
1627                     $unified_info{sources}->{$ddest}->{$s} = 1;
1628                 }
1629             }
1630         }
1631
1632         foreach (keys %shared_sources) {
1633             my $dest = $_;
1634             my $ddest = cleanfile($buildd, $_, $blddir);
1635             if ($unified_info{rename}->{$ddest}) {
1636                 $ddest = $unified_info{rename}->{$ddest};
1637             }
1638             foreach (@{$shared_sources{$dest}}) {
1639                 my $s = cleanfile($sourced, $_, $blddir);
1640
1641                 # If it isn't in the source tree, we assume it's generated
1642                 # in the build tree
1643                 if (! -f $s) {
1644                     $s = cleanfile($buildd, $_, $blddir);
1645                 }
1646                 # We recognise C and asm files
1647                 if ($s =~ /\.[csS]\b$/) {
1648                     (my $o = $_) =~ s/\.[csS]\b$/.o/;
1649                     $o = cleanfile($buildd, $o, $blddir);
1650                     $unified_info{shared_sources}->{$ddest}->{$o} = 1;
1651                     $unified_info{sources}->{$o}->{$s} = 1;
1652                 } else {
1653                     die "unrecognised source file type for shared library: $s\n";
1654                 }
1655             }
1656         }
1657
1658         foreach (keys %generate) {
1659             my $dest = $_;
1660             my $ddest = cleanfile($buildd, $_, $blddir);
1661             if ($unified_info{rename}->{$ddest}) {
1662                 $ddest = $unified_info{rename}->{$ddest};
1663             }
1664             die "more than one generator for $dest: "
1665                     ,join(" ", @{$generate{$_}}),"\n"
1666                     if scalar @{$generate{$_}} > 1;
1667             my @generator = split /\s+/, $generate{$dest}->[0];
1668             $generator[0] = cleanfile($sourced, $generator[0], $blddir),
1669             $unified_info{generate}->{$ddest} = [ @generator ];
1670         }
1671
1672         foreach (keys %depends) {
1673             my $dest = $_;
1674             my $ddest = cleanfile($sourced, $_, $blddir);
1675
1676             # If the destination doesn't exist in source, it can only be
1677             # a generated file in the build tree.
1678             if (! -f $ddest) {
1679                 $ddest = cleanfile($buildd, $_, $blddir);
1680                 if ($unified_info{rename}->{$ddest}) {
1681                     $ddest = $unified_info{rename}->{$ddest};
1682                 }
1683             }
1684             foreach (@{$depends{$dest}}) {
1685                 my $d = cleanfile($sourced, $_, $blddir);
1686
1687                 # If we know it's generated, or assume it is because we can't
1688                 # find it in the source tree, we set file we depend on to be
1689                 # in the build tree rather than the source tree, and assume
1690                 # and that there are lines to build it in a BEGINRAW..ENDRAW
1691                 # section or in the Makefile template.
1692                 if (! -f $d
1693                     || (grep { $d eq $_ }
1694                         map { cleanfile($srcdir, $_, $blddir) }
1695                         (@generated_headers, @generated_by_make_headers))) {
1696                     $d = cleanfile($buildd, $_, $blddir);
1697                 }
1698                 # Take note if the file to depend on is being renamed
1699                 if ($unified_info{rename}->{$d}) {
1700                     $d = $unified_info{rename}->{$d};
1701                 }
1702                 $unified_info{depends}->{$ddest}->{$d} = 1;
1703                 # If we depend on a header file or a perl module, let's make
1704                 # sure it can get included
1705                 if ($d =~ /\.(h|pm)$/) {
1706                     my $i = dirname($d);
1707                     push @{$unified_info{includes}->{$ddest}}, $i
1708                         unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
1709                 }
1710             }
1711         }
1712
1713         foreach (keys %includes) {
1714             my $dest = $_;
1715             my $ddest = cleanfile($sourced, $_, $blddir);
1716
1717             # If the destination doesn't exist in source, it can only be
1718             # a generated file in the build tree.
1719             if (! -f $ddest) {
1720                 $ddest = cleanfile($buildd, $_, $blddir);
1721                 if ($unified_info{rename}->{$ddest}) {
1722                     $ddest = $unified_info{rename}->{$ddest};
1723                 }
1724             }
1725             foreach (@{$includes{$dest}}) {
1726                 my $i = cleandir($sourced, $_, $blddir);
1727                 push @{$unified_info{includes}->{$ddest}}, $i
1728                     unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
1729             }
1730         }
1731     }
1732
1733     ### Make unified_info a bit more efficient
1734     # One level structures
1735     foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
1736         $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
1737     }
1738     # Two level structures
1739     foreach my $l1 (("sources", "shared_sources", "ldadd", "depends")) {
1740         foreach my $l2 (sort keys %{$unified_info{$l1}}) {
1741             $unified_info{$l1}->{$l2} =
1742                 [ sort keys %{$unified_info{$l1}->{$l2}} ];
1743         }
1744     }
1745 }
1746
1747 # For the schemes that need it, we provide the old *_obj configs
1748 # from the *_asm_obj ones
1749 foreach (grep /_(asm|aux)_src$/, keys %target) {
1750     my $src = $_;
1751     (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
1752     ($target{$obj} = $target{$src}) =~ s/\.[csS]\b/.o/g;
1753 }
1754
1755 # Write down our configuration where it fits #########################
1756
1757 open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
1758 print OUT <<"EOF";
1759 package configdata;
1760
1761 use strict;
1762 use warnings;
1763
1764 use Exporter;
1765 #use vars qw(\@ISA \@EXPORT);
1766 our \@ISA = qw(Exporter);
1767 our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables);
1768
1769 EOF
1770 print OUT "our %config = (\n";
1771 foreach (sort keys %config) {
1772     if (ref($config{$_}) eq "ARRAY") {
1773         print OUT "  ", $_, " => [ ", join(", ",
1774                                            map { quotify("perl", $_) }
1775                                            @{$config{$_}}), " ],\n";
1776     } else {
1777         print OUT "  ", $_, " => ", quotify("perl", $config{$_}), ",\n"
1778     }
1779 }
1780 print OUT <<"EOF";
1781 );
1782
1783 EOF
1784 print OUT "our %target = (\n";
1785 foreach (sort keys %target) {
1786     if (ref($target{$_}) eq "ARRAY") {
1787         print OUT "  ", $_, " => [ ", join(", ",
1788                                            map { quotify("perl", $_) }
1789                                            @{$target{$_}}), " ],\n";
1790     } else {
1791         print OUT "  ", $_, " => ", quotify("perl", $target{$_}), ",\n"
1792     }
1793 }
1794 print OUT <<"EOF";
1795 );
1796
1797 EOF
1798 print OUT "our \%available_protocols = (\n";
1799 print OUT "  tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
1800 print OUT "  dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
1801 print OUT <<"EOF";
1802 );
1803
1804 EOF
1805 print OUT "our \@disablables = (\n";
1806 foreach (@disablables) {
1807     print OUT "  ", quotify("perl", $_), ",\n";
1808 }
1809 print OUT <<"EOF";
1810 );
1811
1812 EOF
1813 print OUT "our \%disabled = (\n";
1814 foreach (sort keys %disabled) {
1815     print OUT "  ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
1816 }
1817 print OUT <<"EOF";
1818 );
1819
1820 EOF
1821 print OUT "our %withargs = (\n";
1822 foreach (sort keys %withargs) {
1823     if (ref($withargs{$_}) eq "ARRAY") {
1824         print OUT "  ", $_, " => [ ", join(", ",
1825                                            map { quotify("perl", $_) }
1826                                            @{$withargs{$_}}), " ],\n";
1827     } else {
1828         print OUT "  ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
1829     }
1830 }
1831 print OUT <<"EOF";
1832 );
1833
1834 EOF
1835 if ($builder eq "unified") {
1836     my $recurse;
1837     $recurse = sub {
1838         my $indent = shift;
1839         foreach (@_) {
1840             if (ref $_ eq "ARRAY") {
1841                 print OUT " "x$indent, "[\n";
1842                 foreach (@$_) {
1843                     $recurse->($indent + 4, $_);
1844                 }
1845                 print OUT " "x$indent, "],\n";
1846             } elsif (ref $_ eq "HASH") {
1847                 my %h = %$_;
1848                 print OUT " "x$indent, "{\n";
1849                 foreach (sort keys %h) {
1850                     if (ref $h{$_} eq "") {
1851                         print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
1852                     } else {
1853                         print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
1854                         $recurse->($indent + 8, $h{$_});
1855                     }
1856                 }
1857                 print OUT " "x$indent, "},\n";
1858             } else {
1859                 print OUT " "x$indent, quotify("perl", $_), ",\n";
1860             }
1861         }
1862     };
1863     print OUT "our %unified_info = (\n";
1864     foreach (sort keys %unified_info) {
1865         if (ref $unified_info{$_} eq "") {
1866             print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
1867         } else {
1868             print OUT " "x4, quotify("perl", $_), " =>\n";
1869             $recurse->(8, $unified_info{$_});
1870         }
1871     }
1872     print OUT <<"EOF";
1873 );
1874
1875 EOF
1876 }
1877 print OUT "1;\n";
1878 close(OUT);
1879
1880
1881 print "CC            =$config{cross_compile_prefix}$target{cc}\n";
1882 print "CFLAG         =$target{cflags} $config{cflags}\n";
1883 print "SHARED_CFLAG  =$target{shared_cflag}\n";
1884 print "DEFINES       =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n";
1885 print "LFLAG         =$target{lflags}\n";
1886 print "PLIB_LFLAG    =$target{plib_lflags}\n";
1887 print "EX_LIBS       =$target{ex_libs} $config{ex_libs}\n";
1888 print "APPS_OBJ      =$target{apps_obj}\n";
1889 print "CPUID_OBJ     =$target{cpuid_obj}\n";
1890 print "UPLINK_OBJ    =$target{uplink_obj}\n";
1891 print "BN_ASM        =$target{bn_obj}\n";
1892 print "EC_ASM        =$target{ec_obj}\n";
1893 print "DES_ENC       =$target{des_obj}\n";
1894 print "AES_ENC       =$target{aes_obj}\n";
1895 print "BF_ENC        =$target{bf_obj}\n";
1896 print "CAST_ENC      =$target{cast_obj}\n";
1897 print "RC4_ENC       =$target{rc4_obj}\n";
1898 print "RC5_ENC       =$target{rc5_obj}\n";
1899 print "MD5_OBJ_ASM   =$target{md5_obj}\n";
1900 print "SHA1_OBJ_ASM  =$target{sha1_obj}\n";
1901 print "RMD160_OBJ_ASM=$target{rmd160_obj}\n";
1902 print "CMLL_ENC      =$target{cmll_obj}\n";
1903 print "MODES_OBJ     =$target{modes_obj}\n";
1904 print "PADLOCK_OBJ   =$target{padlock_obj}\n";
1905 print "CHACHA_ENC    =$target{chacha_obj}\n";
1906 print "POLY1305_OBJ  =$target{poly1305_obj}\n";
1907 print "BLAKE2_OBJ    =$target{blake2_obj}\n";
1908 print "PROCESSOR     =$config{processor}\n";
1909 print "RANLIB        =", $target{ranlib} eq '$(CROSS_COMPILE)ranlib' ?
1910                              "$config{cross_compile_prefix}ranlib" :
1911                              "$target{ranlib}", "\n";
1912 print "ARFLAGS       =$target{arflags}\n";
1913 print "PERL          =$config{perl}\n";
1914 print "\n";
1915 print "SIXTY_FOUR_BIT_LONG mode\n" if $config{b64l};
1916 print "SIXTY_FOUR_BIT mode\n" if $config{b64};
1917 print "THIRTY_TWO_BIT mode\n" if $config{b32};
1918 print "BN_LLONG mode\n" if $config{bn_ll};
1919 print "RC4 uses $config{rc4_int}\n" if $config{rc4_int} ne $def_int;
1920
1921 for (@generated_headers) {
1922     mkpath(catdir($blddir, dirname($_)));
1923     run_dofile(catfile($blddir, $_),
1924                catfile($srcdir, $_.".in"));
1925 }
1926
1927 ###
1928 ### When the old "unixmake" scheme goes away, so does this function
1929 ###
1930 sub build_Makefile {
1931     run_dofile("Makefile","Makefile.in");
1932
1933     # Copy all Makefile.in to Makefile (except top-level)
1934     use File::Find;
1935     use IO::File;
1936     find(
1937         {
1938             preprocess => sub {
1939                 grep(!/^\./, @_);
1940             },
1941             wanted => sub {
1942                 return if ($_ ne "Makefile.in" || $File::Find::dir eq ".");
1943                 my $in = IO::File->new($_, "r") or
1944                     die sprintf "Error reading Makefile.in in %s: !$\n",
1945                     $File::Find::dir;
1946                 my $out = IO::File->new("Makefile", "w") or
1947                     die sprintf "Error writing Makefile in %s: !$\n",
1948                     $File::Find::dir;
1949                 print $out "# Generated from $_, do not edit\n";
1950                 while (my $line = <$in>) { print $out $line }
1951                 $in->close() or
1952                     die sprintf "Error reading Makefile.in in %s: !$\n",
1953                     $File::Find::dir;
1954                 $out->close() or
1955                     die sprintf "Error writing Makefile in %s: !$\n",
1956                     $File::Find::dir;
1957             },
1958         },
1959         ".");
1960 }
1961
1962 my %builders = (
1963     unified => sub {
1964         run_dofile(catfile($blddir, $target{build_file}),
1965                    $config{build_file_template},
1966                    catfile($srcdir, "Configurations", "common.tmpl"));
1967     },
1968     unixmake => sub {
1969         build_Makefile();
1970
1971         run_dofile("util/domd", "util/domd.in");
1972         chmod 0755, "util/domd";
1973     },
1974     );
1975
1976 $builders{$builder}->($builder_platform, @builder_opts);
1977
1978 print <<"EOF";
1979
1980 Configured for $target.
1981 EOF
1982
1983 print <<"EOF" if ($disabled{threads} eq "unavailable");
1984
1985 The library could not be configured for supporting multi-threaded
1986 applications as the compiler options required on this system are not known.
1987 See file INSTALL for details if you need multi-threading.
1988 EOF
1989
1990 print <<"EOF" if ($no_shared_warn);
1991
1992 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
1993 platform, so we will pretend you gave the option 'no-pic', which also disables
1994 'shared' and 'dynamic-engine'.  If you know how to implement shared libraries
1995 or position independent code, please let us know (but please first make sure
1996 you have tried with a current version of OpenSSL).
1997 EOF
1998
1999 print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
2000
2001 WARNING: there are indications that another build was made in the source
2002 directory.  This build may have picked up artifacts from that build, the
2003 safest course of action is to clean the source directory and redo this
2004 configuration.
2005 EOF
2006
2007 exit(0);
2008
2009 ######################################################################
2010 #
2011 # Helpers and utility functions
2012 #
2013
2014 # Configuration file reading #########################################
2015
2016 # Note: All of the helper functions are for lazy evaluation.  They all
2017 # return a CODE ref, which will return the intended value when evaluated.
2018 # Thus, whenever there's mention of a returned value, it's about that
2019 # intended value.
2020
2021 # Helper function to implement conditional inheritance depending on the
2022 # value of $disabled{asm}.  Used in inherit_from values as follows:
2023 #
2024 #      inherit_from => [ "template", asm("asm_tmpl") ]
2025 #
2026 sub asm {
2027     my @x = @_;
2028     sub {
2029         $disabled{asm} ? () : @x;
2030     }
2031 }
2032
2033 # Helper function to implement conditional value variants, with a default
2034 # plus additional values based on the value of $config{build_type}.
2035 # Arguments are given in hash table form:
2036 #
2037 #       picker(default => "Basic string: ",
2038 #              debug   => "debug",
2039 #              release => "release")
2040 #
2041 # When configuring with --debug, the resulting string will be
2042 # "Basic string: debug", and when not, it will be "Basic string: release"
2043 #
2044 # This can be used to create variants of sets of flags according to the
2045 # build type:
2046 #
2047 #       cflags => picker(default => "-Wall",
2048 #                        debug   => "-g -O0",
2049 #                        release => "-O3")
2050 #
2051 sub picker {
2052     my %opts = @_;
2053     return sub { add($opts{default} || (),
2054                      $opts{$config{build_type}} || ())->(); }
2055 }
2056
2057 # Helper function to combine several values of different types into one.
2058 # This is useful if you want to combine a string with the result of a
2059 # lazy function, such as:
2060 #
2061 #       cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2062 #
2063 sub combine {
2064     my @stuff = @_;
2065     return sub { add(@stuff)->(); }
2066 }
2067
2068 # Helper function to implement conditional values depending on the value
2069 # of $disabled{threads}.  Can be used as follows:
2070 #
2071 #       cflags => combine("-Wall", threads("-pthread"))
2072 #
2073 sub threads {
2074     my @flags = @_;
2075     return sub { add($disabled{threads} ? () : @flags)->(); }
2076 }
2077
2078
2079
2080 our $add_called = 0;
2081 # Helper function to implement adding values to already existing configuration
2082 # values.  It handles elements that are ARRAYs, CODEs and scalars
2083 sub _add {
2084     my $separator = shift;
2085
2086     # If there's any ARRAY in the collection of values OR the separator
2087     # is undef, we will return an ARRAY of combined values, otherwise a
2088     # string of joined values with $separator as the separator.
2089     my $found_array = !defined($separator);
2090
2091     my @values =
2092         map {
2093             my $res = $_;
2094             while (ref($res) eq "CODE") {
2095                 $res = $res->();
2096             }
2097             if (defined($res)) {
2098                 if (ref($res) eq "ARRAY") {
2099                     $found_array = 1;
2100                     @$res;
2101                 } else {
2102                     $res;
2103                 }
2104             } else {
2105                 ();
2106             }
2107     } (@_);
2108
2109     $add_called = 1;
2110
2111     if ($found_array) {
2112         [ @values ];
2113     } else {
2114         join($separator, grep { defined($_) && $_ ne "" } @values);
2115     }
2116 }
2117 sub add_before {
2118     my $separator = " ";
2119     if (ref($_[$#_]) eq "HASH") {
2120         my $opts = pop;
2121         $separator = $opts->{separator};
2122     }
2123     my @x = @_;
2124     sub { _add($separator, @x, @_) };
2125 }
2126 sub add {
2127     my $separator = " ";
2128     if (ref($_[$#_]) eq "HASH") {
2129         my $opts = pop;
2130         $separator = $opts->{separator};
2131     }
2132     my @x = @_;
2133     sub { _add($separator, @_, @x) };
2134 }
2135
2136 # configuration reader, evaluates the input file as a perl script and expects
2137 # it to fill %targets with target configurations.  Those are then added to
2138 # %table.
2139 sub read_config {
2140     my $fname = shift;
2141     open(CONFFILE, "< $fname")
2142         or die "Can't open configuration file '$fname'!\n";
2143     my $x = $/;
2144     undef $/;
2145     my $content = <CONFFILE>;
2146     $/ = $x;
2147     close(CONFFILE);
2148     my %targets = ();
2149     {
2150         local %table = %::table;    # Protect %table from tampering
2151
2152         eval $content;
2153         warn $@ if $@;
2154     }
2155
2156     # For each target, check that it's configured with a hash table.
2157     foreach (keys %targets) {
2158         if (ref($targets{$_}) ne "HASH") {
2159             if (ref($targets{$_}) eq "") {
2160                 warn "Deprecated target configuration for $_, ignoring...\n";
2161             } else {
2162                 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
2163             }
2164             delete $targets{$_};
2165         }
2166     }
2167
2168     %table = (%table, %targets);
2169
2170 }
2171
2172 # configuration resolver.  Will only resolve all the lazy evaluation
2173 # codeblocks for the chosen target and all those it inherits from,
2174 # recursively
2175 sub resolve_config {
2176     my $target = shift;
2177     my @breadcrumbs = @_;
2178
2179 #    my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
2180
2181     if (grep { $_ eq $target } @breadcrumbs) {
2182         die "inherit_from loop!  target backtrace:\n  "
2183             ,$target,"\n  ",join("\n  ", @breadcrumbs),"\n";
2184     }
2185
2186     if (!defined($table{$target})) {
2187         warn "Warning! target $target doesn't exist!\n";
2188         return ();
2189     }
2190     # Recurse through all inheritances.  They will be resolved on the
2191     # fly, so when this operation is done, they will all just be a
2192     # bunch of attributes with string values.
2193     # What we get here, though, are keys with references to lists of
2194     # the combined values of them all.  We will deal with lists after
2195     # this stage is done.
2196     my %combined_inheritance = ();
2197     if ($table{$target}->{inherit_from}) {
2198         my @inherit_from =
2199             map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2200         foreach (@inherit_from) {
2201             my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2202
2203             # 'template' is a marker that's considered private to
2204             # the config that had it.
2205             delete $inherited_config{template};
2206
2207             foreach (keys %inherited_config) {
2208                 if (!$combined_inheritance{$_}) {
2209                     $combined_inheritance{$_} = [];
2210                 }
2211                 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2212             }
2213         }
2214     }
2215
2216     # We won't need inherit_from in this target any more, since we've
2217     # resolved all the inheritances that lead to this
2218     delete $table{$target}->{inherit_from};
2219
2220     # Now is the time to deal with those lists.  Here's the place to
2221     # decide what shall be done with those lists, all based on the
2222     # values of the target we're currently dealing with.
2223     # - If a value is a coderef, it will be executed with the list of
2224     #   inherited values as arguments.
2225     # - If the corresponding key doesn't have a value at all or is the
2226     #   empty string, the inherited value list will be run through the
2227     #   default combiner (below), and the result becomes this target's
2228     #   value.
2229     # - Otherwise, this target's value is assumed to be a string that
2230     #   will simply override the inherited list of values.
2231     my $default_combiner = add();
2232
2233     my %all_keys =
2234         map { $_ => 1 } (keys %combined_inheritance,
2235                          keys %{$table{$target}});
2236
2237     sub process_values {
2238         my $object    = shift;
2239         my $inherited = shift;  # Always a [ list ]
2240         my $target    = shift;
2241         my $entry     = shift;
2242
2243         $add_called = 0;
2244
2245         while(ref($object) eq "CODE") {
2246             $object = $object->(@$inherited);
2247         }
2248         if (!defined($object)) {
2249             return ();
2250         }
2251         elsif (ref($object) eq "ARRAY") {
2252             local $add_called;  # To make sure recursive calls don't affect it
2253             return [ map { process_values($_, $inherited, $target, $entry) }
2254                      @$object ];
2255         } elsif (ref($object) eq "") {
2256             return $object;
2257         } else {
2258             die "cannot handle reference type ",ref($object)
2259                 ," found in target ",$target," -> ",$entry,"\n";
2260         }
2261     }
2262
2263     foreach (sort keys %all_keys) {
2264         my $previous = $combined_inheritance{$_};
2265
2266         # Current target doesn't have a value for the current key?
2267         # Assign it the default combiner, the rest of this loop body
2268         # will handle it just like any other coderef.
2269         if (!exists $table{$target}->{$_}) {
2270             $table{$target}->{$_} = $default_combiner;
2271         }
2272
2273         $table{$target}->{$_} = process_values($table{$target}->{$_},
2274                                                $combined_inheritance{$_},
2275                                                $target, $_);
2276         unless(defined($table{$target}->{$_})) {
2277             delete $table{$target}->{$_};
2278         }
2279 #        if ($extra_checks &&
2280 #            $previous && !($add_called ||  $previous ~~ $table{$target}->{$_})) {
2281 #            warn "$_ got replaced in $target\n";
2282 #        }
2283     }
2284
2285     # Finally done, return the result.
2286     return %{$table{$target}};
2287 }
2288
2289 sub usage
2290         {
2291         print STDERR $usage;
2292         print STDERR "\npick os/compiler from:\n";
2293         my $j=0;
2294         my $i;
2295         my $k=0;
2296         foreach $i (sort keys %table)
2297                 {
2298                 next if $table{$i}->{template};
2299                 next if $i =~ /^debug/;
2300                 $k += length($i) + 1;
2301                 if ($k > 78)
2302                         {
2303                         print STDERR "\n";
2304                         $k=length($i);
2305                         }
2306                 print STDERR $i . " ";
2307                 }
2308         foreach $i (sort keys %table)
2309                 {
2310                 next if $table{$i}->{template};
2311                 next if $i !~ /^debug/;
2312                 $k += length($i) + 1;
2313                 if ($k > 78)
2314                         {
2315                         print STDERR "\n";
2316                         $k=length($i);
2317                         }
2318                 print STDERR $i . " ";
2319                 }
2320         print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
2321         exit(1);
2322         }
2323
2324 sub run_dofile
2325 {
2326     my $out = shift;
2327     my @templates = @_;
2328
2329     unlink $out || warn "Can't remove $out, $!"
2330         if -f $out;
2331     foreach (@templates) {
2332         die "Can't open $_, $!" unless -f $_;
2333     }
2334     my $cmd = "$config{perl} \"-I.\" \"-Mconfigdata\" $dofile -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2335     #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2336     system($cmd);
2337     exit 1 if $? != 0;
2338     rename("$out.new", $out) || die "Can't rename $out.new, $!";
2339 }
2340
2341 # Configuration printer ##############################################
2342
2343 sub print_table_entry
2344 {
2345     my $target = shift;
2346     my %target = resolve_config($target);
2347     my $type = shift;
2348
2349     # Don't print the templates
2350     return if $target{template};
2351
2352     my @sequence = (
2353         "sys_id",
2354         "cc",
2355         "cflags",
2356         "defines",
2357         "unistd",
2358         "ld",
2359         "lflags",
2360         "plib_lflags",
2361         "ex_libs",
2362         "bn_ops",
2363         "cpuid_obj",
2364         "bn_obj",
2365         "ec_obj",
2366         "des_obj",
2367         "aes_obj",
2368         "bf_obj",
2369         "md5_obj",
2370         "sha1_obj",
2371         "cast_obj",
2372         "rc4_obj",
2373         "rmd160_obj",
2374         "rc5_obj",
2375         "wp_obj",
2376         "cmll_obj",
2377         "modes_obj",
2378         "padlock_obj",
2379         "thread_scheme",
2380         "perlasm_scheme",
2381         "dso_scheme",
2382         "shared_target",
2383         "shared_cflag",
2384         "shared_ldflag",
2385         "shared_rcflag",
2386         "shared_extension",
2387         "shared_extension_simple",
2388         "shared_import_extension",
2389         "dso_extension",
2390         "obj_extension",
2391         "exe_extension",
2392         "ranlib",
2393         "ar",
2394         "arflags",
2395         "multilib",
2396         "build_scheme",
2397         );
2398
2399     if ($type eq "TABLE") {
2400         print "\n";
2401         print "*** $target\n";
2402         foreach (@sequence) {
2403             if (ref($target{$_}) eq "ARRAY") {
2404                 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
2405             } else {
2406                 printf "\$%-12s = %s\n", $_, $target{$_};
2407             }
2408         }
2409     } elsif ($type eq "HASH") {
2410         my $largest =
2411             length((sort { length($a) <=> length($b) } @sequence)[-1]);
2412         print "    '$target' => {\n";
2413         foreach (@sequence) {
2414             if ($target{$_}) {
2415                 if (ref($target{$_}) eq "ARRAY") {
2416                     print "      '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
2417                 } else {
2418                     print "      '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2419                 }
2420             }
2421         }
2422         print "    },\n";
2423     }
2424 }
2425
2426 # Utility routines ###################################################
2427
2428 # On VMS, if the given file is a logical name, File::Spec::Functions
2429 # will consider it an absolute path.  There are cases when we want a
2430 # purely syntactic check without checking the environment.
2431 sub isabsolute {
2432     my $file = shift;
2433
2434     # On non-platforms, we just use file_name_is_absolute().
2435     return file_name_is_absolute($file) unless $^O eq "VMS";
2436
2437     # If the file spec includes a device or a directpry spec,
2438     # file_name_is_absolute() is perfectly safe.
2439     return file_name_is_absolute($file) if $file =~ m|[:\[]|;
2440
2441     # Here, we know the given file spec isn't absolute
2442     return 0;
2443 }
2444
2445 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
2446 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
2447 # realpath() requires that at least all path components except the last is an
2448 # existing directory.  On VMS, the last component of the directory spec must
2449 # exist.
2450 sub absolutedir {
2451     my $dir = shift;
2452
2453     # realpath() is quite buggy on VMS.  It uses LIB$FID_TO_NAME, which
2454     # will return the volume name for the device, no matter what.  Also,
2455     # it will return an incorrect directory spec if the argument is a
2456     # directory that doesn't exist.
2457     if ($^O eq "VMS") {
2458         return rel2abs($dir);
2459     }
2460
2461     # We use realpath() on Unix, since no other will properly clean out
2462     # a directory spec.
2463     use Cwd qw/realpath/;
2464
2465     return realpath($dir);
2466 }
2467
2468 sub quotify {
2469     my %processors = (
2470         perl    => sub { my $x = shift;
2471                          $x =~ s/([\\\$\@"])/\\$1/g;
2472                          return '"'.$x.'"'; },
2473         );
2474     my $for = shift;
2475     my $processor =
2476         defined($processors{$for}) ? $processors{$for} : sub { shift; };
2477
2478     return map { $processor->($_); } @_;
2479 }
2480
2481 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
2482 # $filename is a file name to read from
2483 # $line_concat_cond_re is a regexp detecting a line continuation ending
2484 # $line_concat is a CODEref that takes care of concatenating two lines
2485 sub collect_from_file {
2486     my $filename = shift;
2487     my $line_concat_cond_re = shift;
2488     my $line_concat = shift;
2489
2490     open my $fh, $filename || die "unable to read $filename: $!\n";
2491     return sub {
2492         my $saved_line = "";
2493         $_ = "";
2494         while (<$fh>) {
2495             s|\R$||;
2496             if (defined $line_concat) {
2497                 $_ = $line_concat->($saved_line, $_);
2498                 $saved_line = "";
2499             }
2500             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2501                 $saved_line = $_;
2502                 next;
2503             }
2504             return $_;
2505         }
2506         die "$filename ending with continuation line\n" if $_;
2507         close $fh;
2508         return undef;
2509     }
2510 }
2511
2512 # collect_from_array($array, $line_concat_cond_re, $line_concat)
2513 # $array is an ARRAYref of lines
2514 # $line_concat_cond_re is a regexp detecting a line continuation ending
2515 # $line_concat is a CODEref that takes care of concatenating two lines
2516 sub collect_from_array {
2517     my $array = shift;
2518     my $line_concat_cond_re = shift;
2519     my $line_concat = shift;
2520     my @array = (@$array);
2521
2522     return sub {
2523         my $saved_line = "";
2524         $_ = "";
2525         while (defined($_ = shift @array)) {
2526             s|\R$||;
2527             if (defined $line_concat) {
2528                 $_ = $line_concat->($saved_line, $_);
2529                 $saved_line = "";
2530             }
2531             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2532                 $saved_line = $_;
2533                 next;
2534             }
2535             return $_;
2536         }
2537         die "input text ending with continuation line\n" if $_;
2538         return undef;
2539     }
2540 }
2541
2542 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
2543 # $lineiterator is a CODEref that delivers one line at a time.
2544 # All following arguments are regex/CODEref pairs, where the regexp detects a
2545 # line and the CODEref does something with the result of the regexp.
2546 sub collect_information {
2547     my $lineiterator = shift;
2548     my %collectors = @_;
2549
2550     while(defined($_ = $lineiterator->())) {
2551         s|\R$||;
2552         my $found = 0;
2553         if ($collectors{"BEFORE"}) {
2554             $collectors{"BEFORE"}->($_);
2555         }
2556         foreach my $re (keys %collectors) {
2557             if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
2558                 $collectors{$re}->($lineiterator);
2559                 $found = 1;
2560             };
2561         }
2562         if ($collectors{"OTHERWISE"}) {
2563             $collectors{"OTHERWISE"}->($lineiterator, $_)
2564                 unless $found || !defined $collectors{"OTHERWISE"};
2565         }
2566         if ($collectors{"AFTER"}) {
2567             $collectors{"AFTER"}->($_);
2568         }
2569     }
2570 }