Refactor config - @MK1MF_Builds out, general build scheme in
authorRichard Levitte <levitte@openssl.org>
Mon, 18 May 2015 12:31:49 +0000 (14:31 +0200)
committerRichard Levitte <levitte@openssl.org>
Thu, 21 Jan 2016 23:58:56 +0000 (00:58 +0100)
Time to get rid of @MK1MF_Builds and introduce a more flexible
'build_scheme' configuration key.  Its value may be a string or an
array of strings, meaning we need to teach resolve_config how to
handle ARRAY referenses.

The build scheme is a word that selects a function to create the
appropriate result files for a certain configuration.  Currently valid
build schemes aer "mk1mf" and "unixmake", the plan is however to add
at least one other for a more universal build scheme.

Incidently, this also adds the functions 'add' and 'add_before', which
can be used in a configuration, so instead of having to repeatedly
write a sub like this:

key1 => sub { join(" ", @_, "myvalues"); },
key2 => sub { join(" ", "myvalues", @_); },

one could write this:

key1 => add(" ", "myvalues"),
key2 => add_before(" ", "myvalues"),

The good point with 'add' and 'add_before' is that they handle
inheritances where the values are a misture of scalars and ARRAYs.  If
there are any ARRAY to be found, the resulting value will be an ARRAY,
otherwise it will be a scalar with all the incoming valued joined
together with the separator given as first argument to add/add_before.

Reviewed-by: Rich Salz <rsalz@openssl.org>
Configurations/00-base-templates.conf
Configurations/10-main.conf
Configurations/README
Configure

index 064648f15a355114084832fd314edec530a171c6..90633c4abf6135db7bdabcba65472b2bc3235bc2 100644 (file)
@@ -20,6 +20,7 @@
        poly1305_obj    => "",
 
        unistd          => "<unistd.h>",
        poly1305_obj    => "",
 
        unistd          => "<unistd.h>",
