-open(IN,'<crypto/opensslconf.h.in') || die "unable to read crypto/opensslconf.h.in:$!\n";
-unlink("include/openssl/opensslconf.h.new") || die "unable to remove old include/openssl/opensslconf.h.new:$!\n" if -e "include/openssl/opensslconf.h.new";
-open(OUT,'>include/openssl/opensslconf.h.new') || die "unable to create include/openssl/opensslconf.h.new:$!\n";
-print OUT "/* opensslconf.h */\n";
-print OUT "/* WARNING: Generated automatically from opensslconf.h.in by Configure. */\n\n";
-
-print OUT "#ifdef __cplusplus\n";
-print OUT "extern \"C\" {\n";
-print OUT "#endif\n";
-print OUT "/* OpenSSL was configured with the following options: */\n";
-my $openssl_algorithm_defines_trans = $openssl_algorithm_defines;
-$openssl_experimental_defines =~ s/^\s*#\s*define\s+OPENSSL_NO_(.*)/#ifndef OPENSSL_EXPERIMENTAL_$1\n# ifndef OPENSSL_NO_$1\n# define OPENSSL_NO_$1\n# endif\n#endif/mg;
-$openssl_algorithm_defines_trans =~ s/^\s*#\s*define\s+OPENSSL_(.*)/# if defined(OPENSSL_$1) \&\& !defined($1)\n# define $1\n# endif/mg;
-$openssl_algorithm_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
-$openssl_algorithm_defines = " /* no ciphers excluded */\n" if $openssl_algorithm_defines eq "";
-$openssl_thread_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
-$openssl_sys_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
-$openssl_other_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
-print OUT $openssl_sys_defines;
-print OUT "#ifndef OPENSSL_DOING_MAKEDEPEND\n\n";
-print OUT $openssl_experimental_defines;
-print OUT "\n";
-print OUT $openssl_algorithm_defines;
-print OUT "\n#endif /* OPENSSL_DOING_MAKEDEPEND */\n\n";
-print OUT $openssl_thread_defines;
-print OUT $openssl_other_defines,"\n";
-
-print OUT "/* The OPENSSL_NO_* macros are also defined as NO_* if the application\n";
-print OUT " asks for it. This is a transient feature that is provided for those\n";
-print OUT " who haven't had the time to do the appropriate changes in their\n";
-print OUT " applications. */\n";
-print OUT "#ifdef OPENSSL_ALGORITHM_DEFINES\n";
-print OUT $openssl_algorithm_defines_trans;
-print OUT "#endif\n\n";
-
-print OUT "#define OPENSSL_CPUID_OBJ\n\n" if ($cpuid_obj ne "mem_clr.o");
-
-while (<IN>)
- {
- if (/^#define\s+OPENSSLDIR/)
- {
- my $foo = $openssldir;
- $foo =~ s/\\/\\\\/g;
- print OUT "#define OPENSSLDIR \"$foo\"\n";
- }
- elsif (/^#define\s+ENGINESDIR/)
- {
- my $foo = "$prefix/$libdir/engines";
- $foo =~ s/\\/\\\\/g;
- print OUT "#define ENGINESDIR \"$foo\"\n";
- }
- elsif (/^#((define)|(undef))\s+OPENSSL_EXPORT_VAR_AS_FUNCTION/)
- { printf OUT "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION\n"
- if $export_var_as_fn;
- printf OUT "#%s OPENSSL_EXPORT_VAR_AS_FUNCTION\n",
- ($export_var_as_fn)?"define":"undef"; }
- elsif (/^#define\s+OPENSSL_UNISTD/)
- {
- $unistd = "<unistd.h>" if $unistd eq "";
- print OUT "#define OPENSSL_UNISTD $unistd\n";
- }
- elsif (/^#((define)|(undef))\s+SIXTY_FOUR_BIT_LONG/)
- { printf OUT "#%s SIXTY_FOUR_BIT_LONG\n",($b64l)?"define":"undef"; }
- elsif (/^#((define)|(undef))\s+SIXTY_FOUR_BIT/)
- { printf OUT "#%s SIXTY_FOUR_BIT\n",($b64)?"define":"undef"; }
- elsif (/^#((define)|(undef))\s+THIRTY_TWO_BIT/)
- { printf OUT "#%s THIRTY_TWO_BIT\n",($b32)?"define":"undef"; }
- elsif (/^#((define)|(undef))\s+SIXTEEN_BIT/)
- { printf OUT "#%s SIXTEEN_BIT\n",($b16)?"define":"undef"; }
- elsif (/^#((define)|(undef))\s+EIGHT_BIT/)
- { printf OUT "#%s EIGHT_BIT\n",($b8)?"define":"undef"; }
- elsif (/^#((define)|(undef))\s+BN_LLONG\s*$/)
- { printf OUT "#%s BN_LLONG\n",($bn_ll)?"define":"undef"; }
- elsif (/^\#define\s+DES_LONG\s+.*/)
- { printf OUT "#define DES_LONG unsigned %s\n",
- ($des_int)?'int':'long'; }
- elsif (/^\#(define|undef)\s+DES_PTR/)
- { printf OUT "#%s DES_PTR\n",($des_ptr)?'define':'undef'; }
- elsif (/^\#(define|undef)\s+DES_RISC1/)
- { printf OUT "#%s DES_RISC1\n",($des_risc1)?'define':'undef'; }
- elsif (/^\#(define|undef)\s+DES_RISC2/)
- { printf OUT "#%s DES_RISC2\n",($des_risc2)?'define':'undef'; }
- elsif (/^\#(define|undef)\s+DES_UNROLL/)
- { printf OUT "#%s DES_UNROLL\n",($des_unroll)?'define':'undef'; }
- elsif (/^#define\s+RC4_INT\s/)
- { printf OUT "#define RC4_INT unsigned %s\n",$type[$rc4_int]; }
- elsif (/^#undef\s+RC4_CHUNK/)
- {
- printf OUT "#undef RC4_CHUNK\n" if $rc4_chunk==0;
- printf OUT "#define RC4_CHUNK unsigned long\n" if $rc4_chunk==1;
- printf OUT "#define RC4_CHUNK unsigned long long\n" if $rc4_chunk==2;
- }
- elsif (/^#((define)|(undef))\s+RC4_INDEX/)
- { printf OUT "#%s RC4_INDEX\n",($rc4_idx)?"define":"undef"; }
- elsif (/^#(define|undef)\s+I386_ONLY/)
- { printf OUT "#%s I386_ONLY\n", ($processor eq "386")?
- "define":"undef"; }
- elsif (/^#define\s+MD2_INT\s/)
- { printf OUT "#define MD2_INT unsigned %s\n",$type[$md2_int]; }
- elsif (/^#define\s+IDEA_INT\s/)
- {printf OUT "#define IDEA_INT unsigned %s\n",$type[$idea_int];}
- elsif (/^#define\s+RC2_INT\s/)
- {printf OUT "#define RC2_INT unsigned %s\n",$type[$rc2_int];}
- elsif (/^#(define|undef)\s+BF_PTR/)
- {
- printf OUT "#undef BF_PTR\n" if $bf_ptr == 0;
- printf OUT "#define BF_PTR\n" if $bf_ptr == 1;
- printf OUT "#define BF_PTR2\n" if $bf_ptr == 2;
- }
- else
- { print OUT $_; }
- }
-close(IN);
-print OUT "#ifdef __cplusplus\n";
-print OUT "}\n";
-print OUT "#endif\n";
+ # Make sure the directories we're building in exists
+ mkpath($d);
+
+ my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($base));
+ #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
+ return $res;
+ }
+
+ my @build_infos = ( [ ".", "build.info" ] );
+ foreach (@{$config{dirs}}) {
+ push @build_infos, [ $_, "build.info" ]
+ if (-f catfile($srcdir, $_, "build.info"));
+ }
+ foreach (@{$config{sdirs}}) {
+ push @build_infos, [ catdir("crypto", $_), "build.info" ]
+ if (-f catfile($srcdir, "crypto", $_, "build.info"));
+ }
+ foreach (@{$config{engdirs}}) {
+ push @build_infos, [ catdir("engines", $_), "build.info" ]
+ if (-f catfile($srcdir, "engines", $_, "build.info"));
+ }
+
+ foreach (@build_infos) {
+ my $sourced = catdir($srcdir, $_->[0]);
+ my $buildd = catdir($blddir, $_->[0]);
+
+ mkpath($buildd);
+
+ my $f = $_->[1];
+ # The basic things we're trying to build
+ my @programs = ();
+ my @libraries = ();
+ my @engines = ();
+ my @scripts = ();
+ my @extra = ();
+ my @intermediates = ();
+ my @rawlines = ();
+
+ my %ordinals = ();
+ my %sources = ();
+ my %includes = ();
+ my %depends = ();
+ my %renames = ();
+ my %sharednames = ();
+
+ my $template = Text::Template->new(TYPE => 'FILE',
+ SOURCE => catfile($sourced, $f));
+ die "Something went wrong with $sourced/$f: $!\n" unless $template;
+ my @text =
+ split /^/m,
+ $template->fill_in(HASH => { config => \%config,
+ target => \%target,
+ builddir => abs2rel($buildd, $blddir),
+ sourcedir => abs2rel($sourced, $blddir),
+ buildtop => abs2rel($blddir, $blddir),
+ sourcetop => abs2rel($srcdir, $blddir) },
+ DELIMITERS => [ "{-", "-}" ]);
+
+ # The top item of this stack has the following values
+ # -2 positive already run and we found ELSE (following ELSIF should fail)
+ # -1 positive already run (skip until ENDIF)
+ # 0 negatives so far (if we're at a condition, check it)
+ # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
+ # 2 positive ELSE (following ELSIF should fail)
+ my @skip = ();
+ collect_information(
+ collect_from_array([ @text ],
+ qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
+ $l1 =~ s/\\$//; $l1.$l2 }),
+ # Info we're looking for
+ qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
+ => sub { push @skip, !! $1; },
+ qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
+ => sub { die "ELSIF out of scope" if ! @skip;
+ die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
+ $skip[$#skip] = -1 if $skip[$#skip] != 0;
+ $skip[$#skip] = !! $1
+ if $skip[$#skip] == 0; },
+ qr/^\s*ELSE\s*$/
+ => sub { die "ELSE out of scope" if ! @skip;
+ $skip[$#skip] = -2 if $skip[$#skip] != 0;
+ $skip[$#skip] = 2 if $skip[$#skip] == 0; },
+ qr/^\s*ENDIF\s*$/
+ => sub { die "ENDIF out of scope" if ! @skip;
+ pop @skip; },
+ qr/^\s*PROGRAMS\s*=\s*(.*)\s*$/
+ => sub { push @programs, split(/\s+/, $1)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*LIBS\s*=\s*(.*)\s*$/
+ => sub { push @libraries, split(/\s+/, $1)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*ENGINES\s*=\s*(.*)\s*$/
+ => sub { push @engines, split(/\s+/, $1)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*SCRIPTS\s*=\s*(.*)\s*$/
+ => sub { push @scripts, split(/\s+/, $1)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*EXTRA\s*=\s*(.*)\s*$/
+ => sub { push @extra, split(/\s+/, $1)
+ if !@skip || $skip[$#skip] > 0 },
+
+ qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
+ => sub { push @{$ordinals{$1}}, split(/\s+/, $2)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
+ => sub { push @{$sources{$1}}, split(/\s+/, $2)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
+ => sub { push @{$includes{$1}}, split(/\s+/, $2)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*DEPEND\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
+ => sub { push @{$depends{$1}}, split(/\s+/, $2)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
+ => sub { push @{$renames{$1}}, split(/\s+/, $2)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
+ => sub { push @{$sharednames{$1}}, split(/\s+/, $2)
+ if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
+ => sub {
+ my $lineiterator = shift;
+ my $target_kind = $1;
+ while (defined $lineiterator->()) {
+ chomp;
+ if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
+ die "ENDRAW doesn't match BEGINRAW"
+ if $1 ne $target_kind;
+ last;
+ }
+ next if @skip && $skip[$#skip] <= 0;
+ push @rawlines, $_
+ if ($target_kind eq $target{build_file}
+ || $target_kind eq $target{build_file}."(".$builder_platform.")");
+ }
+ },
+ qr/^(?:#.*|\s*)$/ => sub { },
+ "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" }
+ );
+ die "runaway IF?" if (@skip);
+
+ foreach (keys %renames) {
+ die "$_ renamed to more than one thing: "
+ ,join(" ", @{$renames{$_}}),"\n"
+ if scalar @{$renames{$_}} > 1;
+ my $dest = cleanfile(catfile($buildd, $_), $blddir);
+ my $to = cleanfile(catfile($buildd, $renames{$_}->[0]), $blddir);
+ die "$dest renamed to more than one thing: "
+ ,$unified_info{rename}->{$dest}, $to
+ unless !defined($unified_info{rename}->{$dest})
+ or $unified_info{rename}->{$dest} eq $to;
+ $unified_info{rename}->{$dest} = $to;
+ }
+
+ foreach (@programs) {
+ my $program = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$program}) {
+ $program = $unified_info{rename}->{$program};
+ }
+ $unified_info{programs}->{$program} = 1;
+ }
+
+ foreach (@libraries) {
+ my $library = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$library}) {
+ $library = $unified_info{rename}->{$library};
+ }
+ $unified_info{libraries}->{$library} = 1;
+ }
+
+ die <<"EOF" if $config{no_shared} && scalar @engines;
+ENGINES can only be used if configured with 'shared'.
+This is usually a fault in a build.info file.
+EOF
+ foreach (@engines) {
+ my $library = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$library}) {
+ $library = $unified_info{rename}->{$library};
+ }
+ $unified_info{engines}->{$library} = 1;
+ }
+
+ foreach (@scripts) {
+ my $script = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$script}) {
+ $script = $unified_info{rename}->{$script};
+ }
+ $unified_info{scripts}->{$script} = 1;
+ }
+
+ foreach (@extra) {
+ my $extra = cleanfile(catfile($buildd, $_), $blddir);
+ $unified_info{extra}->{$extra} = 1;
+ }
+
+ push @{$unified_info{rawlines}}, @rawlines;
+
+ if (!$config{no_shared}) {
+ # Check sharednames.
+ foreach (keys %sharednames) {
+ my $dest = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$dest}) {
+ $dest = $unified_info{rename}->{$dest};
+ }
+ die "shared_name for $dest with multiple values: "
+ ,join(" ", @{$sharednames{$_}}),"\n"
+ if scalar @{$sharednames{$_}} > 1;
+ my $to = cleanfile(catfile($buildd, $sharednames{$_}->[0]),
+ $blddir);
+ die "shared_name found for a library $dest that isn't defined\n"
+ unless $unified_info{libraries}->{$dest};
+ die "shared_name for $dest with multiple values: "
+ ,$unified_info{sharednames}->{$dest}, ", ", $to
+ unless !defined($unified_info{sharednames}->{$dest})
+ or $unified_info{sharednames}->{$dest} eq $to;
+ $unified_info{sharednames}->{$dest} = $to;
+ }
+
+ # Additionally, we set up sharednames for libraries that don't
+ # have any, as themselves.
+ foreach (keys %{$unified_info{libraries}}) {
+ if (!defined $unified_info{sharednames}->{$_}) {
+ $unified_info{sharednames}->{$_} = $_
+ }
+ }
+ }
+
+ foreach (keys %ordinals) {
+ my $dest = $_;
+ my $ddest = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$ddest}) {
+ $ddest = $unified_info{rename}->{$ddest};
+ }
+ foreach (@{$ordinals{$dest}}) {
+ my %known_ordinals =
+ (
+ crypto =>
+ cleanfile(catfile($sourced, "util", "libeay.num"), $blddir),
+ ssl =>
+ cleanfile(catfile($sourced, "util", "ssleay.num"), $blddir)
+ );
+ my $o = $known_ordinals{$_};
+ die "Ordinals for $ddest defined more than once\n"
+ if $unified_info{ordinals}->{$ddest};
+ $unified_info{ordinals}->{$ddest} = [ $_, $o ];
+ }
+ }
+
+ foreach (keys %sources) {
+ my $dest = $_;
+ my $ddest = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$ddest}) {
+ $ddest = $unified_info{rename}->{$ddest};
+ }
+ foreach (@{$sources{$dest}}) {
+ my $s = cleanfile(catfile($sourced, $_), $blddir);
+
+ # If it isn't in the source tree, we assume it's generated
+ # in the build tree
+ if (! -f $s) {
+ $s = cleanfile(catfile($buildd, $_), $blddir);
+ }
+ # We recognise C and asm files
+ if ($s =~ /\.[csS]\b$/) {
+ (my $o = $_) =~ s/\.[csS]\b$/.o/;
+ $o = cleanfile(catfile($buildd, $o), $blddir);
+ $unified_info{sources}->{$ddest}->{$o} = 1;
+ $unified_info{sources}->{$o}->{$s} = 1;
+ } else {
+ $unified_info{sources}->{$ddest}->{$s} = 1;
+ }
+ }
+ }
+
+ foreach (keys %depends) {
+ my $dest = $_;
+ my $ddest = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$ddest}) {
+ $ddest = $unified_info{rename}->{$ddest};
+ }
+ foreach (@{$depends{$dest}}) {
+ my $d = cleanfile(catfile($sourced, $_), $blddir);
+
+ # If it isn't found in the source, let's assume it's generated
+ # and that the Makefile template has the lines
+ if (! -f $d) {
+ $d = cleanfile(catfile($buildd, $_), $blddir);
+ }
+ # Take note if the file to depend on is being renamed
+ if ($unified_info{rename}->{$d}) {
+ $d = $unified_info{rename}->{$d};
+ }
+ $unified_info{depends}->{$ddest}->{$d} = 1;
+ # If we depend on a header file, let's make sure it
+ # can get included
+ if ($d =~ /\.h$/) {
+ my $i = dirname($d);
+ push @{$unified_info{includes}->{$ddest}}, $i
+ unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
+ }
+ }
+ }
+
+ foreach (keys %includes) {
+ my $dest = $_;
+ my $ddest = cleanfile(catfile($buildd, $_), $blddir);
+ if ($unified_info{rename}->{$ddest}) {
+ $ddest = $unified_info{rename}->{$ddest};
+ }
+ foreach (@{$includes{$dest}}) {
+ my $i = cleandir(catdir($sourced, $_), $blddir);
+ push @{$unified_info{includes}->{$ddest}}, $i
+ unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
+ }
+ }
+ }
+
+ ### Make unified_info a bit more efficient
+ # One level structures
+ foreach (("programs", "libraries", "engines", "scripts", "extra")) {
+ $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
+ }
+ # Two level structures
+ foreach my $l1 (("sources", "ldadd", "depends")) {
+ foreach my $l2 (sort keys %{$unified_info{$l1}}) {
+ $unified_info{$l1}->{$l2} =
+ [ sort keys %{$unified_info{$l1}->{$l2}} ];
+ }
+ }
+}
+
+# For the schemes that need it, we provide the old *_obj configs
+# from the *_asm_obj ones
+foreach (grep /_asm_src$/, keys %target) {
+ my $src = $_;
+ (my $obj = $_) =~ s/_asm_src$/_obj/;
+ ($target{$obj} = $target{$src}) =~ s/\.[csS]\b/.o/g;
+}
+
+# Write down our configuration where it fits #########################
+
+open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
+print OUT <<"EOF";
+package configdata;
+
+use strict;
+use warnings;
+
+use Exporter;
+#use vars qw(\@ISA \@EXPORT);
+our \@ISA = qw(Exporter);
+our \@EXPORT = qw(\%config \%target %withargs %unified_info);
+
+EOF
+print OUT "our %config = (\n";
+foreach (sort keys %config) {
+ if (ref($config{$_}) eq "ARRAY") {
+ print OUT " ", $_, " => [ ", join(", ",
+ map { quotify("perl", $_) }
+ @{$config{$_}}), " ],\n";
+ } else {
+ print OUT " ", $_, " => ", quotify("perl", $config{$_}), ",\n"
+ }
+}
+print OUT <<"EOF";
+);
+
+EOF
+print OUT "our %target = (\n";
+foreach (sort keys %target) {
+ if (ref($target{$_}) eq "ARRAY") {
+ print OUT " ", $_, " => [ ", join(", ",
+ map { quotify("perl", $_) }
+ @{$target{$_}}), " ],\n";
+ } else {
+ print OUT " ", $_, " => ", quotify("perl", $target{$_}), ",\n"
+ }
+}
+print OUT <<"EOF";
+);
+
+EOF
+print OUT "our \%available_protocols = (\n";
+print OUT " tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
+print OUT " dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
+print OUT <<"EOF";
+);
+
+EOF
+print OUT "our \%disabled = (\n";
+foreach (sort keys %disabled) {
+ print OUT " ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
+}
+print OUT <<"EOF";
+);
+
+EOF
+print OUT "our %withargs = (\n";
+foreach (sort keys %withargs) {
+ if (ref($withargs{$_}) eq "ARRAY") {
+ print OUT " ", $_, " => [ ", join(", ",
+ map { quotify("perl", $_) }
+ @{$withargs{$_}}), " ],\n";
+ } else {
+ print OUT " ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
+ }
+}
+print OUT <<"EOF";
+);
+
+EOF
+if ($builder eq "unified") {
+ my $recurse;
+ $recurse = sub {
+ my $indent = shift;
+ foreach (@_) {
+ if (ref $_ eq "ARRAY") {
+ print OUT " "x$indent, "[\n";
+ foreach (@$_) {
+ $recurse->($indent + 4, $_);
+ }
+ print OUT " "x$indent, "],\n";
+ } elsif (ref $_ eq "HASH") {
+ my %h = %$_;
+ print OUT " "x$indent, "{\n";
+ foreach (sort keys %h) {
+ if (ref $h{$_} eq "") {
+ print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
+ } else {
+ print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
+ $recurse->($indent + 8, $h{$_});
+ }
+ }
+ print OUT " "x$indent, "},\n";
+ } else {
+ print OUT " "x$indent, quotify("perl", $_), ",\n";
+ }
+ }
+ };
+ print OUT "our %unified_info = (\n";
+ foreach (sort keys %unified_info) {
+ if (ref $unified_info{$_} eq "") {
+ print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
+ } else {
+ print OUT " "x4, quotify("perl", $_), " =>\n";
+ $recurse->(8, $unified_info{$_});
+ }
+ }
+ print OUT <<"EOF";
+);
+
+EOF
+}
+print OUT "1;\n";