Configure - Allow CODErefs and ARRAYrefs in configuration setting arrays
This provides for more powerful lazy evaluation and buildup of the setting contents. For example, something like this becomes possible: defines => [ sub { $config{thisorthat} ? "FOO" : () } ] Any undefined result of such functions (such as 'undef' or the empty list) will be ignored. Reviewed-by: Andy Polyakov <appro@openssl.org>
This commit is contained in:
parent
ed49f43a03
commit
b0b92a5bb5
1 changed files with 43 additions and 19 deletions
62
Configure
62
Configure
|
@ -1949,18 +1949,26 @@ sub _add {
|
||||||
|
|
||||||
my @values =
|
my @values =
|
||||||
map {
|
map {
|
||||||
if (ref($_) eq "ARRAY") {
|
my $res = $_;
|
||||||
$found_array = 1;
|
while (ref($res) eq "CODE") {
|
||||||
@$_;
|
$res = $res->();
|
||||||
|
}
|
||||||
|
if (defined($res)) {
|
||||||
|
if (ref($res) eq "ARRAY") {
|
||||||
|
$found_array = 1;
|
||||||
|
@$res;
|
||||||
|
} else {
|
||||||
|
$res;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$_;
|
();
|
||||||
}
|
}
|
||||||
} (@_);
|
} (@_);
|
||||||
|
|
||||||
if ($found_array) {
|
if ($found_array) {
|
||||||
[ @values ];
|
[ @values ];
|
||||||
} else {
|
} else {
|
||||||
join($separator, @values);
|
join($separator, grep { defined($_) && $_ ne "" } @values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sub add_before {
|
sub add_before {
|
||||||
|
@ -2080,6 +2088,30 @@ sub resolve_config {
|
||||||
my %all_keys =
|
my %all_keys =
|
||||||
map { $_ => 1 } (keys %combined_inheritance,
|
map { $_ => 1 } (keys %combined_inheritance,
|
||||||
keys %{$table{$target}});
|
keys %{$table{$target}});
|
||||||
|
|
||||||
|
sub process_values {
|
||||||
|
my $object = shift;
|
||||||
|
my $inherited = shift; # Always a [ list ]
|
||||||
|
my $target = shift;
|
||||||
|
my $entry = shift;
|
||||||
|
|
||||||
|
while(ref($object) eq "CODE") {
|
||||||
|
$object = $object->(@$inherited);
|
||||||
|
}
|
||||||
|
if (!defined($object)) {
|
||||||
|
return ();
|
||||||
|
}
|
||||||
|
elsif (ref($object) eq "ARRAY") {
|
||||||
|
return [ map { process_values($_, $inherited, $target, $entry) }
|
||||||
|
@$object ];
|
||||||
|
} elsif (ref($object) eq "") {
|
||||||
|
return $object;
|
||||||
|
} else {
|
||||||
|
die "cannot handle reference type ",ref($object)
|
||||||
|
," found in target ",$target," -> ",$entry,"\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (sort keys %all_keys) {
|
foreach (sort keys %all_keys) {
|
||||||
|
|
||||||
# Current target doesn't have a value for the current key?
|
# Current target doesn't have a value for the current key?
|
||||||
|
@ -2089,20 +2121,12 @@ sub resolve_config {
|
||||||
$table{$target}->{$_} = $default_combiner;
|
$table{$target}->{$_} = $default_combiner;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $valuetype = ref($table{$target}->{$_});
|
$table{$target}->{$_} = process_values($table{$target}->{$_},
|
||||||
if ($valuetype eq "CODE") {
|
$combined_inheritance{$_},
|
||||||
# CODE reference, execute it with the inherited values as
|
$target, $_);
|
||||||
# arguments.
|
unless(defined($table{$target}->{$_})) {
|
||||||
$table{$target}->{$_} =
|
delete $table{$target}->{$_};
|
||||||
$table{$target}->{$_}->(@{$combined_inheritance{$_}});
|
}
|
||||||
} elsif ($valuetype eq "ARRAY" || $valuetype eq "") {
|
|
||||||
# ARRAY or Scalar, just leave it as is.
|
|
||||||
} else {
|
|
||||||
# Some other type of reference that we don't handle.
|
|
||||||
# Better to abort at this point.
|
|
||||||
die "cannot handle reference type $valuetype,"
|
|
||||||
," found in target $target -> $_\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Finally done, return the result.
|
# Finally done, return the result.
|
||||||
|
|
Loading…
Reference in a new issue