develooper Front page | perl.perl5.porters | Postings from July 2012

disentangling version's XS from util.c and universal.c might bepossible (was Re: supporting untarring of extensions)

Thread Previous | Thread Next
Nicholas Clark
July 12, 2012 06:59
disentangling version's XS from util.c and universal.c might bepossible (was Re: supporting untarring of extensions)
Message ID:
On Wed, Jul 11, 2012 at 10:23:42PM +0100, Nicholas Clark wrote:
> On Wed, Jul 11, 2012 at 09:49:18PM +0100, Nicholas Clark wrote:
> > You're never going to fix with this, because parts of it are
> > hard coded into util.c. Sorry.
> > 
> > (But if it *is* possible to kick parts of util.c out into XS code, then
> > it may well be possible to fix how we handle without changing the
> > build system at all)
> Right. version::vpp provides a pure perl emulation of some of version,
> doesn't it? I see that it wants to use POSIX for locale_h. As an
> experiment, if that's patched to remove that code (assume that it's the "C"
> locale), and util.c is patched to remove all the version:: XS code
> (ie #if 0/#endif), is version::vpp good enough for miniperl to be able to
> get through the entire build process until the build process wants to run
> ./perl ?
> (It's permissible to do evil in lib/ such as loading modules
> and alias symbol tables. That has almost complete control over what miniperl
> actually ends up being when it actually gets to run the real script.)

Answer - for *this* approach, seems no. Better suggestion below.

I've "removed" the version XS functions like this:

diff --git a/universal.c b/universal.c
index a7c480f..654a1c0 100644
--- a/universal.c
+++ b/universal.c
@@ -1360,6 +1360,7 @@ struct xsub_details details[] = {
     {"UNIVERSAL::can", XS_UNIVERSAL_can, NULL},
+#if 0
     {"version::()", XS_version_noop, NULL},
     {"version::new", XS_version_new, NULL},
     {"version::parse", XS_version_new, NULL},
@@ -1388,6 +1389,7 @@ struct xsub_details details[] = {
     {"version::qv", XS_version_qv, NULL},
     {"version::declare", XS_version_qv, NULL},
     {"version::is_qv", XS_version_is_qv, NULL},
     {"utf8::is_utf8", XS_utf8_is_utf8, NULL},
     {"utf8::valid", XS_utf8_valid, NULL},
     {"utf8::encode", XS_utf8_encode, NULL},

I've hacked slightly:

$ diff -u lib/version/ lib/version/
--- lib/version/ 2011-09-25 15:53:55.000000000 +0200
+++ lib/version/  2012-07-12 12:54:39.797804113 +0200
@@ -115,11 +115,11 @@
     return $string;
-package version::vpp;
+package version;
 use strict;
-use POSIX qw/locale_h/;
-use locale;
+##use POSIX qw/locale_h/;
+##use locale;
 use vars qw ($VERSION @ISA @REGEXS);
 $VERSION = 0.94;
@@ -145,8 +145,8 @@
 # implement prescan_version as closely to the C version as possible
-use constant TRUE  => 1;
-use constant FALSE => 0;
+sub TRUE() {1}
+sub FALSE() {0}
 sub isDIGIT {
     my ($char) = shift->thischar();
@@ -573,14 +573,14 @@
            return $self;
-       my $currlocale = setlocale(LC_ALL);
+##     my $currlocale = setlocale(LC_ALL);
        # if the current locale uses commas for decimal points, we
        # just replace commas with decimal places, rather than changing
        # locales
-       if ( localeconv()->{decimal_point} eq ',' ) {
-           $value =~ tr/,/./;
-       }
+##     if ( localeconv()->{decimal_point} eq ',' ) {
+##         $value =~ tr/,/./;
+##     }
        if ( not defined $value or $value =~ /^undef$/ ) {
            # RT #19517 - special case for undef comparison

and I have added this to the end of lib/

require version::vpp;

(note, not use, as @INC isn't set up quite right).

And i hit a roadblock:

$ ./miniperl -Ilib -e 'print "Bother\n" unless $^V eq 5.17.2'
Can't locate in @INC (@INC contains: /home/nick/Perl/perl/cpan/AutoLoader/lib /home/nick/Perl/perl/dist/Carp/lib /home/nick/Perl/perl/dist/Cwd /home/nick/Perl/perl/dist/Cwd/lib /home/nick/Perl/perl/dist/ExtUtils-Command/lib /home/nick/Perl/perl/dist/ExtUtils-Install/lib /home/nick/Perl/perl/cpan/ExtUtils-MakeMaker/lib /home/nick/Perl/perl/dist/ExtUtils-Manifest/lib /home/nick/Perl/perl/cpan/File-Path/lib /home/nick/Perl/perl/ext/re /home/nick/Perl/perl/dist/Term-ReadLine/lib /home/nick/Perl/perl/lib .) at /home/nick/Perl/perl/lib/version/ line 863.

(which prevents lib/ from being built)

The problem is this, and I can't see a direct way round it:

sub _find_magic_vstring {
    my $value = shift;
    my $tvalue = '';
    require B;
    my $sv = B::svref_2object(\$value);
    my $magic = ref($sv) eq 'B::PVMG' ? $sv->MAGIC : undef;
    while ( $magic ) {
	if ( $magic->TYPE eq 'V' ) {
	    $tvalue = $magic->PTR;
	    $tvalue =~ s/^v?(.+)$/v$1/;
	else {
	    $magic = $magic->MOREMAGIC;
    return $tvalue;

so that approach doesn't see to work. So:

> Because if that's a yes, then there looks like a route to getting all
> of etc into cpan/, and that painful can of worms
> squished. 

But I think another approach might well work.

I *think* that the code in version's vutil/vutil.c is (pretty much) exactly
the code in (part of) util.c

1) Hence, it ought to be possible to #include "cpan/version/vutil/vutil.c"
   from util.c, and de-dup the code. It will likely need a few #defines
   and #ifdefs added in a couple of places.

I *think* that the code in universal.c is supposed to be the same as
the version/vutil/vxs.c that ExtUtils::ParseXS generates from vxs.xs

Whilst we have somewhat a bootstrapping problem in that miniperl needs that
code to build lib/ to build ... to build ExtUtils::ParseXS to build
that code, *unlike* DynaLoader this isn't horrible platform specific mess.
So it might well be possible to

2) split out that bit of universal.c into another C file which is #include-ed
   from universal.c

3) potentially, automate *generating* that file from vxs.xs (in some fashion),
   and having a script in regen/ to do this, and a test in t/porting/regen.t
   to check that it doesn't diverge.

Does anyone want to try this, or should I add it to Porting/todo.pod so that
it doesn't get lost?

Nicholas Clark

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About