# New Ticket Created by  James Keenan 
# Please include the string:  [perl #47902]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=47902 >


Over the last few weeks Andy Dougherty and chromatic have pointed out  
some flaws in the logic underlying the tests I have written for the  
config steps, particular those in t/configure/10?-*.t.  We've wrapped  
some of these in TODO blocks, but I've been trying to think of a  
better approach.

One recurring problem -- though not the only problem -- is the fact  
that to jump-start its understanding of the state of a user's system,  
Parrot's Configure.pl relies on the presence of a Perl 5 Config.pm --  
and its exported variable %Config -- to perform initial population of  
many elements in the Parrot::Configure object's internal data  
structure.  This is good enough to start configuration; values  
supplied by %Config are overwritten as necessary throughout the  
configuration steps.  But it means (a) we're got a global variable  
running loose in many of our configuration step classes; and (b)  
different users -- more particularly, different people running the  
tests -- will get different values depending on *which* %Config  
they're using:  one from a Perl 5 they built themselves; a vendor- 
supplied Perl 5; etc.

In the *long* run (Parrot 2.0, if I understand earlier remarks by  
Allison correctly), we want to eliminate this dependency on the  
presence of a working Perl 5 on a user's system.  But in the *short*  
run, if we cannot reduce our dependency on %Config, let's at least  
confine that dependency to just one of our 60 configuration steps  
rather than 15 of them, ranging from step #2 to step #60 (the last).

The patch attached does that.  It confines 'use Config;' to the  
second configuration step, init::defaults.  Any time where a  
subsequent configuration step currently consults %Config in order to  
get a value for element X in the Parrot::Configure object, a similar  
consultation is made in init::defaults and a new element p5Config_X  
is added to that object.  So all the lookups in %Config are made  
within one step, then assigned to their final values in the other 14  
steps which currently 'use Config'.

There was one thorny problem I had to overcome in preparing this  
patch:  Determining that, in the 4 instances where the  
Parrot::Configure::Data::keys() method is used to read the names of  
elements in the Parrot::Configure object, no 'p5Config_X' elements  
are read.  'make' is now completing and 'make test' is passing all  
tests on Linux.

Since this patch affects 16 configuration modules, I would like to  
have it tried out on as many platforms as possible.  Reports from  
Linux and OpenBSD would be particularly helpful, as the init::hints  
step for these two OSes calls OS-specific modules which had lookups  
in %Config.

Thank you very much.
kid51
Index: t/configure/160-gen_config_pm.t
===================================================================
--- t/configure/160-gen_config_pm.t     (revision 23155)
+++ t/configure/160-gen_config_pm.t     (working copy)
@@ -5,9 +5,10 @@
 
 use strict;
 use warnings;
-use Test::More tests =>  2;
+use Test::More qw(no_plan); # tests => 11;
 use Carp;
-use lib qw( lib );
+use lib qw( lib t/configure/testlib );
+use_ok('config::init::defaults');
 use_ok('config::gen::config_pm');
 
 =for hints_for_testing The grand finale!  Try to maximize branch
@@ -15,6 +16,36 @@
 
 =cut
 
+use Parrot::Configure;
+use Parrot::Configure::Options qw( process_options );
+use Parrot::Configure::Test qw( test_step_thru_runstep);
+
+my $args = process_options( {
+    argv            => [],
+    mode            => q{configure},
+} );
+
+my $conf = Parrot::Configure->new();
+
+test_step_thru_runstep($conf, q{init::defaults}, $args);
+
+my ($task, $step_name, @step_params, $step, $ret);
+my $pkg = q{gen::config_pm};
+
+$conf->add_steps($pkg);
+$conf->options->set(%{$args});
+$task = $conf->steps->[1];
+$step_name   = $task->step;
[EMAIL PROTECTED] = @{ $task->params };
+
+$step = $step_name->new();
+ok(defined $step, "$step_name constructor returned defined value");
+isa_ok($step, $step_name);
+ok($step->description(), "$step_name has description");
+
+# ok($step->runstep($conf), "runstep() returned true value");
+
+pass("Keep Devel::Cover happy");
 pass("Completed all tests in $0");
 
 ################### DOCUMENTATION ###################