+       build_scheme    => "unixmake",
     },
 
     x86_asm => {
     },
 
     x86_asm => {
index 06911acac13fc5d37c90dec1783b9954ccf696c0..c5ae5940e20872d1c8dd9c71d2183e5fa1f3438e 100644 (file)
     },
     "solaris-sparcv8-gcc" => {
         inherit_from     => [ "solaris-sparcv7-gcc", asm("sparcv8_asm") ],
     },
     "solaris-sparcv8-gcc" => {
         inherit_from     => [ "solaris-sparcv7-gcc", asm("sparcv8_asm") ],
-        cflags           => sub { join(" ","-mcpu=v8",@_); },
+        cflags           => add_before(" ", "-mcpu=v8"),
     },
     "solaris-sparcv9-gcc" => {
         # -m32 should be safe to add as long as driver recognizes
         # -mcpu=ultrasparc
         inherit_from     => [ "solaris-sparcv7-gcc", asm("sparcv9_asm") ],
     },
     "solaris-sparcv9-gcc" => {
         # -m32 should be safe to add as long as driver recognizes
         # -mcpu=ultrasparc
         inherit_from     => [ "solaris-sparcv7-gcc", asm("sparcv9_asm") ],
-        cflags           => sub { join(" ","-m32 -mcpu=ultrasparc",@_); },
+        cflags           => add_before(" ", "-m32 -mcpu=ultrasparc"),
         debug_cflags     => "-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DPEDANTIC -O -g -pedantic -ansi -Wshadow -Wno-long-long -D__EXTENSIONS__",
     },
     "solaris64-sparcv9-gcc" => {
         debug_cflags     => "-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DPEDANTIC -O -g -pedantic -ansi -Wshadow -Wno-long-long -D__EXTENSIONS__",
     },
     "solaris64-sparcv9-gcc" => {
 ####
     "solaris-sparcv8-cc" => {
         inherit_from     => [ "solaris-sparcv7-cc", asm("sparcv8_asm") ],
 ####
     "solaris-sparcv8-cc" => {
         inherit_from     => [ "solaris-sparcv7-cc", asm("sparcv8_asm") ],
-        cflags           => sub { join(" ","-xarch=v8",@_); },
+        cflags           => add_before(" ", "-xarch=v8"),
     },
     "solaris-sparcv9-cc" => {
         inherit_from     => [ "solaris-sparcv7-cc", asm("sparcv9_asm") ],
     },
     "solaris-sparcv9-cc" => {
         inherit_from     => [ "solaris-sparcv7-cc", asm("sparcv9_asm") ],
-        cflags           => sub { join(" ","-xarch=v8plus -xtarget=ultra",@_); },
+        cflags           => add_before(" ", "-xarch=v8plus -xtarget=ultra"),
     },
     "solaris64-sparcv9-cc" => {
         inherit_from     => [ "solaris-sparcv7-cc", asm("sparcv9_asm") ],
     },
     "solaris64-sparcv9-cc" => {
         inherit_from     => [ "solaris-sparcv7-cc", asm("sparcv9_asm") ],
-        cflags           => sub { join(" ","-xarch=v9 -xtarget=ultra",@_); },
+        cflags           => add_before(" ", "-xarch=v9 -xtarget=ultra"),
         bn_ops           => "BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR",
         shared_ldflag    => "-xarch=v9 -G -dy -z text",
         multilib         => "/64",
         bn_ops           => "BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR",
         shared_ldflag    => "-xarch=v9 -G -dy -z text",
         multilib         => "/64",
     },
     "hpux-parisc1_1-cc" => {
         inherit_from     => [ "hpux-parisc-cc", asm("parisc11_asm") ],
     },
     "hpux-parisc1_1-cc" => {
         inherit_from     => [ "hpux-parisc-cc", asm("parisc11_asm") ],
-        cflags           => sub { join(" ","+DA1.1",@_); },
+        cflags           => add_before(" ", "+DA1.1"),
         multilib         => "/pa1.1",
     },
     "hpux64-parisc2-cc" => {
         multilib         => "/pa1.1",
     },
     "hpux64-parisc2-cc" => {
     },
     "android-armv7" => {
         inherit_from     => [ "android-armeabi" ],
     },
     "android-armv7" => {
         inherit_from     => [ "android-armeabi" ],
-        cflags           => sub { join (" ","-march=armv7-a",@_); },
+        cflags           => add_before(" ", "-march=armv7-a"),
     },
     "android-mips" => {
         inherit_from     => [ "android", asm("mips32_asm") ],
     },
     "android-mips" => {
         inherit_from     => [ "android", asm("mips32_asm") ],
         cc               => "cl",
         cflags           => "-W3 -wd4090 -Gs0 -GF -Gy -nologo -DOPENSSL_SYS_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE",
         dso_scheme       => "win32",
         cc               => "cl",
         cflags           => "-W3 -wd4090 -Gs0 -GF -Gy -nologo -DOPENSSL_SYS_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE",
         dso_scheme       => "win32",
+       build_scheme     => "mk1mf",
     },
     "VC-WIN64I" => {
         inherit_from     => [ "VC-common", asm("ia64_asm") ],
     },
     "VC-WIN64I" => {
         inherit_from     => [ "VC-common", asm("ia64_asm") ],
-        cflags           => sub { join(" ",@_,"-DUNICODE -D_UNICODE"); },
+        cflags           => add(" ", "-DUNICODE -D_UNICODE"),
         sys_id           => "WIN64I",
         bn_ops           => "SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN",
         bn_obj           => sub { my $r=join(" ",@_); $r=~s/bn\-//; $r; },
         rc4_obj          => "",
         perlasm_scheme   => "ias",
         sys_id           => "WIN64I",
         bn_ops           => "SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN",
         bn_obj           => sub { my $r=join(" ",@_); $r=~s/bn\-//; $r; },
         rc4_obj          => "",
         perlasm_scheme   => "ias",
+       build_scheme     => [ "mk1mf", "VC-W64" ],
     },
     "VC-WIN64A" => {
         inherit_from     => [ "VC-common", asm("x86_64_asm") ],
     },
     "VC-WIN64A" => {
         inherit_from     => [ "VC-common", asm("x86_64_asm") ],
-        cflags           => sub { join(" ",@_,"-DUNICODE -D_UNICODE"); },
+        cflags           => add(" ", "-DUNICODE -D_UNICODE"),
         sys_id           => "WIN64A",
         bn_ops           => "SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN",
         bn_obj           => sub { my $r=join(" ",@_); $r=~s/x86_64\-gcc/bn_asm/; $r; },
         perlasm_scheme   => "auto",
         sys_id           => "WIN64A",
         bn_ops           => "SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN",
         bn_obj           => sub { my $r=join(" ",@_); $r=~s/x86_64\-gcc/bn_asm/; $r; },
         perlasm_scheme   => "auto",
+       build_scheme     => [ "mk1mf", "VC-W64" ],
     },
     "VC-WIN32" => {
         # x86 Win32 target defaults to ANSI API, if you want UNICODE,
     },
     "VC-WIN32" => {
         # x86 Win32 target defaults to ANSI API, if you want UNICODE,
         sys_id           => "WIN32",
         bn_ops           => "BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}",
         perlasm_scheme   => "win32n",
         sys_id           => "WIN32",
         bn_ops           => "BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}",
         perlasm_scheme   => "win32n",
+       build_scheme     => [ "mk1mf", "VC-W32" ],
     },
     "VC-CE" => {
         cc               => "cl",
         sys_id           => "WINCE",
         bn_ops           => "BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}",
         dso_scheme       => "win32",
     },
     "VC-CE" => {
         cc               => "cl",
         sys_id           => "WINCE",
         bn_ops           => "BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}",
         dso_scheme       => "win32",
+       build_scheme     => [ "mk1mf", "VC-WCE" ],
     },
 
 #### Borland C++ 4.5
     },
 
 #### Borland C++ 4.5
         sys_id           => "WIN32",
         bn_ops           => "BN_LLONG DES_PTR RC4_INDEX EXPORT_VAR_AS_FN",
         dso_scheme       => "win32",
         sys_id           => "WIN32",
         bn_ops           => "BN_LLONG DES_PTR RC4_INDEX EXPORT_VAR_AS_FN",
         dso_scheme       => "win32",
+       build_scheme     => [ "mk1mf", "BC" ],
     },
 
 #### MinGW
     },
 
 #### MinGW
     "netware-clib" => {
         cc               => "mwccnlm",
         bn_ops           => "${x86_gcc_opts}",
     "netware-clib" => {
         cc               => "mwccnlm",
         bn_ops           => "${x86_gcc_opts}",
+       build_scheme     => [ "mk1mf", "netware" ],
     },
     "netware-clib-bsdsock" => {
         cc               => "mwccnlm",
         bn_ops           => "${x86_gcc_opts}",
     },
     "netware-clib-bsdsock" => {
         cc               => "mwccnlm",
         bn_ops           => "${x86_gcc_opts}",
+       build_scheme     => [ "mk1mf", "netware" ],
     },
     "netware-clib-gcc" => {
         cc               => "i586-netware-gcc",
     },
     "netware-clib-gcc" => {
         cc               => "i586-netware-gcc",
     "netware-libc" => {
         cc               => "mwccnlm",
         bn_ops           => "BN_LLONG ${x86_gcc_opts}",
     "netware-libc" => {
         cc               => "mwccnlm",
         bn_ops           => "BN_LLONG ${x86_gcc_opts}",
+       build_scheme     => [ "mk1mf", "netware" ],
     },
     "netware-libc-bsdsock" => {
         cc               => "mwccnlm",
         bn_ops           => "BN_LLONG ${x86_gcc_opts}",
     },
     "netware-libc-bsdsock" => {
         cc               => "mwccnlm",
         bn_ops           => "BN_LLONG ${x86_gcc_opts}",
+       build_scheme     => [ "mk1mf", "netware" ],
     },
     "netware-libc-gcc" => {
         cc               => "i586-netware-gcc",
     },
     "netware-libc-gcc" => {
         cc               => "i586-netware-gcc",
index e1327e57f9d6607238625afde2f6450e31b58e7c..df55d715496ba44b7de93d5981f2843a11a46b72 100644 (file)
@@ -97,8 +97,16 @@ In each table entry, the following keys are significant:
         shared_target   => The shared library building method used.
                            This is a target found in Makefile.shared.
         build_scheme    => The scheme used to build up a Makefile.
         shared_target   => The shared library building method used.
                            This is a target found in Makefile.shared.
         build_scheme    => The scheme used to build up a Makefile.
-                           (NOTE: this is here for future use, it's
-                           not implemented yet)
+                           In its simplest form, the value is a string
+                           with the name of the build scheme.
+                           The value may also take the form of a list
+                           of strings, if the build_scheme is to have
+                           some options.  In this case, the first
+                           string in the list is the name of the build
+                           scheme.
+                           Currently recognised build schemes are
+                           "mk1mf" and "unixmake".  Others may appear
+                           in the future.
 
         multilib        => On systems that support having multiple
                            implementations of a library (typically a
 
         multilib        => On systems that support having multiple
                            implementations of a library (typically a
index be55d8ce83902c4f9a105a091c07942c3715ac91..96f88b253de343d2ca500880c767a41aa4800b51 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -172,13 +172,6 @@ foreach (sort glob($pattern) ) {
     &read_config($_);
 }
 
     &read_config($_);
 }
 
-my @MK1MF_Builds=qw(VC-WIN64I VC-WIN64A
-                   debug-VC-WIN64I debug-VC-WIN64A
-                   VC-NT VC-CE VC-WIN32 debug-VC-WIN32
-                   BC-32
-                   netware-clib netware-clib-bsdsock
-                   netware-libc netware-libc-bsdsock);
-
 my $prefix="";
 my $libdir="";
 my $openssldir="";
 my $prefix="";
 my $libdir="";
 my $openssldir="";
@@ -763,8 +756,6 @@ my %target = ( %{$table{$base_target}}, resolve_config($target) );
 
 &usage if (!%target || $target{template});
 
 
 &usage if (!%target || $target{template});
 
-my $IsMK1MF=scalar grep /^$target$/,@MK1MF_Builds;
-
 $exe_ext=".exe" if ($target eq "Cygwin" || $target eq "DJGPP" || $target =~ /^mingw/);
 $exe_ext=".nlm" if ($target =~ /netware/);
 $exe_ext=".pm"  if ($target =~ /vos/);
 $exe_ext=".exe" if ($target eq "Cygwin" || $target eq "DJGPP" || $target =~ /^mingw/);
 $exe_ext=".nlm" if ($target =~ /netware/);
 $exe_ext=".pm"  if ($target =~ /vos/);
@@ -782,8 +773,6 @@ $openssldir = catdir($prefix, $openssldir)
     unless file_name_is_absolute($openssldir);
 
 
     unless file_name_is_absolute($openssldir);
 
 
-print "IsMK1MF=$IsMK1MF\n";
-
 # Allow environment CC to override compiler...
 my $cc = $ENV{CC} || $target{cc};
 
 # Allow environment CC to override compiler...
 my $cc = $ENV{CC} || $target{cc};
 
@@ -828,6 +817,9 @@ my $ranlib = $ENV{'RANLIB'} || $target{ranlib};
 my $ar = $ENV{'AR'} || "ar";
 my $arflags = $target{arflags};
 my $multilib = $target{multilib};
 my $ar = $ENV{'AR'} || "ar";
 my $arflags = $target{arflags};
 my $multilib = $target{multilib};
+my @build_scheme =
+    ref($target{build_scheme}) eq "ARRAY"
+    ? @{$target{build_scheme}} : ( $target{build_scheme} );
 
 # if $prefix/lib$multilib is not an existing directory, then
 # assume that it's not searched by linker automatically, in
 
 # if $prefix/lib$multilib is not an existing directory, then
 # assume that it's not searched by linker automatically, in
@@ -976,7 +968,7 @@ if (!$no_shared)
                }
        }
 
                }
        }
 
-if (!$IsMK1MF)
+if ($build_scheme[0] ne "mk1mf")
        {
        # add {no-}static-engine to options to allow mkdef.pl to work without extra arguments
        if ($no_shared)
        {
        # add {no-}static-engine to options to allow mkdef.pl to work without extra arguments
        if ($no_shared)
@@ -1301,6 +1293,7 @@ close(OUT);
 rename($Makefile,"$Makefile.orig") || die "unable to rename $Makefile\n" if -e $Makefile;
 rename("$Makefile.new",$Makefile) || die "unable to rename $Makefile.new\n";
 
 rename($Makefile,"$Makefile.orig") || die "unable to rename $Makefile\n" if -e $Makefile;
 rename("$Makefile.new",$Makefile) || die "unable to rename $Makefile.new\n";
 
+print "IsMK1MF       =", ($build_scheme[0] eq "mk1mf" ? "yes" : "no"), "\n";
 print "CC            =$cc\n";
 print "CFLAG         =$cflags\n";
 print "EX_LIBS       =$lflags\n";
 print "CC            =$cc\n";
 print "CFLAG         =$cflags\n";
 print "EX_LIBS       =$lflags\n";
@@ -1546,17 +1539,25 @@ find(sub {
                 $File::Find::dir;
     }, ".");
 
                 $File::Find::dir;
     }, ".");
 
-{
-    my $perlguess = $perl =~ m@^/@ ? $perl : '/usr/local/bin/perl';
-
-    &dofile("tools/c_rehash",$perlguess,
-           '^#!/'              => '#!%s',
-           '^my \$dir;$'       => 'my $dir = "' . $openssldir . '";',
-           '^my \$prefix;$'    => 'my $prefix = "' . $prefix . '";');
-    &dofile("apps/CA.pl",$perl,
-           '^#!/'              => '#!%s');
-}
-if($IsMK1MF) {
+my %builders = (
+    unixmake => sub {
+       my $perlguess = $perl =~ m@^/@ ? $perl : '/usr/local/bin/perl';
+       my $make_command = "$make PERL=\'$perlguess\'";
+       my $make_targets = "";
+       $make_targets .= " depend" if $depflags ne $default_depflags && $make_depend;
+       (system $make_command.$make_targets) == 0 or die "make $make_targets failed"
+           if $make_targets ne "";
+       &dofile("tools/c_rehash",$perlguess,
+               '^#!/'           => '#!%s',
+               '^my \$dir;$'    => 'my $dir = "' . $openssldir . '";',
+               '^my \$prefix;$' => 'my $prefix = "' . $prefix . '";');
+       &dofile("apps/CA.pl",$perlguess,
+               '^#!/'           => '#!%s');
+       if ($depflags ne $default_depflags && !$make_depend) {
+            $warn_make_depend++;
+        }
+    },
+    mk1mf => sub {
        open (OUT,">crypto/buildinf.h") || die "Can't open buildinf.h";
        printf OUT <<"EOF";
 #ifndef MK1MF_BUILD
        open (OUT,">crypto/buildinf.h") || die "Can't open buildinf.h";
        printf OUT <<"EOF";
 #ifndef MK1MF_BUILD
@@ -1568,28 +1569,18 @@ if($IsMK1MF) {
 #endif
 EOF
        close(OUT);
 #endif
 EOF
        close(OUT);
-} else {
-       my $make_command = "$make PERL=\'$perl\'";
-       my $make_targets = "";
-       $make_targets .= " depend" if $depflags ne $default_depflags && $make_depend;
-       (system $make_command.$make_targets) == 0 or die "make $make_targets failed"
-               if $make_targets ne "";
-       if ($depflags ne $default_depflags && !$make_depend) {
-            $warn_make_depend++;
-        }
-}
 
 
-# create the ms/version32.rc file if needed
-if ($IsMK1MF && ($target !~ /^netware/)) {
-       my ($v1, $v2, $v3, $v4);
-       if ($version_num =~ /^0x([0-9a-f]{1})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{1})L$/i) {
+       # create the ms/version32.rc file if needed
+       if (! grep /^netware/, @build_scheme) {
+           my ($v1, $v2, $v3, $v4);
+           if ($version_num =~ /^0x([0-9a-f]{1})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{1})L$/i) {
                $v1=hex $1;
                $v2=hex $2;
                $v3=hex $3;
                $v4=hex $4;
                $v1=hex $1;
                $v2=hex $2;
                $v3=hex $3;
                $v4=hex $4;
-       }
-       open (OUT,">ms/version32.rc") || die "Can't open ms/version32.rc";
-       print OUT <<"EOF";
+           }
+           open (OUT,">ms/version32.rc") || die "Can't open ms/version32.rc";
+           print OUT <<"EOF";
 #include <winver.h>
 
 LANGUAGE 0x09,0x01
 #include <winver.h>
 
 LANGUAGE 0x09,0x01
@@ -1638,8 +1629,13 @@ BEGIN
     END
 END
 EOF
     END
 END
 EOF
-       close(OUT);
-  }
+           close(OUT);
+       }
+    },
+    );
+
+my ($builder, @builder_opts) = @build_scheme;
+$builders{$builder}->(@builder_opts);
 
 print <<"EOF";
 
 
 print <<"EOF";
 
@@ -1690,6 +1686,43 @@ sub asm {
     }
 }
 
     }
 }
 
