diff options
author | Gurusamy Sarathy <gsar@cpan.org> | 1998-03-01 06:52:26 +0000 |
---|---|---|
committer | Gurusamy Sarathy <gsar@cpan.org> | 1998-03-01 06:52:26 +0000 |
commit | fbbbcc485c1d03c76a91f998e1e4492c8ad56b38 (patch) | |
tree | 3b1a893d2288b11451c4d4419edd75f4f85d2481 /lib | |
parent | c69f6586a27b86846a13e0177336730d72b33c95 (diff) | |
parent | 1c1c7f20b839aeb1c04942d0884c3efb087d3e4a (diff) | |
download | perl-fbbbcc485c1d03c76a91f998e1e4492c8ad56b38.tar.gz |
[asperl] integrate mainline changes
p4raw-id: //depot/asperl@607
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AutoLoader.pm | 2 | ||||
-rw-r--r-- | lib/Cwd.pm | 71 | ||||
-rw-r--r-- | lib/ExtUtils/MM_VMS.pm | 14 | ||||
-rw-r--r-- | lib/Term/ReadLine.pm | 43 | ||||
-rw-r--r-- | lib/Test.pm | 131 | ||||
-rw-r--r-- | lib/Tie/Handle.pm | 161 | ||||
-rw-r--r-- | lib/perl5db.pl | 27 |
7 files changed, 332 insertions, 117 deletions
diff --git a/lib/AutoLoader.pm b/lib/AutoLoader.pm index 2773a90f10..46e0a4be7a 100644 --- a/lib/AutoLoader.pm +++ b/lib/AutoLoader.pm @@ -73,7 +73,7 @@ sub import { # 'auto/POSIX/autosplit.ix' (without the leading 'lib'). # - (my $calldir = $callpkg) =~ s#::#/#; + (my $calldir = $callpkg) =~ s#::#/#g; my $path = $INC{$calldir . '.pm'}; if (defined($path)) { # Try absolute path name. diff --git a/lib/Cwd.pm b/lib/Cwd.pm index 19ff497759..652ee7e493 100644 --- a/lib/Cwd.pm +++ b/lib/Cwd.pm @@ -54,7 +54,7 @@ kept up to date if all packages which use chdir import it from Cwd. use Carp; -$VERSION = '2.00'; +$VERSION = '2.01'; require Exporter; @ISA = qw(Exporter); @@ -82,66 +82,9 @@ sub _backtick_pwd { sub getcwd { - my($dotdots, $cwd, @pst, @cst, $dir, @tst); - - unless (@cst = stat('.')) - { - warn "stat(.): $!"; - return ''; - } - $cwd = ''; - $dotdots = ''; - do - { - $dotdots .= '/' if $dotdots; - $dotdots .= '..'; - @pst = @cst; - unless (opendir(PARENT, $dotdots)) - { - warn "opendir($dotdots): $!"; - return ''; - } - unless (@cst = stat($dotdots)) - { - warn "stat($dotdots): $!"; - closedir(PARENT); - return ''; - } - if ($pst[0] == $cst[0] && $pst[1] == $cst[1]) - { - $dir = undef; - } - else - { - do - { - unless (defined ($dir = readdir(PARENT))) - { - warn "readdir($dotdots): $!"; - closedir(PARENT); - return ''; - } - unless (@tst = lstat("$dotdots/$dir")) - { - # warn "lstat($dotdots/$dir): $!"; - # Just because you can't lstat this directory - # doesn't mean you'll never find the right one. - # closedir(PARENT); - # return ''; - } - } - while ($dir eq '.' || $dir eq '..' || $tst[0] != $pst[0] || - $tst[1] != $pst[1]); - } - $cwd = (defined $dir ? "$dir" : "" ) . "/$cwd" ; - closedir(PARENT); - } while (defined $dir); - chop($cwd) unless $cwd eq '/'; # drop the trailing / - $cwd; + abs_path('.'); } - - # By John Bazik # # Usage: $cwd = &fastcwd; @@ -249,7 +192,7 @@ sub chdir { sub abs_path { - my $start = shift || '.'; + my $start = @_ ? shift : '.'; my($dotdots, $cwd, @pst, @cst, $dir, @tst); unless (@cst = stat( $start )) @@ -276,7 +219,7 @@ sub abs_path } if ($pst[0] == $cst[0] && $pst[1] == $cst[1]) { - $dir = ''; + $dir = undef; } else { @@ -293,10 +236,10 @@ sub abs_path while ($dir eq '.' || $dir eq '..' || $tst[0] != $pst[0] || $tst[1] != $pst[1]); } - $cwd = "$dir/$cwd"; + $cwd = (defined $dir ? "$dir" : "" ) . "/$cwd" ; closedir(PARENT); - } while ($dir); - chop($cwd); # drop the trailing / + } while (defined $dir); + chop($cwd) unless $cwd eq '/'; # drop the trailing / $cwd; } diff --git a/lib/ExtUtils/MM_VMS.pm b/lib/ExtUtils/MM_VMS.pm index dc3b4ceca6..954f6123d5 100644 --- a/lib/ExtUtils/MM_VMS.pm +++ b/lib/ExtUtils/MM_VMS.pm @@ -1422,7 +1422,21 @@ $(INST_STATIC) : $(OBJECT) $(MYEXTLIB) push(@m,' If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET) +'); + # if there was a library to copy, then we can't use MMS$SOURCE_LIST, + # 'cause it's a library and you can't stick them in other libraries. + # In that case, we use $OBJECT instead and hope for the best + if ($self->{MYEXTLIB}) { + push(@m,' + Library/Object/Replace $(MMS$TARGET) $(OBJECT) +'); + } else { + push(@m,' Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST) +'); + } + + push(@m, ' $(NOECHO) $(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR)extralibs.ld\';print F qq{$(EXTRALIBS)\n};close F;" '); push @m, $self->dir_target('$(INST_ARCHAUTODIR)'); diff --git a/lib/Term/ReadLine.pm b/lib/Term/ReadLine.pm index b6923dd1e7..6b0b5e7f23 100644 --- a/lib/Term/ReadLine.pm +++ b/lib/Term/ReadLine.pm @@ -139,12 +139,23 @@ None =head1 ENVIRONMENT -The variable C<PERL_RL> governs which ReadLine clone is loaded. If the -value is false, a dummy interface is used. If the value is true, it -should be tail of the name of the package to use, such as C<Perl> or -C<Gnu>. +The envrironment variable C<PERL_RL> governs which ReadLine clone is +loaded. If the value is false, a dummy interface is used. If the value +is true, it should be tail of the name of the package to use, such as +C<Perl> or C<Gnu>. -If the variable is not set, the best available package is loaded. +As a special case, if the value of this variable is space-separated, +the tail might be used to disable the ornaments by setting the tail to +be C<o=0> or C<ornaments=0>. The head should be as described above, say + +If the variable is not set, or if the head of space-separated list is +empty, the best available package is loaded. + + export "PERL_RL=Perl o=0" # Use Perl ReadLine without ornaments + export "PERL_RL= o=0" # Use best available ReadLine without ornaments + +(Note that processing of C<PERL_RL> for ornaments is in the discretion of the +particular used C<Term::ReadLine::*> package). =cut @@ -205,7 +216,7 @@ sub new { die "method new called with wrong number of arguments" unless @_==2 or @_==4; #local (*FIN, *FOUT); - my ($FIN, $FOUT); + my ($FIN, $FOUT, $ret); if (@_==2) { ($console, $consoleOUT) = findConsole; @@ -215,15 +226,21 @@ sub new { $sel = select(FOUT); $| = 1; # for DB::OUT select($sel); - bless [\*FIN, \*FOUT]; + $ret = bless [\*FIN, \*FOUT]; } else { # Filehandles supplied $FIN = $_[2]; $FOUT = $_[3]; #OUT->autoflush(1); # Conflicts with debugger? $sel = select($FOUT); $| = 1; # for DB::OUT select($sel); - bless [$FIN, $FOUT]; + $ret = bless [$FIN, $FOUT]; } + if ($ret->Features->{ornaments} + and not ($ENV{PERL_RL} and $ENV{PERL_RL} =~ /\bo\w*=0/)) { + local $Term::ReadLine::termcap_nowarn = 1; + $ret->ornaments(1); + } + return $ret; } sub newTTY { @@ -245,7 +262,7 @@ sub Features { \%features } package Term::ReadLine; # So late to allow the above code be defined? -my $which = $ENV{PERL_RL}; +my ($which) = exists $ENV{PERL_RL} ? split /\s+/, $ENV{PERL_RL} : undef; if ($which) { if ($which =~ /\bgnu\b/i){ eval "use Term::ReadLine::Gnu;"; @@ -254,7 +271,7 @@ if ($which) { } else { eval "use Term::ReadLine::$which;"; } -} elsif (defined $which) { # Defined but false +} elsif (defined $which and $which ne '') { # Defined but false # Do nothing fancy } else { eval "use Term::ReadLine::Gnu; 1" or eval "use Term::ReadLine::Perl; 1"; @@ -296,7 +313,11 @@ sub ornaments { $rl_term_set = 'us,ue,md,me' if $rl_term_set == 1; my @ts = split /,/, $rl_term_set, 4; eval { LoadTermCap }; - warn("Cannot find termcap: $@\n"), return unless defined $terminal; + unless (defined $terminal) { + warn("Cannot find termcap: $@\n") unless $Term::ReadLine::termcap_nowarn; + $rl_term_set = ',,,'; + return; + } @rl_term_set = map {$_ ? $terminal->Tputs($_,1) || '' : ''} @ts; return $rl_term_set; } diff --git a/lib/Test.pm b/lib/Test.pm index 7e79da2bf4..b10d104ded 100644 --- a/lib/Test.pm +++ b/lib/Test.pm @@ -2,18 +2,19 @@ use strict; package Test; use Test::Harness 1.1601 (); use Carp; -use vars qw($VERSION @ISA @EXPORT $ntest %todo); -$VERSION = '0.06'; +use vars qw($VERSION @ISA @EXPORT $ntest %todo %history $TestLevel); +$VERSION = '0.08'; require Exporter; @ISA=('Exporter'); @EXPORT= qw(&plan &ok &skip $ntest); +$TestLevel = 0; # how many extra stack frames to skip $|=1; #$^W=1; ? $ntest=1; -# Use of this variable is strongly discouraged. It is set -# exclusively for test coverage analyzers. +# Use of this variable is strongly discouraged. It is set mainly to +# help test coverage analyzers know which test is running. $ENV{REGRESSION_TEST} = $0; sub plan { @@ -34,33 +35,81 @@ sub plan { } } +sub to_value { + my ($v) = @_; + (ref $v or '') eq 'CODE' ? $v->() : $v; +} + +# prototypes are not used for maximum flexibility + +# STDERR is NOT used for diagnostic output that should be fixed before +# the module is released. + sub ok { - my ($ok, $guess) = @_; - carp "(this is ok $ntest)" if defined $guess && $guess != $ntest; - $ok = $ok->() if (ref $ok or '') eq 'CODE'; - if ($ok) { + my ($pkg,$file,$line) = caller($TestLevel); + my $repetition = ++$history{"$file:$line"}; + my $context = ("$file at line $line". + ($repetition > 1 ? " (\#$repetition)" : '')); + my $ok=0; + + if (@_ == 0) { + print "not ok $ntest\n"; + print "# test $context: DOESN'T TEST ANYTHING!\n"; + } else { + my $result = to_value(shift); + my ($expected,$diag); + if (@_ == 0) { + $ok = $result; + } else { + $expected = to_value(shift); + $ok = $result eq $expected; + } if ($todo{$ntest}) { - print("ok $ntest # Wow!\n"); + if ($ok) { + print "ok $ntest # Wow!\n"; + } else { + $diag = to_value(shift) if @_; + if (!$diag) { + print "not ok $ntest # (failure expected)\n"; + } else { + print "not ok $ntest # (failure expected: $diag)\n"; + } + } } else { - print("ok $ntest # (failure expected)\n"); + print "not " if !$ok; + print "ok $ntest\n"; + + if (!$ok) { + $diag = to_value(shift) if @_; + if (!defined $expected) { + if (!$diag) { + print STDERR "# Failed $context\n"; + } else { + print STDERR "# Failed $context: $diag\n"; + } + } else { + print STDERR "# Got: '$result' ($context)\n"; + if (!$diag) { + print STDERR "# Expected: '$expected'\n"; + } else { + print STDERR "# Expected: '$expected' ($diag)\n"; + } + } + } } - } else { - print("not ok $ntest\n"); } ++ $ntest; $ok; } sub skip { - my ($toskip, $ok, $guess) = @_; - carp "(this is skip $ntest)" if defined $guess && $guess != $ntest; - $toskip = $toskip->() if (ref $toskip or '') eq 'CODE'; - if ($toskip) { + if (to_value(shift)) { print "ok $ntest # skip\n"; ++ $ntest; 1; } else { - ok($ok); + local($TestLevel) += 1; #ignore this stack frame + ok(@_); } } @@ -75,42 +124,54 @@ __END__ use strict; use Test; - BEGIN { plan tests => 5, todo => [3,4] } + BEGIN { plan tests => 12, todo => [3,4] } + + ok(0); # failure + ok(1); # success + + ok(0); # ok, expected failure (see todo list, above) + ok(1); # surprise success! + + ok(0,1); # failure: '0' ne '1' + ok('broke','fixed'); # failure: 'broke' ne 'fixed' + ok('fixed','fixed'); # success: 'fixed' eq 'fixed' - ok(0); #failure - ok(1); #success + ok(sub { 1+1 }, 2); # success: '2' eq '2' + ok(sub { 1+1 }, 3); # failure: '2' ne '3' + ok(0, int(rand(2)); # (just kidding! :-) - ok(0); #ok, expected failure (see todo above) - ok(1); #surprise success! + my @list = (0,0); + ok(scalar(@list), 3, "\@list=".join(',',@list)); #extra diagnostics - skip($feature_is_missing, sub {...}); #do platform specific test + skip($feature_is_missing, ...); #do platform specific test =head1 DESCRIPTION -Test::Harness expects to see particular output when it executes test -scripts. This module tries to make conforming just a little bit -easier (and less error prone). +Test::Harness expects to see particular output when it executes tests. +This module aims to make writing proper test scripts just a little bit +easier (and less error prone :-). -=head1 TEST CATEGORIES +=head1 TEST TYPES =over 4 =item * NORMAL TESTS -These tests are expected to succeed. If they don't, something is -wrong! +These tests are expected to succeed. If they don't, something's +screwed up! =item * SKIPPED TESTS -C<skip> should be used to skip tests for which a platform specific -feature isn't available. +Skip tests need a platform specific feature that might or might not be +available. The first argument should evaluate to true if the required +feature is NOT available. After the first argument, skip tests work +exactly the same way as do normal tests. =item * TODO TESTS -TODO tests are designed for the purpose of maintaining an executable -TODO list. These tests are expected NOT to succeed (otherwise the -feature they test would be on the new feature list, not the TODO -list). +TODO tests are designed for maintaining an executable TODO list. +These tests are expected NOT to succeed (otherwise the feature they +test would be on the new feature list, not the TODO list). Packages should NOT be released with successful TODO tests. As soon as a TODO test starts working, it should be promoted to a normal test diff --git a/lib/Tie/Handle.pm b/lib/Tie/Handle.pm new file mode 100644 index 0000000000..c7550530b8 --- /dev/null +++ b/lib/Tie/Handle.pm @@ -0,0 +1,161 @@ +package Tie::Handle; + +=head1 NAME + +Tie::Handle - base class definitions for tied handles + +=head1 SYNOPSIS + + package NewHandle; + require Tie::Handle; + + @ISA = (Tie::Handle); + + sub READ { ... } # Provide a needed method + sub TIEHANDLE { ... } # Overrides inherited method + + + package main; + + tie *FH, 'NewHandle'; + +=head1 DESCRIPTION + +This module provides some skeletal methods for handle-tying classes. See +L<perltie> for a list of the functions required in tying a handle to a package. +The basic B<Tie::Handle> package provides a C<new> method, as well as methods +C<TIESCALAR>, C<FETCH> and C<STORE>. The C<new> method is provided as a means +of grandfathering, for classes that forget to provide their own C<TIESCALAR> +method. + +For developers wishing to write their own tied-handle classes, the methods +are summarized below. The L<perltie> section not only documents these, but +has sample code as well: + +=over + +=item TIEHANDLE classname, LIST + +The method invoked by the command C<tie *glob, classname>. Associates a new +glob instance with the specified class. C<LIST> would represent additional +arguments (along the lines of L<AnyDBM_File> and compatriots) needed to +complete the association. + +=item WRITE this, scalar, length, offset + +Write I<length> bytes of data from I<scalar> starting at I<offset>. + +=item PRINT this, LIST + +Print the values in I<LIST> + +=item PRINTF this, format, LIST + +Print the values in I<LIST> using I<format> + +=item READ this, scalar, length, offset + +Read I<length> bytes of data into I<scalar> starting at I<offset>. + +=item READLINE this + +Read a single line + +=item GETC this + +Get a single character + +=item DESTROY this + +Free the storage associated with the tied handle referenced by I<this>. +This is rarely needed, as Perl manages its memory quite well. But the +option exists, should a class wish to perform specific actions upon the +destruction of an instance. + +=back + +=head1 MORE INFORMATION + +The L<perltie> section contains an example of tying handles. + +=cut + +use Carp; + +sub new { + my $pkg = shift; + $pkg->TIEHANDLE(@_); +} + +# "Grandfather" the new, a la Tie::Hash + +sub TIEHANDLE { + my $pkg = shift; + if (defined &{"{$pkg}::new"}) { + carp "WARNING: calling ${pkg}->new since ${pkg}->TIEHANDLE is missing" + if $^W; + $pkg->new(@_); + } + else { + croak "$pkg doesn't define a TIEHANDLE method"; + } +} + +sub PRINT { + my $self = shift; + if($self->can('WRITE') != \&WRITE) { + my $buf = join(defined $, ? $, : "",@_); + $buf .= $\ if defined $\; + $self->WRITE($buf,length($buf),0); + } + else { + croak ref($self)," doesn't define a PRINT method"; + } +} + +sub PRINTF { + my $self = shift; + + if($self->can('WRITE') != \&WRITE) { + my $buf = sprintf(@_); + $self->WRITE($buf,length($buf),0); + } + else { + croak ref($self)," doesn't define a PRINTF method"; + } +} + +sub READLINE { + my $pkg = ref $_[0]; + croak "$pkg doesn't define a READLINE method"; +} + +sub GETC { + my $self = shift; + + if($self->can('READ') != \&READ) { + my $buf; + $self->READ($buf,1); + return $buf; + } + else { + croak ref($self)," doesn't define a GETC method"; + } +} + +sub READ { + my $pkg = ref $_[0]; + croak "$pkg doesn't define a READ method"; +} + +sub WRITE { + my $pkg = ref $_[0]; + croak "$pkg doesn't define a WRITE method"; +} + +sub CLOSE { + my $pkg = ref $_[0]; + croak "$pkg doesn't define a CLOSE method"; +} + +1; diff --git a/lib/perl5db.pl b/lib/perl5db.pl index 9048ed2baf..a4a1b1aae6 100644 --- a/lib/perl5db.pl +++ b/lib/perl5db.pl @@ -390,9 +390,9 @@ sub DB { if ($val ne $old_watch[$n]) { $signal = 1; print $OUT <<EOP; -Watchpoint $n: $to_watch[$n] changed: -old value: $old_watch[$n] -new value: $val +Watchpoint $n:\t$to_watch[$n] changed: + old value:\t$old_watch[$n] + new value:\t$val EOP $old_watch[$n] = $val; } @@ -409,6 +409,15 @@ EOP if ($emacs) { $position = "\032\032$filename:$line:0\n"; print $LINEINFO $position; + } elsif ($package eq 'DB::fake') { + print_help(<<EOP); +Debugged program terminated. Use B<q> to quit or B<R> to restart, + use B<O> I<inhibit_exit> to avoid stopping after program termination, + B<h q>, B<h R> or B<h O> to get additional info. +EOP + $package = 'main'; + $usercontext = '($@, $!, $,, $/, $\, $^W) = @saved;' . + "package $package;"; # this won't let them modify, alas } else { $sub =~ s/\'/::/; $prefix = $sub =~ /::/ ? "" : "${'package'}::"; @@ -1461,8 +1470,14 @@ sub resetterm { # We forked, so we need a different TTY TTY($fork_TTY); undef $fork_TTY; } else { - print $OUT "Forked, but do not know how to change a TTY.\n", - "Define \$DB::fork_TTY or get_fork_TTY().\n"; + print_help(<<EOP); +I<#########> Forked, but do not know how to change a B<TTY>. I<#########> + Define B<\$DB::fork_TTY> + - or a function B<DB::get_fork_TTY()> which will set B<\$DB::fork_TTY>. + The value of B<\$DB::fork_TTY> should be the name of I<TTY> to use. + On I<UNIX>-like systems one can get the name of a I<TTY> for the given window + by typing B<tty>, and disconnect the I<shell> from I<TTY> by B<sleep 1000000>. +EOP } } @@ -1824,7 +1839,7 @@ B<R> Pure-man-restart of debugger, some of debugger state and the following command-line options: I<-w>, I<-I>, I<-e>. B<h> [I<db_command>] Get help [on a specific debugger command], enter B<|h> to page. B<h h> Summary of debugger commands. -B<q> or B<^D> Quit. Set \$DB::finished to 0 to debug global destruction. +B<q> or B<^D> Quit. Set B<\$DB::finished = 0> to debug global destruction. "; $summary = <<"END_SUM"; |