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