Integrate with Sarathy. perldiag.pod required manual editing.
Jarkko Hietaniemi [Wed, 7 Jul 1999 23:01:16 +0000 (23:01 +0000)]
p4raw-id: //depot/cfgperl@3657

20 files changed:
Changes
configure.com
ext/B/B/Deparse.pm
ext/ByteLoader/Makefile.PL
ext/Fcntl/Fcntl.xs
gv.c
iperlsys.h
lib/ExtUtils/MM_VMS.pm
lib/File/Basename.pm
lib/File/Spec/VMS.pm
perlsfio.h
pod/perldiag.pod
t/base/rs.t
t/lib/io_multihomed.t
t/lib/textfill.t
t/lib/textwrap.t
t/op/filetest.t
t/op/mkdir.t
t/pragma/overload.t
vms/vms.c

diff --git a/Changes b/Changes
index 1c38a7f..cefc49d 100644 (file)
--- a/Changes
+++ b/Changes
@@ -79,6 +79,145 @@ Version 5.005_58        Development release working toward 5.006
 ----------------
 
 ____________________________________________________________________________
+[  3655] By: gsar                                  on 1999/07/07  18:55:45
+        Log: filetest.t and ByteLoader build tweaks from Peter Prymmer
+             <pvhp@forte.com>
+     Branch: perl
+           ! ext/ByteLoader/Makefile.PL t/op/filetest.t
+____________________________________________________________________________
+[  3654] By: gsar                                  on 1999/07/07  18:47:03
+        Log: change#1889 mistakenly removed F_SETLK
+     Branch: perl
+           ! ext/Fcntl/Fcntl.xs
+____________________________________________________________________________
+[  3653] By: gsar                                  on 1999/07/07  18:42:42
+        Log: B::Deparse update
+             From: Stephen McCamant <smccam@uclink4.berkeley.edu>
+             Date: Mon,  5 Jul 1999 17:57:03 -0500 (CDT)
+             Message-ID: <14209.13729.738691.610723@alias-2.pr.mcs.net>
+             Subject: [PATCH _57, long] B::Deparse 0.58
+     Branch: perl
+           ! ext/B/B/Deparse.pm
+____________________________________________________________________________
+[  3652] By: gsar                                  on 1999/07/07  18:41:07
+        Log: From: Ilya Zakharevich <ilya@math.ohio-state.edu>
+             Date: Mon, 5 Jul 1999 18:24:19 -0400 (EDT)
+             Message-Id: <199907052224.SAA10454@monk.mps.ohio-state.edu>
+             Subject: Re: [ID 19990705.001] Overloading boolean conversion
+     Branch: perl
+           ! gv.c t/pragma/overload.t
+____________________________________________________________________________
+[  3651] By: gsar                                  on 1999/07/07  17:47:30
+        Log: missing PerlIO_reopen() (suggested by sam@daemoninc.com)
+     Branch: perl
+           ! perlsfio.h
+____________________________________________________________________________
+[  3650] By: gsar                                  on 1999/07/07  17:45:52
+        Log: applied new parts of suggested patch
+             From: Charles Bailey <BAILEY@newman.upenn.edu>
+             Date: Fri, 02 Jul 1999 19:18:41 -0400 (EDT)
+             Message-id: <01JD3M8W1VXS000S5G@mail.newman.upenn.edu>
+             Subject: [PATCH 5.005_57] Consolidated VMS patch
+     Branch: perl
+          ! configure.com ext/IO/lib/IO/File.pm iperlsys.h
+          ! lib/ExtUtils/MM_VMS.pm lib/File/Basename.pm
+          ! lib/File/Spec/VMS.pm pod/perldiag.pod t/base/rs.t
+          ! t/lib/io_multihomed.t t/lib/textfill.t t/lib/textwrap.t
+           ! t/op/filetest.t t/op/mkdir.t thread.h vms/vms.c
+____________________________________________________________________________
+[  3649] By: jhi                                   on 1999/07/07  13:38:02
+        Log: Sync regcomp warn with reality.
+     Branch: cfgperl
+           ! t/pragma/warn/regcomp
+____________________________________________________________________________
+[  3648] By: jhi                                   on 1999/07/07  13:04:55
+        Log: Integrate with Sarathy; one conflict in t/pragma/warn/recgomp
+             resolved manually.
+     Branch: cfgperl
+         +> pod/perllexwarn.pod t/pragma/warn/6default t/pragma/warn/av
+         +> t/pragma/warn/doop t/pragma/warn/hv t/pragma/warn/malloc
+          +> t/pragma/warn/perlio t/pragma/warn/run t/pragma/warn/utf8
+           - README.lexwarn
+          !> (integrate 79 files)
+____________________________________________________________________________
+[  3647] By: gsar                                  on 1999/07/07  10:32:03
+        Log: From: jan.dubois@ibm.net (Jan Dubois)
+             Date: Thu, 01 Jul 1999 11:17:53 +0200
+             Message-ID: <377b2ca4.14467042@smtp1.ibm.net>
+             Subject: [PATCH 5.005_57] MakeMaker support for pod2html
+     Branch: perl
+          ! lib/ExtUtils/MM_Unix.pm lib/ExtUtils/MM_Win32.pm
+           ! lib/ExtUtils/MakeMaker.pm
+____________________________________________________________________________
+[  3646] By: gsar                                  on 1999/07/07  10:27:55
+        Log: fix undocumented IO::Handle functions as suggested
+             by cj10@cam.ac.uk
+     Branch: perl
+           ! ext/IO/lib/IO/Handle.pm
+____________________________________________________________________________
+[  3645] By: gsar                                  on 1999/07/07  10:18:55
+        Log: prohibit thread join()ing itself (from Dan Sugalski)
+     Branch: perl
+           ! ext/Thread/Thread.xs
+____________________________________________________________________________
+[  3644] By: gsar                                  on 1999/07/07  10:14:26
+        Log: From: "Vishal Bhatia" <vishalb@my-deja.com>
+             Date: Wed, 30 Jun 1999 14:02:42 -0700
+             Message-ID: <LJHFKBDHMHHJDAAA@my-deja.com>
+             Subject:  [PATCH 5.005_57] Compiler and XSUBS
+     Branch: perl
+           ! ext/B/B/C.pm
+____________________________________________________________________________
+[  3643] By: gsar                                  on 1999/07/07  10:08:38
+        Log: mention C<foreach VAR (LIST) BLOCK continue BLOCK> syntax
+             (from François Désarménien <desar@club-internet.fr>)
+     Branch: perl
+           ! pod/perlsyn.pod
+____________________________________________________________________________
+[  3642] By: gsar                                  on 1999/07/07  10:03:24
+        Log: From: Doug MacEachern <dougm@cp.net>
+             Date: Sun, 27 Jun 1999 22:43:25 -0700 (PDT)
+             Message-ID: <Pine.LNX.4.10.9906272236430.389-100000@mojo.eng.cp.net>
+             Subject: [PATCH 5.005_57] add B::PV::{LEN,CUR}
+     Branch: perl
+           ! ext/B/B.xs
+____________________________________________________________________________
+[  3641] By: gsar                                  on 1999/07/07  10:00:57
+        Log: slightly modified version of suggested patch
+             From: Steven N. Hirsch <hirschs@stargate.btv.ibm.com>
+             Date: Mon, 28 Jun 1999 14:23:59 -0400
+             Message-Id: <199906281823.OAA24912@stargate.btv.ibm.com>
+             Subject: [ID 19990628.007] POSIX::tmpnam() broken for threaded 5.00503
+     Branch: perl
+           ! ext/POSIX/POSIX.xs
+____________________________________________________________________________
+[  3640] By: gsar                                  on 1999/07/07  09:45:43
+        Log: lexical warnings update (warning.t fails one test
+             due to leaked scalar, investigation pending)
+             From: paul.marquess@bt.com
+             Date: Sat, 26 Jun 1999 23:19:52 +0100
+             Message-ID: <5104D4DBC598D211B5FE0000F8FE7EB29C6C8E@mbtlipnt02.btlabs.bt.co.uk>
+             Subject: [PATCH 5.005_57] Lexical Warnings - mandatory warning are now default warnings
+     Branch: perl
+          + pod/perllexwarn.pod t/pragma/warn/6default t/pragma/warn/av
+          + t/pragma/warn/doop t/pragma/warn/hv t/pragma/warn/malloc
+           + t/pragma/warn/perlio t/pragma/warn/run t/pragma/warn/utf8
+           - README.lexwarn
+          ! Changes MANIFEST av.c djgpp/djgpp.c doio.c doop.c
+          ! ext/B/B/Asmdata.pm ext/ByteLoader/byterun.c
+          ! ext/ByteLoader/byterun.h gv.c hv.c jpl/JNI/JNI.xs
+          ! lib/warning.pm mg.c op.c os2/os2.c perl.c perlio.c
+          ! pod/perldelta.pod pod/perldiag.pod pod/perlfunc.pod
+          ! pod/perlmodlib.pod pod/perlrun.pod pod/perlvar.pod pp.c
+          ! pp_ctl.c run.c sv.c t/pragma/warn/3both t/pragma/warn/doio
+          ! t/pragma/warn/gv t/pragma/warn/mg t/pragma/warn/op
+          ! t/pragma/warn/perl t/pragma/warn/perly t/pragma/warn/pp
+          ! t/pragma/warn/pp_ctl t/pragma/warn/pp_hot t/pragma/warn/pp_sys
+          ! t/pragma/warn/regcomp t/pragma/warn/regexec t/pragma/warn/sv
+          ! t/pragma/warn/taint t/pragma/warn/toke t/pragma/warn/universal
+          ! t/pragma/warn/util t/pragma/warning.t toke.c utf8.c util.c
+           ! warning.h warning.pl win32/win32.c
+____________________________________________________________________________
 [  3639] By: gsar                                  on 1999/07/07  08:09:30
         Log: From: Brian Jepson <bjepson@home.com>
              Date: Sat, 26 Jun 1999 10:47:45 -0500 (EST)
