Add template reference processing.
authorRichard Levitte <levitte@openssl.org>
Fri, 6 Mar 2015 02:00:53 +0000 (03:00 +0100)
committerRichard Levitte <levitte@openssl.org>
Mon, 16 Mar 2015 21:16:30 +0000 (22:16 +0100)
Template references are words with double brackets, and refer to the
same field in the target pointed at the the double bracketed word.

For example, if a target's configuration has the following entry:

    'cflags' => '-DFOO {{x86_debug}}'

... then {{x86_debug}} will be replaced with the 'cflags' value from
target 'x86_debug'.

Note: template references are resolved recursively, and circular
references are not allowed

Reviewed-by: Andy Polyakov <appro@openssl.org>
Configure

index ed1e985..481eeab 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -304,6 +304,31 @@ sub stringtohash {
     return { map { shift @stringsequence => $_ } split /:/, $in };
 };
 
+# Support function to look for and resolve template references.
+# It uses breadcrumbs to check for circular template references.
+#
+# Note: Any configuration value is also a template.
+sub lookup_templates {
+    my $tableref = shift;
+    my $target = shift;
+    my @breadcrumbs = @_;
+
+    if (grep { $_ eq $target } @breadcrumbs) {
+       die "Template loop!  target backtrace:\n  ",join("\n  ",
+                                                        $target,
+                                                        @breadcrumbs),"\n";
+    }
+
+    foreach my $key (keys %{$tableref->{$target}}) {
+       my $value = $tableref->{$target}->{$key};
+       while ($value =~ /{{([-\w]+)}}/) {
+           lookup_templates($tableref, $1, $target, @breadcrumbs);
+           $value = $`.$tableref->{$1}->{$key}.$';
+       }
+       $tableref->{$target}->{$key} = $value;
+    }
+};
+
 
 # Read configuration target stanzas from a file, so that people can have
 # local files with their own definitions
@@ -445,6 +470,11 @@ sub read_config {
        }
 
        %table = (%table, %targets);
+
+       # Go through all new targets and resolve template references.
+       foreach (keys %targets) {
+           lookup_templates(\%table, $_);
+       }
 }
 
 my ($vol, $dir, $dummy) = File::Spec->splitpath($0);