+# Helper function to implement adding values to already existing configuration
+# values.  It handles elements that are ARRAYs, CODEs and scalars
+sub _add {
+    my $separator = shift;
+
+    # If there's any ARRAY in the collection of values, we will return
+    # an ARRAY of combined values, otherwise a string of joined values
+    # with $separator as the separator.
+    my $found_array = 0;
+
+    my @values =
+       map {
+           if (ref($_) eq "ARRAY") {
+               $found_array = 1;
+               @$_;
+           } else {
+               $_;
+           }
+    } (@_);
+
+    if ($found_array) {
+       [ @values ];
+    } else {
+       join($separator, @values);
+    }
+}
+sub add_before {
+    my $separator = shift;
+    my @x = @_;
+    sub { _add($separator, @x, @_) };
+}
+sub add {
+    my $separator = shift;
+    my @x = @_;
+    sub { _add($separator, @_, @x) };
+}
+
 # configuration reader, evaluates the input file as a perl script and expects
 # it to fill %targets with target configurations.  Those are then added to
 # %table.
 # configuration reader, evaluates the input file as a perl script and expects
 # it to fill %targets with target configurations.  Those are then added to
 # %table.
@@ -1783,7 +1816,7 @@ sub resolve_config {
     #   value.
     # - Otherwise, this target's value is assumed to be a string that
     #   will simply override the inherited list of values.
     #   value.
     # - Otherwise, this target's value is assumed to be a string that
     #   will simply override the inherited list of values.
-    my $default_combiner = sub { join(' ',@_) };
+    my $default_combiner = add(" ");
 
     my %all_keys =
        map { $_ => 1 } (keys %combined_inheritance,
 
     my %all_keys =
        map { $_ => 1 } (keys %combined_inheritance,
@@ -1803,8 +1836,8 @@ sub resolve_config {
            # arguments.
            $table{$target}->{$_} =
                $table{$target}->{$_}->(@{$combined_inheritance{$_}});
            # arguments.
            $table{$target}->{$_} =
                $table{$target}->{$_}->(@{$combined_inheritance{$_}});
-       } elsif ($valuetype eq "") {
-           # Scalar, just leave it as is.
+       } 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.
        } else {
            # Some other type of reference that we don't handle.
            # Better to abort at this point.