summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuke Leto <jonathan@leto.net>2009-06-22 00:13:53 -0700
committerDuke Leto <jonathan@leto.net>2009-06-22 00:13:53 -0700
commitad6656ab324af5697588484c4746401e1770fa57 (patch)
tree71f1fa609fa806ce6f70f6b764262c239f93d782
parenteb78bf8f0da016f321bb20da1ca06461c3356b39 (diff)
parentb953482e2d970eeb88de96a38c087d03db83a5cd (diff)
downloadperl-ad6656ab324af5697588484c4746401e1770fa57.tar.gz
Merge branch 'blead' into debugger_symbols
-rwxr-xr-xConfigure4
-rw-r--r--MANIFEST4
-rw-r--r--Porting/Maintainers.pl58
-rw-r--r--Porting/add-package.pl6
-rwxr-xr-xPorting/core-cpan-diff591
-rw-r--r--Porting/expand-macro.pl8
-rw-r--r--embed.fnc5
-rw-r--r--embed.h8
-rwxr-xr-xext/threads-shared/Makefile.PL2
-rw-r--r--ext/threads-shared/shared.pm8
-rw-r--r--ext/threads-shared/t/0nothread.t9
-rw-r--r--ext/threads-shared/t/av_refs.t4
-rw-r--r--ext/threads-shared/t/av_simple.t4
-rw-r--r--ext/threads-shared/t/blessed.t4
-rw-r--r--ext/threads-shared/t/clone.t4
-rw-r--r--ext/threads-shared/t/cond.t4
-rw-r--r--ext/threads-shared/t/disabled.t7
-rw-r--r--ext/threads-shared/t/hv_refs.t4
-rw-r--r--ext/threads-shared/t/hv_simple.t4
-rw-r--r--ext/threads-shared/t/no_share.t4
-rw-r--r--ext/threads-shared/t/object.t4
-rw-r--r--ext/threads-shared/t/shared_attr.t4
-rw-r--r--ext/threads-shared/t/stress.t4
-rw-r--r--ext/threads-shared/t/sv_refs.t4
-rw-r--r--ext/threads-shared/t/sv_simple.t4
-rw-r--r--ext/threads-shared/t/utf8.t4
-rw-r--r--ext/threads-shared/t/wait.t5
-rw-r--r--ext/threads-shared/t/waithires.t5
-rw-r--r--handy.h6
-rw-r--r--hv.c43
-rw-r--r--lib/CPANPLUS/t/031_CPANPLUS-Internals-Source-SQLite.t80
-rw-r--r--lib/CPANPLUS/t/032_CPANPLUS-Internals-Source-via-sqlite.t14
-rw-r--r--lib/Module/Build.pm9
-rw-r--r--lib/Module/Build/API.pod10
-rw-r--r--lib/Module/Build/Authoring.pod3
-rw-r--r--lib/Module/Build/Base.pm128
-rw-r--r--lib/Module/Build/Compat.pm20
-rw-r--r--lib/Module/Build/Config.pm2
-rw-r--r--lib/Module/Build/ConfigData.pm66
-rw-r--r--lib/Module/Build/Cookbook.pm3
-rw-r--r--lib/Module/Build/Dumper.pm2
-rw-r--r--lib/Module/Build/ModuleInfo.pm2
-rw-r--r--lib/Module/Build/Notes.pm2
-rw-r--r--lib/Module/Build/PPMMaker.pm8
-rw-r--r--lib/Module/Build/Platform/Amiga.pm2
-rw-r--r--lib/Module/Build/Platform/Default.pm2
-rw-r--r--lib/Module/Build/Platform/EBCDIC.pm2
-rw-r--r--lib/Module/Build/Platform/MPEiX.pm2
-rw-r--r--lib/Module/Build/Platform/MacOS.pm2
-rw-r--r--lib/Module/Build/Platform/RiscOS.pm2
-rw-r--r--lib/Module/Build/Platform/Unix.pm9
-rw-r--r--lib/Module/Build/Platform/VMS.pm67
-rw-r--r--lib/Module/Build/Platform/VOS.pm2
-rw-r--r--lib/Module/Build/Platform/Windows.pm2
-rw-r--r--lib/Module/Build/Platform/aix.pm2
-rw-r--r--lib/Module/Build/Platform/cygwin.pm2
-rw-r--r--lib/Module/Build/Platform/darwin.pm2
-rw-r--r--lib/Module/Build/Platform/os2.pm2
-rw-r--r--lib/Module/Build/PodParser.pm2
-rwxr-xr-xlib/Module/Build/scripts/bundle.pl53
-rw-r--r--lib/Module/Build/t/bundled/Tie/CPHash.pm2
-rw-r--r--lib/Module/Build/t/compat.t63
-rw-r--r--lib/Module/Build/t/ext.t8
-rw-r--r--lib/Module/Build/t/extend.t4
-rw-r--r--lib/Module/Build/t/metadata.t20
-rw-r--r--lib/Module/Build/t/runthrough.t19
-rw-r--r--make_patchnum.pl40
-rw-r--r--perl.c13
-rw-r--r--perlio.c12
-rw-r--r--pod/perl5110delta.pod8
-rw-r--r--pod/perlfunc.pod2
-rw-r--r--pod/perlhack.pod54
-rw-r--r--pod/perlre.pod1
-rw-r--r--pod/perlrebackslash.pod1
-rw-r--r--pod/perlrecharclass.pod10
-rw-r--r--pod/perlreref.pod1
-rw-r--r--pod/perltodo.pod6
-rw-r--r--proto.h9
-rw-r--r--regcomp.c32
-rw-r--r--sv.h2
-rw-r--r--t/op/re_tests22
-rw-r--r--t/op/stash.t86
-rw-r--r--util.c138
-rw-r--r--vms/ext/filespec.t1
-rw-r--r--vms/vms.c2
85 files changed, 1337 insertions, 548 deletions
diff --git a/Configure b/Configure
index d50fa26021..85e192c48e 100755
--- a/Configure
+++ b/Configure
@@ -25,7 +25,7 @@
# $Id: Head.U 6 2006-08-25 22:21:46Z rmanfredi $
#
-# Generated on Thu Jun 4 09:30:45 CEST 2009 [metaconfig 3.5 PL0]
+# Generated on Thu Jun 18 16:33:35 CEST 2009 [metaconfig 3.5 PL0]
# (with additional metaconfig patches by perlbug@perl.org)
cat >c1$$ <<EOF
@@ -21384,7 +21384,7 @@ $eunicefix Cppsym.try
./Cppsym < Cppsym.know > Cppsym.true
: Add in any linux cpp "predefined macros":
case "$osname::$gccversion" in
- *linux*::*.*)
+ *linux*::*.*|*gnukfreebsd*::*.*)
tHdrH=_tmpHdr
rm -f $tHdrH'.h' $tHdrH
touch $tHdrH'.h'
diff --git a/MANIFEST b/MANIFEST
index ead080d566..930d640e55 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -2018,8 +2018,6 @@ lib/CPANPLUS/Shell.pm CPANPLUS
lib/CPANPLUS/t/00_CPANPLUS-Internals-Utils.t CPANPLUS tests
lib/CPANPLUS/t/01_CPANPLUS-Configure.t CPANPLUS tests
lib/CPANPLUS/t/02_CPANPLUS-Internals.t CPANPLUS tests
-lib/CPANPLUS/t/031_CPANPLUS-Internals-Source-SQLite.t CPANPLUS tests
-lib/CPANPLUS/t/032_CPANPLUS-Internals-Source-via-sqlite.t CPANPLUS tests
lib/CPANPLUS/t/03_CPANPLUS-Internals-Source.t CPANPLUS tests
lib/CPANPLUS/t/04_CPANPLUS-Module.t CPANPLUS tests
lib/CPANPLUS/t/05_CPANPLUS-Internals-Fetch.t CPANPLUS tests
@@ -2573,7 +2571,6 @@ lib/Module/Build/Platform/Windows.pm Module::Build
lib/Module/Build.pm Module::Build
lib/Module/Build/PodParser.pm Module::Build
lib/Module/Build/PPMMaker.pm Module::Build
-lib/Module/Build/scripts/bundle.pl Module::Build
lib/Module/Build/scripts/config_data Module::Build
lib/Module/Build/t/add_property.t Module::Build
lib/Module/Build/t/basic.t Module::Build
@@ -3707,6 +3704,7 @@ Porting/config_H Sample config.h
Porting/config_h.pl Reorder config_h.SH after metaconfig
Porting/config.sh Sample config.sh
Porting/Contract Social contract for contributed modules in Perl core
+Porting/core-cpan-diff Compare core distros with their CPAN equivalents
Porting/corecpan.pl Reports outdated dual-lived modules
Porting/corelist.pl Generates data for Module::CoreList
Porting/curliff.pl Curliff or liff your curliffable files.
diff --git a/Porting/Maintainers.pl b/Porting/Maintainers.pl
index 10a5c1ae9d..cc6f4c067c 100644
--- a/Porting/Maintainers.pl
+++ b/Porting/Maintainers.pl
@@ -88,6 +88,21 @@ package Maintainers;
'zefram' => 'Andrew Main <zefram@cpan.org>',
);
+
+# IGNORABLE: files which, if they appear in the root of a CPAN
+# distribution, need not appear in core (i.e. core-cpan-diff won't
+# complain if it can't find them)
+
+@IGNORABLE = qw(
+ .cvsignore .dualLivedDiffConfig .gitignore
+ ANNOUNCE Announce Artistic AUTHORS BENCHMARK BUGS Build.PL
+ CHANGELOG ChangeLog CHANGES Changes COPYING Copying CREDITS
+ GOALS HISTORY INSTALL INSTALL.SKIP LICENSE Makefile.PL
+ MANIFEST MANIFEST.SKIP META.yml NEW NOTES ppport.h README
+ SIGNATURE THANKS TODO Todo VERSION WHATSNEW
+);
+
+
# Each entry in the %Modules hash roughly represents a distribution,
# except in the case of CPAN=1, where it *exactly* represents a single
# CPAN distribution.
@@ -119,6 +134,37 @@ package Maintainers;
# included in core are derived from. Note that the file's version may not
# necessarily match the newest version on CPAN.
+# EXCLUDED is a list of files to be excluded from a CPAN tarball before
+# comparing the remaining contents with core. Each item can either be a
+# full pathname (eg 't/foo.t') or a pattern (e.g. qr{^t/}).
+# It defaults to the empty list.
+
+# MAP is a hash that maps CPAN paths to their core equivalents.
+# Each key reprepresents a string prefix, with longest prefixes checked
+# first. The first match causes that prefix to be replaced with the
+# corresponding key. For example, with the following MAP:
+# {
+# 'lib/' => 'lib/',
+# '' => 'lib/Foo/',
+# },
+#
+# these files are mapped as shown:
+#
+# README becomes lib/Foo/README
+# lib/Foo.pm becomes lib/Foo.pm
+#
+# The default is dependent on the type of module.
+# For distributions which appear to be stored under ext/, it defaults to:
+#
+# { '' => 'ext/Foo-Bar/' }
+#
+# otherwise, it's
+#
+# {
+# 'lib/' => 'lib/',
+# '' => 'lib/Foo/Bar/',
+# }
+
%Modules = (
'Archive::Extract' =>
@@ -419,6 +465,8 @@ package Maintainers;
'EXCLUDED' => [ qr{^inc/},
qr{^t/dummy-.*\.hidden$},
qw{ bin/cpanp-boxed
+ t/031_CPANPLUS-Internals-Source-SQLite.t
+ t/032_CPANPLUS-Internals-Source-via-sqlite.t
},
],
'CPAN' => 1,
@@ -1122,11 +1170,11 @@ package Maintainers;
'Module::Build' =>
{
'MAINTAINER' => 'kwilliams',
- 'DISTRIBUTION' => 'EWILHELM/Module-Build-0.32.tar.gz',
+ 'DISTRIBUTION' => 'DAGOLDEN/Module-Build-0.33_02.tar.gz',
'FILES' => q[lib/Module/Build lib/Module/Build.pm],
- 'EXCLUDED' => [ qw{ t/par.t t/signature.t }, ],
+ 'EXCLUDED' => [ qw{ t/par.t t/signature.t scripts/bundle.pl}, ],
'CPAN' => 1,
- 'UPSTREAM' => undef,
+ 'UPSTREAM' => 'cpan',
},
'Module::CoreList' =>
@@ -1195,7 +1243,7 @@ package Maintainers;
'NEXT' =>
{
'MAINTAINER' => 'rafl',
- 'DISTRIBUTION' => 'FLORA/NEXT-0.63.tar.gz',
+ 'DISTRIBUTION' => 'FLORA/NEXT-0.64.tar.gz',
'FILES' => q[lib/NEXT.pm lib/NEXT],
'EXCLUDED' => [ qr{^demo/} ],
'CPAN' => 1,
@@ -1795,7 +1843,7 @@ package Maintainers;
'threads' =>
{
'MAINTAINER' => 'jdhedden',
- 'DISTRIBUTION' => 'JDHEDDEN/threads-1.72.tar.gz',
+ 'DISTRIBUTION' => 'JDHEDDEN/threads-1.73.tar.gz',
'FILES' => q[ext/threads],
'EXCLUDED' => [ qw(examples/pool.pl
t/pod.t
diff --git a/Porting/add-package.pl b/Porting/add-package.pl
index c8fe807cf6..20947c0b53 100644
--- a/Porting/add-package.pl
+++ b/Porting/add-package.pl
@@ -75,12 +75,12 @@ my @LibFiles;
@LibFiles = map { chomp; $_ }
### should we get rid of this file?
grep { $ExcludeRe && $_ =~ $ExcludeRe
- ? do { warn "Removing $_\n";
- system("rm $_") and die "rm '$_' failed: $?";
+ ? do { warn "Removing $Repo/$_\n";
+ system("rm $Repo/$_") and die "rm '$Repo/$_' failed: $?";
undef
}
: 1
- } `find lib -type f`
+ } `find $Repo/lib -type f`
or die "Could not detect library files\n";
print "done\n" if $Verbose;
diff --git a/Porting/core-cpan-diff b/Porting/core-cpan-diff
new file mode 100755
index 0000000000..80d6b7d211
--- /dev/null
+++ b/Porting/core-cpan-diff
@@ -0,0 +1,591 @@
+#!/usr/bin/env perl
+
+# core-cpan-diff: Compare CPAN modules with their equivalent in core
+
+# Originally based on App::DualLivedDiff by Steffen Mueller.
+
+use strict;
+use warnings;
+
+use 5.010;
+
+use Getopt::Long;
+use File::Temp ();
+use File::Path ();
+use File::Spec;
+use Archive::Extract;
+use IO::Uncompress::Gunzip ();
+use File::Compare ();
+use ExtUtils::Manifest;
+
+BEGIN { die "Must be run from root of perl source tree\n" unless -d 'Porting' }
+use lib 'Porting';
+use Maintainers ();
+
+# if running from blead, we may be doing -Ilib, which means when we
+# 'chdir /tmp/foo', Archive::Extract may not find Archive::Tar etc.
+# So preload the things we need, and tell it to check %INC first:
+
+use Archive::Tar;
+use IPC::Open3;
+use IO::Select;
+$Module::Load::Conditional::CHECK_INC_HASH = 1;
+# stop Archive::Extract whinging about lack of Archive::Zip
+$Archive::Extract::WARN = 0;
+
+
+# Files, which if they exist in CPAN but not in perl, will not generate
+# an 'Only in CPAN' listing
+#
+our %IGNORABLE = map { ($_ => 1) }
+ qw(.cvsignore .dualLivedDiffConfig .gitignore
+ ANNOUNCE Announce Artistic AUTHORS BENCHMARK BUGS Build.PL
+ CHANGELOG ChangeLog CHANGES Changes COPYING Copying CREDITS
+ GOALS HISTORY INSTALL INSTALL.SKIP LICENSE Makefile.PL
+ MANIFEST MANIFEST.SKIP META.yml NEW NOTES ppport.h README
+ SIGNATURE THANKS TODO Todo VERSION WHATSNEW);
+
+# where, under the cache dir, to untar stuff to
+
+use constant UNTAR_DIR => 'untarred';
+
+use constant DIFF_CMD => 'diff';
+use constant WGET_CMD => 'wget';
+
+sub usage {
+ print STDERR "\n@_\n\n" if @_;
+ print STDERR <<HERE;
+Usage: $0 [opts] [ -d | -v | -x ] [ -a | module ... ]
+
+-a/--all Scan all dual-life modules.
+
+-c/--cachedir Where to save downloaded CPAN tarball files
+ (defaults to /tmp/something/ with deletion after each run).
+
+-d/--diff Display file differences using diff(1), rather than just
+ listing which files have changed.
+ The diff(1) command is assumed to be in your PATH.
+
+--diffopts Options to pass to the diff command. Defaults to '-u'.
+
+-f|force Force download from CPAN of new 02packages.details.txt file
+ (with --crosscheck only).
+
+-o/--output File name to write output to (defaults to STDOUT).
+
+-r/--reverse Reverses the diff (perl to CPAN).
+
+-v/--verbose List the fate of *all* files in the tarball, not just those
+ that differ or are missing.
+
+-x|crosscheck List the distributions whose current CPAN version differs from
+ that in blead (i.e. the DISTRIBUTION field in Maintainers.pl).
+
+By default (i.e. without the --crosscheck option), for each listed module
+(or with -a, all CPAN modules listed in Maintainers.pl), grab the tarball
+from CPAN associated with that module, and compare the files in it with
+those in the perl source tree.
+
+Must be run from the root of the perl source tree.
+Module names must match the keys of %Modules in Maintainers.pl.
+HERE
+ exit(1);
+}
+
+
+sub run {
+ my $scan_all;
+ my $diff_opts;
+ my $reverse = 0;
+ my $cache_dir;
+ my $use_diff;
+ my $output_file;
+ my $verbose;
+ my $force;
+ my $do_crosscheck;
+
+ GetOptions(
+ 'a|all' => \$scan_all,
+ 'c|cachedir=s' => \$cache_dir,
+ 'd|diff' => \$use_diff,
+ 'diffopts:s' => \$diff_opts,
+ 'f|force' => \$force,
+ 'h|help' => \&usage,
+ 'o|output=s' => \$output_file,
+ 'r|reverse' => \$reverse,
+ 'v|verbose' => \$verbose,
+ 'x|crosscheck' => \$do_crosscheck,
+ ) or usage;
+
+
+ my @modules;
+
+ usage("Cannot mix -a with module list") if $scan_all && @ARGV;
+
+ if ($do_crosscheck) {
+ usage("can't use -r, -d, --diffopts, -v with --crosscheck")
+ if ($reverse || $use_diff || $diff_opts || $verbose);
+ }
+ else {
+ $diff_opts = '-u' unless defined $diff_opts;
+ usage("can't use -f without --crosscheck") if $force;
+ }
+
+ @modules = $scan_all
+ ? grep $Maintainers::Modules{$_}{CPAN},
+ (sort {lc $a cmp lc $b } keys %Maintainers::Modules)
+ : @ARGV;
+ usage("No modules specified") unless @modules;
+
+
+ my $outfh;
+ if (defined $output_file) {
+ open $outfh, '>', $output_file
+ or die "ERROR: could not open file '$output_file' for writing: $!";
+ }
+ else {
+ open $outfh, ">&STDOUT"
+ or die "ERROR: can't dup STDOUT: $!";
+ }
+
+ if (defined $cache_dir) {
+ die "ERROR: no such directory: '$cache_dir'\n" unless -d $cache_dir;
+ }
+
+ if ($do_crosscheck) {
+ do_crosscheck($outfh, $cache_dir, $force, \@modules);
+ }
+ else {
+ do_compare(\@modules, $outfh, $cache_dir, $verbose, $use_diff,
+ $reverse, $diff_opts);
+ }
+}
+
+
+
+# compare a list of modules against their CPAN equivalents
+
+sub do_compare {
+ my ($modules, $outfh, $cache_dir, $verbose,
+ $use_diff, $reverse, $diff_opts) = @_;
+
+
+ # first, make sure we have a directory where they can all be untarred,
+ # and if its a permanent directory, clear any previous content
+ my $untar_dir;
+ if ($cache_dir) {
+ $untar_dir = File::Spec->catdir($cache_dir, UNTAR_DIR);
+ if (-d $untar_dir) {
+ File::Path::rmtree($untar_dir)
+ or die "failed to remove $untar_dir\n";
+ }
+ mkdir $untar_dir
+ or die "mkdir $untar_dir: $!\n";
+ }
+ else {
+ $untar_dir = File::Temp::tempdir( CLEANUP => 1 );
+ }
+
+ my %ignorable = map { ($_ => 1) } @Maintainers::IGNORABLE;
+
+ my %seen_dist;
+ for my $module (@$modules) {
+ print $outfh "\n$module\n" unless $use_diff;
+
+ my $m = $Maintainers::Modules{$module}
+ or die "ERROR: No such module in Maintainers.pl: '$module'\n";
+
+ unless ($m->{CPAN}) {
+ print $outfh "WARNING: $module is not dual-life; skipping\n";
+ next;
+ }
+
+ my $dist = $m->{DISTRIBUTION};
+ die "ERROR: $module has no DISTRIBUTION entry\n" unless defined $dist;
+
+ if ($seen_dist{$dist}) {
+ warn "WARNING: duplicate entry for $dist in $module\n"
+ }
+ $seen_dist{$dist}++;
+
+ my $cpan_dir = get_distribution($cache_dir, $untar_dir, $module, $dist);
+
+
+ my @perl_files = Maintainers::get_module_files($module);
+
+ my $manifest = File::Spec->catfile($cpan_dir, 'MANIFEST');
+ die "ERROR: no such file: $manifest\n" unless -f $manifest;
+
+ my $cpan_files = ExtUtils::Manifest::maniread($manifest);
+ my @cpan_files = sort keys %$cpan_files;
+
+ my ($excluded, $map) = get_map($m, $module, \@perl_files);
+
+ my %perl_unseen;
+ @perl_unseen{@perl_files} = ();
+ my %perl_files = %perl_unseen;
+
+ foreach my $cpan_file (@cpan_files) {
+ my $mapped_file = cpan_to_perl($excluded, $map, $cpan_file);
+ unless (defined $mapped_file) {
+ print $outfh " Excluded: $cpan_file\n" if $verbose;
+ next;
+ }
+
+ if (exists $perl_files{$mapped_file}) {
+ delete $perl_unseen{$mapped_file};
+ }
+ else {
+ # some CPAN files foo are stored in core as foo.packed,
+ # which are then unpacked by 'make test_prep'
+ my $packed_file = "$mapped_file.packed";
+ if (exists $perl_files{$packed_file} ) {
+ if (! -f $mapped_file and -f $packed_file) {
+ print $outfh <<EOF;
+WARNING: $mapped_file not found, but .packed variant exists.
+Perhaps you need to run 'make test_prep'?
+EOF
+ next;
+ }
+ delete $perl_unseen{$packed_file};
+ }
+ else {
+ if ($ignorable{$cpan_file}) {
+ print $outfh " Ignored: $cpan_file\n" if $verbose;
+ next;
+ }
+
+ unless ($use_diff) {
+ print $outfh " CPAN only: $cpan_file",
+ ($cpan_file eq $mapped_file) ? "\n"
+ : " (expected $mapped_file)\n";
+ }
+ next;
+ }
+ }
+
+
+ my $abs_cpan_file = File::Spec->catfile($cpan_dir, $cpan_file);
+
+ # should never happen
+ die "ERROR: can't find file $abs_cpan_file\n" unless -f $abs_cpan_file;
+
+ # might happen if the FILES entry in Maintainers.pl is wrong
+ unless (-f $mapped_file) {
+ print $outfh "WARNING: perl file not found: $mapped_file\n";
+ next;
+ }
+
+
+ if (File::Compare::compare($abs_cpan_file, $mapped_file)) {
+ if ($use_diff) {
+ file_diff($outfh, $abs_cpan_file, $mapped_file,
+ $reverse, $diff_opts);
+ }
+ else {
+ if ($cpan_file eq $mapped_file) {
+ print $outfh " Modified: $cpan_file\n";
+ }
+ else {
+ print $outfh " Modified: $cpan_file $mapped_file\n";
+ }
+ }
+ }
+ elsif ($verbose) {
+ if ($cpan_file eq $mapped_file) {
+ print $outfh " Unchanged: $cpan_file\n";
+ }
+ else {
+ print $outfh " Unchanged: $cpan_file $mapped_file\n";
+ }
+ }
+ }
+ for (sort keys %perl_unseen) {
+ print $outfh " Perl only: $_\n" unless $use_diff;
+ }
+ }
+}
+
+# given FooBar-1.23_45.tar.gz, return FooBar
+
+sub distro_base {
+ my $d = shift;
+ $d =~ s/\.tar\.gz$//;
+ $d =~ s/\.gip$//;
+ $d =~ s/[\d\-_\.]+$//;
+ return $d;
+}
+
+# process --crosscheck action:
+# ie list all distributions whose CPAN versions differ from that listed in
+# Maintainers.pl
+
+sub do_crosscheck {
+ my ($outfh, $cache_dir, $force, $modules) = @_;
+
+ my $file = '02packages.details.txt';
+ my $download_dir = $cache_dir || File::Temp::tempdir( CLEANUP => 1 );
+ my $path = File::Spec->catfile($download_dir, $file);
+ my $gzfile = "$path.gz";
+
+ # grab 02packages.details.txt
+
+ my $url = 'http://www.cpan.org/modules/02packages.details.txt.gz';
+
+ if (! -f $gzfile or $force) {
+ unlink $gzfile;
+ my_getstore($url, $gzfile);
+ }
+ unlink $path;
+ IO::Uncompress::Gunzip::gunzip($gzfile, $path)
+ or die "ERROR: failed to ungzip $gzfile: $IO::Uncompress::Gunzip::GunzipError\n";
+
+ # suck in the data from it
+
+ open my $fh, '<', $path
+ or die "ERROR: open: $file: $!\n";
+
+ my %distros;
+ my %modules;
+
+ while (<$fh>) {
+ next if 1../^$/;
+ chomp;
+ my @f = split ' ', $_;
+ if (@f != 3) {
+ warn "WARNING: $file:$.: line doesn't have three fields (skipping)\n";
+ next;
+ }
+ $modules{$f[0]} = $f[2];
+
+ my $distro = $f[2];
+ $distro =~ s{^.*/}{};
+
+ $distros{distro_base($distro)}{$distro} = 1;
+ }
+
+ for my $module (@$modules) {
+ my $m = $Maintainers::Modules{$module}
+ or die "ERROR: No such module in Maintainers.pl: '$module'\n";
+
+ unless ($m->{CPAN}) {
+ print $outfh "\nWARNING: $module is not dual-life; skipping\n";
+ next;
+ }
+
+
+ # given an try like
+ # Foo::Bar 1.23 foo-bar-1.23.tar.gz,
+ # first compare the module name against Foo::Bar, and failing that,
+ # against foo-bar
+
+ my $pdist = $m->{DISTRIBUTION};
+ die "ERROR: $module has no DISTRIBUTION entry\n" unless defined $pdist;
+ $pdist =~ s{^.*/}{};
+
+ my $cdist = $modules{$module};
+
+ if (defined $cdist) {
+ $cdist =~ s{^.*/}{};
+ }
+ else {
+ my $d = $distros{distro_base($pdist)};
+ unless (defined $d) {
+ print $outfh "\n$module: Can't determine current CPAN entry\n";
+ next;
+ }
+ if (keys %$d > 1) {
+ print $outfh "\n$module: (found more than one CPAN candidate):\n";
+ print $outfh " perl: $pdist\n";
+ print $outfh " CPAN: $_\n" for sort keys %$d;
+ next;
+ }
+ $cdist = (keys %$d)[0];
+ }
+
+ if ($cdist ne $pdist) {
+ print $outfh "\n$module:\n Perl: $pdist\n CPAN: $cdist\n";
+ }
+ }
+}
+
+
+
+# get the EXCLUDED and MAP entries for this module, or
+# make up defauts if they don't exist
+
+sub get_map {
+ my ($m, $module_name, $perl_files) = @_;
+
+ my ($excluded, $map) = @$m{qw(EXCLUDED MAP)};
+
+ $excluded ||= [];
+
+ return $excluded, $map if $map;
+
+ # all files under ext/foo-bar (plus maybe some under t/lib)???
+
+ my $ext;
+ for (@$perl_files) {
+ if (m{^(ext/[^/]+/)}) {
+ if (defined $ext and $ext ne $1) {
+ # more than one ext/$ext/
+ undef $ext;
+ last;
+ }
+ $ext = $1;
+ }
+ elsif (m{^t/lib/}) {
+ next;
+ }
+ else {
+ undef $ext;
+ last;
+ }
+ }
+
+ if (defined $ext) {
+ $map = { '' => $ext },
+ }
+ else {
+ (my $base = $module_name) =~ s{::}{/}g;
+ $base ="lib/$base";
+ $map = {
+ 'lib/' => 'lib/',
+ '' => "$base/",
+ };
+ }
+ return $excluded, $map;
+}
+
+
+# Given an exclude list and a mapping hash, convert a CPAN filename
+# (eg 't/bar.t') to the equivalent perl filename (eg 'lib/Foo/Bar/t/bar.t').
+# Returns an empty list for an excluded file
+
+sub cpan_to_perl {
+ my ($excluded, $map, $cpan_file) = @_;
+
+ for my $exclude (@$excluded) {
+ # may be a simple string to match exactly, or a pattern
+ if (ref $exclude) {
+ return if $cpan_file =~ $exclude;
+ }
+ else {
+ return if $cpan_file eq $exclude;
+ }
+ }
+
+ my $perl_file = $cpan_file;
+
+ # try longest prefix first, then alphabetically on tie-break
+ for my $prefix (sort { length($b) <=> length($a) || $a cmp $b } keys %$map)
+ {
+ last if $perl_file =~ s/^\Q$prefix/$map->{$prefix}/;
+ }
+ return $perl_file;
+}
+
+
+
+# do LWP::Simple::getstore, possibly without LWP::Simple being available
+
+my $lwp_simple_available;
+
+sub my_getstore {
+ my ($url, $file) = @_;
+ unless (defined $lwp_simple_available) {
+ eval { require LWP::Simple };
+ $lwp_simple_available = $@ eq '';
+ }
+ if ($lwp_simple_available) {
+ return LWP::Simple::is_success(LWP::Simple::getstore($url, $file));
+ }
+ else {
+ return system(WGET_CMD, "-O", $file, $url) == 0;
+ }
+}
+
+
+# download and unpack a distribution
+# Returns the full pathname of the extracted directory
+# (eg '/tmp/XYZ/Foo_bar-1.23')
+
+# cache_dir: where to dowenload the .tar.gz file to
+# untar_dir: where to untar or unzup the file
+# module: name of module
+# dist: name of the distribution
+
+sub get_distribution {
+ my ($cache_dir, $untar_dir, $module, $dist) = @_;
+
+ $dist =~ m{.+/([^/]+)$}
+ or die "ERROR: $module: invalid DISTRIBUTION name (no AUTHOR/ prefix): $dist";
+ my $filename = $1;
+
+ my $download_dir = $cache_dir || File::Temp::tempdir( CLEANUP => 1 );
+ my $download_file = File::Spec->catfile($download_dir, $filename);
+
+ # download distribution
+
+ if (-f $download_file and ! -s $download_file ) {
+ # wget can leave a zero-length file on failed download
+ unlink $download_file;
+ }
+
+ unless (-f $download_file) {
+ # not cached
+ $dist =~ /^([A-Z])([A-Z])/
+ or die "ERROR: $module: invalid DISTRIBUTION name (not /^[A-Z]{2}/): $dist";
+
+ my $url = "http://www.cpan.org/modules/by-authors/id/$1/$1$2/$dist";
+ my_getstore($url, $download_file)
+ or die "ERROR: Could not fetch '$url'";
+ }
+
+ # extract distribution
+
+ my $ae = Archive::Extract->new( archive => $download_file);
+ $ae->extract( to => $untar_dir )
+ or die "ERROR: failed to extract distribution '$download_file to temp. dir: " . $ae->error();
+
+ # get the name of the extracted distribution dir
+
+ my $path = File::Spec->catfile($untar_dir, $filename);
+
+ $path =~ s/\.tar\.gz$// or
+ $path =~ s/\.zip$// or
+ die "ERROR: downloaded file does not have a recognised suffix: $path\n";
+
+ die "ERROR: Extracted tarball does not appear as $path\n" unless -d $path;
+
+ return $path;
+}
+
+
+# produce the diff of a single file
+sub file_diff {
+ my $outfh = shift;
+ my $cpan_file = shift;
+ my $perl_file = shift;
+ my $reverse = shift;
+ my $diff_opts = shift;
+
+
+ my @cmd = (DIFF_CMD, split ' ', $diff_opts);
+ if ($reverse) {
+ push @cmd, $perl_file, $cpan_file;
+ }
+ else {
+ push @cmd, $cpan_file, $perl_file;
+ }
+ my $result = `@cmd`;
+
+ $result =~ s{^(--- |\+\+\+ )/tmp/[^/]+/}{$1}gm;
+
+ print $outfh $result;
+}
+
+
+run();
+
diff --git a/Porting/expand-macro.pl b/Porting/expand-macro.pl
index 2cdaa79727..ed8e188efa 100644
--- a/Porting/expand-macro.pl
+++ b/Porting/expand-macro.pl
@@ -32,6 +32,7 @@ if (!(@ARGV = @headers)) {
while (<$fh>) {
push @ARGV, $1 if m!^([^/]+\.h)\t!;
}
+ push @ARGV, 'config.h' if -f 'config.h';
}
my $header;
@@ -56,7 +57,12 @@ my $sentinel = "$macro expands to";
print $out <<"EOF";
#include "EXTERN.h"
#include "perl.h"
-#include "$header"
+EOF
+
+print qq{#include "$header"\n}
+ unless $header eq 'perl.h' or $header eq 'EXTERN.h';
+
+print $out <<"EOF";
#line 4 "$sentinel"
$macro$args
EOF
diff --git a/embed.fnc b/embed.fnc
index 68f38171c7..ae5c9f67fb 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -1354,6 +1354,7 @@ paRxo |void* |get_arena |const size_t svtype|const U32 misc
#if defined(PERL_IN_HV_C) || defined(PERL_DECL_PROT)
s |void |hsplit |NN HV *hv
s |void |hfreeentries |NN HV *hv
+s |I32 |anonymise_cv |NULLOK const char *stash|NN SV *val
sa |HE* |new_he
sanR |HEK* |save_hek_flags |NN const char *str|I32 len|U32 hash|int flags
sn |void |hv_magic_check |NN HV *hv|NN bool *needs_copy|NN bool *needs_store
@@ -1593,7 +1594,7 @@ Es |UV |reg_recode |const char value|NN SV **encp
Es |regnode*|regpiece |NN struct RExC_state_t *pRExC_state \
|NN I32 *flagp|U32 depth
Es |regnode*|reg_namedseq |NN struct RExC_state_t *pRExC_state \
- |NULLOK UV *valuep
+ |NULLOK UV *valuep|NULLOK I32 *flagp
Es |void |reginsert |NN struct RExC_state_t *pRExC_state \
|U8 op|NN regnode *opnd|U32 depth
Es |void |regtail |NN struct RExC_state_t *pRExC_state \
@@ -1833,7 +1834,7 @@ s |const char *|vdie_croak_common|NULLOK const char *pat|NULLOK va_list *args \
s |bool |vdie_common |NULLOK const char *message|STRLEN msglen\
|I32 utf8|bool warn
sr |char * |write_no_mem
-#if defined(PERL_MEM_LOG) && defined(PERL_MEM_LOG_STDERR)
+#if defined(PERL_MEM_LOG) && !defined(PERL_MEM_LOG_NOIMPL)
sn |void |mem_log_common |enum mem_log_type mlt|const UV n|const UV typesize \
|NN const char *type_name|NULLOK const SV *sv \
|Malloc_t oldalloc|Malloc_t newalloc \
diff --git a/embed.h b/embed.h
index e320dc5654..6f6877f364 100644
--- a/embed.h
+++ b/embed.h
@@ -1179,6 +1179,7 @@
#ifdef PERL_CORE
#define hsplit S_hsplit
#define hfreeentries S_hfreeentries
+#define anonymise_cv S_anonymise_cv
#define new_he S_new_he
#define save_hek_flags S_save_hek_flags
#define hv_magic_check S_hv_magic_check
@@ -1621,7 +1622,7 @@
#define vdie_common S_vdie_common
#define write_no_mem S_write_no_mem
#endif
-#if defined(PERL_MEM_LOG) && defined(PERL_MEM_LOG_STDERR)
+#if defined(PERL_MEM_LOG) && !defined(PERL_MEM_LOG_NOIMPL)
#ifdef PERL_CORE
#define mem_log_common S_mem_log_common
#endif
@@ -3515,6 +3516,7 @@
#ifdef PERL_CORE
#define hsplit(a) S_hsplit(aTHX_ a)
#define hfreeentries(a) S_hfreeentries(aTHX_ a)
+#define anonymise_cv(a,b) S_anonymise_cv(aTHX_ a,b)
#define new_he() S_new_he(aTHX)
#define save_hek_flags S_save_hek_flags
#define hv_magic_check S_hv_magic_check
@@ -3756,7 +3758,7 @@
#define reg_node(a,b) S_reg_node(aTHX_ a,b)
#define reg_recode(a,b) S_reg_recode(aTHX_ a,b)
#define regpiece(a,b,c) S_regpiece(aTHX_ a,b,c)
-#define reg_namedseq(a,b) S_reg_namedseq(aTHX_ a,b)
+#define reg_namedseq(a,b,c) S_reg_namedseq(aTHX_ a,b,c)
#define reginsert(a,b,c,d) S_reginsert(aTHX_ a,b,c,d)
#define regtail(a,b,c,d) S_regtail(aTHX_ a,b,c,d)
#define reg_scan_name(a,b) S_reg_scan_name(aTHX_ a,b)
@@ -3968,7 +3970,7 @@
#define vdie_common(a,b,c,d) S_vdie_common(aTHX_ a,b,c,d)
#define write_no_mem() S_write_no_mem(aTHX)
#endif
-#if defined(PERL_MEM_LOG) && defined(PERL_MEM_LOG_STDERR)
+#if defined(PERL_MEM_LOG) && !defined(PERL_MEM_LOG_NOIMPL)
#ifdef PERL_CORE
#define mem_log_common S_mem_log_common
#endif
diff --git a/ext/threads-shared/Makefile.PL b/ext/threads-shared/Makefile.PL
index 78566171db..05c738397f 100755
--- a/ext/threads-shared/Makefile.PL
+++ b/ext/threads-shared/Makefile.PL
@@ -62,7 +62,7 @@ if (not grep { $_ eq 'PERL_CORE=1' } @ARGV) {
'Carp' => 0,
'XSLoader' => 0,
'Scalar::Util' => 0,
- 'threads' => 1.71,
+ 'threads' => 1.73,
'Test' => 0,
'Test::More' => 0,
diff --git a/ext/threads-shared/shared.pm b/ext/threads-shared/shared.pm
index 6f606b0181..722e3ceb73 100644
--- a/ext/threads-shared/shared.pm
+++ b/ext/threads-shared/shared.pm
@@ -7,7 +7,7 @@ use warnings;
use Scalar::Util qw(reftype refaddr blessed);
-our $VERSION = '1.28';
+our $VERSION = '1.29';
my $XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
@@ -187,7 +187,7 @@ threads::shared - Perl extension for sharing data structures between threads
=head1 VERSION
-This document describes threads::shared version 1.28
+This document describes threads::shared version 1.29
=head1 SYNOPSIS
@@ -401,7 +401,7 @@ important to check the value of the variable and go back to waiting if the
requirement is not fulfilled. For example, to pause until a shared counter
drops to zero:
- { lock($counter); cond_wait($count) until $counter == 0; }
+ { lock($counter); cond_wait($counter) until $counter == 0; }
=item cond_timedwait VARIABLE, ABS_TIMEOUT
@@ -588,7 +588,7 @@ L<threads::shared> Discussion Forum on CPAN:
L<http://www.cpanforum.com/dist/threads-shared>
Annotated POD for L<threads::shared>:
-L<http://annocpan.org/~JDHEDDEN/threads-shared-1.28/shared.pm>
+L<http://annocpan.org/~JDHEDDEN/threads-shared-1.29/shared.pm>
Source repository:
L<http://code.google.com/p/threads-shared/>
diff --git a/ext/threads-shared/t/0nothread.t b/ext/threads-shared/t/0nothread.t
index 36b1564a52..7609fbee1e 100644
--- a/ext/threads-shared/t/0nothread.t
+++ b/ext/threads-shared/t/0nothread.t
@@ -1,13 +1,6 @@
use strict;
use warnings;
-BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
-}
-
use Test::More (tests => 53);
### Start of Testing ###
@@ -65,7 +58,7 @@ sub array
ok((require threads::shared),"Require module");
-if ($threads::shared::VERSION && ! exists($ENV{'PERL_CORE'})) {
+if ($threads::shared::VERSION && ! $ENV{'PERL_CORE'}) {
diag('Testing threads::shared ' . $threads::shared::VERSION);
}
diff --git a/ext/threads-shared/t/av_refs.t b/ext/threads-shared/t/av_refs.t
index 2e77031280..8106e3253a 100644
--- a/ext/threads-shared/t/av_refs.t
+++ b/ext/threads-shared/t/av_refs.t
@@ -2,10 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
use Config;
if (! $Config{'useithreads'}) {
print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
diff --git a/ext/threads-shared/t/av_simple.t b/ext/threads-shared/t/av_simple.t
index 67d9a32f3a..7fab9b2b76 100644
--- a/ext/threads-shared/t/av_simple.t
+++ b/ext/threads-shared/t/av_simple.t
@@ -2,10 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
use Config;
if (! $Config{'useithreads'}) {
print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
diff --git a/ext/threads-shared/t/blessed.t b/ext/threads-shared/t/blessed.t
index 225725f6f9..2599423434 100644
--- a/ext/threads-shared/t/blessed.t
+++ b/ext/threads-shared/t/blessed.t
@@ -2,10 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
use Config;
if (! $Config{'useithreads'}) {
print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
diff --git a/ext/threads-shared/t/clone.t b/ext/threads-shared/t/clone.t
index 64ef93a74e..fd31181126 100644
--- a/ext/threads-shared/t/clone.t
+++ b/ext/threads-shared/t/clone.t
@@ -2,10 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
use Config;
if (! $Config{'useithreads'}) {
print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
diff --git a/ext/threads-shared/t/cond.t b/ext/threads-shared/t/cond.t
index 3a6bfdf438..c2f02a42ed 100644
--- a/ext/threads-shared/t/cond.t
+++ b/ext/threads-shared/t/cond.t
@@ -2,10 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
use Config;
if (! $Config{'useithreads'}) {
print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
diff --git a/ext/threads-shared/t/disabled.t b/ext/threads-shared/t/disabled.t
index 161bc7909e..46e781e494 100644
--- a/ext/threads-shared/t/disabled.t
+++ b/ext/threads-shared/t/disabled.t
@@ -1,13 +1,6 @@
use strict;
use warnings;
-BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
-}
-
use Test;
plan tests => 31;
diff --git a/ext/threads-shared/t/hv_refs.t b/ext/threads-shared/t/hv_refs.t
index 3985b3c3bb..ecefdc6d5b 100644
--- a/ext/threads-shared/t/hv_refs.t
+++ b/ext/threads-shared/t/hv_refs.t
@@ -2,10 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
use Config;
if (! $Config{'useithreads'}) {
print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
diff --git a/ext/threads-shared/t/hv_simple.t b/ext/threads-shared/t/hv_simple.t
index e80cd0882d..574d8d5508 100644
--- a/ext/threads-shared/t/hv_simple.t
+++ b/ext/threads-shared/t/hv_simple.t
@@ -2,10 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
use Config;
if (! $Config{'useithreads'}) {
print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
diff --git a/ext/threads-shared/t/no_share.t b/ext/threads-shared/t/no_share.t
index 7c97b228ab..21703ae664 100644
--- a/ext/threads-shared/t/no_share.t
+++ b/ext/threads-shared/t/no_share.t
@@ -2,10 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
use Config;
if (! $Config{'useithreads'}) {
print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
diff --git a/ext/threads-shared/t/object.t b/ext/threads-shared/t/object.t
index 394ed6a581..4e3c189037 100644
--- a/ext/threads-shared/t/object.t
+++ b/ext/threads-shared/t/object.t
@@ -2,10 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
use Config;
if (! $Config{'useithreads'}) {
print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
diff --git a/ext/threads-shared/t/shared_attr.t b/ext/threads-shared/t/shared_attr.t
index 09f231032e..9085e27f30 100644
--- a/ext/threads-shared/t/shared_attr.t
+++ b/ext/threads-shared/t/shared_attr.t
@@ -2,10 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
use Config;
if (! $Config{'useithreads'}) {
print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
diff --git a/ext/threads-shared/t/stress.t b/ext/threads-shared/t/stress.t
index 9fe1c217d1..e36ab0ab3a 100644
--- a/ext/threads-shared/t/stress.t
+++ b/ext/threads-shared/t/stress.t
@@ -2,10 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
use Config;
if (! $Config{'useithreads'}) {
print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
diff --git a/ext/threads-shared/t/sv_refs.t b/ext/threads-shared/t/sv_refs.t
index 30173bd29e..5cc6a22ecd 100644
--- a/ext/threads-shared/t/sv_refs.t
+++ b/ext/threads-shared/t/sv_refs.t
@@ -2,10 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
use Config;
if (! $Config{'useithreads'}) {
print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
diff --git a/ext/threads-shared/t/sv_simple.t b/ext/threads-shared/t/sv_simple.t
index f4cbcf280b..9d264f7d31 100644
--- a/ext/threads-shared/t/sv_simple.t
+++ b/ext/threads-shared/t/sv_simple.t
@@ -2,10 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
use Config;
if (! $Config{'useithreads'}) {
print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
diff --git a/ext/threads-shared/t/utf8.t b/ext/threads-shared/t/utf8.t
index 42e7c3f414..6e0e664d1c 100644
--- a/ext/threads-shared/t/utf8.t
+++ b/ext/threads-shared/t/utf8.t
@@ -2,10 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
use Config;
if (! $Config{'useithreads'}) {
print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
diff --git a/ext/threads-shared/t/wait.t b/ext/threads-shared/t/wait.t
index b0a7cc1e85..2c367fd075 100644
--- a/ext/threads-shared/t/wait.t
+++ b/ext/threads-shared/t/wait.t
@@ -2,11 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
-
# Import test.pl into its own package
{
package Test;
diff --git a/ext/threads-shared/t/waithires.t b/ext/threads-shared/t/waithires.t
index 4cda602f9e..ae82448f57 100644
--- a/ext/threads-shared/t/waithires.t
+++ b/ext/threads-shared/t/waithires.t
@@ -2,11 +2,6 @@ use strict;
use warnings;
BEGIN {
- if ($ENV{'PERL_CORE'}){
- chdir 't';
- unshift @INC, '../lib';
- }
-
# Import test.pl into its own package
{
package Test;
diff --git a/handy.h b/handy.h
index 9e8f50a30b..d39066752c 100644
--- a/handy.h
+++ b/handy.h
@@ -761,7 +761,7 @@ PoisonWith(0xEF) for catching access to freed memory.
* which more importantly get the immediate calling environment (file and
* line number, and C function name if available) passed in. This info can
* then be used for logging the calls, for which one gets a sample
- * implementation if PERL_MEM_LOG_STDERR is defined.
+ * implementation unless -DPERL_MEM_LOG_NOIMPL is also defined.
*
* Known problems:
* - all memory allocs do not get logged, only those
@@ -783,6 +783,8 @@ PoisonWith(0xEF) for catching access to freed memory.
* (keyed by the allocation address?), and maintain that
* through reallocs and frees, but how to do that without
* any News() happening...?
+ * - lots of -Ddefines to get useful/controllable output
+ * - lots of ENV reads
*/
PERL_EXPORT_C Malloc_t Perl_mem_log_alloc(const UV n, const UV typesize, const char *type_name, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname);
@@ -792,7 +794,7 @@ PERL_EXPORT_C Malloc_t Perl_mem_log_realloc(const UV n, const UV typesize, const
PERL_EXPORT_C Malloc_t Perl_mem_log_free(Malloc_t oldalloc, const char *filename, const int linenumber, const char *funcname);
# ifdef PERL_CORE
-# ifdef PERL_MEM_LOG_STDERR
+# ifndef PERL_MEM_LOG_NOIMPL
enum mem_log_type {
MLT_ALLOC,
MLT_REALLOC,
diff --git a/hv.c b/hv.c
index ebb10fbd34..8d1c6a95c9 100644
--- a/hv.c
+++ b/hv.c
@@ -1468,8 +1468,8 @@ Perl_hv_free_ent(pTHX_ HV *hv, register HE *entry)
if (!entry)
return;
val = HeVAL(entry);
- if (val && isGV(val) && isGV_with_GP(val) && GvCVu(val) && HvNAME_get(hv))
- mro_method_changed_in(hv); /* deletion of method from stash */
+ if (HvNAME(hv) && anonymise_cv(HvNAME(hv), val) && GvCVu(val))
+ mro_method_changed_in(hv);
SvREFCNT_dec(val);
if (HeKLEN(entry) == HEf_SVKEY) {
SvREFCNT_dec(HeKEY_sv(entry));
@@ -1482,6 +1482,29 @@ Perl_hv_free_ent(pTHX_ HV *hv, register HE *entry)
del_HE(entry);
}
+static I32
+S_anonymise_cv(pTHX_ const char *stash, SV *val)
+{
+ CV *cv;
+
+ PERL_ARGS_ASSERT_ANONYMISE_CV;
+
+ if (val && isGV(val) && isGV_with_GP(val) && (cv = GvCV(val))) {
+ if ((SV *)CvGV(cv) == val) {
+ SV *gvname;
+ GV *anongv;
+
+ gvname = Perl_newSVpvf(aTHX_ "%s::__ANON__", stash ? stash : "__ANON__");
+ anongv = gv_fetchsv(gvname, GV_ADDMULTI, SVt_PVCV);
+ SvREFCNT_dec(gvname);
+ CvGV(cv) = anongv;
+ CvANON_on(cv);
+ return 1;
+ }
+ }
+ return 0;
+}
+
void
Perl_hv_delayfree_ent(pTHX_ HV *hv, register HE *entry)
{
@@ -1646,6 +1669,22 @@ S_hfreeentries(pTHX_ HV *hv)
if (!orig_array)
return;
+ if (HvNAME(hv) && orig_array != NULL) {
+ /* symbol table: make all the contained subs ANON */
+ STRLEN i;
+ XPVHV *xhv = (XPVHV*)SvANY(hv);
+
+ for (i = 0; i <= xhv->xhv_max; i++) {
+ HE *entry = (HvARRAY(hv))[i];
+ for (; entry; entry = HeNEXT(entry)) {
+ SV *val = HeVAL(entry);
+ /* we need to put the subs in the __ANON__ symtable, as
+ * this one is being cleared. */
+ anonymise_cv(NULL, val);
+ }
+ }
+ }
+
if (SvOOK(hv)) {
/* If the hash is actually a symbol table with a name, look after the
name. */
diff --git a/lib/CPANPLUS/t/031_CPANPLUS-Internals-Source-SQLite.t b/lib/CPANPLUS/t/031_CPANPLUS-Internals-Source-SQLite.t
deleted file mode 100644
index 730e04bd14..0000000000
--- a/lib/CPANPLUS/t/031_CPANPLUS-Internals-Source-SQLite.t
+++ /dev/null
@@ -1,80 +0,0 @@
-### make sure we can find our conf.pl file
-BEGIN {
- use FindBin;
- require "$FindBin::Bin/inc/conf.pl";
-}
-
-use strict;
-
-use Module::Load;
-use Test::More eval { load 'CPANPLUS::Internals::Source::SQLite'; 1 }
- ? 'no_plan'
- : (skip_all => "SQLite engine not available");
-
-use Data::Dumper;
-use File::Basename qw[dirname];
-use CPANPLUS::Error;
-use CPANPLUS::Backend;
-use CPANPLUS::Internals::Constants;
-
-my $conf = gimme_conf();
-
-### make sure we use the SQLite engine
-$conf->set_conf( source_engine => 'CPANPLUS::Internals::Source::SQLite' );
-
-my $cb = CPANPLUS::Backend->new( $conf );
-my $mod = TEST_CONF_MODULE;
-my $auth = TEST_CONF_AUTHOR;
-
-ok( $cb->reload_indices( update_source => 1 ),
- "Building trees" );
-ok( $cb->__sqlite_dbh, " Got a DBH " );
-ok( $cb->__sqlite_file, " Got a DB file" );
-
-
-### make sure we have trees and they're hashes
-{ ok( $cb->author_tree, "Got author tree" );
- isa_ok( $cb->author_tree, "HASH" );
-
- ok( $cb->module_tree, "Got module tree" );
- isa_ok( $cb->module_tree, "HASH" );
-}
-
-### save state, shouldn't work
-{ CPANPLUS::Error->flush;
- my $rv = $cb->save_state;
-
- ok( !$rv, "Saving state not implemented" );
- like( CPANPLUS::Error->stack_as_string, qr/not implemented/i,
- " Diagnostics confirmed" );
-}
-
-### test look ups
-{ my %map = (
- $auth => 'author_tree',
- $mod => 'module_tree',
- );
-
- while( my($str, $meth) = each %map ) {
-
- ok( $str, "Trying to retrieve $str" );
- ok( $cb->$meth( $str ), " Got $str object via ->$meth" );
- ok( $cb->$meth->{$str}, " Got author object via ->{ $str }" );
- ok( exists $cb->$meth->{ $str },
- " Testing exists() " );
- ok( not(exists( $cb->$meth->{ $$ } )),
- " And non-exists() " );
- cmp_ok( scalar(keys(%{ $cb->$meth })), ">", 1,
- " Got keys()" );
-
- cmp_ok( scalar(keys(%{ $cb->$meth })), '==', scalar(keys(%{ $cb->$meth })),
- " Keys == Values" );
-
- while( my($key,$val) = each %{ $cb->$meth } ) {
- ok( $key, " Retrieved $key via each()" );
- ok( $val, " And value" );
- ok( ref $val, " Value is a ref: $val" );
- can_ok( $val, '_id' );
- }
- }
-}
diff --git a/lib/CPANPLUS/t/032_CPANPLUS-Internals-Source-via-sqlite.t b/lib/CPANPLUS/t/032_CPANPLUS-Internals-Source-via-sqlite.t
deleted file mode 100644
index 46505f53e8..0000000000
--- a/lib/CPANPLUS/t/032_CPANPLUS-Internals-Source-via-sqlite.t
+++ /dev/null
@@ -1,14 +0,0 @@
-use strict;
-use FindBin;
-
-use Module::Load;
-
-local $ENV{CPANPLUS_SOURCE_ENGINE} = 'CPANPLUS::Internals::Source::SQLite';
-
-my $old = select STDERR; $|++;
-select $old; $|++;
-my $rv = do("$FindBin::Bin/03_CPANPLUS-Internals-Source.t") or do {
- die $@ if $@;
- die $! if $!;
-};
-
diff --git a/lib/Module/Build.pm b/lib/Module/Build.pm
index fe453b5d67..ae9639a512 100644
--- a/lib/Module/Build.pm
+++ b/lib/Module/Build.pm
@@ -15,7 +15,7 @@ use Module::Build::Base;
use vars qw($VERSION @ISA);
@ISA = qw(Module::Build::Base);
-$VERSION = '0.32_01';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
# Okay, this is the brute-force method of finding out what kind of
@@ -312,10 +312,9 @@ module for source distribution through a medium like CPAN. It will create a
tarball of the files listed in F<MANIFEST> and compress the tarball using
GZIP compression.
-By default, this action will use the external C<tar> and C<gzip>
-executables on Unix-like platforms, and the C<Archive::Tar> module
-elsewhere. However, you can force it to use whatever executable you
-want by supplying an explicit C<tar> (and optional C<gzip>) parameter:
+By default, this action will use the C<Archive::Tar> module. However, you can
+force it to use binary "tar" and "gzip" executables by supplying an explicit
+C<tar> (and optional C<gzip>) parameter:
./Build dist --tar C:\path\to\tar.exe --gzip C:\path\to\zip.exe
diff --git a/lib/Module/Build/API.pod b/lib/Module/Build/API.pod
index 83e93f5ccb..ab0691bf30 100644
--- a/lib/Module/Build/API.pod
+++ b/lib/Module/Build/API.pod
@@ -182,6 +182,16 @@ installed.
See the documentation for L<Module::Build::Authoring/"PREREQUISITES">
for the details of how requirements can be specified.
+=item create_license
+
+[version 0.31]
+
+This parameter tells Module::Build to automatically create a
+F<LICENSE> file at the top level of your distribution, containing the
+full text of the author's chosen license. This requires
+C<Software::License> on the author's machine, and further requires
+that the C<license> parameter specifies a license that it knows about.
+
=item create_makefile_pl
[version 0.19]
diff --git a/lib/Module/Build/Authoring.pod b/lib/Module/Build/Authoring.pod
index 871effdf69..a0a7dc37be 100644
--- a/lib/Module/Build/Authoring.pod
+++ b/lib/Module/Build/Authoring.pod
@@ -159,7 +159,8 @@ or C<CPANPLUS> will be expected to pick C<configure_requires> out of the
F<META.yml> file and install these items before running the
C<Build.PL>.
-*TODO* auto-add M::B? In what circumstances?
+If no configure_requires is specified, the current version of Module::Build
+is automatically added to configure_requires.
=item build_requires
diff --git a/lib/Module/Build/Base.pm b/lib/Module/Build/Base.pm
index 703218b56c..2f6282e871 100644
--- a/lib/Module/Build/Base.pm
+++ b/lib/Module/Build/Base.pm
@@ -4,7 +4,7 @@ package Module::Build::Base;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32_01';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
BEGIN { require 5.00503 }
@@ -129,6 +129,7 @@ sub _construct {
%input,
},
phash => {},
+ stash => {}, # temporary caching, not stored in _build
}, $package;
$self->_set_defaults;
@@ -1039,7 +1040,7 @@ sub dist_version {
my $version_from = File::Spec->catfile( split( qr{/}, $dist_version_from ) );
my $pm_info = Module::Build::ModuleInfo->new_from_file( $version_from )
or die "Can't find file $version_from to determine version";
- $p->{dist_version} = $pm_info->version();
+ $p->{dist_version} = $self->normalize_version( $pm_info->version() );
}
die ("Can't determine distribution version, must supply either 'dist_version',\n".
@@ -3424,7 +3425,7 @@ sub file_qr {
sub dist_dir {
my ($self) = @_;
- return "$self->{properties}{dist_name}-$self->{properties}{dist_version}";
+ return join "-", $self->dist_name, $self->dist_version;
}
sub ppm_name {
@@ -3566,34 +3567,71 @@ sub do_create_metafile {
push @INC, File::Spec->catdir($self->blib, 'lib');
}
- $self->write_metafile;
+ if ( $self->write_metafile( $self->metafile, $self->generate_metadata ) ) {
+ $self->{wrote_metadata} = 1;
+ $self->_add_to_manifest('MANIFEST', $metafile);
+ }
+
+ return 1;
}
-sub write_metafile {
+sub generate_metadata {
my $self = shift;
- my $metafile = $self->metafile;
+ my $node = {};
if ($self->_mb_feature('YAML_support')) {
require YAML;
require YAML::Node;
-
# We use YAML::Node to get the order nice in the YAML file.
- $self->prepare_metadata( my $node = YAML::Node->new({}) );
-
+ $self->prepare_metadata( $node = YAML::Node->new({}) );
+ } else {
+ require Module::Build::YAML;
+ my @order_keys;
+ $self->prepare_metadata($node, \@order_keys);
+ $node->{_order} = \@order_keys;
+ }
+ return $node;
+}
+
+sub write_metafile {
+ my $self = shift;
+ my ($metafile, $node) = @_;
+
+ if ($self->_mb_feature('YAML_support')) {
+ # XXX this is probably redundant, but stick with it
+ require YAML;
+ require YAML::Node;
+ delete $node->{_order}; # XXX also probably redundant, but for safety
# YAML API changed after version 0.30
my $yaml_sub = $YAML::VERSION le '0.30' ? \&YAML::StoreFile : \&YAML::DumpFile;
- $self->{wrote_metadata} = $yaml_sub->($metafile, $node );
-
+ $yaml_sub->( $metafile, $node );
} else {
+ # XXX probably redundant
require Module::Build::YAML;
- my (%node, @order_keys);
- $self->prepare_metadata(\%node, \@order_keys);
- $node{_order} = \@order_keys;
- &Module::Build::YAML::DumpFile($metafile, \%node);
- $self->{wrote_metadata} = 1;
+ &Module::Build::YAML::DumpFile($metafile, $node);
}
+ return 1;
+}
- $self->_add_to_manifest('MANIFEST', $metafile);
+sub normalize_version {
+ my ($self, $version) = @_;
+ if ( $version =~ /[=<>!,]/ ) { # logic, not just version
+ # take as is without modification
+ }
+ elsif ( ref $version eq 'version' ||
+ ref $version eq 'Module::Build::Version' ) { # version objects
+ my $string = $version->stringify;
+ # normalize leading-v: "v1.2" -> "v1.2.0"
+ $version = substr($string,0,1) eq 'v' ? $version->normal : $string;
+ }
+ elsif ( $version =~ /^[^v][^.]*\.[^.]+\./ ) { # no leading v, multiple dots
+ # normalize string tuples without "v": "1.2.3" -> "v1.2.3"
+ $version = "v$version";
+ }
+ else {
+ # leave alone
+ }
+ return $version;
}
sub prepare_metadata {
@@ -3613,38 +3651,57 @@ sub prepare_metadata {
die "ERROR: Missing required field '$_' for META.yml\n"
unless defined($node->{$name}) && length($node->{$name});
}
- $node->{version} = '' . $node->{version}; # Stringify version objects
+ $node->{version} = $self->normalize_version($node->{version});
if (defined( my $l = $self->license )) {
die "Unknown license string '$l'"
- unless exists $self->valid_licenses->{ $self->license };
+ unless exists $self->valid_licenses->{ $l };
- if (my $key = $self->valid_licenses->{ $self->license }) {
+ if (my $key = $self->valid_licenses->{ $l }) {
my $class = "Software::License::$key";
if (eval "use $class; 1") {
# S::L requires a 'holder' key
$node->{resources}{license} = $class->new({holder=>"nobody"})->url;
- } else {
- $node->{resources}{license} = $self->_license_url($key);
+ }
+ else {
+ $node->{resources}{license} = $self->_license_url($l);
}
}
+ # XXX we are silently omitting the url for any unknown license
}
if (exists $p->{configure_requires}) {
foreach my $spec (keys %{$p->{configure_requires}}) {
warn ("Warning: $spec is listed in 'configure_requires', but ".
- "it is not found in any of the other prereq fields.\n")
- unless grep exists $p->{$_}{$spec},
- grep !/conflicts$/, @{$self->prereq_action_types};
+ "it is not found in any of the other prereq fields.\n")
+ unless grep exists $p->{$_}{$spec},
+ grep !/conflicts$/, @{$self->prereq_action_types};
+ }
+ }
+
+ # copy prereq data structures so we can modify them before writing to META
+ my %prereq_types;
+ for my $type ( 'configure_requires', @{$self->prereq_action_types} ) {
+ if (exists $p->{$type}) {
+ for my $mod ( keys %{ $p->{$type} } ) {
+ $prereq_types{$type}{$mod} =
+ $self->normalize_version($p->{$type}{$mod});
+ }
}
}
- foreach ( 'configure_requires', @{$self->prereq_action_types} ) {
- if (exists $p->{$_} and keys %{ $p->{$_} }) {
- $add_node->($_, $p->{$_});
+ # add current Module::Build to configure_requires if there
+ # isn't a configure_requires already specified
+ if ( ! $prereq_types{'configure_requires'} ) {
+ for my $t ('configure_requires', 'build_requires') {
+ $prereq_types{$t}{'Module::Build'} = $VERSION;
}
}
+ for my $t ( keys %prereq_types ) {
+ $add_node->($t, $prereq_types{$t});
+ }
+
if (exists $p->{dynamic_config}) {
$add_node->('dynamic_config', $p->{dynamic_config});
}
@@ -3663,8 +3720,8 @@ sub prepare_metadata {
$add_node->('generated_by', "Module::Build version $Module::Build::VERSION");
$add_node->('meta-spec',
- {version => '1.2',
- url => 'http://module-build.sourceforge.net/META-spec-v1.2.html',
+ {version => '1.4',
+ url => 'http://module-build.sourceforge.net/META-spec-v1.4.html',
});
while (my($k, $v) = each %{$self->meta_add}) {
@@ -3801,9 +3858,10 @@ sub find_dist_packages {
}
}
- # Stringify versions. Can't use exists() here because of bug in YAML::Node.
+ # Normalize versions. Can't use exists() here because of bug in YAML::Node.
+ # XXX "bug in YAML::Node" comment seems irrelvant -- dagolden, 2009-05-18
for (grep defined $_->{version}, values %prime) {
- $_->{version} = '' . $_->{version};
+ $_->{version} = $self->normalize_version( $_->{version} );
}
return \%prime;
@@ -4144,13 +4202,13 @@ sub cbuilder {
# Returns a CBuilder object
my $self = shift;
- my $p = $self->{properties};
- return $p->{_cbuilder} if $p->{_cbuilder};
+ my $s = $self->{stash};
+ return $s->{_cbuilder} if $s->{_cbuilder};
die "Module::Build is not configured with C_support"
unless $self->_mb_feature('C_support');
require ExtUtils::CBuilder;
- return $p->{_cbuilder} = ExtUtils::CBuilder->new(
+ return $s->{_cbuilder} = ExtUtils::CBuilder->new(
config => $self->config,
($self->quiet ? (quiet => 1 ) : ()),
);
diff --git a/lib/Module/Build/Compat.pm b/lib/Module/Build/Compat.pm
index 7025f1cef3..b3ace5c5da 100644
--- a/lib/Module/Build/Compat.pm
+++ b/lib/Module/Build/Compat.pm
@@ -2,7 +2,7 @@ package Module::Build::Compat;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32_01';
+$VERSION = '0.33_02';
use File::Spec;
use IO::File;
@@ -143,7 +143,9 @@ EOF
eval "use Module::Build::Compat 0.02; 1" or die $@;
%s
Module::Build::Compat->run_build_pl(args => \@ARGV);
- exit(0) unless(-e 'Build'); # cpantesters convention
+ my $build_script = 'Build';
+ $build_script .= '.com' if $^O eq 'VMS';
+ exit(0) unless(-e $build_script); # cpantesters convention
require %s;
Module::Build::Compat->write_makefile(build_class => '%s');
EOF
@@ -176,7 +178,7 @@ EOF
$MM_Args{EXE_FILES} = [ sort keys %{$build->script_files} ] if $build->script_files;
- $MM_Args{PL_FILES} = $build->PL_files if $build->PL_files;
+ $MM_Args{PL_FILES} = $build->PL_files || {};
local $Data::Dumper::Terse = 1;
my $args = Data::Dumper::Dumper(\%MM_Args);
@@ -288,13 +290,17 @@ all : force_do_it
realclean : force_do_it
$perl $Build realclean
$unlink
+distclean : force_do_it
+ $perl $Build distclean
+ $unlink
+
force_do_it :
@ $noop
EOF
foreach my $action ($class->known_actions) {
- next if $action =~ /^(all|realclean|force_do_it)$/; # Don't double-define
+ next if $action =~ /^(all|distclean|realclean|force_do_it)$/; # Don't double-define
$maketext .= <<"EOF";
$action : force_do_it
$perl $Build $action
@@ -501,11 +507,7 @@ ever have to install Module::Build if they use the Makefile.PL, but
they won't get to take advantage of Module::Build's extra features
either.
-If you go this route, make sure you explicitly set C<PL_FILES> in the
-call to C<WriteMakefile()> (probably to an empty hash reference), or
-else MakeMaker will mistakenly run the Build.PL and you'll get an
-error message about "Too early to run Build script" or something. For
-good measure, of course, test both the F<Makefile.PL> and the
+For good measure, of course, test both the F<Makefile.PL> and the
F<Build.PL> before shipping.
=item 3.
diff --git a/lib/Module/Build/Config.pm b/lib/Module/Build/Config.pm
index 194b050973..bf543eb4eb 100644
--- a/lib/Module/Build/Config.pm
+++ b/lib/Module/Build/Config.pm
@@ -2,7 +2,7 @@ package Module::Build::Config;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Config;
diff --git a/lib/Module/Build/ConfigData.pm b/lib/Module/Build/ConfigData.pm
index 7bc3998bf1..3f539afd47 100644
--- a/lib/Module/Build/ConfigData.pm
+++ b/lib/Module/Build/ConfigData.pm
@@ -22,6 +22,9 @@ sub config_names { keys %$config }
sub write {
my $me = __FILE__;
require IO::File;
+
+ # Can't use Module::Build::Dumper here because M::B is only a
+ # build-time prereq of this module
require Data::Dumper;
my $mode_orig = (stat $me)[2] & 07777;
@@ -33,9 +36,11 @@ sub write {
}
die "Couldn't find __DATA__ token in $me" if eof($fh);
- local $Data::Dumper::Terse = 1;
seek($fh, tell($fh), 0);
- $fh->print( Data::Dumper::Dumper([$config, $features, $auto_features]) );
+ my $data = [$config, $features, $auto_features];
+ $fh->print( 'do{ my '
+ . Data::Dumper->new([$data],['x'])->Purity(1)->Dump()
+ . '$x; }' );
truncate($fh, tell($fh));
$fh->close;
@@ -159,36 +164,37 @@ authorship claim or copyright claim to the contents of C<Module::Build::ConfigDa
__DATA__
-[
- {},
- {},
- {
- 'YAML_support' => {
- 'requires' => {
- 'YAML' => ' >= 0.35, != 0.49_01 '
- },
- 'description' => 'Use YAML.pm to write META.yml files'
- },
- 'manpage_support' => {
- 'requires' => {
- 'Pod::Man' => 0
- },
- 'description' => 'Create Unix man pages'
- },
- 'C_support' => {
+do{ my $x = [
+ {},
+ {},
+ {
+ 'YAML_support' => {
'requires' => {
- 'ExtUtils::CBuilder' => '0.15'
+ 'YAML' => ' >= 0.35, != 0.49_01 '
},
- 'recommends' => {
- 'ExtUtils::ParseXS' => '1.02'
- },
- 'description' => 'Compile/link C & XS code'
+ 'description' => 'Use YAML.pm to write META.yml files'
},
- 'HTML_support' => {
+ 'manpage_support' => {
'requires' => {
- 'Pod::Html' => 0
+ 'Pod::Man' => 0
},
- 'description' => 'Create HTML documentation'
- }
- }
- ]
+ 'description' => 'Create Unix man pages'
+ },
+ 'C_support' => {
+ 'requires' => {
+ 'ExtUtils::CBuilder' => '0.15'
+ },
+ 'recommends' => {
+ 'ExtUtils::ParseXS' => '1.02'
+ },
+ 'description' => 'Compile/link C & XS code'
+ },
+ 'HTML_support' => {
+ 'requires' => {
+ 'Pod::Html' => 0
+ },
+ 'description' => 'Create HTML documentation'
+ }
+ }
+ ];
+$x; } \ No newline at end of file
diff --git a/lib/Module/Build/Cookbook.pm b/lib/Module/Build/Cookbook.pm
index e0c85df949..9a76ba095a 100644
--- a/lib/Module/Build/Cookbook.pm
+++ b/lib/Module/Build/Cookbook.pm
@@ -1,14 +1,13 @@
package Module::Build::Cookbook;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
=head1 NAME
Module::Build::Cookbook - Examples of Module::Build Usage
-
=head1 DESCRIPTION
C<Module::Build> isn't conceptually very complicated, but examples are
diff --git a/lib/Module/Build/Dumper.pm b/lib/Module/Build/Dumper.pm
index f3751bfeb2..3765c84c51 100644
--- a/lib/Module/Build/Dumper.pm
+++ b/lib/Module/Build/Dumper.pm
@@ -1,7 +1,7 @@
package Module::Build::Dumper;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
# This is just a split-out of a wrapper function to do Data::Dumper
# stuff "the right way". See:
diff --git a/lib/Module/Build/ModuleInfo.pm b/lib/Module/Build/ModuleInfo.pm
index d9821fe031..eb1d9bf70f 100644
--- a/lib/Module/Build/ModuleInfo.pm
+++ b/lib/Module/Build/ModuleInfo.pm
@@ -8,7 +8,7 @@ package Module::Build::ModuleInfo;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use File::Spec;
diff --git a/lib/Module/Build/Notes.pm b/lib/Module/Build/Notes.pm
index fca40b7496..3a83b01012 100644
--- a/lib/Module/Build/Notes.pm
+++ b/lib/Module/Build/Notes.pm
@@ -4,7 +4,7 @@ package Module::Build::Notes;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Data::Dumper;
use IO::File;
diff --git a/lib/Module/Build/PPMMaker.pm b/lib/Module/Build/PPMMaker.pm
index 413608631c..11909ce5c9 100644
--- a/lib/Module/Build/PPMMaker.pm
+++ b/lib/Module/Build/PPMMaker.pm
@@ -2,7 +2,7 @@ package Module::Build::PPMMaker;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
# This code is mostly borrowed from ExtUtils::MM_Unix 6.10_03, with a
@@ -130,8 +130,10 @@ sub _varchname { # Copied from PPM.pm
my ($self, $config) = @_;
my $varchname = $config->{archname};
# Append "-5.8" to architecture name for Perl 5.8 and later
- if (defined($^V) && ord(substr($^V,1)) >= 8) {
- $varchname .= sprintf("-%d.%d", ord($^V), ord(substr($^V,1)));
+ if ($] >= 5.008) {
+ my $vstring = sprintf "%vd", $^V;
+ $vstring =~ s/\.\d+$//;
+ $varchname .= "-$vstring";
}
return $varchname;
}
diff --git a/lib/Module/Build/Platform/Amiga.pm b/lib/Module/Build/Platform/Amiga.pm
index 4f5eb14bfd..ee5c4f9e0e 100644
--- a/lib/Module/Build/Platform/Amiga.pm
+++ b/lib/Module/Build/Platform/Amiga.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::Amiga;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Module::Build::Base;
diff --git a/lib/Module/Build/Platform/Default.pm b/lib/Module/Build/Platform/Default.pm
index c3f6a504ba..98128e259d 100644
--- a/lib/Module/Build/Platform/Default.pm
+++ b/lib/Module/Build/Platform/Default.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::Default;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Module::Build::Base;
diff --git a/lib/Module/Build/Platform/EBCDIC.pm b/lib/Module/Build/Platform/EBCDIC.pm
index 26c3ee5892..9d8a88ac1a 100644
--- a/lib/Module/Build/Platform/EBCDIC.pm
+++ b/lib/Module/Build/Platform/EBCDIC.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::EBCDIC;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Module::Build::Base;
diff --git a/lib/Module/Build/Platform/MPEiX.pm b/lib/Module/Build/Platform/MPEiX.pm
index f59902023c..e4d531c8a0 100644
--- a/lib/Module/Build/Platform/MPEiX.pm
+++ b/lib/Module/Build/Platform/MPEiX.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::MPEiX;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Module::Build::Base;
diff --git a/lib/Module/Build/Platform/MacOS.pm b/lib/Module/Build/Platform/MacOS.pm
index f7e22a3b84..f3b5dcf798 100644
--- a/lib/Module/Build/Platform/MacOS.pm
+++ b/lib/Module/Build/Platform/MacOS.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::MacOS;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Module::Build::Base;
use vars qw(@ISA);
diff --git a/lib/Module/Build/Platform/RiscOS.pm b/lib/Module/Build/Platform/RiscOS.pm
index 1f732f5808..458c02d7a9 100644
--- a/lib/Module/Build/Platform/RiscOS.pm
+++ b/lib/Module/Build/Platform/RiscOS.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::RiscOS;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Module::Build::Base;
diff --git a/lib/Module/Build/Platform/Unix.pm b/lib/Module/Build/Platform/Unix.pm
index 498e248d73..e6177c8a17 100644
--- a/lib/Module/Build/Platform/Unix.pm
+++ b/lib/Module/Build/Platform/Unix.pm
@@ -2,20 +2,13 @@ package Module::Build::Platform::Unix;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Module::Build::Base;
use vars qw(@ISA);
@ISA = qw(Module::Build::Base);
-sub make_tarball {
- my $self = shift;
- $self->{args}{tar} ||= ['tar'];
- $self->{args}{gzip} ||= ['gzip'];
- $self->SUPER::make_tarball(@_);
-}
-
sub is_executable {
# We consider the owner bit to be authoritative on a file, because
# -x will always return true if the user is root and *any*
diff --git a/lib/Module/Build/Platform/VMS.pm b/lib/Module/Build/Platform/VMS.pm
index 69912c8afc..8175f6cbd2 100644
--- a/lib/Module/Build/Platform/VMS.pm
+++ b/lib/Module/Build/Platform/VMS.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::VMS;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32_01';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Module::Build::Base;
@@ -229,8 +229,9 @@ sub _infer_xs_spec {
=item rscan_dir
-Inherit the standard version but remove dots at end of name. This may not be
-necessary if File::Find has been fixed or DECC$FILENAME_UNIX_REPORT is in effect.
+Inherit the standard version but remove dots at end of name.
+If the extended character set is in effect, do not remove dots from filenames
+with Unix path delimiters.
=cut
@@ -239,7 +240,11 @@ sub rscan_dir {
my $result = $self->SUPER::rscan_dir( $dir, $pattern );
- for my $file (@$result) { $file =~ s/\.$//; }
+ for my $file (@$result) {
+ if (!_efs() && ($file =~ m#/#)) {
+ $file =~ s/\.$//;
+ }
+ }
return $result;
}
@@ -254,7 +259,7 @@ sub dist_dir {
my $self = shift;
my $dist_dir = $self->SUPER::dist_dir;
- $dist_dir =~ s/\./_/g;
+ $dist_dir =~ s/\./_/g unless _efs();
return $dist_dir;
}
@@ -322,6 +327,11 @@ sub _detildefy {
# break up the paths for the merge
my $home = VMS::Filespec::unixify($ENV{HOME});
+ # In the default VMS mode, the trailing slash is present.
+ # In Unix report mode it is not. The parsing logic assumes that
+ # it is present.
+ $home .= '/' unless $home =~ m#/$#;
+
# Trivial case of just ~ by it self
if ($spec eq '') {
$home =~ s#/$##;
@@ -361,9 +371,8 @@ sub _detildefy {
# Now put the two cases back together
$arg = File::Spec::Unix->catpath($hvol, $newdirs, $file);
- } else {
- return $arg;
}
+ return $arg;
}
@@ -376,7 +385,9 @@ lossy.
=cut
-sub find_perl_interpreter { return $^X; }
+sub find_perl_interpreter {
+ return VMS::Filespec::vmsify($^X);
+}
=item localize_file_path
@@ -386,8 +397,9 @@ Convert the file path to the local syntax
sub localize_file_path {
my ($self, $path) = @_;
+ $path = VMS::Filespec::vmsify($path);
$path =~ s/\.\z//;
- return VMS::Filespec::vmsify($path);
+ return $path;
}
=item localize_dir_path
@@ -415,6 +427,43 @@ sub ACTION_clean {
}
}
+
+# Need to look up the feature settings. The preferred way is to use the
+# VMS::Feature module, but that may not be available to dual life modules.
+
+my $use_feature;
+BEGIN {
+ if (eval { local $SIG{__DIE__}; require VMS::Feature; }) {
+ $use_feature = 1;
+ }
+}
+
+# Need to look up the UNIX report mode. This may become a dynamic mode
+# in the future.
+sub _unix_rpt {
+ my $unix_rpt;
+ if ($use_feature) {
+ $unix_rpt = VMS::Feature::current("filename_unix_report");
+ } else {
+ my $env_unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} || '';
+ $unix_rpt = $env_unix_rpt =~ /^[ET1]/i;
+ }
+ return $unix_rpt;
+}
+
+# Need to look up the EFS character set mode. This may become a dynamic
+# mode in the future.
+sub _efs {
+ my $efs;
+ if ($use_feature) {
+ $efs = VMS::Feature::current("efs_charset");
+ } else {
+ my $env_efs = $ENV{'DECC$EFS_CHARSET'} || '';
+ $efs = $env_efs =~ /^[ET1]/i;
+ }
+ return $efs;
+}
+
=back
=head1 AUTHOR
diff --git a/lib/Module/Build/Platform/VOS.pm b/lib/Module/Build/Platform/VOS.pm
index ca77134a77..ca7270ff18 100644
--- a/lib/Module/Build/Platform/VOS.pm
+++ b/lib/Module/Build/Platform/VOS.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::VOS;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Module::Build::Base;
diff --git a/lib/Module/Build/Platform/Windows.pm b/lib/Module/Build/Platform/Windows.pm
index c8b412c510..72f0444859 100644
--- a/lib/Module/Build/Platform/Windows.pm
+++ b/lib/Module/Build/Platform/Windows.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::Windows;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Config;
diff --git a/lib/Module/Build/Platform/aix.pm b/lib/Module/Build/Platform/aix.pm
index c8c5b49abc..e2f3eb6861 100644
--- a/lib/Module/Build/Platform/aix.pm
+++ b/lib/Module/Build/Platform/aix.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::aix;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Module::Build::Platform::Unix;
diff --git a/lib/Module/Build/Platform/cygwin.pm b/lib/Module/Build/Platform/cygwin.pm
index 62c6573a61..d9bc6e1c51 100644
--- a/lib/Module/Build/Platform/cygwin.pm
+++ b/lib/Module/Build/Platform/cygwin.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::cygwin;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Module::Build::Platform::Unix;
diff --git a/lib/Module/Build/Platform/darwin.pm b/lib/Module/Build/Platform/darwin.pm
index aa87fb6ef2..173d2b5f85 100644
--- a/lib/Module/Build/Platform/darwin.pm
+++ b/lib/Module/Build/Platform/darwin.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::darwin;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Module::Build::Platform::Unix;
diff --git a/lib/Module/Build/Platform/os2.pm b/lib/Module/Build/Platform/os2.pm
index ba124dd7c9..3e22affe62 100644
--- a/lib/Module/Build/Platform/os2.pm
+++ b/lib/Module/Build/Platform/os2.pm
@@ -2,7 +2,7 @@ package Module::Build::Platform::os2;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use Module::Build::Platform::Unix;
diff --git a/lib/Module/Build/PodParser.pm b/lib/Module/Build/PodParser.pm
index 0012aab621..142ddfecf8 100644
--- a/lib/Module/Build/PodParser.pm
+++ b/lib/Module/Build/PodParser.pm
@@ -2,7 +2,7 @@ package Module::Build::PodParser;
use strict;
use vars qw($VERSION);
-$VERSION = '0.32';
+$VERSION = '0.33_02';
$VERSION = eval $VERSION;
use vars qw(@ISA);
diff --git a/lib/Module/Build/scripts/bundle.pl b/lib/Module/Build/scripts/bundle.pl
deleted file mode 100755
index 78de143426..0000000000
--- a/lib/Module/Build/scripts/bundle.pl
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/perl
-
-# this is just a first crack and it uses File::Fu because I'm lazy.
-
-=head1 using
-
-This installs from a fresh Module::Build to your inc/inc_Module-Build
-directory. Use it from within your dist:
-
- perl /path/to/Module-Build/scripts/bundle.pl
-
-You still need to manually add the following to your Build.PL
-
- use lib 'inc';
- use latest 'Module::Build';
-
-You also need to regen your manifest.
-
- perl Build.PL
- ./Build distmeta; >MANIFEST; ./Build manifest; svn diff MANIFEST
-
-=cut
-
-use warnings;
-use strict;
-
-use File::Fu;
-use File::Copy ();
-
-my $inc_dir = shift(@ARGV);
-$inc_dir = File::Fu->dir($inc_dir || 'inc/inc_Module-Build');
-$inc_dir->create unless($inc_dir->e);
-$inc_dir = $inc_dir->absolutely;
-
-
-my $mb_dir = File::Fu->program_dir->dirname;
-
-$mb_dir->chdir_for(sub {
- my $temp = File::Fu->temp_dir('mb_bundle');
- local @INC = @INC;
- unshift(@INC, 'lib', 'inc');
- require Module::Build;
- my $builder = Module::Build->new_from_context;
- $builder->dispatch(install =>
- install_base => $temp,
- install_path => {lib => $inc_dir},
- );
-});
-
-my $latest = $mb_dir/'inc'+'latest.pm';
-File::Copy::copy($latest, 'inc');
-
-# vim:ts=2:sw=2:et:sta
diff --git a/lib/Module/Build/t/bundled/Tie/CPHash.pm b/lib/Module/Build/t/bundled/Tie/CPHash.pm
index 8bf69bbd14..36aea85a8c 100644
--- a/lib/Module/Build/t/bundled/Tie/CPHash.pm
+++ b/lib/Module/Build/t/bundled/Tie/CPHash.pm
@@ -5,7 +5,7 @@ package Tie::CPHash;
#
# Author: Christopher J. Madsen <cjm@pobox.com>
# Created: 08 Nov 1997
-# $Revision: 5841 $ $Date: 2006-03-21 05:27:29 -0800 (Tue, 21 Mar 2006) $
+# $Revision: 5841 $ $Date: 2006-03-21 08:27:29 -0500 (Tue, 21 Mar 2006) $
#
# This program is free software; you can redistribute it and/or modify
# it under the same terms as Perl itself.
diff --git a/lib/Module/Build/t/compat.t b/lib/Module/Build/t/compat.t
index cb219aab42..a5d880cb7c 100644
--- a/lib/Module/Build/t/compat.t
+++ b/lib/Module/Build/t/compat.t
@@ -135,8 +135,7 @@ ok $mb, "Module::Build->new_from_context";
$foo_builder = Foo::Builder->new_from_context;
});
foreach my $style ('passthrough', 'small') {
- Module::Build::Compat->create_makefile_pl($style, $foo_builder);
- ok -e 'Makefile.PL', "$style Makefile.PL created";
+ create_makefile_pl($style, $foo_builder);
# Should fail with "can't find Foo/Builder.pm"
my $result;
@@ -153,8 +152,7 @@ ok $mb, "Module::Build->new_from_context";
$bar_builder = Module::Build->subclass( class => 'Bar::Builder' )->new_from_context;
});
foreach my $style ('passthrough', 'small') {
- Module::Build::Compat->create_makefile_pl($style, $bar_builder);
- ok -e 'Makefile.PL', "$style Makefile.PL created via subclass";
+ create_makefile_pl($style, $bar_builder);
my $result;
stdout_of( sub {
$result = $mb->run_perl_script('Makefile.PL');
@@ -165,7 +163,7 @@ ok $mb, "Module::Build->new_from_context";
{
# Make sure various Makefile.PL arguments are supported
- Module::Build::Compat->create_makefile_pl('passthrough', $mb);
+ create_makefile_pl('passthrough', $mb);
my $libdir = File::Spec->catdir( $tmp, 'libdir' );
my $result;
@@ -255,7 +253,7 @@ ok $mb, "Module::Build->new_from_context";
# C<glob> on MSWin32 uses $ENV{HOME} if defined to do tilde-expansion
local $ENV{HOME} = 'C:/' if $^O =~ /MSWin/ && !exists( $ENV{HOME} );
- Module::Build::Compat->create_makefile_pl('passthrough', $mb);
+ create_makefile_pl('passthrough', $mb);
stdout_of( sub {
$mb->run_perl_script('Makefile.PL', [], ['INSTALL_BASE=~/foo']);
@@ -290,8 +288,8 @@ sub test_makefile_types {
ok $mb, "Module::Build->new_from_context";
# Create and test Makefile.PL
- Module::Build::Compat->create_makefile_pl($type, $mb);
- ok -e 'Makefile.PL', "$type Makefile.PL created";
+ create_makefile_pl($type, $mb);
+
test_makefile_pl_requires_perl( $opts{requires}{perl} );
test_makefile_creation($mb);
test_makefile_prereq_pm( $opts{requires} );
@@ -321,8 +319,11 @@ sub test_makefile_types {
ok $success, "make realclean ran without error";
# Try again with some Makefile.PL arguments
- test_makefile_creation($mb, [], 'INSTALLDIRS=vendor', 1);
+ test_makefile_creation($mb, [], 'INSTALLDIRS=vendor', 'realclean');
+ # Try again using distclean
+ test_makefile_creation($mb, [], '', 'distclean');
+
1 while unlink 'Makefile.PL';
ok ! -e 'Makefile.PL', "cleaned up Makefile";
}
@@ -344,10 +345,12 @@ sub test_makefile_creation {
ok -e $makefile, "$makefile exists";
if ($cleanup) {
- $output = stdout_of( sub {
- $build->do_system(@make, 'realclean');
+ # default to 'realclean' unless we recognize the clean method
+ $cleanup = 'realclean' unless $cleanup =~ /^(dist|real)clean$/;
+ my ($stdout, $stderr ) = stdout_stderr_of (sub {
+ $build->do_system(@make, $cleanup);
});
- ok ! -e '$makefile', "$makefile cleaned up";
+ ok ! -e $makefile, "$makefile cleaned up with $cleanup";
}
else {
pass '(skipping cleanup)'; # keep test count constant
@@ -369,17 +372,17 @@ sub test_makefile_pl_files {
my $expected = shift;
SKIP: {
- skip "$makefile not found", 1 unless -e $makefile;
- my $pl_files = find_params_in_makefile()->{PL_FILES} || {};
- is_deeply $pl_files, $expected,
- "$makefile has correct PL_FILES line";
+ skip 1, 'Makefile.PL not found' unless -e 'Makefile.PL';
+ my $args = extract_writemakefile_args() || {};
+ is_deeply $args->{PL_FILES}, $expected,
+ "Makefile.PL has correct PL_FILES line";
}
}
sub test_makefile_pl_requires_perl {
my $perl_version = shift || q{};
SKIP: {
- skip 'Makefile.PL not found', 1 unless -e 'Makefile.PL';
+ skip 1, 'Makefile.PL not found' unless -e 'Makefile.PL';
my $file_contents = slurp 'Makefile.PL';
my $found_requires = $file_contents =~ m{^require $perl_version;}ms;
if (length $perl_version) {
@@ -417,3 +420,29 @@ sub find_params_in_makefile {
return \%params;
}
+
+sub extract_writemakefile_args {
+ SKIP: {
+ skip 1, 'Makefile.PL not found' unless -e 'Makefile.PL';
+ my $file_contents = slurp 'Makefile.PL';
+ my ($args) = $file_contents =~ m{^WriteMakefile\n\((.*)\).*;}ms;
+ ok $args, "Found WriteMakefile arguments"
+ or diag "Makefile.PL:\n$file_contents";
+ my %args = eval $args or diag $args; ## no critic
+ return \%args;
+ }
+}
+
+sub create_makefile_pl {
+ Module::Build::Compat->create_makefile_pl(@_);
+ my $ok = ok -e 'Makefile.PL', "$_[0] Makefile.PL created";
+
+ # Some really conservative make's, like HP/UX, assume files with the same
+ # timestamp are out of date. Send the Makefile.PL one second into the past
+ # so its older than the Makefile it will generate.
+ # See [rt.cpan.org 45700]
+ my $mtime = (stat("Makefile.PL"))[9];
+ utime $mtime, $mtime - 1, "Makefile.PL";
+
+ return $ok;
+}
diff --git a/lib/Module/Build/t/ext.t b/lib/Module/Build/t/ext.t
index 3b01a799af..30c648bbb3 100644
--- a/lib/Module/Build/t/ext.t
+++ b/lib/Module/Build/t/ext.t
@@ -129,7 +129,7 @@ foreach my $test (@win_splits) {
my @data = map values(%$_), @unix_splits, @win_splits;
for my $d (@data) {
- chomp(my $out = Module::Build->_backticks('perl', '-le', 'print join " ", map "{$_}", @ARGV', @$d));
+ chomp(my $out = Module::Build->_backticks($^X, '-le', 'print join " ", map "{$_}", @ARGV', @$d));
is($out, join(' ', map "{$_}", @$d), "backticks round trip for ".join('',map "{$_}", @$d));
}
}
@@ -137,6 +137,12 @@ foreach my $test (@win_splits) {
{
# Make sure run_perl_script() propagates @INC
my $dir = MBTest->tmpdir;
+ if ($^O eq 'VMS') {
+ # VMS can store INC paths in Unix format with out the trailing
+ # directory delimiter.
+ $dir = VMS::Filespec::unixify($dir);
+ $dir =~ s#/$##;
+ }
local @INC = ($dir, @INC);
my $output = stdout_of( sub { Module::Build->run_perl_script('-le', [], ['print for @INC']) } );
like $output, qr{^\Q$dir\E}m;
diff --git a/lib/Module/Build/t/extend.t b/lib/Module/Build/t/extend.t
index 4c964216ec..f939defaaf 100644
--- a/lib/Module/Build/t/extend.t
+++ b/lib/Module/Build/t/extend.t
@@ -50,7 +50,9 @@ print "Hello, World!\n";
$mb->test_files('*t*');
my $files = $mb->test_files;
ok grep {$_ eq 'script'} @$files;
- ok grep {$_ eq File::Spec->catfile('t', 'basic.t')} @$files;
+ my $t_basic_t = File::Spec->catfile('t', 'basic.t');
+ $t_basic_t = VMS::Filespec::vmsify($t_basic_t) if $^O eq 'VMS';
+ ok grep {$_ eq $t_basic_t} @$files;
ok !grep {$_ eq 'Build.PL' } @$files;
# Make sure order is preserved
diff --git a/lib/Module/Build/t/metadata.t b/lib/Module/Build/t/metadata.t
index caa7d473fa..1def8af377 100644
--- a/lib/Module/Build/t/metadata.t
+++ b/lib/Module/Build/t/metadata.t
@@ -33,14 +33,24 @@ $dist->regen;
my $simple_file = 'lib/Simple.pm';
my $simple2_file = 'lib/Simple2.pm';
- #TODO:
# Traditional VMS will return the file in in lower case, and is_deeply
# does exact case comparisons.
- # When ODS-5 support is active for preserved case file names, this will
- # need to be changed.
+ # When ODS-5 support is active for preserved case file names we do not
+ # change the case.
if ($^O eq 'VMS') {
- $simple_file = lc($simple_file);
- $simple2_file = lc($simple2_file);
+ my $lower_case_expect = 1;
+ my $vms_efs_case = 0;
+ if (eval 'require VMS::Feature') {
+ $vms_efs_case = VMS::Feature::current("efs_case_preserve");
+ } else {
+ my $efs_case = $ENV{'DECC$EFS_CASE_PRESERVE'} || '';
+ $vms_efs_case = $efs_case =~ /^[ET1]/i;
+ }
+ $lower_case_expect = 0 if $vms_efs_case;
+ if ($lower_case_expect) {
+ $simple_file = lc($simple_file);
+ $simple2_file = lc($simple2_file);
+ }
}
diff --git a/lib/Module/Build/t/runthrough.t b/lib/Module/Build/t/runthrough.t
index e095a60a59..98913281d2 100644
--- a/lib/Module/Build/t/runthrough.t
+++ b/lib/Module/Build/t/runthrough.t
@@ -73,11 +73,22 @@ ok -e $mb->build_script;
my $dist_dir = 'Simple-0.01';
-# VMS may or may not need to modify the name, vmsify will do this if
-# the name looks like a UNIX directory.
+# VMS in traditional mode needs the $dist_dir name to not have a '.' in it
+# as this is a directory delimiter. In extended character set mode the dot
+# is permitted for Unix format file specifications.
if ($^O eq 'VMS') {
- my @dist_dirs = File::Spec->splitdir(VMS::Filespec::vmsify($dist_dir.'/'));
- $dist_dir = $dist_dirs[0];
+ my $Is_VMS_noefs = 1;
+ my $vms_efs = 0;
+ if (eval 'require VMS::Feature') {
+ $vms_efs = VMS::Feature::current("efs_charset");
+ } else {
+ my $efs_charset = $ENV{'DECC$EFS_CHARSET'} || '';
+ $vms_efs = $efs_charset =~ /^[ET1]/i;
+ }
+ $Is_VMS_noefs = 0 if $vms_efs;
+ if ($Is_VMS_noefs) {
+ $dist_dir = 'Simple-0_01';
+ }
}
is $mb->dist_dir, $dist_dir;
diff --git a/make_patchnum.pl b/make_patchnum.pl
index 2bacd4bcad..1644d419d6 100644
--- a/make_patchnum.pl
+++ b/make_patchnum.pl
@@ -13,7 +13,7 @@ make_patchnum.pl - make patchnum
perl make_patchnum.pl
-=head1 DESCRITPTION
+=head1 DESCRIPTION
This program creates the files holding the information
about locally applied patches to the source code. The created
@@ -23,7 +23,7 @@ files are C<git_version.h> and C<lib/Config_git.pl>.
Contains status information from git in a form meant to be processed
by the tied hash logic of Config.pm. It is actually optional,
-although -V will look strange without it.
+although -V:git.\* will be uninformative without it.
C<git_version.h> contains similar information in a C header file
format, designed to be used by patchlevel.h. This file is obtained
@@ -40,8 +40,25 @@ Same terms as Perl itself.
=cut
+# from a -Dmksymlink target dir, I need to cd to the git-src tree to
+# use git (like script does). Presuming that's not unique, one fix is
+# to follow Configure's symlink-path to run git. Maybe GIT_DIR or
+# path-args can solve it, if so we should advise here, I tried only
+# very briefly ('cd -' works too).
+
+my ($subcd, $srcdir);
+our $opt_v = scalar grep $_ eq '-v', @ARGV;
+
BEGIN {
my $root=".";
+ # test 1st to see if we're a -Dmksymlinks target dir
+ $subcd = '';
+ $srcdir = $root;
+ if (-l "./Configure") {
+ $srcdir = readlink("./Configure");
+ $srcdir =~ s/Configure//;
+ $subcd = "cd $srcdir &&"; # activate backtick fragment
+ }
while (!-e "$root/perl.c" and length($root)<100) {
if ($root eq '.') {
$root="..";
@@ -71,14 +88,20 @@ sub write_file {
}
sub backtick {
+ # only for git. If we're in a -Dmksymlinks build-dir, we need to
+ # cd to src so git will work . Probably a better way.
my $command = shift;
if (wantarray) {
- my @result= `$command`;
+ my @result= `$subcd $command`;
+ warn "$subcd $command: \$?=$?\n" if $?;
+ print "#> $subcd $command ->\n @result\n" if !$? and $opt_v;
chomp @result;
return @result;
} else {
- my $result= `$command`;
+ my $result= `$subcd $command`;
$result="" if ! defined $result;
+ warn "$subcd $command: \$?=$?\n" if $?;
+ print "#> $subcd $command ->\n $result\n" if !$? and $opt_v;
chomp $result;
return $result;
}
@@ -102,14 +125,15 @@ sub write_files {
my $unpushed_commits = '/*no-op*/';
my ($read, $branch, $snapshot_created, $commit_id, $describe)= ("") x 5;
my ($changed, $extra_info, $commit_title, $new_patchnum, $status)= ("") x 5;
+
if (my $patch_file= read_file(".patch")) {
($branch, $snapshot_created, $commit_id, $describe) = split /\s+/, $patch_file;
$extra_info = "git_snapshot_date='$snapshot_created'";
$commit_title = "Snapshot of:";
}
-elsif (-d path_to('.git')) {
+elsif (-d "$srcdir/.git") {
# git branch | awk 'BEGIN{ORS=""} /\*/ { print $2 }'
- ($branch) = map { /\* ([^(]\S*)/ ? $1 : () } backtick('git branch');
+ ($branch) = map { /\* ([^(]\S*)/ ? $1 : () } backtick("git branch");
my ($remote,$merge);
if (length $branch) {
$merge= backtick("git config branch.$branch.merge");
@@ -139,12 +163,12 @@ git_remote_branch='$remote/$merge'
git_unpushed='$unpushed_commit_list'";
}
}
- if ($changed) {
+ if ($changed) { # not touched since init'd. never true.
$changed = 'true';
$commit_title = "Derived from:";
$status='"uncommitted-changes"'
} else {
- $status='/*clean-working-directory*/'
+ $status='/*clean-working-directory-maybe*/'
}
$commit_title ||= "Commit id:";
}
diff --git a/perl.c b/perl.c
index 8b4f8d7065..e70bf7e4e3 100644
--- a/perl.c
+++ b/perl.c
@@ -1772,17 +1772,8 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
# ifdef PERL_MEM_LOG
" PERL_MEM_LOG"
# endif
-# ifdef PERL_MEM_LOG_ENV
- " PERL_MEM_LOG_ENV"
-# endif
-# ifdef PERL_MEM_LOG_ENV_FD
- " PERL_MEM_LOG_ENV_FD"
-# endif
-# ifdef PERL_MEM_LOG_STDERR
- " PERL_MEM_LOG_STDERR"
-# endif
-# ifdef PERL_MEM_LOG_TIMESTAMP
- " PERL_MEM_LOG_TIMESTAMP"
+# ifdef PERL_MEM_LOG_NOIMPL
+ " PERL_MEM_LOG_NOIMPL"
# endif
# ifdef PERL_USE_DEVEL
" PERL_USE_DEVEL"
diff --git a/perlio.c b/perlio.c
index 10a32c163e..4fe4fa7178 100644
--- a/perlio.c
+++ b/perlio.c
@@ -1773,10 +1773,7 @@ PerlIO_has_base(PerlIO *f)
if (tab)
return (tab->Get_base != NULL);
- SETERRNO(EINVAL, LIB_INVARG);
}
- else
- SETERRNO(EBADF, SS_IVCHAN);
return 0;
}
@@ -1790,11 +1787,8 @@ PerlIO_fast_gets(PerlIO *f)
if (tab)
return (tab->Set_ptrcnt != NULL);
- SETERRNO(EINVAL, LIB_INVARG);
}
}
- else
- SETERRNO(EBADF, SS_IVCHAN);
return 0;
}
@@ -1807,10 +1801,7 @@ PerlIO_has_cntptr(PerlIO *f)
if (tab)
return (tab->Get_ptr != NULL && tab->Get_cnt != NULL);
- SETERRNO(EINVAL, LIB_INVARG);
}
- else
- SETERRNO(EBADF, SS_IVCHAN);
return 0;
}
@@ -1823,10 +1814,7 @@ PerlIO_canset_cnt(PerlIO *f)
if (tab)
return (tab->Set_ptrcnt != NULL);
- SETERRNO(EINVAL, LIB_INVARG);
}
- else
- SETERRNO(EBADF, SS_IVCHAN);
return 0;
}
diff --git a/pod/perl5110delta.pod b/pod/perl5110delta.pod
index afd1b35492..720b5d273b 100644
--- a/pod/perl5110delta.pod
+++ b/pod/perl5110delta.pod
@@ -109,6 +109,14 @@ to avoid relying on the object's underlying structure).
This pragma allows you to lexically disable or enable overloading
for some or all operations. (Yuval Kogman)
+=head2 C<\N> regex escape
+
+A new regex escape has been added, C<\N>. It will match any character that
+is not a newline, independently from the presence or absence of the single
+line match modifier C</s>. (If C<\N> is followed by an opening brace and
+by a letter, perl will still assume that a Unicode character name is
+coming, so compatibility is preserved.) (Rafael Garcia-Suarez)
+
=head1 Modules and Pragmata
=head2 Pragmata Changes
diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index 826df27ef0..4593352f7c 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -4349,8 +4349,8 @@ steps to ensure that C<readline> was successful.
for (;;) {
undef $!;
unless (defined( $line = <> )) {
+ last if eof;
die $! if $!;
- last; # reached EOF
}
# ...
}
diff --git a/pod/perlhack.pod b/pod/perlhack.pod
index 72c2fc06fc..b4cfc4fe6d 100644
--- a/pod/perlhack.pod
+++ b/pod/perlhack.pod
@@ -321,10 +321,12 @@ might start to make sense - don't worry if it doesn't yet, because the
best way to study it is to read it in conjunction with poking at Perl
source, and we'll do that later on.
-You might also want to look at Gisle Aas's illustrated perlguts -
-there's no guarantee that this will be absolutely up-to-date with the
-latest documentation in the Perl core, but the fundamentals will be
-right. ( http://gisle.aas.no/perl/illguts/ )
+Gisle Aas's illustrated perlguts (also known as I<illguts>) is wonderful,
+although a little out of date with regard to some size details; the
+various SV structures have since been reworked for smaller memory footprint.
+The fundamentals are right however, and the pictures are very helpful.
+
+L<http://www.perl.org/tpc/1998/Perl_Language_and_Modules/Perl%20Illustrated/>
=item L<perlxstut> and L<perlxs>
@@ -2940,27 +2942,29 @@ by C<-DPERL_MEM_LOG> instead.
=head2 PERL_MEM_LOG
-If compiled with C<-DPERL_MEM_LOG>, all Newx() and Renew() allocations
-and Safefree() in the Perl core go through logging functions, which is
-handy for breakpoint setting. If also compiled with C<-DPERL_MEM_LOG_STDERR>,
-the allocations and frees are logged to STDERR (or more precisely, to the
-file descriptor 2) in these logging functions, with the calling source code
-file and line number (and C function name, if supported by the C compiler).
-
-This logging is somewhat similar to C<-Dm> but independent of C<-DDEBUGGING>,
-and at a higher level (the C<-Dm> is directly at the point of C<malloc()>,
-while the C<PERL_MEM_LOG> is at the level of C<New()>).
-
-In addition to memory allocations, SV allocations will be logged, just as
-with C<-Dm>. However, since the logging doesn't use PerlIO, all SV allocations
-are logged and no extra SV allocations are introduced by enabling the logging.
-If compiled with C<-DDEBUG_LEAKING_SCALARS>, the serial number for each SV
-allocation is also logged.
-
-You can control the logging from your environment if you compile with
-C<-DPERL_MEM_LOG_ENV>. Then you need to explicitly set C<PERL_MEM_LOG> and/or
-C<PERL_SV_LOG> to a non-zero value to enable logging of memory and/or SV
-allocations.
+If compiled with C<-DPERL_MEM_LOG>, both memory and SV allocations go
+through logging functions, which is handy for breakpoint setting.
+
+Unless C<-DPERL_MEM_LOG_NOIMPL> is also compiled, the logging
+functions read $ENV{PERL_MEM_LOG} to determine whether to log the
+event, and if so how:
+
+ $ENV{PERL_MEM_LOG} =~ /m/ Log all memory ops
+ $ENV{PERL_MEM_LOG} =~ /s/ Log all SV ops
+ $ENV{PERL_MEM_LOG} =~ /t/ include timestamp in Log
+ $ENV{PERL_MEM_LOG} =~ /^(\d+)/ write to FD given (default is 2)
+
+Memory logging is somewhat similar to C<-Dm> but is independent of
+C<-DDEBUGGING>, and at a higher level; all uses of Newx(), Renew(),
+and Safefree() are logged with the caller's source code file and line
+number (and C function name, if supported by the C compiler). In
+contrast, C<-Dm> is directly at the point of C<malloc()>. SV logging
+is similar.
+
+Since the logging doesn't use PerlIO, all SV allocations are logged
+and no extra SV allocations are introduced by enabling the logging.
+If compiled with C<-DDEBUG_LEAKING_SCALARS>, the serial number for
+each SV allocation is also logged.
=head2 Profiling
diff --git a/pod/perlre.pod b/pod/perlre.pod
index a076d3ad66..ee1c2cb940 100644
--- a/pod/perlre.pod
+++ b/pod/perlre.pod
@@ -271,6 +271,7 @@ X<word> X<whitespace> X<character class> X<backreference>
\g{name} Named backreference
\k<name> Named backreference
\K Keep the stuff left of the \K, don't include it in $&
+ \N Any character but \n
\v Vertical whitespace
\V Not vertical whitespace
\h Horizontal whitespace
diff --git a/pod/perlrebackslash.pod b/pod/perlrebackslash.pod
index ddd7abee38..40f73fcbc1 100644
--- a/pod/perlrebackslash.pod
+++ b/pod/perlrebackslash.pod
@@ -83,6 +83,7 @@ quoted constructs>.
\l Lowercase next character.
\L Lowercase till \E.
\n (Logical) newline character.
+ \N Any character but newline.
\N{} Named (Unicode) character.
\p{}, \pP Character with a Unicode property.
\P{}, \PP Character without a Unicode property.
diff --git a/pod/perlrecharclass.pod b/pod/perlrecharclass.pod
index a626dd9bb9..930c0fc4e4 100644
--- a/pod/perlrecharclass.pod
+++ b/pod/perlrecharclass.pod
@@ -38,7 +38,6 @@ Here are some examples:
"\n" =~ /(?s:.)/ # Match (local 'single line' modifier)
"ab" =~ /^.$/ # No match (dot matches one character)
-
=head2 Backslashed sequences
Perl regular expressions contain many backslashed sequences that
@@ -59,6 +58,7 @@ more detail below.
\S Match a non-white space character.
\h Match a horizontal white space character.
\H Match a character that isn't horizontal white space.
+ \N Match a character that isn't newline.
\v Match a vertical white space character.
\V Match a character that isn't vertical white space.
\pP, \p{Prop} Match a character matching a Unicode property.
@@ -94,7 +94,7 @@ Any character that isn't matched by C<\w> will be matched by C<\W>.
=head3 White space
-C<\s> matches any single character that is consider white space. In the
+C<\s> matches any single character that is considered white space. In the
ASCII range, C<\s> matches the horizontal tab (C<\t>), the new line
(C<\n>), the form feed (C<\f>), the carriage return (C<\r>), and the
space (the vertical tab, C<\cK> is not matched by C<\s>). The exact set
@@ -113,6 +113,12 @@ C<\h> will match any character that is considered horizontal white space;
this includes the space and the tab characters. C<\H> will match any character
that is not considered horizontal white space.
+C<\N>, like the dot, will match any character that is not a newline. The
+difference is that C<\N> will not be influenced by the single line C</s>
+regular expression modifier. (Note that, since C<\N{}> is also used for
+Unicode named characters, if C<\N> is followed by an opening brace and
+by a letter, perl will assume that a Unicode character name is coming.)
+
C<\v> will match any character that is considered vertical white space;
this includes the carriage return and line feed characters (newline).
C<\V> will match any character that is not considered vertical white space.
diff --git a/pod/perlreref.pod b/pod/perlreref.pod
index b9fb3b0202..87baab25e8 100644
--- a/pod/perlreref.pod
+++ b/pod/perlreref.pod
@@ -125,6 +125,7 @@ and L<perlunicode> for details.
\S A non-whitespace character
\h An horizontal white space
\H A non horizontal white space
+ \N A non newline (like . without /s)
\v A vertical white space
\V A non vertical white space
\R A generic newline (?>\v|\x0D\x0A)
diff --git a/pod/perltodo.pod b/pod/perltodo.pod
index cf0304aae9..c84b51e368 100644
--- a/pod/perltodo.pod
+++ b/pod/perltodo.pod
@@ -1101,12 +1101,6 @@ combines the code in pp_entersub, pp_leavesub. This should probably
be done 1st in XS, and using B::Generate to patch the new OP into the
optrees.
-=head2 C<\N>
-
-It should be possible to add a C<\N> regex assertion, meaning "every
-character except C<\n>° independently of the context. That would
-of course imply that C<\N> couldn't be followed by an opening C<{>.
-
=head1 Big projects
Tasks that will get your name mentioned in the description of the "Highlights
diff --git a/proto.h b/proto.h
index 78f17ddedb..fc06fb188a 100644
--- a/proto.h
+++ b/proto.h
@@ -4254,6 +4254,11 @@ STATIC void S_hfreeentries(pTHX_ HV *hv)
#define PERL_ARGS_ASSERT_HFREEENTRIES \
assert(hv)
+STATIC I32 S_anonymise_cv(pTHX_ const char *stash, SV *val)
+ __attribute__nonnull__(pTHX_2);
+#define PERL_ARGS_ASSERT_ANONYMISE_CV \
+ assert(val)
+
STATIC HE* S_new_he(pTHX)
__attribute__malloc__
__attribute__warn_unused_result__;
@@ -5178,7 +5183,7 @@ STATIC regnode* S_regpiece(pTHX_ struct RExC_state_t *pRExC_state, I32 *flagp, U
#define PERL_ARGS_ASSERT_REGPIECE \
assert(pRExC_state); assert(flagp)
-STATIC regnode* S_reg_namedseq(pTHX_ struct RExC_state_t *pRExC_state, UV *valuep)
+STATIC regnode* S_reg_namedseq(pTHX_ struct RExC_state_t *pRExC_state, UV *valuep, I32 *flagp)
__attribute__nonnull__(pTHX_1);
#define PERL_ARGS_ASSERT_REG_NAMEDSEQ \
assert(pRExC_state)
@@ -5884,7 +5889,7 @@ STATIC bool S_vdie_common(pTHX_ const char *message, STRLEN msglen, I32 utf8, bo
STATIC char * S_write_no_mem(pTHX)
__attribute__noreturn__;
-#if defined(PERL_MEM_LOG) && defined(PERL_MEM_LOG_STDERR)
+#if defined(PERL_MEM_LOG) && !defined(PERL_MEM_LOG_NOIMPL)
STATIC void S_mem_log_common(enum mem_log_type mlt, const UV n, const UV typesize, const char *type_name, const SV *sv, Malloc_t oldalloc, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname)
__attribute__nonnull__(4)
__attribute__nonnull__(8)
diff --git a/regcomp.c b/regcomp.c
index e06152820c..bc7086f8df 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -6553,7 +6553,7 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
/* reg_namedseq(pRExC_state,UVp)
This is expected to be called by a parser routine that has
- recognized'\N' and needs to handle the rest. RExC_parse is
+ recognized '\N' and needs to handle the rest. RExC_parse is
expected to point at the first char following the N at the time
of the call.
@@ -6567,11 +6567,11 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
be returned to indicate failure. (This will NOT be a valid pointer
to a regnode.)
- If value is null then it is assumed that we are parsing normal text
+ If valuep is null then it is assumed that we are parsing normal text
and inserts a new EXACT node into the program containing the resolved
string and returns a pointer to the new node. If the string is
zerolength a NOTHING node is emitted.
-
+
On success RExC_parse is set to the char following the endbrace.
Parsing failures will generate a fatal errorvia vFAIL(...)
@@ -6585,7 +6585,7 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
*/
STATIC regnode *
-S_reg_namedseq(pTHX_ RExC_state_t *pRExC_state, UV *valuep)
+S_reg_namedseq(pTHX_ RExC_state_t *pRExC_state, UV *valuep, I32 *flagp)
{
char * name; /* start of the content of the name */
char * endbrace; /* endbrace following the name */
@@ -6597,8 +6597,22 @@ S_reg_namedseq(pTHX_ RExC_state_t *pRExC_state, UV *valuep)
PERL_ARGS_ASSERT_REG_NAMEDSEQ;
- if (*RExC_parse != '{') {
- vFAIL("Missing braces on \\N{}");
+ if (*RExC_parse != '{' ||
+ (*RExC_parse == '{' && RExC_parse[1]
+ && strchr("0123456789", RExC_parse[1])))
+ {
+ GET_RE_DEBUG_FLAGS_DECL;
+ if (valuep)
+ /* no bare \N in a charclass */
+ vFAIL("Missing braces on \\N{}");
+ GET_RE_DEBUG_FLAGS;
+ nextchar(pRExC_state);
+ ret = reg_node(pRExC_state, REG_ANY);
+ *flagp |= HASWIDTH|SIMPLE;
+ RExC_naughty++;
+ RExC_parse--;
+ Set_Node_Length(ret, 1); /* MJD */
+ return ret;
}
name = RExC_parse+1;
endbrace = strchr(RExC_parse, '}');
@@ -7159,12 +7173,12 @@ tryagain:
}
break;
case 'N':
- /* Handle \N{NAME} here and not below because it can be
+ /* Handle \N and \N{NAME} here and not below because it can be
multicharacter. join_exact() will join them up later on.
Also this makes sure that things like /\N{BLAH}+/ and
\N{BLAH} being multi char Just Happen. dmq*/
++RExC_parse;
- ret= reg_namedseq(pRExC_state, NULL);
+ ret= reg_namedseq(pRExC_state, NULL, flagp);
break;
case 'k': /* Handle \k<NAME> and \k'NAME' */
parse_named_seq:
@@ -7964,7 +7978,7 @@ parseit:
from earlier versions, OTOH that behaviour was broken
as well. */
UV v; /* value is register so we cant & it /grrr */
- if (reg_namedseq(pRExC_state, &v)) {
+ if (reg_namedseq(pRExC_state, &v, NULL)) {
goto parseit;
}
value= v;
diff --git a/sv.h b/sv.h
index 243b798e85..8c83e9a031 100644
--- a/sv.h
+++ b/sv.h
@@ -902,7 +902,7 @@ in gv.h: */
#endif
/*
-=for apidoc Am|char*|SvGAMAGIC|SV* sv
+=for apidoc Am|U32|SvGAMAGIC|SV* sv
Returns true if the SV has get magic or overloading. If either is true then
the scalar is active data, and has the potential to return a new value every
diff --git a/t/op/re_tests b/t/op/re_tests
index f9b070d62c..0c04840117 100644
--- a/t/op/re_tests
+++ b/t/op/re_tests
@@ -31,6 +31,12 @@ ab*bc abbbbc y $+[0] 6
.{3,4} abbbbc y $& abbb
.{3,4} abbbbc y $-[0] 0
.{3,4} abbbbc y $+[0] 4
+\N{1} abbbbc y $& a
+\N{1} abbbbc y $-[0] 0
+\N{1} abbbbc y $+[0] 1
+\N{3,4} abbbbc y $& abbb
+\N{3,4} abbbbc y $-[0] 0
+\N{3,4} abbbbc y $+[0] 4
ab{0,}bc abbbbc y $& abbbbc
ab{0,}bc abbbbc y $-[0] 0
ab{0,}bc abbbbc y $+[0] 6
@@ -69,8 +75,11 @@ abc$ aabcd n - -
$ abc y $&
a.c abc y $& abc
a.c axc y $& axc
+a\Nc abc y $& abc
a.*c axyzc y $& axyzc
+a\N*c axyzc y $& axyzc
a.*c axyzd n - -
+a\N*c axyzd n - -
a[bc]d abc n - -
a[bc]d abd y $& abd
a[b]d abd y $& abd
@@ -78,6 +87,7 @@ a[b]d abd y $& abd
.[b]. abd y $& abd
.[b]. aBd n - -
(?i:.[b].) abd y $& abd
+(?i:\N[b]\N) abd y $& abd
a[b-d]e abd n - -
a[b-d]e ace y $& ace
a[b-d] aac y $& ac
@@ -315,6 +325,7 @@ a[-]?c ac y $& ac
'$'i ABC y $&
'a.c'i ABC y $& ABC
'a.c'i AXC y $& AXC
+'a\Nc'i ABC y $& ABC
'a.*?c'i AXYZC y $& AXYZC
'a.*c'i AXYZD n - -
'a[bc]d'i ABC n - -
@@ -497,8 +508,11 @@ a(?:b|(c|e){1,2}?|d)+?(.) ace y $1$2 ce
'(?-i:a)b'i AB n - -
'((?-i:a))b'i AB n - -
'((?-i:a.))b'i a\nB n - -
+'((?-i:a\N))b'i a\nB n - -
'((?s-i:a.))b'i a\nB y $1 a\n
+'((?s-i:a\N))b'i a\nB n - -
'((?s-i:a.))b'i B\nB n - -
+'((?s-i:a\N))b'i B\nB n - -
(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b))) cabbbb y $& cabbbb
(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb))) caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb y $& caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
'(ab)\d\1'i Ab4ab y $1 Ab
@@ -531,6 +545,8 @@ x(~~)*(?:(?:F)?)? x~~ y - -
((?s).)c(?!.) a\nb\nc\n y $1:$& \n:\nc
((?s)b.)c(?!.) a\nb\nc\n y $1 b\n
((?s)b.)c(?!.) a\nb\nc\n y $1:$& b\n:b\nc
+((?s)b.)c(?!\N) a\nb\nc\n y $1:$& b\n:b\nc
+'(b.)c(?!\N)'s a\nb\nc\n y $1:$& b\n:b\nc
^b a\nb\nc\n n - -
()^b a\nb\nc\n n - -
((?m)^b) a\nb\nc\n y $1 b
@@ -1294,6 +1310,7 @@ X(\w+)(?=\s)|X(\w+) Xab y [$1-$2] [-ab]
(?|(?|(a)|(b))|(?|(c)|(d))) c y $1 c
(?|(?|(a)|(b))|(?|(c)|(d))) d y $1 d
(.)(?|(.)(.)x|(.)d)(.) abcde y $1-$2-$3-$4-$5- b-c--e--
+(\N)(?|(\N)(\N)x|(\N)d)(\N) abcde y $1-$2-$3-$4-$5- b-c--e--
#Bug #41492
(?(DEFINE)(?<A>(?&B)+)(?<B>a))(?&A) a y $& a
(?(DEFINE)(?<A>(?&B)+)(?<B>a))(?&A) aa y $& aa
@@ -1340,7 +1357,10 @@ foo(\h)bar foo\tbar y $1 \t
(\H)(\h) foo\tbar y $1-$2 o-\t
(\h)(\H) foo\tbar y $1-$2 \t-b
-.*\z foo\n y - -
+.*\z foo\n y -$&- --
+\N*\z foo\n y -$&- --
+.*\Z foo\n y -$&- -foo-
+\N*\Z foo\n y -$&- -foo-
^(?:(\d)x)?\d$ 1 y ${\(defined($1)?1:0)} 0
.*?(?:(\w)|(\w))x abx y $1-$2 b-
diff --git a/t/op/stash.t b/t/op/stash.t
index 4d8bc7c54d..e2f8901011 100644
--- a/t/op/stash.t
+++ b/t/op/stash.t
@@ -7,7 +7,7 @@ BEGIN {
BEGIN { require "./test.pl"; }
-plan( tests => 13 );
+plan( tests => 30 );
# Used to segfault (bug #15479)
fresh_perl_is(
@@ -58,6 +58,84 @@ ok( !eval q{ defined %schoenmaker:: }, 'works in eval("")' );
# now tests with strictures
-use strict;
-ok( !defined %pig::, q(referencing a non-existent stash doesn't produce stricture errors) );
-ok( !exists $pig::{bodine}, q(referencing a non-existent stash element doesn't produce stricture errors) );
+{
+ use strict;
+ ok( !defined %pig::, q(referencing a non-existent stash doesn't produce stricture errors) );
+ ok( !exists $pig::{bodine}, q(referencing a non-existent stash element doesn't produce stricture errors) );
+}
+
+SKIP: {
+ eval { require B; 1 } or skip "no B", 12;
+
+ *b = \&B::svref_2object;
+ my $CVf_ANON = B::CVf_ANON();
+
+ my $sub = do {
+ package one;
+ \&{"one"};
+ };
+ delete $one::{one};
+ my $gv = b($sub)->GV;
+
+ isa_ok( $gv, "B::GV", "deleted stash entry leaves CV with valid GV");
+ is( b($sub)->CvFLAGS & $CVf_ANON, $CVf_ANON, "...and CVf_ANON set");
+ is( eval { $gv->NAME }, "__ANON__", "...and an __ANON__ name");
+ is( eval { $gv->STASH->NAME }, "one", "...but leaves stash intact");
+
+ $sub = do {
+ package two;
+ \&{"two"};
+ };
+ %two:: = ();
+ $gv = b($sub)->GV;
+
+ isa_ok( $gv, "B::GV", "cleared stash leaves CV with valid GV");
+ is( b($sub)->CvFLAGS & $CVf_ANON, $CVf_ANON, "...and CVf_ANON set");
+ is( eval { $gv->NAME }, "__ANON__", "...and an __ANON__ name");
+ is( eval { $gv->STASH->NAME }, "__ANON__", "...and an __ANON__ stash");
+
+ $sub = do {
+ package three;
+ \&{"three"};
+ };
+ undef %three::;
+ $gv = b($sub)->GV;
+
+ isa_ok( $gv, "B::GV", "undefed stash leaves CV with valid GV");
+ is( b($sub)->CvFLAGS & $CVf_ANON, $CVf_ANON, "...and CVf_ANON set");
+ is( eval { $gv->NAME }, "__ANON__", "...and an __ANON__ name");
+ is( eval { $gv->STASH->NAME }, "__ANON__", "...and an __ANON__ stash");
+
+ TODO: {
+ local $TODO = "anon CVs not accounted for yet";
+
+ $sub = do {
+ package four;
+ sub { 1 };
+ };
+ %four:: = ();
+ $gv = b($sub)->GV;
+
+ isa_ok( $gv, "B::GV", "cleared stash leaves anon CV with valid GV");
+ is( eval { $gv->STASH->NAME }, "__ANON__", "...and an __ANON__ stash");
+
+ $sub = do {
+ package five;
+ sub { 1 };
+ };
+ undef %five::;
+ $gv = b($sub)->GV;
+
+ isa_ok( $gv, "B::GV", "undefed stash leaves anon CV with valid GV");
+ is( eval { $gv->STASH->NAME }, "__ANON__", "...and an __ANON__ stash");
+ }
+
+ # [perl #58530]
+ fresh_perl_is(
+ 'sub foo { 1 }; use overload q/""/ => \&foo;' .
+ 'delete $main::{foo}; bless []',
+ "",
+ {},
+ "no segfault with overload/deleted stash entry [#58530]",
+ );
+}
diff --git a/util.c b/util.c
index 469a9dac47..d8d28647f2 100644
--- a/util.c
+++ b/util.c
@@ -5471,38 +5471,35 @@ Perl_free_global_struct(pTHX_ struct perl_vars *plvarsp)
#ifdef PERL_MEM_LOG
-/*
- * PERL_MEM_LOG: the Perl_mem_log_..() will be compiled.
+/* -DPERL_MEM_LOG: the Perl_mem_log_..() is compiled, including the
+ * the default implementation, unless -DPERL_MEM_LOG_NOIMPL is also
+ * given, and you supply your own implementation.
+ *
+ * The default implementation reads a single env var, PERL_MEM_LOG,
+ * expecting one or more of the following:
*
- * PERL_MEM_LOG_ENV: if defined, during run time the environment
- * variables PERL_MEM_LOG and PERL_SV_LOG will be consulted, and
- * if the integer value of that is true, the logging will happen.
- * (The default is to always log if the PERL_MEM_LOG define was
- * in effect.)
+ * \d+ - fd fd to write to : must be 1st (atoi)
+ * 'm' - memlog was PERL_MEM_LOG=1
+ * 's' - svlog was PERL_SV_LOG=1
+ * 't' - timestamp was PERL_MEM_LOG_TIMESTAMP=1
*
- * PERL_MEM_LOG_TIMESTAMP: if defined, a timestamp will be logged
- * before every memory logging entry. This can be turned off at run
- * time by setting the environment variable PERL_MEM_LOG_TIMESTAMP
- * to zero.
+ * This makes the logger controllable enough that it can reasonably be
+ * added to the system perl.
*/
-/*
- * PERL_MEM_LOG_SPRINTF_BUF_SIZE: size of a (stack-allocated) buffer
+/* -DPERL_MEM_LOG_SPRINTF_BUF_SIZE=X: size of a (stack-allocated) buffer
* the Perl_mem_log_...() will use (either via sprintf or snprintf).
*/
#define PERL_MEM_LOG_SPRINTF_BUF_SIZE 128
-/*
- * PERL_MEM_LOG_FD: the file descriptor the Perl_mem_log_...() will
- * log to. You can also define in compile time PERL_MEM_LOG_ENV_FD,
- * in which case the environment variable PERL_MEM_LOG_FD will be
- * consulted for the file descriptor number to use.
+/* -DPERL_MEM_LOG_FD=N: the file descriptor the Perl_mem_log_...()
+ * writes to. In the default logger, this is settable at runtime.
*/
#ifndef PERL_MEM_LOG_FD
# define PERL_MEM_LOG_FD 2 /* If STDERR is too boring for you. */
#endif
-#ifdef PERL_MEM_LOG_STDERR
+#ifndef PERL_MEM_LOG_NOIMPL
# ifdef DEBUG_LEAKING_SCALARS
# define SV_LOG_SERIAL_FMT " [%lu]"
@@ -5513,23 +5510,25 @@ Perl_free_global_struct(pTHX_ struct perl_vars *plvarsp)
# endif
static void
-S_mem_log_common(enum mem_log_type mlt, const UV n, const UV typesize, const char *type_name, const SV *sv, Malloc_t oldalloc, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname)
+S_mem_log_common(enum mem_log_type mlt, const UV n,
+ const UV typesize, const char *type_name, const SV *sv,
+ Malloc_t oldalloc, Malloc_t newalloc,
+ const char *filename, const int linenumber,
+ const char *funcname)
{
-# if defined(PERL_MEM_LOG_ENV) || defined(PERL_MEM_LOG_ENV_FD)
- const char *s;
-# endif
+ const char *pmlenv;
PERL_ARGS_ASSERT_MEM_LOG_COMMON;
-# ifdef PERL_MEM_LOG_ENV
- s = PerlEnv_getenv(mlt < MLT_NEW_SV ? "PERL_MEM_LOG" : "PERL_SV_LOG");
- if (s ? atoi(s) : 0)
-# endif
+ pmlenv = PerlEnv_getenv("PERL_MEM_LOG");
+ if (!pmlenv)
+ return;
+ if (mlt < MLT_NEW_SV ? strchr(pmlenv,'m') : strchr(pmlenv,'s'))
{
/* We can't use SVs or PerlIO for obvious reasons,
* so we'll use stdio and low-level IO instead. */
char buf[PERL_MEM_LOG_SPRINTF_BUF_SIZE];
-# ifdef PERL_MEM_LOG_TIMESTAMP
+
# ifdef HAS_GETTIMEOFDAY
# define MEM_LOG_TIME_FMT "%10d.%06d: "
# define MEM_LOG_TIME_ARG (int)tv.tv_sec, (int)tv.tv_usec
@@ -5545,24 +5544,17 @@ S_mem_log_common(enum mem_log_type mlt, const UV n, const UV typesize, const cha
* gettimeofday() (see ext/Time-HiRes), the easiest way is
* probably that they would be used to fill in the struct
* timeval. */
-# endif
{
- int fd = PERL_MEM_LOG_FD;
STRLEN len;
+ int fd = atoi(pmlenv);
+ if (!fd)
+ fd = PERL_MEM_LOG_FD;
-# ifdef PERL_MEM_LOG_ENV_FD
- if ((s = PerlEnv_getenv("PERL_MEM_LOG_FD"))) {
- fd = atoi(s);
- }
-# endif
-# ifdef PERL_MEM_LOG_TIMESTAMP
- s = PerlEnv_getenv("PERL_MEM_LOG_TIMESTAMP");
- if (!s || atoi(s)) {
+ if (strchr(pmlenv, 't')) {
len = my_snprintf(buf, sizeof(buf),
MEM_LOG_TIME_FMT, MEM_LOG_TIME_ARG);
PerlLIO_write(fd, buf, len);
}
-# endif
switch (mlt) {
case MLT_ALLOC:
len = my_snprintf(buf, sizeof(buf),
@@ -5593,54 +5585,78 @@ S_mem_log_common(enum mem_log_type mlt, const UV n, const UV typesize, const cha
filename, linenumber, funcname,
PTR2UV(sv) _SV_LOG_SERIAL_ARG(sv));
break;
+ default:
+ len = 0;
}
PerlLIO_write(fd, buf, len);
}
}
}
+#endif /* !PERL_MEM_LOG_NOIMPL */
+
+#ifndef PERL_MEM_LOG_NOIMPL
+# define \
+ mem_log_common_if(alty, num, tysz, tynm, sv, oal, nal, flnm, ln, fnnm) \
+ mem_log_common (alty, num, tysz, tynm, sv, oal, nal, flnm, ln, fnnm)
+#else
+/* this is suboptimal, but bug compatible. User is providing their
+ own implemenation, but is getting these functions anyway, and they
+ do nothing. But _NOIMPL users should be able to cope or fix */
+# define \
+ mem_log_common_if(alty, num, tysz, tynm, u, oal, nal, flnm, ln, fnnm) \
+ /* mem_log_common_if_PERL_MEM_LOG_NOIMPL */
#endif
Malloc_t
-Perl_mem_log_alloc(const UV n, const UV typesize, const char *type_name, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname)
-{
-#ifdef PERL_MEM_LOG_STDERR
- mem_log_common(MLT_ALLOC, n, typesize, type_name, NULL, NULL, newalloc, filename, linenumber, funcname);
-#endif
+Perl_mem_log_alloc(const UV n, const UV typesize, const char *type_name,
+ Malloc_t newalloc,
+ const char *filename, const int linenumber,
+ const char *funcname)
+{
+ mem_log_common_if(MLT_ALLOC, n, typesize, type_name,
+ NULL, NULL, newalloc,
+ filename, linenumber, funcname);
return newalloc;
}
Malloc_t
-Perl_mem_log_realloc(const UV n, const UV typesize, const char *type_name, Malloc_t oldalloc, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname)
-{
-#ifdef PERL_MEM_LOG_STDERR
- mem_log_common(MLT_REALLOC, n, typesize, type_name, NULL, oldalloc, newalloc, filename, linenumber, funcname);
-#endif
+Perl_mem_log_realloc(const UV n, const UV typesize, const char *type_name,
+ Malloc_t oldalloc, Malloc_t newalloc,
+ const char *filename, const int linenumber,
+ const char *funcname)
+{
+ mem_log_common_if(MLT_REALLOC, n, typesize, type_name,
+ NULL, oldalloc, newalloc,
+ filename, linenumber, funcname);
return newalloc;
}
Malloc_t
-Perl_mem_log_free(Malloc_t oldalloc, const char *filename, const int linenumber, const char *funcname)
+Perl_mem_log_free(Malloc_t oldalloc,
+ const char *filename, const int linenumber,
+ const char *funcname)
{
-#ifdef PERL_MEM_LOG_STDERR
- mem_log_common(MLT_FREE, 0, 0, "", NULL, oldalloc, NULL, filename, linenumber, funcname);
-#endif
+ mem_log_common_if(MLT_FREE, 0, 0, "", NULL, oldalloc, NULL,
+ filename, linenumber, funcname);
return oldalloc;
}
void
-Perl_mem_log_new_sv(const SV *sv, const char *filename, const int linenumber, const char *funcname)
+Perl_mem_log_new_sv(const SV *sv,
+ const char *filename, const int linenumber,
+ const char *funcname)
{
-#ifdef PERL_MEM_LOG_STDERR
- mem_log_common(MLT_NEW_SV, 0, 0, "", sv, NULL, NULL, filename, linenumber, funcname);
-#endif
+ mem_log_common_if(MLT_NEW_SV, 0, 0, "", sv, NULL, NULL,
+ filename, linenumber, funcname);
}
void
-Perl_mem_log_del_sv(const SV *sv, const char *filename, const int linenumber, const char *funcname)
+Perl_mem_log_del_sv(const SV *sv,
+ const char *filename, const int linenumber,
+ const char *funcname)
{
-#ifdef PERL_MEM_LOG_STDERR
- mem_log_common(MLT_DEL_SV, 0, 0, "", sv, NULL, NULL, filename, linenumber, funcname);
-#endif
+ mem_log_common_if(MLT_DEL_SV, 0, 0, "", sv, NULL, NULL,
+ filename, linenumber, funcname);
}
#endif /* PERL_MEM_LOG */
diff --git a/vms/ext/filespec.t b/vms/ext/filespec.t
index 5dd27c9b9d..b40cc816f3 100644
--- a/vms/ext/filespec.t
+++ b/vms/ext/filespec.t
@@ -83,6 +83,7 @@ __DATA__
# Basic VMS to Unix filespecs
__some_:[__where_.__over_]__the_.__rainbow_ unixify /__some_/__where_/__over_/__the_.__rainbow_ ^
+__some_:<__where_.__over_>__the_.__rainbow_ unixify /__some_/__where_/__over_/__the_.__rainbow_ ^
[.__some_.__where_.__over_]__the_.__rainbow_ unixify __some_/__where_/__over_/__the_.__rainbow_ ^
[-.__some_.__where_.__over_]__the_.__rainbow_ unixify ../__some_/__where_/__over_/__the_.__rainbow_ ^
[.__some_.--.__where_.__over_]__the_.__rainbow_ unixify __some_/../../__where_/__over_/__the_.__rainbow_ ^
diff --git a/vms/vms.c b/vms/vms.c
index 0896934634..9e94935692 100644
--- a/vms/vms.c
+++ b/vms/vms.c
@@ -7346,7 +7346,7 @@ static char *int_tounixspec(const char *spec, char *rslt, int * utf8_fl)
}
if (*cp2 == ':') {
*(cp1++) = '/';
- if (*(cp2+1) == '[') cp2++;
+ if (*(cp2+1) == '[' || *(cp2+1) == '<') cp2++;
}
else if (*cp2 == ']' || *cp2 == '>') {
if (*(cp1-1) != '/') *(cp1++) = '/'; /* Don't double after ellipsis */