index 6a1c37a..350d64a 100644 (file)
@@ -1837,7 +1837,7 @@ $ echo "you might, for example, want to build GDBM_File instead of
 $ echo "SDBM_File if you have the GDBM library built on your machine
 $ echo "
 $ echo "Which modules do you want to build into perl?"
-$ dflt = "Fcntl Errno IO Opcode Data::Dumper attrs re VMS::Stdio VMS::DCLsym B SDBM_File"
+$ dflt = "Fcntl Errno IO Opcode Byteloader Devel::Peek Data::Dumper attrs re VMS::Stdio VMS::DCLsym B SDBM_File"
 $ if Using_Dec_C.eqs."Yes"
 $ THEN
 $   dflt = dflt + " POSIX"
index e00bd22..0eb319e 100644 (file)
@@ -7,7 +7,7 @@
 # but essentially none of his code remains.
 
 package B::Deparse;
-use Carp 'cluck';
+use Carp 'cluck', 'croak';
 use B qw(class main_root main_start main_cv svref_2object opnumber
         OPf_WANT OPf_WANT_VOID OPf_WANT_SCALAR OPf_WANT_LIST
         OPf_KIDS OPf_REF OPf_STACKED OPf_SPECIAL
@@ -16,7 +16,7 @@ use B qw(class main_root main_start main_cv svref_2object opnumber
         SVf_IOK SVf_NOK SVf_ROK SVf_POK
         PMf_KEEP PMf_GLOBAL PMf_CONTINUE PMf_EVAL PMf_ONCE
         PMf_MULTILINE PMf_SINGLELINE PMf_FOLD PMf_EXTENDED);
-$VERSION = 0.57;
+$VERSION = 0.58;
 use strict;
 
 # Changes between 0.50 and 0.51:
@@ -66,19 +66,34 @@ use strict;
 # - added unquote option for expanding "" into concats, etc.
 # - split method and proto parts of pp_entersub into separate functions
 # - various minor cleanups
+# Changes after 0.57:
+# - added parens in \&foo (patch by Albert Dvornik)
+# Changes between 0.57 and 0.58:
+# - fixed `0' statements that weren't being printed
+# - added methods for use from other programs
+#   (based on patches from James Duncan and Hugo van der Sanden)
+# - added -si and -sT to control indenting (also based on a patch from Hugo)
+# - added -sv to print something else instead of '???'
+# - preliminary version of utf8 tr/// handling
 
 # Todo:
+# - finish tr/// changes
+# - add option for even more parens (generalize \&foo change)
 # - {} around variables in strings ("${var}letters")
 #   base/lex.t 25-27
 #   comp/term.t 11
 # - left/right context
 # - recognize `use utf8', `use integer', etc
-# - handle swash-based utf8 tr/// (ick, looks hard)
+# - treat top-level block specially for incremental output
+# - interpret in high bit chars in string as utf8 \x{...} (when?)
+# - copy comments (look at real text with $^P) 
 # - avoid semis in one-statement blocks
 # - associativity of &&=, ||=, ?:
 # - ',' => '=>' (auto-unquote?)
 # - break long lines ("\r" as discretionary break?)
-# - ANSI color syntax highlighting?
+# - configurable syntax highlighting: ANSI color, HTML, TeX, etc.
+# - more style options: brace style, hex vs. octal, quotes, ...
+# - print big ints as hex/octal instead of decimal (heuristic?)
 # - include values of variables (e.g. set in BEGIN)
 # - coordinate with Data::Dumper (both directions? see previous)
 # - version using op_next instead of op_first/sibling?
@@ -123,6 +138,9 @@ use strict;
 # linenums: -l
 # unquote: -q
 # cuddle: ` ' or `\n', depending on -sC
+# indent_size: -si
+# use_tabs: -sT
+# ex_const: -sv
 
 # A little explanation of how precedence contexts and associativity
 # work:
@@ -296,39 +314,57 @@ sub style_opts {
     while (length($opt = substr($opts, 0, 1))) {
        if ($opt eq "C") {
            $self->{'cuddle'} = " ";
+           $opts = substr($opts, 1);
+       } elsif ($opt eq "i") {
+           $opts =~ s/^i(\d+)//;
+           $self->{'indent_size'} = $1;
+       } elsif ($opt eq "T") {
+           $self->{'use_tabs'} = 1;
+           $opts = substr($opts, 1);
+       } elsif ($opt eq "v") {
+           $opts =~ s/^v([^.]*)(.|$)//;
+           $self->{'ex_const'} = $1;
        }
-       $opts = substr($opts, 1);
     }
 }
 
+sub new {
+    my $class = shift;
+    my $self = bless {}, $class;
+    $self->{'subs_todo'} = [];
+    $self->{'curstash'} = "main";
+    $self->{'cuddle'} = "\n";
+    $self->{'indent_size'} = 4;
+    $self->{'use_tabs'} = 0;
+    $self->{'ex_const'} = "'???'";
+    while (my $arg = shift @_) {
+       if (substr($arg, 0, 2) eq "-u") {
+           $self->stash_subs(substr($arg, 2));
+       } elsif ($arg eq "-p") {
+           $self->{'parens'} = 1;
+       } elsif ($arg eq "-l") {
+           $self->{'linenums'} = 1;
+       } elsif ($arg eq "-q") {
+           $self->{'unquote'} = 1;
+       } elsif (substr($arg, 0, 2) eq "-s") {
+           $self->style_opts(substr $arg, 2);
+       }
+    }
+    return $self;
+}
+
 sub compile {
     my(@args) = @_;
     return sub { 
-       my $self = bless {};
-       my $arg;
-       $self->{'subs_todo'} = [];
+       my $self = B::Deparse->new(@args);
        $self->stash_subs("main");
        $self->{'curcv'} = main_cv;
-       $self->{'curstash'} = "main";
-       $self->{'cuddle'} = "\n";
-       while ($arg = shift @args) {
-           if (substr($arg, 0, 2) eq "-u") {
-               $self->stash_subs(substr($arg, 2));
-           } elsif ($arg eq "-p") {
-               $self->{'parens'} = 1;
-           } elsif ($arg eq "-l") {
-               $self->{'linenums'} = 1;
-           } elsif ($arg eq "-q") {
-               $self->{'unquote'} = 1;
-           } elsif (substr($arg, 0, 2) eq "-s") {
-               $self->style_opts(substr $arg, 2);
-           }
-       }
        $self->walk_sub(main_cv, main_start);
        print $self->print_protos;
        @{$self->{'subs_todo'}} =
-           sort {$a->[0] <=> $b->[0]} @{$self->{'subs_todo'}};
-       print indent($self->deparse(main_root, 0)), "\n" unless null main_root;
+         sort {$a->[0] <=> $b->[0]} @{$self->{'subs_todo'}};
+       print $self->indent($self->deparse(main_root, 0)), "\n"
+         unless null main_root;
        my @text;
        while (scalar(@{$self->{'subs_todo'}})) {
            push @text, $self->next_todo;
@@ -337,6 +373,13 @@ sub compile {
     }
 }
 
+sub coderef2text {
+    my $self = shift;
+    my $sub = shift;
+    croak "Usage: ->coderef2text(CODEREF)" unless ref($sub) eq "CODE";
+    return $self->indent($self->deparse_sub(svref_2object($sub)));
+}
+
 sub deparse {
     my $self = shift;
     my($op, $cx) = @_;
@@ -347,16 +390,21 @@ sub deparse {
 }
 
 sub indent {
+    my $self = shift;
     my $txt = shift;
     my @lines = split(/\n/, $txt);
     my $leader = "";
+    my $level = 0;
     my $line;
     for $line (@lines) {
-       if (substr($line, 0, 1) eq "\t") {
-           $leader = $leader . "    ";
-           $line = substr($line, 1);
-       } elsif (substr($line, 0, 1) eq "\b") {
-           $leader = substr($leader, 0, length($leader) - 4);
+       my $cmd = substr($line, 0, 1);
+       if ($cmd eq "\t" or $cmd eq "\b") {
+           $level += ($cmd eq "\t" ? 1 : -1) * $self->{'indent_size'};
+           if ($self->{'use_tabs'}) {
+               $leader = "\t" x ($level / 8) . " " x ($level % 8);
+           } else {
+               $leader = " " x $level;
+           }
            $line = substr($line, 1);
        }
        if (substr($line, 0, 1) eq "\f") {
@@ -635,7 +683,7 @@ sub pp_leave {
            last if null $kid;
        }
        $expr .= $self->deparse($kid, 0);
-       push @exprs, $expr if $expr;
+       push @exprs, $expr if length $expr;
     }
     if ($cx > 0) { # inside an expression
        return "do { " . join(";\n", @exprs) . " }";
@@ -657,7 +705,7 @@ sub pp_scope {
            last if null $kid;
        }
        $expr .= $self->deparse($kid, 0);
-       push @exprs, $expr if $expr;
+       push @exprs, $expr if length $expr;
     }
     if ($cx > 0) { # inside an expression, (a do {} while for lineseq)
        return "do { " . join(";\n", @exprs) . " }";
@@ -796,7 +844,7 @@ sub pp_not {
 
 sub unop {
     my $self = shift;
-    my($op, $cx, $name, $prec, $flags) = (@_, 0, 0);
+    my($op, $cx, $name) = @_;
     my $kid;
     if ($op->flags & OPf_KIDS) {
        $kid = $op->first;
@@ -1320,7 +1368,7 @@ sub logop {
 }
 
 sub pp_and { logop(@_, "and", 3, "&&", 11, "if") }
-sub pp_or {  logop(@_, "or",  2, "||", 10, "unless") }
+sub pp_or  { logop(@_, "or",  2, "||", 10, "unless") }
 sub pp_xor { logop(@_, "xor", 2, "",   0,  "") }
 
 sub logassignop {
@@ -1515,7 +1563,7 @@ sub mapop {
     $kid = $kid->first->sibling; # skip a pushmark
     my $code = $kid->first; # skip a null
     if (is_scope $code) {
-       $code = "{" . $self->deparse($code, 1) . "} ";
+       $code = "{" . $self->deparse($code, 0) . "} ";
     } else {
        $code = $self->deparse($code, 24) . ", ";
     }
@@ -1732,7 +1780,8 @@ sub pp_null {
     my $self = shift;
     my($op, $cx) = @_;
     if (class($op) eq "OP") {
-       return "'???'" if $op->targ == OP_CONST; # old value is lost
+       # old value is lost
+       return $self->{'ex_const'} if $op->targ == OP_CONST;
     } elsif ($op->first->ppaddr eq "pp_pushmark") {
        return $self->pp_list($op, $cx);
     } elsif ($op->first->ppaddr eq "pp_enter") {
@@ -2368,7 +2417,8 @@ sub collapse {
        if ($c <= $#chars - 2 and $chars[$c + 1] == $tr + 1 and
            $chars[$c + 2] == $tr + 2)
        {
-           for (; $c <= $#chars and $chars[$c + 1] == $chars[$c] + 1; $c++) {}
+           for (; $c <= $#chars-1 and $chars[$c + 1] == $chars[$c] + 1; $c++)
+             {}
            $str .= "-";
            $str .= pchr($chars[$c]);
        }
@@ -2376,10 +2426,12 @@ sub collapse {
     return $str;
 }
 
-sub pp_trans {
-    my $self = shift;
-    my($op, $cx) = @_;
-    my(@table) = unpack("s256", $op->pv);
+# XXX This has trouble with hyphens in the replacement (tr/bac/-AC/),
+# and backslashes.
+
+sub tr_decode_byte {
+    my($table, $flags) = @_;
+    my(@table) = unpack("s256", $table);
     my($c, $tr, @from, @to, @delfrom, $delhyphen);
     if ($table[ord "-"] != -1 and 
        $table[ord("-") - 1] == -1 || $table[ord("-") + 1] == -1)
@@ -2401,10 +2453,8 @@ sub pp_trans {
            push @delfrom, $c;
        }
     }
-    my $flags;
     @from = (@from, @delfrom);
-    if ($op->private & OPpTRANS_COMPLEMENT) {
-       $flags .= "c";
+    if ($flags & OPpTRANS_COMPLEMENT) {
        my @newfrom = ();
        my %from;
        @from{@from} = (1) x @from;
@@ -2413,16 +2463,136 @@ sub pp_trans {
        }
        @from = @newfrom;
     }
-    if ($op->private & OPpTRANS_DELETE) {
-       $flags .= "d";
-    } else {
+    unless ($flags & OPpTRANS_DELETE) {
        pop @to while $#to and $to[$#to] == $to[$#to -1];
     }
-    $flags .= "s" if $op->private & OPpTRANS_SQUASH;
     my($from, $to);
     $from = collapse(@from);
     $to = collapse(@to);
     $from .= "-" if $delhyphen;
+    return ($from, $to);
+}
+
+sub tr_chr {
+    my $x = shift;
+    if ($x == ord "-") {
+       return "\\-";
+    } else {
+       return chr $x;
+    }
+}
+
+# XXX This doesn't yet handle all cases correctly either
+
+sub tr_decode_utf8 {
+    my($swash_hv, $flags) = @_;
+    my %swash = $swash_hv->ARRAY;
+    my $final = undef;
+    $final = $swash{'FINAL'}->IV if exists $swash{'FINAL'};
+    my $none = $swash{"NONE"}->IV;
+    my $extra = $none + 1;
+    my(@from, @delfrom, @to);
+    my $line;
+    foreach $line (split /\n/, $swash{'LIST'}->PV) {
+       my($min, $max, $result) = split(/\t/, $line);
+       $min = hex $min;
+       if (length $max) {
+           $max = hex $max;
+       } else {
+           $max = $min;
+       }
+       $result = hex $result;
+       if ($result == $extra) {
+           push @delfrom, [$min, $max];            
+       } else {
+           push @from, [$min, $max];
+           push @to, [$result, $result + $max - $min];
+       }
+    }
+    for my $i (0 .. $#from) {
+       if ($from[$i][0] == ord '-') {
+           unshift @from, splice(@from, $i, 1);
+           unshift @to, splice(@to, $i, 1);
+           last;
+       } elsif ($from[$i][1] == ord '-') {
+           $from[$i][1]--;
+           $to[$i][1]--;
+           unshift @from, ord '-';
+           unshift @to, ord '-';
+           last;
+       }
+    }
+    for my $i (0 .. $#delfrom) {
+       if ($delfrom[$i][0] == ord '-') {
+           push @delfrom, splice(@delfrom, $i, 1);
+           last;
+       } elsif ($delfrom[$i][1] == ord '-') {
+           $delfrom[$i][1]--;
+           push @delfrom, ord '-';
+           last;
+       }
+    }
+    if (defined $final and $to[$#to][1] != $final) {
+       push @to, [$final, $final];
+    }
+    push @from, @delfrom;
+    if ($flags & OPpTRANS_COMPLEMENT) {
+       my @newfrom;
+       my $next = 0;
+       for my $i (0 .. $#from) {
+           push @newfrom, [$next, $from[$i][0] - 1];
+           $next = $from[$i][1] + 1;
+       }
+       @from = ();
+       for my $range (@newfrom) {
+           if ($range->[0] <= $range->[1]) {
+               push @from, $range;
+           }
+       }
+    }
+    my($from, $to, $diff);
+    for my $chunk (@from) {
+       $diff = $chunk->[1] - $chunk->[0];
+       if ($diff > 1) {
+           $from .= tr_chr($chunk->[0]) . "-" . tr_chr($chunk->[1]);
+       } elsif ($diff == 1) {
+           $from .= tr_chr($chunk->[0]) . tr_chr($chunk->[1]);
+       } else {
+           $from .= tr_chr($chunk->[0]);
+       }
+    }
+    for my $chunk (@to) {
+       $diff = $chunk->[1] - $chunk->[0];
+       if ($diff > 1) {
+           $to .= tr_chr($chunk->[0]) . "-" . tr_chr($chunk->[1]);
+       } elsif ($diff == 1) {
+           $to .= tr_chr($chunk->[0]) . tr_chr($chunk->[1]);
+       } else {
+           $to .= tr_chr($chunk->[0]);
+       }
+    }
+    #$final = sprintf("%04x", $final) if defined $final;
+    #$none = sprintf("%04x", $none) if defined $none;
+    #$extra = sprintf("%04x", $extra) if defined $extra;    
+    #print STDERR "final: $final\n none: $none\nextra: $extra\n";
+    #print STDERR $swash{'LIST'}->PV;
+    return (escape_str($from), escape_str($to));
+}
+
+sub pp_trans {
+    my $self = shift;
+    my($op, $cx) = @_;
+    my($from, $to);
+    if (class($op) eq "PVOP") {
+       ($from, $to) = tr_decode_byte($op->pv, $op->private);
+    } else { # class($op) eq "SVOP"
+       ($from, $to) = tr_decode_utf8($op->sv->RV, $op->private);
+    }
+    my $flags = "";
+    $flags .= "c" if $op->private & OPpTRANS_COMPLEMENT;
+    $flags .= "d" if $op->private & OPpTRANS_DELETE;
+    $to = "" if $from eq $to and $flags eq "";
+    $flags .= "s" if $op->private & OPpTRANS_SQUASH;
     return "tr" . double_delim($from, $to) . $flags;
 }
 
@@ -2596,7 +2766,8 @@ B::Deparse - Perl compiler backend to produce perl code
 
 =head1 SYNOPSIS
 
-B<perl> B<-MO=Deparse>[B<,-u>I<PACKAGE>][B<,-p>][B<,-l>][B<,-s>I<LETTERS>] I<prog.pl>
+B<perl> B<-MO=Deparse>[B<,-u>I<PACKAGE>][B<,-p>][B<,-q>][B<,-l>][B<,-s>I<LETTERS>]
+     I<prog.pl>
 
 =head1 DESCRIPTION
 
@@ -2674,8 +2845,8 @@ Normally, B::Deparse deparses the main code of a program, all the subs
 called by the main program (and all the subs called by them,
 recursively), and any other subs in the main:: package. To include
 subs in other packages that aren't called directly, such as AUTOLOAD,
-DESTROY, other subs called automatically by perl, and methods, which
-aren't resolved to subs until runtime, use the B<-u> option. The
+DESTROY, other subs called automatically by perl, and methods (which
+aren't resolved to subs until runtime), use the B<-u> option. The
 argument to B<-u> is the name of a package, and should follow directly
 after the 'u'. Multiple B<-u> options may be given, separated by
 commas.  Note that unlike some other backends, B::Deparse doesn't
@@ -2684,8 +2855,9 @@ invoke it yourself.
 
 =item B<-s>I<LETTERS>
 
-Tweak the style of B::Deparse's output. At the moment, only one style
-option is implemented:
+Tweak the style of B::Deparse's output. The letters should follow
+directly after the 's', with no space or punctuation. The following
+options are available:
 
 =over 4
 
@@ -2710,10 +2882,76 @@ instead of
 
 The default is not to cuddle.
 
+=item B<i>I<NUMBER>
+
+Indent lines by multiples of I<NUMBER> columns. The default is 4 columns.
+
+=item B<T>
+
+Use tabs for each 8 columns of indent. The default is to use only spaces.
+For instance, if the style options are B<-si4T>, a line that's indented
+3 times will be preceded by one tab and four spaces; if the options were
+B<-si8T>, the same line would be preceded by three tabs.
+
+=item B<v>I<STRING>B<.>
+
+Print I<STRING> for the value of a constant that can't be determined
+because it was optimized away (mnemonic: this happens when a constant
+is used in B<v>oid context). The end of the string is marked by a period.
+The string should be a valid perl expression, generally a constant.
+Note that unless it's a number, it probably needs to be quoted, and on
+a command line quotes need to be protected from the shell. Some
+conventional values include 0, 1, 42, '', 'foo', and
+'Useless use of constant omitted' (which may need to be
+B<-sv"'Useless use of constant omitted'.">
+or something similar depending on your shell). The default is '???'.
+If you're using B::Deparse on a module or other file that's require'd,
+you shouldn't use a value that evaluates to false, since the customary
+true constant at the end of a module will be in void context when the
+file is compiled as a main program.
+
 =back
 
 =back
 
+=head1 USING B::Deparse AS A MODULE
+
+=head2 Synopsis
+
+    use B::Deparse;
+    $deparse = B::Deparse->new("-p", "-sC");
+    $body = $deparse->coderef2text(\&func);
+    eval "sub func $body"; # the inverse operation
+
+=head2 Description
+
+B::Deparse can also be used on a sub-by-sub basis from other perl
+programs.
+
+=head2 new
+
+    $deparse = B::Deparse->new(OPTIONS)
+
+Create an object to store the state of a deparsing operation and any
+options. The options are the same as those that can be given on the
+command line (see L</OPTIONS>); options that are separated by commas
+after B<-MO=Deparse> should be given as separate strings. Some
+options, like B<-u>, don't make sense for a single subroutine, so
+don't pass them.
+
+=head2 coderef2text
+
+    $body = $deparse->coderef2text(\&func)
+    $body = $deparse->coderef2text(sub ($$) { ... })
+
+Return source code for the body of a subroutine (a block, optionally
+preceded by a prototype in parens), given a reference to the
+sub. Because a subroutine can have no names, or more than one name,
+this method doesn't return a complete subroutine definition -- if you
+want to eval the result, you should prepend "sub subname ", or "sub "
+for an anonymous function constructor. Unless the sub was defined in
+the main:: package, the code will include a package declaration.
+
 =head1 BUGS
 
 See the 'to do' list at the beginning of the module file.
@@ -2721,6 +2959,8 @@ See the 'to do' list at the beginning of the module file.
 =head1 AUTHOR
 
 Stephen McCamant <smccam@uclink4.berkeley.edu>, based on an earlier
-version by Malcolm Beattie <mbeattie@sable.ox.ac.uk>.
+version by Malcolm Beattie <mbeattie@sable.ox.ac.uk>, with
+contributions from Gisle Aas, James Duncan, Albert Dvornik, Hugo van
+der Sanden, Gurusamy Sarathy, and Nick Ing-Simmons.
 
 =cut
index 1facb5a..c3cfcc7 100644 (file)
@@ -4,5 +4,6 @@ WriteMakefile(
     NAME               => 'ByteLoader',
     VERSION_FROM       => 'ByteLoader.pm',
     XSPROTOARG         => '-noprototypes',
+    MAN3PODS           => {},     # Pods will be built by installman.
     OBJECT             => 'byterun$(OBJ_EXT) ByteLoader$(OBJ_EXT)',
 );
index a8e0e8a..2446ab7 100644 (file)
@@ -108,6 +108,12 @@ constant(char *name, int arg)
 #else
                goto not_there;
 #endif
+           if (strEQ(name, "F_SETLK"))
+#ifdef F_SETLK
+               return F_SETLK;
+#else
+               goto not_there;
+#endif
            if (strEQ(name, "F_SETLK64"))
 #ifdef F_SETLK64
                return F_SETLK64;
diff --git a/gv.c b/gv.c
index d1cf7ae..9fcf55b 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -1466,7 +1466,7 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
       case dec_amg:
        SvSetSV(left,res); return left;
       case not_amg:
-       ans=!SvOK(res); break;
+       ans=!SvTRUE(res); break;
       }
       return boolSV(ans);
     } else if (method==copy_amg) {
index d3ac12f..2adb321 100644 (file)
@@ -777,10 +777,11 @@ struct IPerlLIOInfo
 #define PerlLIO_ioctl(fd, u, buf)      ioctl((fd), (u), (buf))
 #define PerlLIO_isatty(fd)             isatty((fd))
 #define PerlLIO_lseek(fd, offset, mode)        lseek((fd), (offset), (mode))
+#define PerlLIO_stat(name, buf)                Stat((name), (buf))
 #ifdef HAS_LSTAT
-#define PerlLIO_lstat(name, buf)       lstat((name), (buf))
+#  define PerlLIO_lstat(name, buf)     lstat((name), (buf))
 #else
-#define PerlLIO_lstat(name, buf)       PerlLIO_stat((name), (buf))
+#  define PerlLIO_lstat(name, buf)     PerlLIO_stat((name), (buf))
 #endif
 #define PerlLIO_mktemp(file)           mktemp((file))
 #define PerlLIO_mkstemp(file)          mkstemp((file))
@@ -789,7 +790,6 @@ struct IPerlLIOInfo
 #define PerlLIO_read(fd, buf, count)   read((fd), (buf), (count))
 #define PerlLIO_rename(old, new)       rename((old), (new))
 #define PerlLIO_setmode(fd, mode)      setmode((fd), (mode))
-#define PerlLIO_stat(name, buf)                Stat((name), (buf))
 #define PerlLIO_tmpnam(str)            tmpnam((str))
 #define PerlLIO_umask(mode)            umask((mode))
 #define PerlLIO_unlink(file)           unlink((file))
index c77eebe..ba4c2cc 100644 (file)
@@ -14,7 +14,7 @@ use VMS::Filespec;
 use File::Basename;
 
 use vars qw($Revision);
-$Revision = '5.52 (12-Sep-1998)';
+$Revision = '5.56 (27-Apr-1999)';
 
 unshift @MM::ISA, 'ExtUtils::MM_VMS';
 
@@ -626,10 +626,13 @@ sub constants {
     my(@m,$def,$macro);
 
     if ($self->{DEFINE} ne '') {
-       my(@defs) = split(/\s+/,$self->{DEFINE});
-       foreach $def (@defs) {
+       my(@terms) = split(/\s+/,$self->{DEFINE});
+       my(@defs,@udefs);
+       foreach $def (@terms) {
            next unless $def;
-           if ($def =~ s/^-D//) {       # If it was a Unix-style definition
+           my $targ = \@defs;
+           if ($def =~ s/^-([DU])//) {       # If it was a Unix-style definition
+               if ($1 eq 'U') { $targ = \@udefs; }
                $def =~ s/='(.*)'$/=$1/;  # then remove shell-protection ''
                $def =~ s/^'(.*)'$/$1/;   # from entire term or argument
            }
@@ -637,8 +640,11 @@ sub constants {
                $def =~ s/"/""/g;  # Protect existing " from DCL
                $def = qq["$def"]; # and quote to prevent parsing of =
            }
+           push @$targ, $def;
        }
-       $self->{DEFINE} = join ',',@defs;
+       $self->{DEFINE} = '';
+       if (@defs)  { $self->{DEFINE}  = '/Define=(' . join(',',@defs)  . ')'; }
+       if (@udefs) { $self->{DEFINE} .= '/Undef=('  . join(',',@udefs) . ')'; }
     }
 
     if ($self->{OBJECT} =~ /\s/) {
@@ -842,27 +848,25 @@ sub cflags {
     # Deal with $self->{DEFINE} here since some C compilers pay attention
     # to only one /Define clause on command line, so we have to
     # conflate the ones from $Config{'ccflags'} and $self->{DEFINE}
-    if ($quals =~ m:(.*)/define=\(?([^\(\/\)\s]+)\)?(.*)?:i) {
-       $quals = "$1/Define=($2," . ($self->{DEFINE} ? "$self->{DEFINE}," : '') .
-                "\$(DEFINE_VERSION),\$(XS_DEFINE_VERSION))$3";
-    }
-    else {
-       $quals .= '/Define=(' . ($self->{DEFINE} ? "$self->{DEFINE}," : '') .
-                 '$(DEFINE_VERSION),$(XS_DEFINE_VERSION))';
+    # ($self->{DEFINE} has already been VMSified in constants() above)
+    if ($self->{DEFINE}) { $quals .= $self->{DEFINE}; }
+    for $type (qw(Def Undef)) {
+       my(@terms);
+       while ($quals =~ m:/${type}i?n?e?=([^/]+):ig) {
+               my $term = $1;
+               $term =~ s:^\((.+)\)$:$1:;
+               push @terms, $term;
+           }
+       if ($type eq 'Def') {
+           push @terms, qw[ $(DEFINE_VERSION) $(XS_DEFINE_VERSION) ];
+       }
+       if (@terms) {
+           $quals =~ s:/${type}i?n?e?=[^/]+::ig;
+           $quals .= "/${type}ine=(" . join(',',@terms) . ')';
+       }
     }
 
     $libperl or $libperl = $self->{LIBPERL_A} || "libperl.olb";
-# This whole section is commented out, since I don't think it's necessary (or applicable)
-#    if ($libperl =~ s/^$Config{'dbgprefix'}//) { $libperl =~ s/perl([^Dd]*)\./perld$1./; }
-#    if ($libperl =~ /libperl(\w+)\./i) {
-#      my($type) = uc $1;
-#      my(%map) = ( 'D'  => 'DEBUGGING', 'E' => 'EMBED', 'M' => 'MULTIPLICITY',
-#                   'DE' => 'DEBUGGING,EMBED', 'DM' => 'DEBUGGING,MULTIPLICITY',
-#                   'EM' => 'EMBED,MULTIPLICITY', 'DEM' => 'DEBUGGING,EMBED,MULTIPLICITY' );
-#      my($add) = join(',', grep { $quals !~ /\b$_\b/ } split(/,/,$map{$type}));
-#      $quals =~ s:/define=\(([^\)]+)\):/Define=($1,$add):i if $add;
-#      $self->{PERLTYPE} ||= $type;
-#    }
 
     # Likewise with $self->{INC} and /Include
     if ($self->{'INC'}) {
@@ -873,7 +877,7 @@ sub cflags {
        }
     }
     $quals .= "$incstr)";
-    $quals =~ s/\(,/\(/g;
+#    $quals =~ s/,,/,/g; $quals =~ s/\(,/(/g;
     $self->{CCFLAGS} = $quals;
 
     $self->{OPTIMIZE} ||= $flagoptstr || $Config{'optimize'};
index 191eff9..d1c8666 100644 (file)
@@ -124,7 +124,7 @@ directory name to be F<.>).
 
 
 ## use strict;
-# A bit of juggling to insure that C<use re 'taint';> awlays works, since
+# A bit of juggling to insure that C<use re 'taint';> always works, since
 # File::Basename is used during the Perl build, when the re extension may
 # not be available.
 BEGIN {
index 30440c2..d13f5e6 100644 (file)
@@ -22,6 +22,74 @@ See File::Spec::Unix for a documentation of the methods provided
 there. This package overrides the implementation of these methods, not
 the semantics.
 
+=cut
+
+sub eliminate_macros {
+    my($self,$path) = @_;
+    return '' unless $path;
+    $self = {} unless ref $self;
+    my($npath) = unixify($path);
+    my($complex) = 0;
+    my($head,$macro,$tail);
+
+    # perform m##g in scalar context so it acts as an iterator
+    while ($npath =~ m#(.*?)\$\((\S+?)\)(.*)#g) { 
+        if ($self->{$2}) {
+            ($head,$macro,$tail) = ($1,$2,$3);
+            if (ref $self->{$macro}) {
+                if (ref $self->{$macro} eq 'ARRAY') {
+                    $macro = join ' ', @{$self->{$macro}};
+                }
+                else {
+                    print "Note: can't expand macro \$($macro) containing ",ref($self->{$macro}),
+                          "\n\t(using MMK-specific deferred substitutuon; MMS will break)\n";
+                    $macro = "\cB$macro\cB";
+                    $complex = 1;
+                }
+            }
+            else { ($macro = unixify($self->{$macro})) =~ s#/$##; }
+            $npath = "$head$macro$tail";
+        }
+    }
+    if ($complex) { $npath =~ s#\cB(.*?)\cB#\${$1}#g; }
+    $npath;
+}
+
+sub fixpath {
+    my($self,$path,$force_path) = @_;
+    return '' unless $path;
+    $self = bless {} unless ref $self;
+    my($fixedpath,$prefix,$name);
+
+    if ($path =~ m#^\$\([^\)]+\)$# || $path =~ m#[/:>\]]#) { 
+        if ($force_path or $path =~ /(?:DIR\)|\])$/) {
+            $fixedpath = vmspath($self->eliminate_macros($path));
+        }
+        else {
+            $fixedpath = vmsify($self->eliminate_macros($path));
+        }
+    }
+    elsif ((($prefix,$name) = ($path =~ m#^\$\(([^\)]+)\)(.+)#)) && $self->{$prefix}) {
+        my($vmspre) = $self->eliminate_macros("\$($prefix)");
+        # is it a dir or just a name?
+        $vmspre = ($vmspre =~ m|/| or $prefix =~ /DIR$/) ? vmspath($vmspre) : '';
+        $fixedpath = ($vmspre ? $vmspre : $self->{$prefix}) . $name;
+        $fixedpath = vmspath($fixedpath) if $force_path;
+    }
+    else {
+        $fixedpath = $path;
+        $fixedpath = vmspath($fixedpath) if $force_path;
+    }
+    # No hints, so we try to guess
+    if (!defined($force_path) and $fixedpath !~ /[:>(.\]]/) {
+        $fixedpath = vmspath($fixedpath) if -d $fixedpath;
+    }
+    # Trim off root dirname if it's had other dirs inserted in front of it.
+    $fixedpath =~ s/\.000000([\]>])/$1/;
+    $fixedpath;
+}
+
+
 =head2 Methods always loaded
 
 =over
index d6731e4..c4ed5c7 100644 (file)
@@ -18,6 +18,7 @@ extern int    _stdprintf _ARG_((const char*, ...));
 #define PerlIO_write(f,buf,count)      sfwrite(f,buf,count)
 #define PerlIO_open(path,mode)         sfopen(NULL,path,mode)
 #define PerlIO_fdopen(fd,mode)         _stdopen(fd,mode)
+#define PerlIO_reopen(path,mode,f)     sfopen(f,path,mode)
 #define PerlIO_close(f)                        sfclose(f)
 #define PerlIO_puts(f,s)               sfputr(f,s,-1)
 #define PerlIO_putc(f,c)               sfputc(f,c)
index 5f6ec2a..4e23040 100644 (file)
@@ -441,6 +441,12 @@ the return value of your socket() call?  See L<perlfunc/bind>.
 %ENV, it encountered a logical name or symbol definition which was too long,
 so it was truncated to the string shown.
 
+=item Buffer overflow in prime_env_iter: %s
+
+(W) A warning peculiar to VMS.  While Perl was preparing to iterate over
+%ENV, it encountered a logical name or symbol definition which was too long,
+so it was truncated to the string shown.
+
 =item Callback called exit
 
 (F) A subroutine invoked from an external package via perl_call_sv()
@@ -482,6 +488,13 @@ from the CRTL's internal environment array and discovered the array was
 missing.  You need to figure out where your CRTL misplaced its environ
 or define F<PERL_ENV_TABLES> (see L<perlvms>) so that environ is not searched.
 
+=item Can't read CRTL environ
+
+(S) A warning peculiar to VMS.  Perl tried to read an element of %ENV
+from the CRTL's internal environment array and discovered the array was
+missing.  You need to figure out where your CRTL misplaced its environ
+or define F<PERL_ENV_TABLES> (see L<perlvms>) so that environ is not searched.
+
 =item Can't "redo" outside a block
 
 (F) A "redo" statement was executed to restart the current block, but
@@ -1007,10 +1020,11 @@ package. If method name is C<???>, this is an internal error.
 =item Character class syntax [%s] belongs inside character classes
 
 (W) The character class constructs [: :], [= =], and [. .]  go
-I<inside> character classes, the [] are part of the construct.  For
-example: /[[:alpha:]]/
+I<inside> character classes, the [] are part of the construct,
+for example: /[012[:alpha:]345]/.  Note that the last two constructs
+are not currently implemented, they are placeholders for future extensions.
 
-=item Character class syntax [ .] is reserved for future extensions
+=item Character class syntax [. .] is reserved for future extensions
 
 (W) Within regular expression character classes ([]) the syntax beginning
 with "[." and ending with ".]" is reserved for future extensions.
@@ -1820,6 +1834,14 @@ to UTC.  If it's not, define the logical name F<SYS$TIMEZONE_DIFFERENTIAL>
 to translate to the number of seconds which need to be added to UTC to
 get local time.
 
+=item no UTC offset information; assuming local time is UTC
+
+(S) A warning peculiar to VMS.  Per was unable to find the local
+timezone offset, so it's assuming that local system time is equivalent
+to UTC.  If it's not, define the logical name F<SYS$TIMEZONE_DIFFERENTIAL>
+to translate to the number of seconds which need to be added to UTC to
+get local time.
+
 =item Not a CODE reference
 
 (F) Perl was trying to evaluate a reference to a code value (that is, a
@@ -2694,6 +2716,17 @@ rebuild Perl with a CRTL that does, or redefine F<PERL_ENV_TABLES> (see
 L<perlvms>) so that the environ array isn't the target of the change to
 %ENV which produced the warning.
 
+=item This Perl can't reset CRTL eviron elements (%s)
+
+=item This Perl can't set CRTL environ elements (%s=%s)
+
+(W) Warnings peculiar to VMS.  You tried to change or delete an element
+of the CRTL's internal environ array, but your copy of Perl wasn't
+built with a CRTL that contained the setenv() function.  You'll need to
+rebuild Perl with a CRTL that does, or redefine F<PERL_ENV_TABLES> (see
+L<perlvms>) so that the environ array isn't the target of the change to
+%ENV which produced the warning.
+
 =item times not implemented
 
 (F) Your version of the C library apparently doesn't do times().  I suspect
@@ -2855,6 +2888,13 @@ iterating over it, and someone else stuck a message in the stream of
 data Perl expected.  Someone's very confused, or perhaps trying to
 subvert Perl's population of %ENV for nefarious purposes.
 
+=item Unknown process %x sent message to prime_env_iter: %s
+
+(P) An error peculiar to VMS.  Perl was reading values for %ENV before
+iterating over it, and someone else stuck a message in the stream of
+data Perl expected.  Someone's very confused, or perhaps trying to
+subvert Perl's population of %ENV for nefarious purposes.
+
 =item unmatched () in regexp
 
 (F) Unbackslashed parentheses must always be balanced in regular
@@ -3063,6 +3103,13 @@ element from a CLI symbol table, and found a resultant string longer
 than 1024 characters.  The return value has been truncated to 1024
 characters.
 
+=item Value of CLI symbol "%s" too long
+
+(W) A warning peculiar to VMS.  Perl tried to read the value of an %ENV
+element from a CLI symbol table, and found a resultant string longer
+than 1024 characters.  The return value has been truncated to 1024
+characters.
+
 =item Variable "%s" is not imported%s
 
 (F) While "use strict" in effect, you referred to a global variable
index 07cc8fd..021d699 100755 (executable)
@@ -122,8 +122,7 @@ if ($^O eq 'VMS') {
   if ($bar eq "z\n") {print "ok 14\n";} else {print "not ok 14\n";}
 
   close TESTFILE;
-  unlink "./foo.bar";
-  unlink "./foo.com";  
+  1 while unlink qw(foo.bar foo.com foo.fdl);
 } else {
   # Nobody else does this at the moment (well, maybe OS/390, but they can
   # put their own tests in) so we just punt
index 8dc46e9..7337a5f 100644 (file)
@@ -21,7 +21,6 @@ BEGIN {
        elsif ($Config{'extensions'} !~ /\bIO\b/) {
            $reason = 'IO extension unavailable';
        }
-       undef $reason if $^O eq 'VMS' and $Config{d_socket};
        if ($reason) {
            print "1..0 # Skip: $reason\n";
            exit 0;
index 9ae6de9..daeee23 100755 (executable)
@@ -5,6 +5,8 @@ BEGIN {
     unshift @INC, '../lib';
 }
 
+use Text::Wrap qw(&fill);
+
 @tests = (split(/\nEND\n/s, <<DONE));
 TEST1
 Cyberdog Information
index aee2500..bb1d5ca 100755 (executable)
@@ -4,6 +4,7 @@ BEGIN {
     chdir 't' if -d 't';
     unshift @INC, '../lib';
 }
+use Text::Wrap qw(&wrap);
 
 @tests = (split(/\nEND\n/s, <<DONE));
 TEST1
index 1e095be..66eaa39 100644 (file)
@@ -35,7 +35,10 @@ eval '$> = 1';               # so switch uid (may not be implemented)
 
 print "# oldeuid = $oldeuid, euid = $>\n";
 
-if ($bad_chmod) {
+if (!$Config{d_seteuid}) {
+    print "ok 6 #skipped, no seteuid\n";
+}
+elsif ($bad_chmod) {
     print "#[$@]\nok 6 #skipped\n";
 }
 else {
index fc91b6b..4bd1b21 100755 (executable)
@@ -4,7 +4,14 @@
 
 print "1..7\n";
 
-$^O eq 'MSWin32' ? `del /s /q blurfl 2>&1` : `rm -rf blurfl`;
+if ($^O eq 'VMS') { # May as well test the library too
+  unshift @INC, '../lib';
+  require File::Path;
+  File::Path::rmtree('blurfl');
+}
+else {
+  $^O eq 'MSWin32' ? `del /s /q blurfl 2>&1` : `rm -rf blurfl`;
+}
 
 # tests 3 and 7 rather naughtily expect English error messages
 $ENV{'LC_ALL'} = 'C';
index 7fd0196..ff8d805 100755 (executable)
@@ -899,5 +899,22 @@ test $bar->{two}, 11;              # 205
 $bar->{three} = 13;
 test $bar->[3], 13;            # 206
 
+{
+  package B;
+  use overload bool => sub { ${+shift} };
+}
+
+my $aaa;
+{ my $bbbb = 0; $aaa = bless \$bbbb, B }
+
+test !$aaa, 1;
+
+unless ($aaa) {
+  test 'ok', 'ok';
+} else {
+  test 'is not', 'ok';
+}
+
+
 # Last test is:
-sub last {206}
+sub last {208}
index af35fbd..031f1c6 100644 (file)
--- a/vms/vms.c
+++ b/vms/vms.c
@@ -466,15 +466,22 @@ prime_env_iter(void)
       key = cp1;  keylen = cp2 - cp1;
       if (keylen && hv_exists(seenhv,key,keylen)) continue;
       while (*cp2 && *cp2 != '=') cp2++;
-      while (*cp2 && *cp2 != '"') cp2++;
-      for (cp1 = buf + retlen; *cp1 != '"'; cp1--) ;
-      if ((!keylen || (cp1 - cp2 <= 0)) && ckWARN(WARN_INTERNAL)) {
+      while (*cp2 && *cp2 == '=') cp2++;
+      while (*cp2 && *cp2 == ' ') cp2++;
+      if (*cp2 == '"') {  /* String translation; may embed "" */
+        for (cp1 = buf + retlen; *cp1 != '"'; cp1--) ;
+        cp2++;  cp1--; /* Skip "" surrounding translation */
+      }
+      else {  /* Numeric translation */
+        for (cp1 = cp2; *cp1 && *cp1 != ' '; cp1++) ;
+        cp1--;  /* stop on last non-space char */
+      }
+      if ((!keylen || (cp1 - cp2 < -1)) && ckWARN(WARN_INTERNAL)) {
         warner(WARN_INTERNAL,"Ill-formed message in prime_env_iter: |%s|",buf);
         continue;
       }
-      /* Skip "" surrounding translation */
       PERL_HASH(hash,key,keylen);
-      hv_store(envhv,key,keylen,newSVpv(cp2+1,cp1 - cp2 - 1),hash);
+      hv_store(envhv,key,keylen,newSVpvn(cp2,cp1 - cp2 + 1),hash);
       hv_store(seenhv,key,keylen,&PL_sv_yes,hash);
     }
     if (cmddsc.dsc$w_length == 14) { /* We just read LNM$FILE_DEV */
@@ -917,7 +924,7 @@ static int waitpid_asleep = 0;
  * to a mbx; that's the caller's responsibility.
  */
 static unsigned long int
-pipe_eof(FILE *fp)
+pipe_eof(FILE *fp, int immediate)
 {
   char devnam[NAM$C_MAXRSS+1], *cp;
   unsigned long int chan, iosb[2], retsts, retsts2;
@@ -929,7 +936,8 @@ pipe_eof(FILE *fp)
     if ((cp = strrchr(devnam,':')) != NULL) *(cp+1) = '\0';
     devdsc.dsc$w_length = strlen(devnam);
     _ckvmssts(sys$assign(&devdsc,&chan,0,0));
-    retsts = sys$qiow(0,chan,IO$_WRITEOF,iosb,0,0,0,0,0,0,0,0);
+    retsts = sys$qiow(0,chan,IO$_WRITEOF|(immediate?IO$M_NOW|IO$M_NORSWAIT:0),
+             iosb,0,0,0,0,0,0,0,0);
     if (retsts & 1) retsts = iosb[0];
     retsts2 = sys$dassgn(chan);  /* Be sure to deassign the channel */
     if (retsts & 1) retsts = retsts2;
@@ -956,7 +964,7 @@ pipe_exit_routine()
 
     while (info) {
       if (info->mode != 'r' && !info->done) {
-        if (pipe_eof(info->fp) & 1) did_stuff = 1;
+        if (pipe_eof(info->fp, 1) & 1) did_stuff = 1;
       }
       info = info->next;
     }
@@ -1098,7 +1106,7 @@ I32 my_pclose(FILE *fp)
     /* If we were writing to a subprocess, insure that someone reading from
      * the mailbox gets an EOF.  It looks like a simple fclose() doesn't
      * produce an EOF record in the mailbox.  */
-    if (info->mode != 'r' && !info->done) pipe_eof(info->fp);
+    if (info->mode != 'r' && !info->done) pipe_eof(info->fp,0);
     PerlIO_close(info->fp);
 
     if (info->done) retsts = info->completion;