Integrate mainline
Nick Ing-Simmons [Fri, 20 Jul 2001 06:18:53 +0000 (06:18 +0000)]
p4raw-id: //depot/perlio@11413

24 files changed:
MANIFEST
doio.c
ext/B/B/Deparse.pm
ext/Encode/Encode/Tcl.pm
ext/Encode/Encode/euc-jp-0212.enc [new file with mode: 0644]
ext/POSIX/POSIX.t
ext/Time/HiRes/HiRes.xs
gv.c
hints/darwin.sh
hints/rhapsody.sh
numeric.c
pod/perlfunc.pod
pod/perlhack.pod
pod/perlre.pod
pp_sys.c
sv.c
t/README
t/lib/commonsense.t [moved from t/base/commonsense.t with 100% similarity]
t/op/arith.t
t/op/sprintf.t
thread.h
utils/h2xs.PL
win32/perlhost.h
win32/win32.c

index f0b0c1b..ac5b4f2 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -1845,7 +1845,6 @@ scope.c                           Scope entry and exit code
 scope.h                                Scope entry and exit header
 sv.c                           Scalar value code
 sv.h                           Scalar value header
-t/base/commonsense.t           See if configuration meets basic needs
 t/base/cond.t                  See if conditionals work
 t/base/if.t                    See if if works
 t/base/lex.t                   See if lexical items work
@@ -1888,6 +1887,7 @@ t/io/read.t                       See if read works
 t/io/tell.t                    See if file seeking works
 t/io/utf8.t                    See if file seeking works
 t/lib/1_compile.t              See if the various libraries and extensions compile
+t/lib/commonsense.t            See if configuration meets basic needs
 t/lib/compmod.pl               Helper for 1_compile.t
 t/lib/dprof/test1_t            Perl code profiler tests
 t/lib/dprof/test1_v            Perl code profiler tests
diff --git a/doio.c b/doio.c
index d0d28b0..e8ee679 100644 (file)
--- a/doio.c
+++ b/doio.c
@@ -235,6 +235,7 @@ Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
        if ((*type == IoTYPE_RDWR) && /* scary */
            (*(type+1) == IoTYPE_RDONLY || *(type+1) == IoTYPE_WRONLY) &&
            ((!num_svs || (tend > type+1 && tend[-1] != IoTYPE_PIPE)))) {
+        TAINT_PROPER("open");
            mode[1] = *type++;
            writing = 1;
        }