Index: t/configure/125-auto_headers-04.t
===================================================================
--- t/configure/125-auto_headers-04.t   (revision 23155)
+++ t/configure/125-auto_headers-04.t   (working copy)
@@ -5,7 +5,7 @@
 
 use strict;
 use warnings;
-use Test::More tests => 15;
+use Test::More tests => 14;
 use Carp;
 use Config;
 use lib qw( lib t/configure/testlib );
@@ -42,8 +42,7 @@
 isa_ok( $step, $step_name );
 ok( $step->description(), "$step_name has description" );
 
-auto::headers::_set_from_Config($conf, \%Config);
-ok($conf->data->get('i_netinetin'), "Mapping made correctly");
+auto::headers::_set_from_Config($conf);
 ok(! $conf->data->get('i_niin'), "Mapping made correctly");
 
 {
Index: t/configure/102-init_defaults-01.t
===================================================================
--- t/configure/102-init_defaults-01.t  (revision 23155)
+++ t/configure/102-init_defaults-01.t  (working copy)
@@ -7,7 +7,6 @@
 use warnings;
 use Test::More tests => 6;
 use Carp;
-use Data::Dumper;
 use lib qw( lib );
 use_ok('config::init::defaults');
 use Parrot::Configure;
Index: t/configure/125-auto_headers-01.t
===================================================================
--- t/configure/125-auto_headers-01.t   (revision 23155)
+++ t/configure/125-auto_headers-01.t   (working copy)
@@ -43,7 +43,6 @@
 my $ret = $step->runstep($conf);
 ok( $ret, "$step_name runstep() returned true value" );
 is($step->result(), q{skipped}, "Expected result was set");
-
 pass("Completed all tests in $0");
 
 ################### DOCUMENTATION ###################
Index: config/init/defaults.pm
===================================================================
--- config/init/defaults.pm     (revision 23155)
+++ config/init/defaults.pm     (working copy)
@@ -41,6 +41,34 @@
 sub runstep {
     my ( $self, $conf ) = @_;
 
+    # Later configuration steps need access to values from the Perl 5
+    # %Config.  However, other later configuration steps may change
+    # the corresponding values in the Parrot::Configure object.  In
+    # order to provide access to the original values from Perl 5
+    # %Config, we grab those settings we need now and store them in 
+    # special keys within the Parrot::Configure object.
+    # This is a two-stage process.
+
+    # Stage 1:
+    foreach my $orig ( qw|
+        archname
+        ccflags
+        d_socklen_t
+        longsize
+        optimize
+        osname
+        sig_name
+        use64bitint
+    | ) {
+        $conf->data->set( qq{p5Config_$orig} => $Config{$orig} );
+    }
+
+    # Stage 2 (anticipating needs of config/auto/headers.pm):
+    $conf->data->set(
+        map { q|p5Config_| . $_ => $Config{$_} }
+            grep { /^i_/ } keys %Config
+    );
+
     # We need a Glossary somewhere!
     $conf->data->set(
         debugging => $conf->options->get('debugging') ? 1 : 0,
Index: config/init/hints/openbsd.pm
===================================================================
--- config/init/hints/openbsd.pm        (revision 23155)
+++ config/init/hints/openbsd.pm        (working copy)
@@ -5,7 +5,6 @@
 
 use strict;
 use warnings;
-use Config;
 
 sub runstep {
     my ( $self, $conf ) = @_;
@@ -22,7 +21,7 @@
     }
     $conf->data->set( libs => $libs );
 
-    if ( ( split( m/-/, $Config{archname}, 2 ) )[0] eq 'powerpc' ) {
+    if ( ( split( m/-/, $conf->data->get('p5Config_archname'), 2 ) )[0] eq 
'powerpc' ) {
         $conf->data->set( as => 'as -mregnames' );
     }
 
Index: config/init/hints/linux.pm
===================================================================
--- config/init/hints/linux.pm  (revision 23155)
+++ config/init/hints/linux.pm  (working copy)
@@ -6,7 +6,7 @@
 use strict;
 use warnings;
 
-use Config;
+#use Config;
 
 our $verbose;
 
@@ -147,7 +147,9 @@
         libparrot_soname       => 
'-Wl,-soname=libparrot$(SHARE_EXT).$(SOVERSION)',
     );
 
-    if ( ( split( m/-/, $Config{archname}, 2 ) )[0] eq 'ia64' ) {
+#    if ( ( split( m/-/, $Config{archname}, 2 ) )[0] eq 'ia64' ) {
+     if ( ( split( m/-/, $conf->data->get('p5Config_archname'), 2 ) )[0] eq 
'ia64' ) {
+
         $conf->data->set( platform_asm => 1 );
     }
     return;
Index: config/init/optimize.pm
===================================================================
--- config/init/optimize.pm     (revision 23155)
+++ config/init/optimize.pm     (working copy)
@@ -19,7 +19,7 @@
 
 use base qw(Parrot::Configure::Step::Base);
 
-use Config;
+#use Config;
 use Parrot::Configure::Step;
 
 
@@ -56,7 +56,8 @@
 
             # use perl5's value
             # gcc 4.1 doesn't like -mcpu=xx, i.e. it's deprecated
-            my $opts = $Config{optimize};
+#            my $opts = $Config{optimize};
+            my $opts = $conf->data->get('p5Config_optimize');
             my $gccversion = $conf->data->get( 'gccversion' );
             my $arch_opt = 'cpu';
             if ( defined $gccversion and $gccversion > 3.3 ) {
Index: config/auto/gdbm.pm
===================================================================
--- config/auto/gdbm.pm (revision 23155)
+++ config/auto/gdbm.pm (working copy)
@@ -19,7 +19,7 @@
 
 use base qw(Parrot::Configure::Step::Base);
 
-use Config;
+#use Config;
 use Parrot::Configure::Step ':auto';
 
 
@@ -53,7 +53,8 @@
     my $linkflags = $conf->data->get('linkflags');
     my $ccflags   = $conf->data->get('ccflags');
 
-    my $osname = $Config{osname};
+#    my $osname = $Config{osname};
+    my $osname = $conf->data->get('p5Config_osname');
 
     # On OS X check the presence of the gdbm header in the standard
     # Fink location.
Index: config/auto/socklen_t.pm
===================================================================
--- config/auto/socklen_t.pm    (revision 23155)
+++ config/auto/socklen_t.pm    (working copy)
@@ -19,7 +19,7 @@
 
 use base qw(Parrot::Configure::Step::Base);
 
-use Config;
+#use Config;
 
 use Parrot::Configure::Step ':auto';
 
@@ -44,7 +44,8 @@
 
 sub _probe_for_socklen_t {
     my $conf = shift;
-    return $conf->data->get('has_socklen_t') || $Config{d_socklen_t};
+#    return $conf->data->get('has_socklen_t') || $Config{d_socklen_t};
+    return $conf->data->get('has_socklen_t') || 
$conf->data->get('p5Config_d_socklen_t');
 }
 
 sub _evaluate_socklen_t {
Index: config/auto/signal.pm
===================================================================
--- config/auto/signal.pm       (revision 23155)
+++ config/auto/signal.pm       (working copy)
@@ -84,10 +84,11 @@
 # Any changes made here will be lost.
 #
 EOF
-    use Config;
+#    use Config;
     my ( $i, $name );
     $i = 0;
-    foreach $name ( split( ' ', $Config{sig_name} ) ) {
+#    foreach $name ( split( ' ', $Config{sig_name} ) ) {
+    foreach $name ( split( ' ', $conf->data->get('p5Config_sig_name') ) ) {
         print {$O} ".constant SIG$name\t$i\n" if $i;
         $i++;
     }
Index: config/auto/pack.pm
===================================================================
--- config/auto/pack.pm (revision 23155)
+++ config/auto/pack.pm (working copy)
@@ -19,7 +19,7 @@
 use base qw(Parrot::Configure::Step::Base);
 
 use Parrot::Configure::Step;
-use Config;
+#use Config;
 
 
 sub _init {
@@ -47,14 +47,20 @@
         my $which = $_ eq 'intvalsize' ? 'packtype_i' : 'packtype_op';
         my $size = $conf->data->get($_);
         my $format;
-        if ( ( $] >= 5.006 ) && ( $size == $longsize ) && ( $size == 
$Config{longsize} ) ) {
+#        if ( ( $] >= 5.006 ) && ( $size == $longsize ) && ( $size == 
$Config{longsize} ) ) {
+        if (    
+            ( $] >= 5.006 ) &&
+            ( $size == $longsize ) &&
+            ( $size == $conf->data->get('p5Config_longsize') )
+        ) {
             $format = 'l!';
         }
         elsif ( $size == 4 ) {
             $format = 'l';
         }
-        elsif ( $size == 8 || $Config{use64bitint} eq 'define' ) {
-
+#        elsif ( $size == 8 || $Config{use64bitint} eq 'define' ) {
+       elsif ( $size == 8 ||
+            $conf->data->get('p5Config_use64bitint') eq 'define' ) {
             # pp_pack is annoying, and this won't work unless sizeof(UV) >= 8
             $format = 'q';
         }
Index: config/auto/m4.pm
===================================================================
--- config/auto/m4.pm   (revision 23155)
+++ config/auto/m4.pm   (working copy)
@@ -19,7 +19,7 @@
 
 use base qw(Parrot::Configure::Step::Base);
 
-use Config;
+#use Config;
 use Parrot::Configure::Step ':auto', 'capture_output';
 
 
@@ -40,7 +40,8 @@
     $verbose = $conf->options->get( 'verbose' );
     print $/ if $verbose;
 
-    my $archname = $Config{archname};
+#    my $archname = $Config{archname};
+    my $archname = $conf->data->get('p5Config_archname');
     my ( $cpuarch, $osname ) = split m/-/, $archname, 2;
     if ( !defined $osname ) {
         ( $osname, $cpuarch ) = ( $cpuarch, "" );
Index: config/auto/gmp.pm
===================================================================
--- config/auto/gmp.pm  (revision 23155)
+++ config/auto/gmp.pm  (working copy)
@@ -18,7 +18,7 @@
 
 use base qw(Parrot::Configure::Step::Base);
 
-use Config;
+#use Config;
 use Parrot::Configure::Step ':auto';
 
 
@@ -63,7 +63,8 @@
         $conf->data->add( ' ', libs => '-lgmp' );
     }
 
-    my $osname = $Config{osname};
+#    my $osname = $Config{osname};
+    my $osname = $conf->data->get('p5Config_osname');
 
     # On OS X check the presence of the gmp header in the standard
     # Fink location.
Index: config/auto/readline.pm
===================================================================
--- config/auto/readline.pm     (revision 23155)
+++ config/auto/readline.pm     (working copy)
@@ -18,7 +18,7 @@
 
 use base qw(Parrot::Configure::Step::Base);
 
-use Config;
+#use Config;
 use Parrot::Configure::Step ':auto';
 
 
@@ -53,7 +53,8 @@
         $conf->data->add( ' ', libs => '-lreadline' );
     }
 
-    my $osname = $Config{osname};
+#    my $osname = $Config{osname};
+    my $osname = $conf->data->get('p5Config_osname');
 
     # On OS X check the presence of the readline header in the standard
     # Fink/macports location.
Index: config/auto/gcc.pm
===================================================================
--- config/auto/gcc.pm  (revision 23155)
+++ config/auto/gcc.pm  (working copy)
@@ -362,8 +362,9 @@
             next unless $opt;    # Ignore blank lines
 
             if ( $opt =~ /-mno-accumulate-outgoing-args/ ) {
-                use Config;
-                if ( $Config{archname} !~ /86/ ) {
+#                use Config;
+#                if ( $Config{archname} !~ /86/ ) {
+                 if ( $conf->data->get('p5Config_archname') !~ /86/ ) {
                     $opt =~ s/-mno-accumulate-outgoing-args//;
                 }
             }
Index: config/auto/alignptrs.pm
===================================================================
--- config/auto/alignptrs.pm    (revision 23155)
+++ config/auto/alignptrs.pm    (working copy)
@@ -19,7 +19,7 @@
 use base qw(Parrot::Configure::Step::Base);
 
 use Parrot::Configure::Step ':auto';
-use Config;
+#use Config;
 
 
 sub _init {
@@ -45,7 +45,8 @@
         $align = $conf->data->get('ptr_alignment');
         $result_str .= "configured: ";
     }
-    elsif ( $^O eq 'hpux' && $Config{ccflags} !~ /DD64/ ) {
+#    elsif ( $^O eq 'hpux' && $Config{ccflags} !~ /DD64/ ) {
+    elsif ( $^O eq 'hpux' && $conf->data->get('p5Config_ccflags') !~ /DD64/ ) {
 
         # HP-UX 10.20/32 hangs in this test.
         $align = 4;
Index: config/gen/config_h.pm
===================================================================
--- config/gen/config_h.pm      (revision 23155)
+++ config/gen/config_h.pm      (working copy)
@@ -71,6 +71,7 @@
 EOF
 
     for ( sort( $conf->data->keys() ) ) {
+        next if /^p5Config_/;
         next unless /i_(\w+)/;
         if ( $conf->data->get($_) ) {
             print {$HH} "#define PARROT_HAS_HEADER_\U$1 1\n";
@@ -107,6 +108,7 @@
 
 EOF
     for ( sort( $conf->data->keys() ) ) {
+        next if /^p5Config_/;
         next unless /HAS_(\w+)/;
         if ( $conf->data->get($_) ) {
             print {$HH} "#define PARROT_HAS_\U$1 1\n";
@@ -120,6 +122,7 @@
 
 EOF
     for ( sort( $conf->data->keys() ) ) {
+        next if /^p5Config_/;
         next unless /D_(\w+)/;
         my $val;
         if ( $val = $conf->data->get($_) ) {
Index: config/gen/platform.pm
===================================================================
--- config/gen/platform.pm      (revision 23155)
+++ config/gen/platform.pm      (working copy)
@@ -19,7 +19,7 @@
 
 use base qw(Parrot::Configure::Step::Base);
 
-use Config;
+#use Config;
 
 use Parrot::Configure::Step qw(copy_if_diff);
 
@@ -43,7 +43,8 @@
     $platform = "win32" if $platform =~ /^mingw/;
     $platform =~ s/^ms//;
 
-    if ( ( split m/-/, $Config{archname}, 2 )[0] eq 'ia64' ) {
+#    if ( ( split m/-/, $Config{archname}, 2 )[0] eq 'ia64' ) {
+    if ( ( split m/-/, $conf->data->get('p5Config_archname'), 2 )[0] eq 'ia64' 
) {
         $platform = 'ia64';
     }
 
Index: config/gen/config_pm.pm
===================================================================
--- config/gen/config_pm.pm     (revision 23155)
+++ config/gen/config_pm.pm     (working copy)
@@ -38,6 +38,13 @@
 
     $conf->data->clean;
 
+    my @p5Config_keys;
+    foreach my $key (keys %{$conf->data->{c}}) {
+        my $del = delete $conf->data->{c}->{$key}
+            if $key =~ /^p5Config_/; 
+        push @p5Config_keys, $del; 
+    }
+
     genfile( 'config/gen/config_pm/myconfig.in', 'myconfig' );
 
     open( my $IN, "<", "config/gen/config_pm/Config_pm.in" )

Reply via email to