index 08f073e..4c8dc74 100644 (file)
@@ -768,8 +768,9 @@ sub deparse_format {
     my @text;
     local($self->{'curcv'}) = $form;
     local($self->{'curcvlex'});
+    local($self->{'in_format'}) = 1;
     local(@$self{qw'curstash warnings hints'})
-               = @$self{'curstash warnings hints'};
+               = @$self{qw'curstash warnings hints'};
     my $op = $form->ROOT;
     my $kid;
     $op = $op->first->first; # skip leavewrite, lineseq
@@ -1064,7 +1065,7 @@ sub lineseq {
     }
     my $body = join(";\n", grep {length} @exprs);
     my $subs = "";
-    if (defined $root && defined $limit_seq) {
+    if (defined $root && defined $limit_seq && !$self->{'in_format'}) {
        $subs = join "\n", $self->seq_subs($limit_seq);
     }
     return join(";\n", grep {length} $body, $subs);
index e8c41e4..eb13c5f 100644 (file)
@@ -78,7 +78,11 @@ sub loadEncoding
      $type = substr($line,0,1);
      last unless $type eq '#';
     }
-   my $class = ref($obj).('::'.(($type eq 'H') ? 'HanZi' : ($type eq 'E') ? 'Escape' : 'Table'));
+   my $class = ref($obj).('::'.(
+       ($type eq 'X') ? 'Extended' :
+       ($type eq 'H') ? 'HanZi' :
+       ($type eq 'E') ? 'Escape' : 'Table'
+       ));
    # carp "Loading $file";
    bless $obj,$class;
    return $obj if $obj->read($fh,$obj->name,$type);
@@ -270,25 +274,25 @@ sub decode
  my $std = $seq->[0];
  my $cur = $std;
  my @sta = ($std, undef, undef, undef); # G0 .. G3 state
- my($g1,$g2,$g3) = (0,0,0);
+ my $s   = 0; # state of SO-SI.   0 (G0) or 1 (G1);
+ my $ss  = 0; # state of SS2,SS3. 0 (G0), 2 (G2) or 3 (G3);
  my $uni;
  while (length($str)){
    my $uch = substr($str,0,1,'');
    if($uch eq "\e"){
     if($str =~ s/^($esc)//)
      {
-      my $esc = "\e$1";
-      $sta[ $grp->{$esc} ] = $esc if $tbl->{$esc};
+      my $e = "\e$1";
+      $sta[ $grp->{$e} ] = $e if $tbl->{$e};
      }
     # appearance of "\eN\eO" or "\eO\eN" isn't supposed.
-    # but coincidental ON of G2 and G3 is explicitly avoided.
     elsif($str =~ s/^N//)
      {
-      $g2 = 1; $g3 = 0;
+      $ss = 2;
      }
     elsif($str =~ s/^O//)
      {
-      $g3 = 1; $g2 = 0;
+      $ss = 3;
      }
     else
      {
@@ -298,17 +302,17 @@ sub decode
     next;
    }
    if($uch eq "\x0e"){
-    $g1 = 1; next;
+    $s = 1; next;
    }
    if($uch eq "\x0f"){
-    $g1 = 0; next;
+    $s = 0; next;
    }
 
-   $cur = $g3 ? $sta[3] : $g2 ? $sta[2] : $g1 ? $sta[1] : $sta[0];
+   $cur = $ss ? $sta[$ss] : $sta[$s];
 
    if(ref($tbl->{$cur}) eq 'Encode::XS'){
      $uni .= $tbl->{$cur}->decode($uch);
-     $g2 = $g3 = 0;
+     $ss = 0;
      next;
    }
    my $ch    = ord($uch);
@@ -330,7 +334,7 @@ sub decode
      $x = '';
     }
    $uni .= $x;
-   $g2 = $g3 = 0;
+   $ss = 0;
   }
  $_[1] = $str if $chk;
  return $uni;
@@ -346,15 +350,14 @@ sub encode
  my $fin = $obj->{'final'};
  my $std = $seq->[0];
  my $str = $ini;
- my @sta = ($std,undef,undef,undef);
- my @pre = ($std,undef,undef,undef);
+ my @sta = ($std,undef,undef,undef); # G0 .. G3 state
  my $cur = $std;
- my $pG = 0;
- my $cG = 0;
+ my $pG = 0; # previous G: 0 or 1.
+ my $cG = 0; # current G: 0,1,2,3. 
 
- if($ini)
+ if($ini && defined $grp->{$ini})
   {
-    $sta[ $grp->{$ini} ] = $pre[ $grp->{$ini} ] = $ini;
+    $sta[ $grp->{$ini} ] = $ini;
   }
 
  while (length($uni)){
@@ -377,22 +380,141 @@ sub encode
     $x = pack(&$rep($x),$x);
    }
   $cG   = $grp->{$cur};
-  $str .= $pre[ $cG ] = $cur if $cur ne $pre[ $cG ];
+  $str .= $sta[$cG] = $cur unless $cG < 2 && $cur eq $sta[$cG];
 
   $str .= $cG == 0 && $pG == 1 ? "\cO" :
           $cG == 1 && $pG == 0 ? "\cN" :
           $cG == 2 ? "\eN" :
-          $cG == 3 ? "\eO" :        "";
+          $cG == 3 ? "\eO" : "";
   $str .= $x;
   $pG = $cG if $cG < 2;
  }
- $str .= $std  unless $cur eq $std;
  $str .= "\cO" if $pG == 1; # back to G0
+ $str .= $std  unless $std eq $sta[0]; # GO to ASCII
  $str .= $fin; # necessary?
  $_[1] = $uni if $chk;
  return $str;
 }
 
+
+package Encode::Tcl::Extended;
+use base 'Encode::Encoding';
+
+use Carp;
+
+sub read
+{
+ my ($obj,$fh,$name) = @_;
+ my(%tbl, $enc, %ssc, @key);
+ while (<$fh>)
+  {
+   my ($key,$val) = /^(\S+)\s+(.*)$/;
+   $val =~ s/\{(.*?)\}/$1/;
+   $val =~ s/\\x([0-9a-f]{2})/chr(hex($1))/ge;
+
+   if($enc = Encode->getEncoding($key)){
+     push @key, $val;
+     $tbl{$val} = ref($enc) eq 'Encode::Tcl'
+       ? $enc->loadEncoding : $enc;
+     $ssc{$val} = substr($val,1) if $val =~ /^>/;
+   }else{
+     $obj->{$key} = $val;
+   }
+  }
+ $obj->{'SSC'} = \%ssc; # single shift char
+ $obj->{'Tbl'} = \%tbl; # encoding tables
+ $obj->{'Key'} = \@key; # keys of table hash
+ return $obj;
+}
+
+sub decode
+{
+ my ($obj,$str,$chk) = @_;
+ my $tbl = $obj->{'Tbl'};
+ my $ssc = $obj->{'SSC'};
+ my $cur = ''; # current state
+ my $uni;
+ while (length($str)){
+   my $uch = substr($str,0,1,'');
+   my $ch  = ord($uch);
+   if(!$cur && $ch > 0x7F)
+    {
+     $cur = '>';
+     $cur .= $uch, next if $ssc->{$cur.$uch};
+    }
+   $ch ^= 0x80 if $cur;
+
+   if(ref($tbl->{$cur}) eq 'Encode::XS'){
+     $uni .= $tbl->{$cur}->decode(chr($ch));
+     $cur = '';
+     next;
+   }
+   my $rep   = $tbl->{$cur}->{'Rep'};
+   my $touni = $tbl->{$cur}->{'ToUni'};
+   my $x;
+   if (&$rep($ch) eq 'C')
+    {
+     $x = $touni->[0][$ch];
+    }
+   else
+    {
+     $x = $touni->[$ch][0x80 ^ ord(substr($str,0,1,''))];
+    }
+   unless (defined $x)
+    {
+     last if $chk;
+     # What do we do here ?
+     $x = '';
+    }
+   $uni .= $x;
+   $cur = '';
+  }
+ $_[1] = $str if $chk;
+ return $uni;
+}
+
+sub encode
+{
+ my ($obj,$uni,$chk) = @_;
+ my $tbl = $obj->{'Tbl'};
+ my $ssc = $obj->{'SSC'};
+ my $key = $obj->{'Key'};
+ my $str;
+ my $cur;
+
+ while (length($uni)){
+  my $ch = substr($uni,0,1,'');
+  my $x;
+  foreach my $k (@$key){
+   $x = ref($tbl->{$k}) eq 'Encode::XS'
+    ? $k =~ /^>/
+      ? $tbl->{$k}->encode(chr(0x80 ^ ord $ch),1)
+      : $tbl->{$k}->encode($ch,1)
+    : $tbl->{$k}->{FmUni}->{$ch};
+   $cur = $k, last if defined $x;
+  }
+  if(ref($tbl->{$cur}) ne 'Encode::XS')
+   {
+    my $def = $tbl->{$cur}->{'Def'};
+    my $rep = $tbl->{$cur}->{'Rep'};
+    unless (defined $x){
+     last if ($chk);
+     $x = $def;
+    }
+    my $r = &$rep($x);
+    $x = pack($r,
+      $cur =~ /^>/
+        ? $r eq 'C' ? 0x80 ^ $x : 0x8080 ^ $x
+        : $x);
+   }
+
+  $str .= $ssc->{$cur} if defined $ssc->{$cur};
+  $str .= $x;
+ }
+ $_[1] = $uni if $chk;
+ return $str;
+}
+
 package Encode::Tcl::HanZi;
 use base 'Encode::Encoding';
 
diff --git a/ext/Encode/Encode/euc-jp-0212.enc b/ext/Encode/Encode/euc-jp-0212.enc
new file mode 100644 (file)
index 0000000..23d7325
--- /dev/null
@@ -0,0 +1,7 @@
+# Encoding file: euc-jp-0212, extended
+X
+name           euc-jp-0212
+ascii          {}
+jis0208                >{}
+7bit-kana      >\x8e
+jis0212                >\x8f
index 2c80924..2c52f26 100755 (executable)
@@ -87,7 +87,7 @@ if ($Config{d_strtod}) {
     $lc = &POSIX::setlocale(&POSIX::LC_NUMERIC, 'C') if $Config{d_setlocale};
     ($n, $x) = &POSIX::strtod('3.14159_OR_SO');
 # we're just checking that strtod works, not how accurate it is
-    print (("3.14159" eq $n + 0) && ($x == 6) ?
+    print ((abs("3.14159" - $n) < 1e-6) && ($x == 6) ?
           "ok 14\n" : "not ok 14\n");
     &POSIX::setlocale(&POSIX::LC_NUMERIC, $lc) if $Config{d_setlocale};
 } else { print "# strtod not present\n", "ok 14\n"; }
index a16dccc..77ce9e2 100644 (file)
@@ -276,11 +276,12 @@ usleep(useconds)
         int useconds 
 
 void
-sleep(fseconds)
-        NV fseconds 
+sleep(...)
        CODE:
-       int useconds = fseconds * 1000000;
-       usleep (useconds);
+       if (items > 0)
+           usleep((int)(SvNV(ST(0)) * 1000000));
+       else
+           PerlProc_pause();
 
 #endif
 
diff --git a/gv.c b/gv.c
index e4951a0..b049218 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -938,6 +938,17 @@ Perl_gv_fetchpv(pTHX_ const char *nambeg, I32 add, I32 sv_type)
     case '7':
     case '8':
     case '9':
+       /* ensures variable is only digits */
+       /* ${"1foo"} fails this test (and is thus writeable) */
+       /* added by japhy, but borrowed from is_gv_magical */
+
+       if (len > 1) {
+           const char *end = name + len;
+           while (--end > name) {
+               if (!isDIGIT(*end)) return gv;
+           }
+       }
+
       ro_magicalize:
        SvREADONLY_on(GvSV(gv));
       magicalize:
index 9ff2747..da34d65 100644 (file)
@@ -41,10 +41,12 @@ usenm='true';
 #libc='/usr/lib/libSystem.dylib';
 
 # Optimize.
-optimize='-O3';
+if [ "x$optimize" = 'x' ]; then
+    optimize='-O3'
+fi
 
-# We have a prototype for telldir.
-ccflags="${ccflags} -pipe -fno-common -DHAS_TELLDIR_PROTOTYPE";
+# XXX Unclear why we require -pipe and -fno-common here.
+ccflags="${ccflags} -pipe -fno-common"
 
 # At least on Darwin 1.3.x:
 #
index 2fe2b44..96d57f2 100644 (file)
@@ -43,8 +43,8 @@ libc='/System/Library/Frameworks/System.framework/System';
 # Optimize.
 optimize='-O3';
 
-# We have a prototype for telldir.
-ccflags="${ccflags} -pipe -fno-common -DHAS_TELLDIR_PROTOTYPE";
+# XXX Unclear why we require -pipe and -fno-common here.
+ccflags="${ccflags} -pipe -fno-common"
 
 # cpp-precomp is problematic.
 cppflags='-traditional-cpp';
index ec93d6b..4363669 100644 (file)
--- a/numeric.c
+++ b/numeric.c
@@ -629,6 +629,10 @@ Perl_my_atof2(pTHX_ const char* orig, NV* value)
     I32 ipart = 0;     /* index into part[] */
     I32 offcount;      /* number of digits in least significant part */
 
+    /* leading whitespace */
+    while (isSPACE(*s))
+       ++s;
+
     /* sign */
     switch (*s) {
        case '-':
index fcd6f57..3f86c6a 100644 (file)
@@ -3490,9 +3490,10 @@ you will have to use a block returning its value instead:
 
 Equivalent to C<print FILEHANDLE sprintf(FORMAT, LIST)>, except that C<$\>
 (the output record separator) is not appended.  The first argument
-of the list will be interpreted as the C<printf> format.  If C<use locale> is
-in effect, the character used for the decimal point in formatted real numbers
-is affected by the LC_NUMERIC locale.  See L<perllocale>.
+of the list will be interpreted as the C<printf> format. See C<sprintf>
+for an explanation of the format argument. If C<use locale> is in effect,
+the character used for the decimal point in formatted real numbers is
+affected by the LC_NUMERIC locale.  See L<perllocale>.
 
 Don't fall into the trap of using a C<printf> when a simple
 C<print> would do.  The C<print> is more efficient and less
index f44036d..3c0208e 100644 (file)
@@ -350,7 +350,7 @@ from Andreas K
 
 =back
 
-=head3 Why rsync the source tree
+=head2 Why rsync the source tree
 
 =over 4
 
@@ -378,7 +378,7 @@ more ... (see Sarathy's remark).
 
 =back
 
-=head3 Why rsync the patches
+=head2 Why rsync the patches
 
 =over 4
 
@@ -469,20 +469,23 @@ for reference.
 
 =head2 Submitting patches
 
-Always submit patches to I<perl5-porters@perl.org>.  This lets other
-porters review your patch, which catches a surprising number of errors
-in patches.  Either use the diff program (available in source code
-form from I<ftp://ftp.gnu.org/pub/gnu/>), or use Johan Vromans'
-I<makepatch> (available from I<CPAN/authors/id/JV/>).  Unified diffs
-are preferred, but context diffs are accepted.  Do not send RCS-style
-diffs or diffs without context lines.  More information is given in
-the I<Porting/patching.pod> file in the Perl source distribution.
-Please patch against the latest B<development> version (e.g., if
-you're fixing a bug in the 5.005 track, patch against the latest
-5.005_5x version).  Only patches that survive the heat of the
-development branch get applied to maintenance versions.
-
-Your patch should update the documentation and test suite.
+Always submit patches to I<perl5-porters@perl.org>.  If you're
+patching a core module and there's an author listed, send the author a
+copy (see L<Patching a core module>).  This lets other porters review
+your patch, which catches a surprising number of errors in patches.
+Either use the diff program (available in source code form from
+I<ftp://ftp.gnu.org/pub/gnu/>), or use Johan Vromans' I<makepatch>
+(available from I<CPAN/authors/id/JV/>).  Unified diffs are preferred,
+but context diffs are accepted.  Do not send RCS-style diffs or diffs
+without context lines.  More information is given in the
+I<Porting/patching.pod> file in the Perl source distribution.  Please
+patch against the latest B<development> version (e.g., if you're
+fixing a bug in the 5.005 track, patch against the latest 5.005_5x
+version).  Only patches that survive the heat of the development
+branch get applied to maintenance versions.
+
+Your patch should update the documentation and test suite.  See
+L<Writing a test>.
 
 To report a bug in Perl, use the program I<perlbug> which comes with
 Perl (if you can't get Perl to work, send mail to the address
@@ -570,6 +573,13 @@ Modules shipped as part of the Perl core live in the F<lib/> and F<ext/>
 subdirectories: F<lib/> is for the pure-Perl modules, and F<ext/>
 contains the core XS modules.
 
+=item Tests
+
+There are tests for nearly all the modules, built-ins and major bits
+of functionality.  Test files all have a .t suffix.  Module tests live
+in the F<lib/> and F<ext/> directories next to the module being
+tested.  Others live in F<t/>.  See L<Writing a test>
+
 =item Documentation
 
 Documentation maintenance includes looking after everything in the
@@ -1535,6 +1545,98 @@ We end up with a patch looking a little like this:
 And finally, we submit it, with our rationale, to perl5-porters. Job
 done!
 
+=head2 Patching a core module
+
+This works just like patching anything else, with an extra
+consideration.  Many core modules also live on CPAN.  If this is so,
+patch the CPAN version instead of the core and send the patch off to
+the module maintainer (with a copy to p5p).  This will help the module
+maintainer keep the CPAN version in sync with the core version without
+constantly scanning p5p.
+
+
+=head2 Writing a test
+
+Every module and built-in function has an associated test file (or
+should...).  If you add or change functionality, you have to write a
+test.  If you fix a bug, you have to write a test so that bug never
+comes back.  If you alter the docs, it would be nice to test what the
+new documentation says.
+
+In short, if you submit a patch you probably also have to patch the
+tests.
+
+For modules, the test file is right next to the module itself.
+F<lib/strict.t> tests F<lib/strict.pm>.  This is a recent innovation,
+so there are some snags (and it would be wonderful for you to brush
+them out), but it basically works that way.  Everything else lives in
+F<t/>.
+
+=over 3
+
+=item F<t/base/>
+
+Testing of the absolute basic functionality of Perl.  Things like
+C<if>, basic file reads and writes, simple regexes, etc.  These are
+run first in the test suite and if any of them fail, something is
+I<really> broken.
+
+=item F<t/cmd/>
+
+These test the basic control structures, C<if/else>, C<while>,
+subroutines, etc... 
+
+=item F<t/comp/>
+
+Tests basic issues of how Perl parses and compiles itself.
+
+=item F<t/io/>
+
+Tests for built-in IO functions, including command line arguments.
+
+=item F<t/lib/>
+
+The old home for the module tests, you shouldn't put anything new in
+here.  There are still some bits and pieces hanging around in here
+that need to be moved.  Perhaps you could move them?  Thanks!
+
+=item F<t/op/>
+
+Tests for perl's built in functions that don't fit into any of the
+other directories.
+
+=item F<t/pod/>
+
+Tests for POD directives.  There are still some tests for the Pod
+modules hanging around in here that need to be moved out into F<lib/>.
+
+=item F<t/run/>
+
+Testing features of how perl actually runs, including exit codes and
+handling of PERL* environment variables.
+
+=back
+
+The core uses the same testing style as the rest of Perl, a simple
+"ok/not ok" run through Test::Harness, but there are a few special
+considerations.
+
+For most libraries and extensions, you'll want to use the Test::More
+library rather than rolling your own test functions.  If a module test
+doesn't use Test::More, consider rewriting it so it does.  For the
+rest it's best to use a simple C<print "ok $test_num\n"> style to avoid
+broken core functionality from causing the whole test to collapse.
+
+When you say "make test" Perl uses the F<t/TEST> program to run the
+test suite.  All tests are run from the F<t/> directory, B<not> the
+directory which contains the test.  This causes some problems with the
+tests in F<lib/>, so here's some opportunity for some patching.
+
+You must be triply conscious of cross-platform concerns.  This usually
+boils down to using File::Spec and avoiding things like C<fork()> and
+C<system()> unless absolutely necessary.
+
+
 =head1 EXTERNAL TOOLS FOR DEBUGGING PERL
 
 Sometimes it helps to use external tools while debugging and
index e5f9066..c295f60 100644 (file)
@@ -4,10 +4,16 @@ perlre - Perl regular expressions
 
 =head1 DESCRIPTION
 
-This page describes the syntax of regular expressions in Perl.  For a
-description of how to I<use> regular expressions in matching
-operations, plus various examples of the same, see discussions
-of C<m//>, C<s///>, C<qr//> and C<??> in L<perlop/"Regexp Quote-Like Operators">.
+This page describes the syntax of regular expressions in Perl.  
+
+if you haven't used regular expressions before, a quick-start
+introduction is available in L<perlrequick>, and a longer tutorial
+introduction is available in L<perlretut>.
+
+For reference on how regular expressions are used in matching
+operations, plus various examples of the same, see discussions of
+C<m//>, C<s///>, C<qr//> and C<??> in L<perlop/"Regexp Quote-Like
+Operators">.
 
 Matching operations can have various modifiers.  Modifiers
 that relate to the interpretation of the regular expression inside
@@ -1270,6 +1276,10 @@ from the reference content.
 
 =head1 SEE ALSO
 
+L<perlrequick>.
+
+L<perlretut>.
+
 L<perlop/"Regexp Quote-Like Operators">.
 
 L<perlop/"Gory details of parsing quoted constructs">.
index 0451d5a..6a74b11 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -3874,6 +3874,10 @@ PP(pp_fork)
     Pid_t childpid;
     GV *tmpgv;
 
+#   if defined(USE_ITHREADS) && !defined(HAS_PTHREAD_ATFORK)
+       Perl_croak(aTHX_ "No pthread_atfork() -- fork() too unsafe");
+#   endif
+
     EXTEND(SP, 1);
     PERL_FLUSHALL_FOR_CHILD;
     childpid = fork();
diff --git a/sv.c b/sv.c
index 09832cf..f74adea 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -8366,13 +8366,6 @@ Perl_re_dup(pTHX_ REGEXP *r, clone_params *param)
     New(0, ret->endp, npar, I32);
     Copy(r->startp, ret->startp, npar, I32);
 
-    if (r->regstclass) {
-       New(0, ret->regstclass, 1, regnode);
-       StructCopy(r->regstclass, ret->regstclass, regnode);
-    }
-    else
-       ret->regstclass = NULL;
-
     New(0, ret->substrs, 1, struct reg_substr_data);
     for (s = ret->substrs->data, i = 0; i < 3; i++, s++) {
        s->min_offset = r->substrs->data[i].min_offset;
@@ -8380,6 +8373,7 @@ Perl_re_dup(pTHX_ REGEXP *r, clone_params *param)
        s->substr     = sv_dup_inc(r->substrs->data[i].substr, param);
     }
 
+    ret->regstclass = NULL;
     if (r->data) {
        struct reg_data *d;
        int count = r->data->count;
@@ -8403,6 +8397,7 @@ Perl_re_dup(pTHX_ REGEXP *r, clone_params *param)
                New(0, d->data[i], 1, struct regnode_charclass_class);
                StructCopy(r->data->data[i], d->data[i],
                            struct regnode_charclass_class);
+               ret->regstclass = (regnode*)d->data[i];
                break;
            case 'o':
            case 'n':
@@ -8420,8 +8415,6 @@ Perl_re_dup(pTHX_ REGEXP *r, clone_params *param)
     Copy(r->offsets, ret->offsets, 2*len+1, U32);
 
     ret->precomp        = SAVEPV(r->precomp);
-    ret->subbeg         = SAVEPV(r->subbeg);
-    ret->sublen         = r->sublen;
     ret->refcnt         = r->refcnt;
     ret->minlen         = r->minlen;
     ret->prelen         = r->prelen;
@@ -8430,6 +8423,13 @@ Perl_re_dup(pTHX_ REGEXP *r, clone_params *param)
     ret->lastcloseparen = r->lastcloseparen;
     ret->reganch        = r->reganch;
 
+    ret->sublen         = r->sublen;
+
+    if (RX_MATCH_COPIED(ret))
+       ret->subbeg  = SAVEPV(r->subbeg);
+    else
+       ret->subbeg = Nullch;
+
     ptr_table_store(PL_ptr_table, r, ret);
     return ret;
 }
index 7cff553..b4b1f53 100644 (file)
--- a/t/README
+++ b/t/README
@@ -1,4 +1,6 @@
-This is the perl test library.  To run all the tests, just type './TEST'.
+This is the perl test library.  To run most of the tests, just type './TEST'
+(which will not run the tests residing in lib/ or ext/.  In order to run
+all of the tests type 'make test' from the build direcotory above t/).
 
 To add new tests, just look at the current tests and do likewise.
 
@@ -10,12 +12,17 @@ ignores lines beginning with '#'.
 
 If you know that Perl is basically working but expect that some tests
 will fail, you may want to use Test::Harness thusly:
+        cd t
        ./perl -I../lib harness
 This method pinpoints failed tests automatically.
 
 If you come up with new tests, please send them to perlbug@perl.org.
 
-Tests in the base/ directory ought to be runnable with plain miniperl.
+Tests in the t/base/ directory ought to be runnable with plain miniperl.
 That is, they should not require Config.pm nor should they require any
 extensions to have been built.  TEST will abort if any tests in the
-base/ directory fail.
+t/base/ directory fail.
+
+Tests in the t/comp/, t/cmd/, t/run/, t/io/, and t/op/ directories should
+also be runnable by miniperl and not require Config.pm, but failures
+to comply will not cause TEST to abort like for t/base/.
similarity index 100%
rename from t/base/commonsense.t
rename to t/lib/commonsense.t
index 2847acb..8b8e2bc 100755 (executable)
@@ -1,6 +1,6 @@
 #!./perl -w
 
-print "1..109\n";
+print "1..113\n";
 
 sub try ($$) {
    print +($_[1] ? "ok" : "not ok"), " $_[0]\n";
@@ -204,3 +204,10 @@ tryeq 106, 46339 * 46341, 0x7ffea80f;
 tryeq 107, 46339 * -46341, -0x7ffea80f;
 tryeq 108, -46339 * 46341, -0x7ffea80f;
 tryeq 109, -46339 * -46341, 0x7ffea80f;
+
+# leading space should be ignored
+
+tryeq 110, 1 + " 1", 2;
+tryeq 111, 3 + " -1", 2;
+tryeq 112, 1.2, " 1.2";
+tryeq 113, -1.2, " -1.2";
index 3ac559d..89992d6 100755 (executable)
@@ -11,8 +11,8 @@ BEGIN {
     @INC = '../lib';
 }   
 use warnings;
-# %Config is needed to obtain archname for VAX (since @INC is now insufficient)
-use Config;
+# we do not load %Config since this test resides in op and needs
+# to run under the minitest target even without Config.pm working.
 
 # strictness
 my @tests = ();
@@ -36,10 +36,11 @@ $SIG{__WARN__} = sub {
 };
 
 my $Is_VMS_VAX = 0;
-# The redundant $^O check might help non VMS platforms avoid %Config load
-if ($^O eq 'VMS' &&
-      defined($Config{'archname'}) && $Config{'archname'} eq 'VMS_VAX') {
-    $Is_VMS_VAX = 1;
+# We use HW_MODEL since ARCH_NAME was not in VMS V5.*
+if ($^O eq 'VMS') {
+    my $hw_model;
+    chomp($hw_model = `write sys\$output f\$getsyi("HW_MODEL")`);
+    $Is_VMS_VAX = $hw_model < 1024 ? 1 : 0;
 }
 
 for ($i = 1; @tests; $i++) {
index a82c01b..3b26b17 100644 (file)
--- a/thread.h
+++ b/thread.h
@@ -310,13 +310,8 @@ void Perl_atfork_unlock(void);
 #    define PTHREAD_ATFORK(prepare,parent,child)               \
        pthread_atfork(prepare,parent,child)
 #  else
-#    ifdef HAS_FORK
-#      define PTHREAD_ATFORK(prepare,parent,child)             \
-        Perl_croak(aTHX_ "No pthread_atfork() -- fork() too unsafe");
-#    else
-#      define PTHREAD_ATFORK(prepare,parent,child)             \
-        NOOP
-#    endif
+#    define PTHREAD_ATFORK(prepare,parent,child)               \
+       NOOP
 #  endif
 #endif
 
@@ -474,7 +469,3 @@ typedef struct condpair {
 #ifndef INIT_THREADS
 #  define INIT_THREADS NOOP
 #endif
-
-#ifndef PTHREAD_ATFORK
-#  define PTHREAD_ATFORK(prepare,parent,child) NOOP
-#endif
index 292a461..c27d24b 100644 (file)
@@ -43,9 +43,9 @@ h2xs - convert .h C header files to Perl extensions
 
 =head1 SYNOPSIS
 
-B<h2xs> [B<-ACOPXacdfkmx>] [B<-F> addflags] [B<-M> fmask] [B<-n> module_name] [B<-o> tmask] [B<-p> prefix] [B<-s> subs] [B<-v> version] [B<-b> compat_version] [headerfile ... [extra_libraries]]
+B<h2xs> [B<OPTIONS> ...] [headerfile ... [extra_libraries]]
 
-B<h2xs> B<-h>
+B<h2xs> B<-h>|B<-?>|B<--help>
 
 =head1 DESCRIPTION
 
@@ -197,6 +197,17 @@ The default is IV (signed integer).  Currently all macros found during the
 header scanning process will be assumed to have this type.  Future versions
 of C<h2xs> may gain the ability to make educated guesses.
 
+=item B<--use-new-tests>
+
+When B<--compat-version> (B<-b>) is present the generated tests will use
+C<Test::More> rather then C<Test> which is the default for versions before
+5.7.2 .   C<Test::More> will be added to PREREQ_PM in the generated
+C<Makefile.PL>.
+
+=item B<--use-old-tests>
+
+Will force the generation of test code that uses the older C<Test> module.
+
 =item B<-v>, B<--version>=I<version>
 
 Specify a version number for this extension.  This version number is added
@@ -462,6 +473,8 @@ OPTIONS:
                           Perl function names.
     -s, --const-subs      Create subroutines for specified macros.
     -t, --default-type    Default type for autoloaded constants
+        --use-new-tests   Use Test::More in backward compatible modules
+        --use-old-tests   Use the module Test rather than Test::More
     -v, --version         Specify a version number for this extension.
     -x, --autogen-xsubs   Autogenerate XSUBs using C::Scan.
 
@@ -492,7 +505,9 @@ my ($opt_A,
     $opt_v,
     $opt_x,
     $opt_b,
-    $opt_t
+    $opt_t,
+    $new_test,
+    $old_test
    );
 
 Getopt::Long::Configure('bundling');
@@ -519,7 +534,9 @@ my %options = (
                 'const-subs|s=s'     => \$opt_s,
                 'default-type|t=s'   => \$opt_t,
                 'version|v=s'        => \$opt_v,
-                'autogen-xsubs|x=s'  => \$opt_x
+                'autogen-xsubs|x=s'  => \$opt_x,
+                'use-new-tests'      => \$new_test,
+                'use-old-tests'      => \$old_test
               );
 
 GetOptions(%options) || usage;
@@ -529,8 +546,8 @@ usage if $opt_h;
 if( $opt_b ){
     usage "You cannot use -b and -m at the same time.\n" if ($opt_b && $opt_m);
     $opt_b =~ /^\d+\.\d+\.\d+/ ||
-       usage "You must provide the backwards compatibility version in X.Y.Z form. " .
-           "(i.e. 5.5.0)\n";
+    usage "You must provide the backwards compatibility version in X.Y.Z form. "
+          .  "(i.e. 5.5.0)\n";
     my ($maj,$min,$sub) = split(/\./,$opt_b,3);
     $compat_version = sprintf("%d.%03d%02d",$maj,$min,$sub);
 } 
@@ -1104,6 +1121,13 @@ my $pod = <<"END" unless $opt_P;
 #  use $module;
 #  blah blah blah
 #
+#=head1 ABSTRACT
+#
+#  This should be the abstract for $module.
+#  The abstract is used when making PPD (Perl Package Description) files.
+#  If you don't want an ABSTRACT you should also edit Makefile.PL to
+#  remove the ABSTRACT_FROM option.
+#
 #=head1 DESCRIPTION
 #
 #Stub documentation for $module, created by h2xs. It looks like the
@@ -1623,6 +1647,17 @@ EOP
 warn "Writing $ext$modpname/Makefile.PL\n";
 open(PL, ">Makefile.PL") || die "Can't create $ext$modpname/Makefile.PL: $!\n";
 
+my $prereq_pm;
+
+if ( $compat_version < 5.00702 and $new_test )
+{
+  $prereq_pm = q%'Test::More'  =>  0%;
+}
+else
+{
+  $prereq_pm = '';
+}
+
 print PL <<END;
 use ExtUtils::MakeMaker;
 # See lib/ExtUtils/MakeMaker.pm for details of how to influence
@@ -1630,7 +1665,7 @@ use ExtUtils::MakeMaker;
 WriteMakefile(
     'NAME'             => '$module',
     'VERSION_FROM'     => '$modfname.pm', # finds \$VERSION
-    'PREREQ_PM'                => {}, # e.g., Module::Name => 1.1
+    'PREREQ_PM'                => {$prereq_pm}, # e.g., Module::Name => 1.1
     (\$] >= 5.005 ?    ## Add these new keywords supported since 5.005
       (ABSTRACT_FROM => '$modfname.pm', # retrieve abstract from module
        AUTHOR     => '$author <$email>') : ()),
@@ -1669,6 +1704,18 @@ open(RM, ">README") || die "Can't create $ext$modpname/README:$!\n";
 my $thisyear = (gmtime)[5] + 1900;
 my $rmhead = "$modpname version $TEMPLATE_VERSION";
 my $rmheadeq = "=" x length($rmhead);
+
+my $rm_prereq;
+
+if ( $compat_version < 5.00702 and $new_test )
+{
+   $rm_prereq = 'Test::More';
+}
+else
+{
+   $rm_prereq = 'blah blah blah';
+}
+
 print RM <<_RMEND_;
 $rmhead
 $rmheadeq
@@ -1697,7 +1744,7 @@ DEPENDENCIES
 
 This module requires these other modules and libraries:
 
-  blah blah blah
+  $rm_prereq
 
 COPYRIGHT AND LICENCE
 
@@ -1720,6 +1767,7 @@ warn "Writing $ext$modpname/$testfile\n";
 my $tests = @const_names ? 2 : 1;
 
 open EX, ">$testfile" or die "Can't create $ext$modpname/$testfile: $!\n";
+
 print EX <<_END_;
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl 1.t'
@@ -1728,22 +1776,34 @@ print EX <<_END_;
 
 # change 'tests => $tests' to 'tests => last_test_to_print';
 
+_END_
+
+my $test_mod = 'Test::More';
+
+if ( $old_test or ($compat_version < 5.007 and not $new_test ))
+{
+  my $test_mod = 'Test';
+
+  print EX <<_END_;
 use Test;
 BEGIN { plan tests => $tests };
 use $module;
 ok(1); # If we made it this far, we're ok.
 
 _END_
-if (@const_names) {
-  my $const_names = join " ", @const_names;
-  print EX <<'_END_';
+
+   if (@const_names) {
+     my $const_names = join " ", @const_names;
+     print EX <<'_END_';
 
 my $fail;
 foreach my $constname (qw(
 _END_
-  print EX wrap ("\t", "\t", $const_names);
-  print EX (")) {\n");
-  print EX <<_END_;
+
+     print EX wrap ("\t", "\t", $const_names);
+     print EX (")) {\n");
+
+     print EX <<_END_;
   next if (eval "my \\\$a = \$constname; 1");
   if (\$\@ =~ /^Your vendor has not defined $module macro \$constname/) {
     print "# pass: \$\@";
@@ -1759,14 +1819,51 @@ if (\$fail) {
 }
 
 _END_
+  }
+}
+else
+{
+  print EX <<_END_;
+use Test::More tests => $tests;
+BEGIN { use_ok('$module') };
+
+_END_
+
+   if (@const_names) {
+     my $const_names = join " ", @const_names;
+     print EX <<'_END_';
+
+my $fail = 0;
+foreach my $constname (qw(
+_END_
+
+     print EX wrap ("\t", "\t", $const_names);
+     print EX (")) {\n");
+
+     print EX <<_END_;
+  next if (eval "my \\\$a = \$constname; 1");
+  if (\$\@ =~ /^Your vendor has not defined $module macro \$constname/) {
+    print "# pass: \$\@";
+  } else {
+    print "# fail: \$\@";
+    \$fail = 1;
+  }
+
+}
+
+ok( \$fail == 0 , 'Constants' );
+_END_
+  }
 }
-print EX <<'_END_';
+
+print EX <<_END_;
 #########################
 
-# Insert your test code below, the Test module is use()ed here so read
-# its man page ( perldoc Test ) for help writing this test script.
+# Insert your test code below, the $test_mod module is use()ed here so read
+# its man page ( perldoc $test_mod ) for help writing this test script.
 
 _END_
+
 close(EX) || die "Can't close $ext$modpname/$testfile: $!\n";
 
 unless ($opt_C) {
index 815be84..57f4e31 100644 (file)
@@ -2315,9 +2315,10 @@ CPerlHost::Reset(void)
 void
 CPerlHost::Clearenv(void)
 {
+    dTHXo;
     char ch;
     LPSTR lpPtr, lpStr, lpEnvPtr;
-    if(m_lppEnvList != NULL) {
+    if (m_lppEnvList != NULL) {
        /* set every entry to an empty string */
        for(DWORD index = 0; index < m_dwEnvCount; ++index) {
            char* ptr = strchr(m_lppEnvList[index], '=');
@@ -2340,6 +2341,8 @@ CPerlHost::Clearenv(void)
            ch = *++lpPtr;
            *lpPtr = 0;
            Add(lpStr);
+           if (!w32_pseudo_id)
+               (void)win32_putenv(lpStr);
            *lpPtr = ch;
        }
        lpStr += strlen(lpStr) + 1;
@@ -2352,22 +2355,23 @@ CPerlHost::Clearenv(void)
 char*
 CPerlHost::Getenv(const char *varname)
 {
-    char* pEnv = Find(varname);
-    if(pEnv == NULL) {
-       pEnv = win32_getenv(varname);
-    }
-    else {
-       if(!*pEnv)
-           pEnv = 0;
+    dTHXo;
+    if (w32_pseudo_id) {
+       char *pEnv = Find(varname);
+       if (pEnv && *pEnv)
+           return pEnv;
     }
-
-    return pEnv;
+    return win32_getenv(varname);
 }
 
 int
 CPerlHost::Putenv(const char *envstring)
 {
+    dTHXo;
     Add(envstring);
+    if (!w32_pseudo_id)
+       return win32_putenv(envstring);
+
     return 0;
 }
 
index 5f4a177..033ebb9 100644 (file)
@@ -518,7 +518,7 @@ get_shell(void)
         */
        const char* defaultshell = (IsWinNT()
                                    ? "cmd.exe /x/c" : "command.com /c");
-       const char *usershell = getenv("PERL5SHELL");
+       const char *usershell = PerlEnv_getenv("PERL5SHELL");
        w32_perlshell_items = tokenize(usershell ? usershell : defaultshell,
                                       &w32_perlshell_tokens,
                                       &w32_perlshell_vec);
@@ -3096,7 +3096,7 @@ qualified_path(const char *cmd)
     }
 
     /* look in PATH */
-    pathstr = win32_getenv("PATH");
+    pathstr = PerlEnv_getenv("PATH");
     New(0, fullcmd, MAX_PATH+1, char);
     curfullcmd = fullcmd;