Integrate mainline (t/lib/b.t fails test 2...)
Nick Ing-Simmons [Tue, 17 Apr 2001 16:33:51 +0000 (16:33 +0000)]
p4raw-id: //depot/perlio@9726

51 files changed:
AUTHORS
Changes
MANIFEST
Porting/makerel
ext/B/B.pm
ext/B/B/Concise.pm
ext/B/B/Deparse.pm
ext/B/O.pm
ext/File/Glob/bsd_glob.c
ext/List/Util/ChangeLog [new file with mode: 0644]
ext/List/Util/Makefile.PL [new file with mode: 0644]
ext/List/Util/README [new file with mode: 0644]
ext/List/Util/Util.xs [new file with mode: 0644]
ext/List/Util/lib/List/Util.pm [new file with mode: 0644]
ext/List/Util/lib/Scalar/Util.pm [new file with mode: 0644]
ext/Time/HiRes/HiRes.pm
ext/Time/HiRes/HiRes.xs
gv.c
lib/Class/Struct.pm
lib/Exporter/Heavy.pm
lib/ExtUtils/Install.pm
lib/ExtUtils/Installed.pm
lib/Net/Ping.pm
lib/Shell.pm
lib/constant.pm
lib/utf8.pm
op.c
patchlevel.h
pod/perlebcdic.pod
pod/perltie.pod
pod/perltoc.pod
t/lib/cwd.t
t/lib/exporter.t [new file with mode: 0644]
t/lib/time-hires.t
t/lib/u-blessed.t [new file with mode: 0755]
t/lib/u-dualvar.t [new file with mode: 0755]
t/lib/u-first.t [new file with mode: 0755]
t/lib/u-max.t [new file with mode: 0755]
t/lib/u-maxstr.t [new file with mode: 0755]
t/lib/u-min.t [new file with mode: 0755]
t/lib/u-minstr.t [new file with mode: 0755]
t/lib/u-readonly.t [new file with mode: 0644]
t/lib/u-reduce.t [new file with mode: 0755]
t/lib/u-reftype.t [new file with mode: 0755]
t/lib/u-sum.t [new file with mode: 0755]
t/lib/u-tainted.t [new file with mode: 0644]
t/lib/u-weak.t [new file with mode: 0755]
t/op/loopctl.t
t/pragma/warnings.t
utf8.c
utils/dprofpp.PL

diff --git a/AUTHORS b/AUTHORS
index 9dadb9b..4c998b6 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -73,7 +73,7 @@ Calle Dybedahl                 <calle@lysator.liu.se>
 Carl M. Fongheiser             <cmf@ins.infonet.net>
 Carl Witty                     <cwitty@newtonlabs.com>
 Cary D. Renzema                <caryr@mxim.com>
-Casey R. Tweten                <crt@kiski.net>
+Casey West                     <casey@geeknest.com>
 Castor Fu
 Chaim Frenkel                  <chaimf@pobox.com>
 Charles Bailey                 <bailey@newman.upenn.edu>
@@ -145,7 +145,7 @@ Dominic Dunlop                 <domo@computer.org>
 Dominique Dumont               <Dominique_Dumont@grenoble.hp.com>
 Doug Campbell                  <soup@ampersand.com>
 Doug MacEachern                <dougm@covalent.net>
-Douglas E. Wegscheid           <wegscd@whirlpool.com>
+Douglas E. Wegscheid           <dwegscheid@qtm.net>
 Douglas Lankshear              <dougl@activestate.com>
 Dov Grobgeld                   <dov@Orbotech.Co.IL>
 Drago Goricanec                <drago@raptor.otsd.ts.fujitsu.co.jp>
diff --git a/Changes b/Changes
index 4515b81..9a418bf 100644 (file)
--- a/Changes
+++ b/Changes
@@ -31,6 +31,364 @@ or any other branch.
 Version v5.7.1         Development release working toward v5.8
 --------------
 ____________________________________________________________________________
+[  9717] By: jhi                                   on 2001/04/16  03:06:28
+        Log: Regen toc.
+     Branch: perl
+          ! pod/perltoc.pod
+____________________________________________________________________________
+[  9716] By: jhi                                   on 2001/04/16  02:58:42
+        Log: Subject: [PATCH: perl@9699] updates to apidoc in utf8.c
+             From: Prymmer/Kahn <pvhp@best.com>
+             Date: Sun, 15 Apr 2001 20:47:45 -0700 (PDT)
+             Message-ID: <Pine.BSF.4.21.0104152037470.8946-100000@shell8.ba.best.com>
+     Branch: perl
+          ! utf8.c
+____________________________________________________________________________
+[  9715] By: jhi                                   on 2001/04/15  23:40:35
+        Log: Subject: Re: Net::Ping patch, adds stream protocol
+             From: bronson@rinspin.com (Scott Bronson)
+             Date: Tue, 10 Apr 2001 23:58:33 -0700
+             Message-ID: <20010410235833.N29719@rinspin.com>
+     Branch: perl
+          ! lib/Net/Ping.pm
+____________________________________________________________________________
+[  9714] By: jhi                                   on 2001/04/15  23:31:46
+        Log: Printing out the ok messages helps successful testing.
+     Branch: perl
+          ! t/lib/time-hires.t
+____________________________________________________________________________
+[  9713] By: jhi                                   on 2001/04/15  21:43:24
+        Log: Update Douglas Wegscheid's email.
+     Branch: perl
+          ! AUTHORS
+____________________________________________________________________________
+[  9712] By: jhi                                   on 2001/04/15  21:40:41
+        Log: Subject: [PATCH t/lib/exporter.t lib/Exporter/Heavy.pm] Testing Exporter
+             From: Michael G Schwern <schwern@pobox.com>
+             Date: Sat, 14 Apr 2001 22:40:50 +0100
+             Message-ID: <20010414224050.A1872@blackrider.blackstar.co.uk>
+     Branch: perl
+          + t/lib/exporter.t
+          ! MANIFEST lib/Exporter/Heavy.pm
+____________________________________________________________________________
+[  9711] By: jhi                                   on 2001/04/15  21:39:21
+        Log: Subject: [PATCH t/op/loopctl.t] Exit via last, part 1
+             From: Michael G Schwern <schwern@pobox.com>
+             Date: Sat, 14 Apr 2001 22:13:59 +0100
+             Message-ID: <20010414221359.A413@blackrider.blackstar.co.uk>
+     Branch: perl
+          ! t/op/loopctl.t
+____________________________________________________________________________
+[  9710] By: jhi                                   on 2001/04/15  21:30:19
+        Log: Subject: [PATCH t/pragma/warnings.t] Doesn't skip RCS files
+             From: Michael G Schwern <schwern@pobox.com>
+             Date: Sat, 14 Apr 2001 22:05:32 +0100
+             Message-ID: <20010414220531.A30178@blackrider.blackstar.co.uk>
+     Branch: perl
+          ! t/pragma/warnings.t
+____________________________________________________________________________
+[  9709] By: jhi                                   on 2001/04/15  19:34:09
+        Log: Integrate changes #9706,9707 from maintperl into mainline.
+             
+             change#7210 broke .packlist generation
+             
+             ExtUtils::Installed doesn't quote regex metacharacters in paths
+             before using them in match; also make it work for dosish platforms
+     Branch: perl
+         !> lib/ExtUtils/Install.pm lib/ExtUtils/Installed.pm
+____________________________________________________________________________
+[  9708] By: jhi                                   on 2001/04/15  19:31:01
+        Log: Test also the scalar aspect of getitimer().
+     Branch: perl
+          ! t/lib/time-hires.t
+____________________________________________________________________________
+[  9707] By: gsar                                  on 2001/04/15  17:24:20
+        Log: ExtUtils::Installed doesn't quote regex metacharacters in paths
+             before using them in match; also make it work for dosish platforms
+     Branch: maint-5.6/perl
+          ! lib/ExtUtils/Installed.pm
+____________________________________________________________________________
+[  9706] By: gsar                                  on 2001/04/15  17:21:59
+        Log: change#7210 broke .packlist generation (listed only filename
+             rather than fully qualified path name)
+     Branch: maint-5.6/perl
+          ! lib/ExtUtils/Install.pm
+____________________________________________________________________________
+[  9705] By: jhi                                   on 2001/04/15  12:36:33
+        Log: Add interval timer (setitimer, getitimer) support to Time::HiRes.
+     Branch: perl
+          ! ext/Time/HiRes/HiRes.pm ext/Time/HiRes/HiRes.xs
+          ! t/lib/time-hires.t
+____________________________________________________________________________
+[  9704] By: jhi                                   on 2001/04/15  10:49:08
+        Log: Subject: [PATCH: perl@9622]update perlebcdic.pod with UTF tbl; tweak utf8.pm
+             From: Prymmer/Kahn <pvhp@best.com>
+             Date: Sat, 14 Apr 2001 21:36:24 -0700 (PDT)
+             Message-ID: <Pine.BSF.4.21.0104142127580.27582-100000@shell8.ba.best.com>
+     Branch: perl
+          ! lib/utf8.pm pod/perlebcdic.pod
+____________________________________________________________________________
+[  9703] By: jhi                                   on 2001/04/15  02:26:26
+        Log: I keep forgetting to sort MANIFEST.
+     Branch: perl
+          ! MANIFEST
+____________________________________________________________________________
+[  9702] By: jhi                                   on 2001/04/15  02:07:47
+        Log: Add Scalar-List-Utils 1.02, from Graham Barr.
+             Now we have blessed, reftype, tainted, first, reduce, ...
+     Branch: perl
+          + ext/List/Util/ChangeLog ext/List/Util/Makefile.PL
+          + ext/List/Util/README ext/List/Util/Util.xs
+          + ext/List/Util/lib/List/Util.pm
+          + ext/List/Util/lib/Scalar/Util.pm t/lib/u-blessed.t
+          + t/lib/u-dualvar.t t/lib/u-first.t t/lib/u-max.t
+          + t/lib/u-maxstr.t t/lib/u-min.t t/lib/u-minstr.t
+          + t/lib/u-readonly.t t/lib/u-reduce.t t/lib/u-reftype.t
+          + t/lib/u-sum.t t/lib/u-tainted.t t/lib/u-weak.t
+          ! MANIFEST
+____________________________________________________________________________
+[  9701] By: jhi                                   on 2001/04/14  15:05:25
+        Log: Subject: RE: dprofpp.pl updates 
+             From: Carl Eklof <CEklof@endeca.com>
+             Date: Thu, 12 Apr 2001 18:45:46 -0400
+             Message-ID: <D99914D9109BD411823800508BD957180E1269@exch01.ops.endeca.com>
+     Branch: perl
+          ! utils/dprofpp.PL
+____________________________________________________________________________
+[  9700] By: jhi                                   on 2001/04/14  14:44:55
+        Log: Do not just blindly add CR.
+     Branch: perl
+          ! Porting/makerel
+____________________________________________________________________________
+[  9699] By: jhi                                   on 2001/04/13  13:17:01
+        Log: Update Changes.
+     Branch: perl
+          ! Changes patchlevel.h
+____________________________________________________________________________
+[  9698] By: jhi                                   on 2001/04/13  12:44:48
+        Log: Integrate perlio.
+     Branch: perl
+         !> ext/PerlIO/Scalar/Scalar.xs
+____________________________________________________________________________
+[  9697] By: jhi                                   on 2001/04/13  12:29:15
+        Log: Add more debug output to the test.
+     Branch: perl
+          ! t/lib/cwd.t
+____________________________________________________________________________
+[  9696] By: nick                                  on 2001/04/13  10:14:29
+        Log: Fix core dump on binmode($fh,'Scalar')
+     Branch: perlio
+          ! ext/PerlIO/Scalar/Scalar.xs
+____________________________________________________________________________
+[  9695] By: nick                                  on 2001/04/13  09:05:42
+        Log: Integrate mainline
+     Branch: perlio
+         +> ext/Time/HiRes/Changes ext/Time/HiRes/HiRes.pm
+         +> ext/Time/HiRes/HiRes.xs ext/Time/HiRes/Makefile.PL
+         +> t/lib/time-hires.t
+         !> AUTHORS MANIFEST Makefile.SH Todo-5.6 configure.com
+         !> ext/Digest/MD5/MD5.xs ext/File/Glob/Glob.pm
+         !> ext/File/Glob/Glob.xs ext/File/Glob/bsd_glob.c
+         !> ext/File/Glob/bsd_glob.h ext/MIME/Base64/Base64.xs
+         !> hints/uts.sh hints/vmesa.sh lib/Devel/SelfStubber.pm opcode.pl
+         !> pod/perlfaq5.pod pp.c regexec.c t/comp/proto.t
+         !> t/lib/md5-file.t t/op/pat.t win32/Makefile win32/makefile.mk
+____________________________________________________________________________
+[  9694] By: jhi                                   on 2001/04/12  22:23:35
+        Log: Integrate change #9693 from maintperl into mainline.
+             
+             $VERSION and Version() on the same line provokes a warning from
+             CPAN.pm (from Jonathan Leffler <jleffler@informix.com>)
+     Branch: perl
+         !> lib/Devel/SelfStubber.pm
+____________________________________________________________________________
+[  9693] By: gsar                                  on 2001/04/12  21:55:56
+        Log: $VERSION and Version() on the same line provokes a warning from
+             CPAN.pm (from Jonathan Leffler <jleffler@informix.com>)
+     Branch: maint-5.6/perl
+          ! lib/Devel/SelfStubber.pm
+____________________________________________________________________________
+[  9692] By: jhi                                   on 2001/04/12  13:54:00
+        Log: This is at least 5.005.
+     Branch: perl
+          ! ext/Time/HiRes/HiRes.xs
+____________________________________________________________________________
+[  9691] By: jhi                                   on 2001/04/12  13:37:20
+        Log: Non-UNIX platforms extensions update.  (Well, UTS is UNIX.)
+     Branch: perl
+          ! Makefile.SH configure.com hints/uts.sh hints/vmesa.sh
+          ! win32/Makefile win32/makefile.mk
+____________________________________________________________________________
+[  9690] By: jhi                                   on 2001/04/12  01:34:46
+        Log: Integrate Time::Hires 1.20 from Douglas E. Wegscheid.
+     Branch: perl
+          + ext/Time/HiRes/Changes ext/Time/HiRes/HiRes.pm
+          + ext/Time/HiRes/HiRes.xs ext/Time/HiRes/Makefile.PL
+          + t/lib/time-hires.t
+          ! MANIFEST
+____________________________________________________________________________
+[  9689] By: jhi                                   on 2001/04/12  00:28:39
+        Log: Subject: [PATCH] Digest::MD5 on UTF8 strings
+             From: Gisle Aas <gisle@ActiveState.com>
+             Date: 11 Apr 2001 16:36:11 -0700
+             Message-ID: <lrlmp7102c.fsf@caliper.ActiveState.com>
+     Branch: perl
+          ! ext/Digest/MD5/MD5.xs t/lib/md5-file.t
+____________________________________________________________________________
+[  9688] By: jhi                                   on 2001/04/12  00:27:39
+        Log: Subject: Re: [PATCH] [ID 20010410.001] Not OK: perl v5.7.1 on i386-freebsd 4.3-rc (UNINSTALLED)
+             From: Gisle Aas <gisle@ActiveState.com>
+             Date: 11 Apr 2001 11:13:24 -0700
+             Message-ID: <lrbsq371a3.fsf@caliper.ActiveState.com>
+     Branch: perl
+          ! ext/MIME/Base64/Base64.xs
+____________________________________________________________________________
+[  9687] By: jhi                                   on 2001/04/11  19:51:47
+        Log: Slight update on the Todo list.  (Should integrate to Todo?) 
+     Branch: perl
+          ! Todo-5.6
+____________________________________________________________________________
+[  9686] By: jhi                                   on 2001/04/11  16:54:25
+        Log: Subject: [PATCH opcode.pl] Documentation of table format
+             From: Simon Cozens <simon@netthink.co.uk>
+             Date: Wed, 11 Apr 2001 12:59:31 +0100
+             Message-ID: <20010411125931.A25681@netthink.co.uk>
+     Branch: perl
+          ! opcode.pl
+____________________________________________________________________________
+[  9685] By: jhi                                   on 2001/04/11  16:53:15
+        Log: Subject: [PATCH] prototype("CORE::recv")
+             From: Simon Cozens <simon@netthink.co.uk>
+             Date: Wed, 11 Apr 2001 13:24:35 +0100
+             Message-ID: <20010411132435.A26169@netthink.co.uk>
+     Branch: perl
+          ! pp.c t/comp/proto.t
+____________________________________________________________________________
+[  9684] By: jhi                                   on 2001/04/11  16:47:13
+        Log: FAQ (and AUTHORS) update from Dan Carson: the information
+             was several years obsolete, Term::Readkey has been updated
+             to have the functionality.
+     Branch: perl
+          ! AUTHORS pod/perlfaq5.pod
+____________________________________________________________________________
+[  9683] By: jhi                                   on 2001/04/11  12:15:46
+        Log: Subject: Re: [PATCH] [ID 20010410.001] Not OK: perl v5.7.1 on i386-freebsd 4.3-rc (UNINSTALLED)
+             From: Calle Dybedahl <calle@lysator.liu.se>
+             Date: 10 Apr 2001 16:44:16 +0200
+             Message-ID: <86d7akbyrj.fsf@tezcatlipoca.algonet.se>
+     Branch: perl
+          ! ext/MIME/Base64/Base64.xs
+____________________________________________________________________________
+[  9682] By: jhi                                   on 2001/04/11  12:12:26
+        Log: A more minimal fix for 20010410.006 from Hugo.
+     Branch: perl
+          ! regexec.c
+____________________________________________________________________________
+[  9681] By: jhi                                   on 2001/04/11  11:34:23
+        Log: Integrate changes #9678,9679 from maintline into mainperl.
+             
+             addendum to change#9676
+             
+             up $File::Glob::VERSION; add a note pointing out the version of
+             the OpenBSD glob bsd_glob.c resembles
+     Branch: perl
+         !> ext/File/Glob/Glob.pm ext/File/Glob/bsd_glob.c
+         !> ext/File/Glob/bsd_glob.h
+____________________________________________________________________________
+[  9680] By: jhi                                   on 2001/04/11  11:30:38
+        Log: Bad test numbering in integrate in #9677.
+             Fixes ID 20010411.001.
+     Branch: perl
+          ! t/op/pat.t
+____________________________________________________________________________
+[  9679] By: gsar                                  on 2001/04/11  03:38:40
+        Log: up $File::Glob::VERSION; add a note pointing out the version of
+             the OpenBSD glob bsd_glob.c resembles
+     Branch: maint-5.6/perl
+          ! ext/File/Glob/Glob.pm ext/File/Glob/bsd_glob.c
+          ! ext/File/Glob/bsd_glob.h
+____________________________________________________________________________
+[  9678] By: gsar                                  on 2001/04/11  03:09:48
+        Log: addendum to change#9676: some missing changes from OpenBSD glob.c
+             revision 1.8.10.1 found here:
+             
+             http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gen/glob.c
+     Branch: maint-5.6/perl
+          ! ext/File/Glob/bsd_glob.c
+____________________________________________________________________________
+[  9677] By: jhi                                   on 2001/04/11  02:54:39
+        Log: Integrate changes #9675,9676 from maintperl into mainline.
+             
+             fix for bug 20010410.006, undo change#7115
+             
+             port the OpenBSD glob() security patch
+     Branch: perl
+         !> ext/File/Glob/Glob.pm ext/File/Glob/Glob.xs
+         !> ext/File/Glob/bsd_glob.c ext/File/Glob/bsd_glob.h regexec.c
+         !> t/op/pat.t
+____________________________________________________________________________
+[  9676] By: gsar                                  on 2001/04/11  02:19:02
+        Log: port the glob() security patch found at:
+             
+             ftp://ftp.openbsd.org/pub/OpenBSD/patches/2.8/common/025_glob.patch
+             
+             CERT advisory for the issue is here:
+             
+             http://www.cert.org/advisories/CA-2001-07.html
+             
+             Note that the security scare is only relevant for those who are
+             foolish enough to build suidperl (which is now officially discouraged)
+     Branch: maint-5.6/perl
+          ! ext/File/Glob/Glob.pm ext/File/Glob/Glob.xs
+          ! ext/File/Glob/bsd_glob.c ext/File/Glob/bsd_glob.h
+____________________________________________________________________________
+[  9675] By: gsar                                  on 2001/04/10  23:52:11
+        Log: fix for bug 20010410.006
+             
+             undo change#7115 (came into maint-5.6 as change#8156)
+             
+             add tests to keep it from coming back
+     Branch: maint-5.6/perl
+          ! regexec.c t/op/pat.t
+____________________________________________________________________________
+[  9674] By: nick                                  on 2001/04/10  20:39:31
+        Log: Integrate mainline
+     Branch: perlio
+         +> Porting/testall.atom
+         !> MANIFEST t/lib/lc-all.t t/lib/lc-constants.t
+         !> t/lib/lc-country.t t/lib/lc-currency.t t/lib/lc-language.t
+         !> t/lib/lc-uk.t t/pod/find.t
+____________________________________________________________________________
+[  9673] By: nick                                  on 2001/04/10  18:46:14
+        Log: Integrate against change 9670 aka perl-5.7.1
+     Branch: perlio
+         +> jpl/ChangeLog jpl/README.JUST-JNI jpl/docs/Tutorial.pod
+         !> (integrate 53 files)
+____________________________________________________________________________
+[  9672] By: jhi                                   on 2001/04/10  13:45:01
+        Log: Add a script for doing cumulative profile of the test suite.
+             (Requires ATOM, that is, Tru64.)
+     Branch: perl
+          + Porting/testall.atom
+          ! MANIFEST
+____________________________________________________________________________
+[  9671] By: jhi                                   on 2001/04/10  12:38:53
+        Log: Missing std block.
+     Branch: perl
+          ! t/lib/lc-all.t t/lib/lc-constants.t t/lib/lc-country.t
+          ! t/lib/lc-currency.t t/lib/lc-language.t t/lib/lc-uk.t
+          ! t/pod/find.t
+____________________________________________________________________________
+[  9670] By: jhi                                   on 2001/04/10  01:25:58
+        Log: This is 5.7.1.
+     Branch: perl
+          ! patchlevel.h
+____________________________________________________________________________
+[  9669] By: jhi                                   on 2001/04/10  01:09:14
+        Log: Update Changes.
+     Branch: perl
+          ! Changes patchlevel.h
+____________________________________________________________________________
 [  9668] By: jhi                                   on 2001/04/10  01:00:38
         Log: Regen toc.
      Branch: perl
index a9196bb..d12e44e 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -363,6 +363,12 @@ ext/IPC/SysV/hints/cygwin.pl       Hint for IPC::SysV for named architecture
 ext/IPC/SysV/hints/next_3.pl   Hint for IPC::SysV for named architecture
 ext/IPC/SysV/t/msg.t           IPC::SysV extension Perl module
 ext/IPC/SysV/t/sem.t           IPC::SysV extension Perl module
+ext/List/Util/ChangeLog        Util extension
+ext/List/Util/Makefile.PL      Util extension
+ext/List/Util/README           Util extension
+ext/List/Util/Util.xs  Util extension
+ext/List/Util/lib/List/Util.pm List::Util
+ext/List/Util/lib/Scalar/Util.pm       Scalar::Util
 ext/MIME/Base64/Base64.pm      MIME::Base64 extension
 ext/MIME/Base64/Base64.xs      MIME::Base64 extension
 ext/MIME/Base64/Changes                MIME::Base64 extension
@@ -1474,6 +1480,7 @@ t/lib/english.t           See if English works
 t/lib/env-array.t      See if Env works for arrays
 t/lib/env.t            See if Env works
 t/lib/errno.t          See if Errno works
+t/lib/exporter.t        See if Exporter works
 t/lib/fatal.t           See if Fatal works
 t/lib/fields.t          See if base/fields works
 t/lib/filecache.t      See if FileCache works
@@ -1608,6 +1615,19 @@ t/lib/tie-substrhash.t   Test for Tie::SubstrHash
 t/lib/time-hires.t     Time::HiRes
 t/lib/timelocal.t      See if Time::Local works
 t/lib/trig.t           See if Math::Trig works
+t/lib/u-blessed.t      Scalar::Util
+t/lib/u-dualvar.t      Scalar::Util
+t/lib/u-first.t                List::Util
+t/lib/u-max.t          List::Util
+t/lib/u-maxstr.t       List::Util
+t/lib/u-min.t          List::Util
+t/lib/u-minstr.t       List::Util
+t/lib/u-readonly.t     Scalar::Util
+t/lib/u-reduce.t       List::Util
+t/lib/u-reftype.t      Scalar::Util
+t/lib/u-sum.t          List::Util
+t/lib/u-tainted.t      Scalar::Util
+t/lib/u-weak.t         Scalar::Util
 t/lib/xs-typemap.t     test that typemaps work
 t/op/64bitint.t                See if 64 bit integers work
 t/op/anonsub.t         See if anonymous subroutines work
index 138fffa..4c50085 100644 (file)
@@ -141,7 +141,7 @@ my @crlf = qw(
     win32/Makefile
     win32/makefile.mk
 );
-system("perl -pi -e 's/\$/\\r/' @crlf");
+system("perl -pi -e 's/\015*\012/\015\012/' @crlf");
 print "\n";
 
 chdir ".." or die $!;
index 7ee1d19..a33ff2b 100644 (file)
@@ -66,7 +66,12 @@ sub B::GV::SAFENAME {
   # The regex below corresponds to the isCONTROLVAR macro
   # from toke.c
 
-  $name =~ s/^([\cA-\cZ\c\\c[\c]\c?\c_\c^])/"^".chr(64 ^ ord($1))/e;
+  $name =~ s/^([\cA-\cZ\c\\c[\c]\c?\c_\c^])/"^".
+       chr( utf8::unicode_to_native( 64 ^ ord($1) ))/e;
+
+  # When we say unicode_to_native we really mean ascii_to_native,
+  # which matters iff this is a non-ASCII platform (EBCDIC).
+
   return $name;
 }
 
index cb352eb..dd37ecc 100644 (file)
@@ -283,7 +283,7 @@ $priv{$_}{16} = "TARGMY"
        "link", "symlink", "mkdir", "rmdir", "wait", "waitpid", "system",
        "exec", "kill", "getppid", "getpgrp", "setpgrp", "getpriority",
        "setpriority", "time", "sleep");
-@{$priv{"const"}}{8,16,32,64,128} = ("STRICT","ENTERED", "$[", "BARE", "WARN");
+@{$priv{"const"}}{8,16,32,64,128} = ("STRICT","ENTERED", '$[', "BARE", "WARN");
 $priv{"flip"}{64} = $priv{"flop"}{64} = "LINENUM";
 $priv{"list"}{64} = "GUESSED";
 $priv{"delete"}{64} = "SLICE";
@@ -339,7 +339,16 @@ sub concise_op {
     $h{svclass} = $h{svaddr} = $h{svval} = "";
     if ($h{class} eq "PMOP") {
        my $precomp = $op->precomp;
-       $precomp = defined($precomp) ? "/$precomp/" : "";
+       if (defined $precomp) {
+           # Escape literal control sequences
+           for ($precomp) {
+               s/\t/\\t/g; s/\n/\\n/g; s/\r/\\r/g;
+               # How can we do the below portably?
+               #s/([\0-\037\177-\377])/"\\".sprintf("%03o", ord($1))/eg;
+           }
+           $precomp = "/$precomp/";
+       }
+       else { $precomp = ""; }
        my $pmreplroot = $op->pmreplroot;
        my ($pmreplroot, $pmreplstart);
        if ($ {$pmreplroot = $op->pmreplroot} && $pmreplroot->isa("B::GV")) {
index d08ccac..02a271b 100644 (file)
@@ -8,11 +8,12 @@
 
 package B::Deparse;
 use Carp 'cluck', 'croak';
-use B qw(class main_root main_start main_cv svref_2object opnumber
+use B qw(class main_root main_start main_cv svref_2object opnumber cstring
         OPf_WANT OPf_WANT_VOID OPf_WANT_SCALAR OPf_WANT_LIST
         OPf_KIDS OPf_REF OPf_STACKED OPf_SPECIAL
         OPpLVAL_INTRO OPpENTERSUB_AMPER OPpSLICE OPpCONST_BARE
         OPpTRANS_SQUASH OPpTRANS_DELETE OPpTRANS_COMPLEMENT OPpTARGET_MY
+        OPpCONST_ARYBASE
         SVf_IOK SVf_NOK SVf_ROK SVf_POK
          CVf_METHOD CVf_LOCKED CVf_LVALUE
         PMf_KEEP PMf_GLOBAL PMf_CONTINUE PMf_EVAL PMf_ONCE
@@ -355,6 +356,8 @@ sub new {
     $self->{'linenums'} = 0;
     $self->{'parens'} = 0;
     $self->{'ex_const'} = "'???'";
+    $self->{'arybase'} = 0;
+    $self->{'warnings'} = "\0"x12;
     while (my $arg = shift @_) {
        if (substr($arg, 0, 2) eq "-u") {
            $self->stash_subs(substr($arg, 2));
@@ -406,6 +409,8 @@ sub deparse {
 #    cluck if class($op) eq "NULL";
 #    cluck unless $op;
 #    return $self->$ {\("pp_" . $op->name)}($op, $cx);
+require Carp;
+Carp::confess() unless defined $op;
     my $meth = "pp_" . $op->name;
     return $self->$meth($op, $cx);
 }
@@ -725,6 +730,7 @@ sub lineseq {
        $expr .= $self->deparse($ops[$i], 0);
        push @exprs, $expr if length $expr;
     }
+    for(@exprs[0..@exprs-1]) { s/;\n\z// }
     return join(";\n", @exprs);
 }
 
@@ -760,7 +766,8 @@ sub scopeop {
     if ($cx > 0) { # inside an expression, (a do {} while for lineseq)
        return "do { " . $self->lineseq(@kids) . " }";
     } else {
-       return $self->lineseq(@kids) . ";";
+       my $lineseq = $self->lineseq(@kids);
+       return (length ($lineseq) ? "$lineseq;" : "");
     }
 }
 
@@ -812,6 +819,28 @@ sub pp_nextstate {
        push @text, "\f#line " . $op->line . 
          ' "' . $op->file, qq'"\n';
     }
+    if ($self->{'arybase'} != $op->arybase) {
+       push @text, '$[ = '. $op->arybase .";\n";
+       $self->{'arybase'} = $op->arybase;
+    }
+
+    my $warnings = $op->warnings;
+    my $warning_bits;
+    if ($warnings->isa("B::SPECIAL") && $$warnings == 4) {
+       $warning_bits = $warnings::Bits{"all"};
+    }
+    elsif ($warnings->isa("B::SPECIAL")) {
+        $warning_bits = "\0"x12;
+    }
+    else {
+       $warning_bits = $warnings->PV;
+    }
+
+    if ($self->{'warnings'} ne $warning_bits) {
+       push @text, 'BEGIN {${^WARNING_BITS} = '. cstring($warning_bits) ."}\n";
+       $self->{'warnings'} = $warning_bits;
+    }
+
     return join("", @text);
 }
 
@@ -1822,6 +1851,7 @@ sub loop_common {
              $self->deparse($cont, 0) . "\n\b}\cK";
        }
     } else {
+       return "" if !defined $body;
        $cont = "\cK";
        $body = $self->deparse($body, 0);
     }
@@ -1938,7 +1968,8 @@ sub pp_aelemfast {
     my $self = shift;
     my($op, $cx) = @_;
     my $gv = $self->gv_or_padgv($op);
-    return "\$" . $self->gv_name($gv) . "[" . $op->private . "]";
+    return "\$" . $self->gv_name($gv) . "[" .
+                 ($op->private + $self->{'arybase'}) . "]";
 }
 
 sub rv2x {
@@ -2019,6 +2050,25 @@ sub elem {
            $left . $self->deparse($idx, 1) . $right;
     }
     $idx = $self->deparse($idx, 1);
+
+    # Outer parens in an array index will confuse perl
+    # if we're interpolating in a regular expression, i.e.
+    # /$x$foo[(-1)]/ is *not* the same as /$x$foo[-1]/
+    #
+    # If $self->{parens}, then an initial '(' will
+    # definitely be paired with a final ')'. If
+    # !$self->{parens}, the misleading parens won't
+    # have been added in the first place.
+    #
+    # [You might think that we could get "(...)...(...)"
+    # where the initial and final parens do not match
+    # each other. But we can't, because the above would
+    # only happen if there's an infix binop between the
+    # two pairs of parens, and *that* means that the whole
+    # expression would be parenthesized as well.]
+    #
+    $idx =~ s/^\((.*)\)$/$1/ if $self->{'parens'};
+
     return "\$" . $array . $left . $idx . $right;
 }
 
@@ -2377,11 +2427,13 @@ sub const {
     my $sv = shift;
     if (class($sv) eq "SPECIAL") {
        return ('undef', '1', '0')[$$sv-1]; # sv_undef, sv_yes, sv_no
+    } elsif (class($sv) eq "NULL") {
+       return 'undef';
     } elsif ($sv->FLAGS & SVf_IOK) {
        return $sv->int_value;
     } elsif ($sv->FLAGS & SVf_NOK) {
        return $sv->NV;
-    } elsif ($sv->FLAGS & SVf_ROK) {
+    } elsif ($sv->FLAGS & SVf_ROK && $sv->can("RV")) {
        return "\\(" . const($sv->RV) . ")"; # constant folded
     } else {
        my $str = $sv->PV;
@@ -2410,6 +2462,9 @@ sub pp_const {
 #    }
     my $sv = $self->const_sv($op);
 #    return const($sv);
+    if ($op->private & OPpCONST_ARYBASE) {
+       return '$[';
+    }
     my $c = const $sv; 
     return $c =~ /^-\d/ ? $self->maybe_parens($c, $cx, 21) : $c;
 }
index 2ef91ed..338d803 100644 (file)
@@ -4,18 +4,28 @@ use Carp;
 
 sub import {
     my ($class, $backend, @options) = @_;
-    eval "use B::$backend ()";
-    if ($@) {
-       croak "use of backend $backend failed: $@";
-    }
-    my $compilesub = &{"B::${backend}::compile"}(@options);
-    if (ref($compilesub) eq "CODE") {
-       minus_c;
-       save_BEGINs;
-       eval 'CHECK { &$compilesub() }';
-    } else {
-       die $compilesub;
-    }
+    eval q[
+       BEGIN {
+           minus_c;
+           save_BEGINs;
+       }
+
+       CHECK {
+           use B::].$backend.q[ ();
+           if ($@) {
+               croak "use of backend $backend failed: $@";
+           }
+
+
+           my $compilesub = &{"B::${backend}::compile"}(@options);
+           if (ref($compilesub) ne "CODE") {
+               die $compilesub;
+           }
+
+           &$compilesub();
+       }
+    ];
+    die $@ if $@;
 }
 
 1;
index ef9ca30..0ea502a 100644 (file)
@@ -95,16 +95,20 @@ static char sscsid[]=  "$OpenBSD: glob.c,v 1.8.10.1 2001/04/10 jason Exp $";
 #endif
 
 #ifndef ARG_MAX
-#  ifdef _SC_ARG_MAX
-#    define    ARG_MAX         (sysconf(_SC_ARG_MAX))
+#  ifdef MACOS_TRADITIONAL
+#    define            ARG_MAX         65536   /* Mac OS is actually unlimited */
 #  else
-#    ifdef _POSIX_ARG_MAX
-#      define  ARG_MAX         _POSIX_ARG_MAX
+#    ifdef _SC_ARG_MAX
+#      define          ARG_MAX         (sysconf(_SC_ARG_MAX))
 #    else
-#      ifdef WIN32
-#        define        ARG_MAX         14500   /* from VC's limits.h */
+#      ifdef _POSIX_ARG_MAX
+#        define                ARG_MAX         _POSIX_ARG_MAX
 #      else
-#        define        ARG_MAX         4096    /* from POSIX, be conservative */
+#        ifdef WIN32
+#          define      ARG_MAX         14500   /* from VC's limits.h */
+#        else
+#          define      ARG_MAX         4096    /* from POSIX, be conservative */
+#        endif
 #      endif
 #    endif
 #  endif
@@ -492,7 +496,7 @@ glob0(const Char *pattern, glob_t *pglob)
 
 #ifdef MACOS_TRADITIONAL
        if ( (*pattern == BG_TILDE) && (pglob->gl_flags & GLOB_TILDE) ) {
-               return(globextend(pattern, pglob));
+               return(globextend(pattern, pglob, &limit));
        }
 #endif
 
diff --git a/ext/List/Util/ChangeLog b/ext/List/Util/ChangeLog
new file mode 100644 (file)
index 0000000..bd9814c
--- /dev/null
@@ -0,0 +1,85 @@
+Change 482 on 2000/04/10 by <gbarr@pobox.com> (Graham Barr)
+
+       Check for SvMAGICAL on argument for reftype and blessed
+
+Change 366 on 2000/03/03 by <gbarr@pobox.com> (Graham Barr)
+
+       Release 1.01
+
+Change 365 on 2000/03/03 by <gbarr@pobox.com> (Graham Barr)
+
+       - Added auto-detection for a compiler and install the perl version
+         if not found
+       - Better perl implemenation of reftype, should be thread-safe now
+
+Change 364 on 2000/03/03 by <gbarr@pobox.com> (Graham Barr)
+
+       - Added some examples of simple subs that have been requested
+         but not added
+       - Updated copyright dates
+
+Change 344 on 1999/11/10 by <gbarr@pobox.com> (Graham Barr)
+
+       - Better testcase for reftype
+
+Change 343 on 1999/11/10 by <gbarr@pobox.com> (Graham Barr)
+
+       - Modules are now called List::Util & Scalar::Util
+       - Supports non-XS install
+       - perl version of reftype now returns "REF" when it should
+
+Change 311 on 1999/06/01 by <gbarr@pobox.com> (Graham Barr)
+
+       Updated README
+
+Change 275 on 1999/03/22 by <gbarr@pobox.com> (Graham Barr)
+
+       Removed forall as it is very broken
+
+Change 274 on 1999/03/22 by <gbarr@pobox.com> (Graham Barr)
+
+       Added List::Util::forall
+
+Change 273 on 1999/03/21 by <gbarr@pobox.com> (Graham Barr)
+
+       Added weaken and isweak to Ref::Util
+
+Change 272 on 1999/03/21 by <gbarr@pobox.com> (Graham Barr)
+
+       Add new .pm files to repository
+
+Change 271 on 1999/03/21 by <gbarr@pobox.com> (Graham Barr)
+
+       - Split into three packages Ref::Util, List::Util and Scalar::DualVar
+       - readonly and clock were removed in favor of other modules
+
+Change 270 on 1999/03/21 by <gbarr@pobox.com> (Graham Barr)
+
+       Rename package
+
+Change 269 on 1999/03/21 by <gbarr@pobox.com> (Graham Barr)
+
+       - Added reftype
+       - improved reduce by not doing a sub call
+       - reduce now uses $a and $b
+       - now compiles with 5.005_5x
+
+Change 178 on 1998/07/26 by <gbarr@pobox.com> (Graham Barr)
+
+       Modified XS code so it will compile with 5.004 and 5.005
+
+Change 115 on 1998/02/21 by <gbarr@pobox.com> (Graham Barr)
+
+       Fri Feb 20 1998 Graham Barr <gbarr@pobox.com>
+       
+       t/min.t, t/max.t
+       - Change sor to do a numerical sort
+       
+       Fri Dec 19 1997 Graham Barr <gbarr@pobox.com>
+       
+       - Added readonly()
+       
+       Wed Nov 19 1997 Graham Barr <gbarr@pobox.com>
+       
+       - Initial release
+
diff --git a/ext/List/Util/Makefile.PL b/ext/List/Util/Makefile.PL
new file mode 100644 (file)
index 0000000..079437b
--- /dev/null
@@ -0,0 +1,7 @@
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+    VERSION_FROM    => "lib/List/Util.pm",
+    NAME            => "List::Util",
+);
+
diff --git a/ext/List/Util/README b/ext/List/Util/README
new file mode 100644 (file)
index 0000000..086af5e
--- /dev/null
@@ -0,0 +1,31 @@
+This distribution is a replacement for the builtin distribution.
+
+This package contains a selection of subroutines that people have
+expressed would be nice to have in the perl core, but the usage would not
+really be high enough to warrant the use of a keyword, and the size so
+small such that being individual extensions would be wasteful.
+
+After unpacking the distribution, to install this module type
+        perl Makefile.PL
+        make
+        make test
+        make install
+
+This distribution provides
+
+  min
+  max
+  minstr
+  maxstr
+  sum
+  reduce
+  reftype
+  blessed
+  weaken   (5.005_57 and later only)
+  isweak   (5.005_57 and later only)
+  dualvar
+
+Copyright (c) 1997-2000 Graham Barr <gbarr@pobox.com>. All rights reserved.
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
diff --git a/ext/List/Util/Util.xs b/ext/List/Util/Util.xs
new file mode 100644 (file)
index 0000000..1e6d8f6
--- /dev/null
@@ -0,0 +1,340 @@
+/* Copyright (c) 1997-2000 Graham Barr <gbarr@pobox.com>. All rights reserved.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the same terms as Perl itself.
+ */
+
+#include <EXTERN.h>
+#include <perl.h>
+#include <XSUB.h>
+#include <patchlevel.h>
+
+#if PATCHLEVEL < 5
+#  ifndef gv_stashpvn
+#    define gv_stashpvn(n,l,c) gv_stashpv(n,c)
+#  endif
+#  ifndef SvTAINTED
+
+static bool
+sv_tainted(SV *sv)
+{
+    if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
+       MAGIC *mg = mg_find(sv, 't');
+       if (mg && ((mg->mg_len & 1) || (mg->mg_len & 2) && mg->mg_obj == sv))
+           return TRUE;
+    }
+    return FALSE;
+}
+
+#    define SvTAINTED_on(sv) sv_magic((sv), Nullsv, 't', Nullch, 0)
+#    define SvTAINTED(sv) (SvMAGICAL(sv) && sv_tainted(sv))
+#  endif
+#  define PL_defgv defgv
+#  define PL_op op
+#  define PL_curpad curpad
+#  define CALLRUNOPS runops
+#  define PL_curpm curpm
+#  define PL_sv_undef sv_undef
+#  define PERL_CONTEXT struct context
+#endif
+#if (PATCHLEVEL < 5) || (PATCHLEVEL == 5 && SUBVERSION <50)
+#  ifndef PL_tainting
+#    define PL_tainting tainting
+#  endif
+#  ifndef PL_stack_base
+#    define PL_stack_base stack_base
+#  endif
+#  ifndef PL_stack_sp
+#    define PL_stack_sp stack_sp
+#  endif
+#  ifndef PL_ppaddr
+#    define PL_ppaddr ppaddr
+#  endif
+#endif
+
+MODULE=List::Util      PACKAGE=List::Util
+
+void
+min(...)
+PROTOTYPE: @
+ALIAS:
+    min = 0
+    max = 1
+CODE:
+{
+    int index;
+    NV retval;
+    SV *retsv;
+    if(!items) {
+       XSRETURN_UNDEF;
+    }
+    retsv = ST(0);
+    retval = SvNV(retsv);
+    for(index = 1 ; index < items ; index++) {
+       SV *stacksv = ST(index);
+       NV val = SvNV(stacksv);
+       if(val < retval ? !ix : ix) {
+           retsv = stacksv;
+           retval = val;
+       }
+    }
+    ST(0) = retsv;
+    XSRETURN(1);
+}
+
+
+
+NV
+sum(...)
+PROTOTYPE: @
+CODE:
+{
+    int index;
+    NV ret;
+    if(!items) {
+       XSRETURN_UNDEF;
+    }
+    RETVAL = SvNV(ST(0));
+    for(index = 1 ; index < items ; index++) {
+       RETVAL += SvNV(ST(index));
+    }
+}
+OUTPUT:
+    RETVAL
+
+
+void
+minstr(...)
+PROTOTYPE: @
+ALIAS:
+    minstr = 2
+    maxstr = 0
+CODE:
+{
+    SV *left;
+    int index;
+    if(!items) {
+       XSRETURN_UNDEF;
+    }
+    /*
+      sv_cmp & sv_cmp_locale return 1,0,-1 for gt,eq,lt
+      so we set ix to the value we are looking for
+      xsubpp does not allow -ve values, so we start with 0,2 and subtract 1
+    */
+    ix -= 1;
+    left = ST(0);
+#ifdef OPpLOCALE
+    if(MAXARG & OPpLOCALE) {
+       for(index = 1 ; index < items ; index++) {
+           SV *right = ST(index);
+           if(sv_cmp_locale(left, right) == ix)
+               left = right;
+       }
+    }
+    else {
+#endif
+       for(index = 1 ; index < items ; index++) {
+           SV *right = ST(index);
+           if(sv_cmp(left, right) == ix)
+               left = right;
+       }
+#ifdef OPpLOCALE
+    }
+#endif
+    ST(0) = left;
+    XSRETURN(1);
+}
+
+
+
+void
+reduce(block,...)
+    SV * block
+PROTOTYPE: &@
+CODE:
+{
+    SV *ret;
+    int index;
+    I32 markix;
+    GV *agv,*bgv,*gv;
+    HV *stash;
+    CV *cv;
+    OP *reducecop;
+    if(items <= 1) {
+       XSRETURN_UNDEF;
+    }
+    agv = gv_fetchpv("a", TRUE, SVt_PV);
+    bgv = gv_fetchpv("b", TRUE, SVt_PV);
+    SAVESPTR(GvSV(agv));
+    SAVESPTR(GvSV(bgv));
+    cv = sv_2cv(block, &stash, &gv, 0);
+    reducecop = CvSTART(cv);
+    SAVESPTR(CvROOT(cv)->op_ppaddr);
+    CvROOT(cv)->op_ppaddr = PL_ppaddr[OP_NULL];
+    SAVESPTR(PL_curpad);
+    PL_curpad = AvARRAY((AV*)AvARRAY(CvPADLIST(cv))[1]);
+    SAVETMPS;
+    SAVESPTR(PL_op);
+    ret = ST(1);
+    markix = sp - PL_stack_base;
+    for(index = 2 ; index < items ; index++) {
+       GvSV(agv) = ret;
+       GvSV(bgv) = ST(index);
+       PL_op = reducecop;
+       CALLRUNOPS(aTHX);
+       ret = *PL_stack_sp;
+    }
+    ST(0) = ret;
+    XSRETURN(1);
+}
+
+void
+first(block,...)
+    SV * block
+PROTOTYPE: &@
+CODE:
+{
+    SV *ret;
+    int index;
+    I32 markix;
+    GV *gv;
+    HV *stash;
+    CV *cv;
+    OP *reducecop;
+    if(items <= 1) {
+       XSRETURN_UNDEF;
+    }
+    SAVESPTR(GvSV(PL_defgv));
+    cv = sv_2cv(block, &stash, &gv, 0);
+    reducecop = CvSTART(cv);
+    SAVESPTR(CvROOT(cv)->op_ppaddr);
+    CvROOT(cv)->op_ppaddr = PL_ppaddr[OP_NULL];
+    SAVESPTR(PL_curpad);
+    PL_curpad = AvARRAY((AV*)AvARRAY(CvPADLIST(cv))[1]);
+    SAVETMPS;
+    SAVESPTR(PL_op);
+    markix = sp - PL_stack_base;
+    for(index = 1 ; index < items ; index++) {
+       GvSV(PL_defgv) = ST(index);
+       PL_op = reducecop;
+       CALLRUNOPS(aTHX);
+       if (SvTRUE(*PL_stack_sp)) {
+         ST(0) = ST(index);
+         XSRETURN(1);
+       }
+    }
+    XSRETURN_UNDEF;
+}
+
+MODULE=List::Util      PACKAGE=Scalar::Util
+
+void
+dualvar(num,str)
+    SV *       num
+    SV *       str
+PROTOTYPE: $$
+CODE:
+{
+    STRLEN len;
+    char *ptr = SvPV(str,len);
+    ST(0) = sv_newmortal();
+    SvUPGRADE(ST(0),SVt_PVNV);
+    sv_setpvn(ST(0),ptr,len);
+    if(SvNOKp(num) || !SvIOKp(num)) {
+       SvNVX(ST(0)) = SvNV(num);
+       SvNOK_on(ST(0));
+    }
+    else {
+       SvIVX(ST(0)) = SvIV(num);
+       SvIOK_on(ST(0));
+    }
+    if(PL_tainting && (SvTAINTED(num) || SvTAINTED(str)))
+       SvTAINTED_on(ST(0));
+    XSRETURN(1);
+}
+
+char *
+blessed(sv)
+    SV * sv
+PROTOTYPE: $
+CODE:
+{
+    if (SvMAGICAL(sv))
+       mg_get(sv);
+    if(!sv_isobject(sv)) {
+       XSRETURN_UNDEF;
+    }
+    RETVAL = sv_reftype(SvRV(sv),TRUE);
+}
+OUTPUT:
+    RETVAL
+
+char *
+reftype(sv)
+    SV * sv
+PROTOTYPE: $
+CODE:
+{
+    if (SvMAGICAL(sv))
+       mg_get(sv);
+    if(!SvROK(sv)) {
+       XSRETURN_UNDEF;
+    }
+    RETVAL = sv_reftype(SvRV(sv),FALSE);
+}
+OUTPUT:
+    RETVAL
+
+void
+weaken(sv)
+       SV *sv
+PROTOTYPE: $
+CODE:
+#ifdef SvWEAKREF
+       sv_rvweaken(sv);
+#else
+       croak("weak references are not implemented in this release of perl");
+#endif
+
+SV *
+isweak(sv)
+       SV *sv
+PROTOTYPE: $
+CODE:
+#ifdef SvWEAKREF
+       ST(0) = boolSV(SvROK(sv) && SvWEAKREF(sv));
+       XSRETURN(1);
+#else
+       croak("weak references are not implemented in this release of perl");
+#endif
+
+int
+readonly(sv)
+       SV *sv
+PROTOTYPE: $
+CODE:
+  RETVAL = SvREADONLY(sv);
+OUTPUT:
+  RETVAL
+
+int
+tainted(sv)
+       SV *sv
+PROTOTYPE: $
+CODE:
+  RETVAL = SvTAINTED(sv);
+OUTPUT:
+  RETVAL
+
+BOOT:
+{
+#ifndef SvWEAKREF
+    HV *stash = gv_stashpvn("Scalar::Util", 12, TRUE);
+    GV *vargv = *(GV**)hv_fetch(stash, "EXPORT_FAIL", 11, TRUE);
+    AV *varav;
+    if (SvTYPE(vargv) != SVt_PVGV)
+       gv_init(vargv, stash, "Scalar::Util", 12, TRUE);
+    varav = GvAVn(vargv);
+    av_push(varav, newSVpv("weaken",6));
+    av_push(varav, newSVpv("isweak",6));
+#endif
+}
diff --git a/ext/List/Util/lib/List/Util.pm b/ext/List/Util/lib/List/Util.pm
new file mode 100644 (file)
index 0000000..053134d
--- /dev/null
@@ -0,0 +1,229 @@
+# List::Util.pm
+#
+# Copyright (c) 1997-2000 Graham Barr <gbarr@pobox.com>. All rights reserved.
+# This program is free software; you can redistribute it and/or
+# modify it under the same terms as Perl itself.
+
+package List::Util;
+
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT_OK = qw(first min max minstr maxstr reduce sum);
+$VERSION = $VERSION = "1.02";
+
+eval {
+  require DynaLoader;
+  local @ISA = qw(DynaLoader);
+  bootstrap List::Util $VERSION;
+  1
+};
+
+eval <<'ESQ' unless defined &reduce;
+
+# This code is only compiled if the XS did not load
+
+use vars qw($a $b);
+
+sub reduce (&@) {
+  my $code = shift;
+
+  return shift unless @_ > 1;
+
+  my $caller = caller;
+  local(*{$caller."::a"}) = \my $a;
+  local(*{$caller."::b"}) = \my $b;
+
+  $a = shift;
+  foreach (@_) {
+    $b = $_;
+    $a = &{$code}();
+  }
+
+  $a;
+}
+
+sub sum (@) { reduce { $a + $b } @_ }
+
+sub min (@) { reduce { $a < $b ? $a : $b } @_ }
+
+sub max (@) { reduce { $a > $b ? $a : $b } @_ }
+
+sub minstr (@) { reduce { $a lt $b ? $a : $b } @_ }
+
+sub maxstr (@) { reduce { $a gt $b ? $a : $b } @_ }
+
+sub first (&@) {
+  my $code = shift;
+
+  foreach (@_) {
+    return $_ if &{$code}();
+  }
+
+  undef;
+}
+ESQ
+
+1;
+
+__END__
+
+=head1 NAME
+
+List::Util - A selection of general-utility list subroutines
+
+=head1 SYNOPSIS
+
+    use List::Util qw(first sum min max minstr maxstr reduce);
+
+=head1 DESCRIPTION
+
+C<List::Util> contains a selection of subroutines that people have
+expressed would be nice to have in the perl core, but the usage would
+not really be high enough to warrant the use of a keyword, and the size
+so small such that being individual extensions would be wasteful.
+
+By default C<List::Util> does not export any subroutines. The
+subroutines defined are
+
+=over 4
+
+=item first BLOCK LIST
+
+Similar to C<grep> in that it evaluates BLOCK setting C<$_> to each element
+of LIST in turn. C<first> returns the first element where the result from
+BLOCK is a true value. If BLOCK never returns true or LIST was empty then
+C<undef> is returned.
+
+    $foo = first { defined($_) } @list    # first defined value in @list
+    $foo = first { $_ > $value } @list    # first value in @list which
+                                          # is greater than $value
+    
+This function could be implemented using C<reduce> like this
+
+    $foo = reduce { defined($a) ? $a : wanted($b) ? $b : undef } undef, @list
+
+for example wanted() could be defined() which would return the first
+defined value in @list
+
+=item max LIST
+
+Returns the entry in the list with the highest numerical value. If the
+list is empty then C<undef> is returned.
+
+    $foo = max 1..10                # 10
+    $foo = max 3,9,12               # 12
+    $foo = max @bar, @baz           # whatever
+
+This function could be implemented using C<reduce> like this
+
+    $foo = reduce { $a > $b ? $a : $b } 1..10
+
+=item maxstr LIST
+
+Similar to C<max>, but treats all the entries in the list as strings
+and returns the highest string as defined by the C<gt> operator.
+If the list is empty then C<undef> is returned.
+    $foo = maxstr 'A'..'Z'                 # 'Z'
+    $foo = maxstr "hello","world"   # "world"
+    $foo = maxstr @bar, @baz        # whatever
+
+This function could be implemented using C<reduce> like this
+
+    $foo = reduce { $a gt $b ? $a : $b } 'A'..'Z'
+
+=item min LIST
+
+Similar to C<max> but returns the entry in the list with the lowest
+numerical value. If the list is empty then C<undef> is returned.
+
+    $foo = min 1..10                # 1
+    $foo = min 3,9,12               # 3
+    $foo = min @bar, @baz           # whatever
+
+This function could be implemented using C<reduce> like this
+
+    $foo = reduce { $a < $b ? $a : $b } 1..10
+
+=item minstr LIST
+
+Similar to C<min>, but treats all the entries in the list as strings
+and returns the lowest string as defined by the C<lt> operator.
+If the list is empty then C<undef> is returned.
+
+    $foo = maxstr 'A'..'Z'                 # 'A'
+    $foo = maxstr "hello","world"   # "hello"
+    $foo = maxstr @bar, @baz        # whatever
+
+This function could be implemented using C<reduce> like this
+
+    $foo = reduce { $a lt $b ? $a : $b } 'A'..'Z'
+
+=item reduce BLOCK LIST
+
+Reduces LIST by calling BLOCK multiple times, setting C<$a> and C<$b>
+each time. The first call will be with C<$a> and C<$b> set to the first
+two elements of the list, subsequent calls will be done by
+setting C<$a> to the result of the previous call and C<$b> to the next
+element in the list. 
+
+Returns the result of the last call to BLOCK. If LIST is empty then
+C<undef> is returned. If LIST only contains one element then that
+element is returned and BLOCK is not executed.
+
+    $foo = reduce { $a < $b ? $a : $b } 1..10       # min
+    $foo = reduce { $a lt $b ? $a : $b } 'aa'..'zz' # minstr
+    $foo = reduce { $a + $b } 1 .. 10               # sum
+    $foo = reduce { $a . $b } @bar                  # concat
+
+=item sum LIST
+
+Returns the sum of all the elements in LIST.
+
+    $foo = sum 1..10                # 55
+    $foo = sum 3,9,12               # 24
+    $foo = sum @bar, @baz           # whatever
+
+This function could be implemented using C<reduce> like this
+
+    $foo = reduce { $a + $b } 1..10
+
+=back
+
+=head1 SUGGESTED ADDITIONS
+
+The following are additions that have been requested, but I have been reluctant
+to add due to them being very simple to implement in perl
+
+  # One argument is true
+
+  sub any { $_ && return 1 for @_; 0 }
+
+  # All arguments are true
+
+  sub all { $_ || return 0 for @_; 1 }
+
+  # All arguments are false
+
+  sub none { $_ && return 0 for @_; 1 }
+
+  # One argument is false
+
+  sub notall { $_ || return 1 for @_; 0 }
+
+  # How many elements are true
+
+  sub true { scalar grep { $_ } @_ }
+
+  # How many elements are false
+
+  sub false { scalar grep { !$_ } @_ }
+
+=head1 COPYRIGHT
+
+Copyright (c) 1997-2000 Graham Barr <gbarr@pobox.com>. All rights reserved.
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
diff --git a/ext/List/Util/lib/Scalar/Util.pm b/ext/List/Util/lib/Scalar/Util.pm
new file mode 100644 (file)
index 0000000..ee65667
--- /dev/null
@@ -0,0 +1,169 @@
+# Scalar::Util.pm
+#
+# Copyright (c) 1997-2000 Graham Barr <gbarr@pobox.com>. All rights reserved.
+# This program is free software; you can redistribute it and/or
+# modify it under the same terms as Perl itself.
+
+package Scalar::Util;
+
+require Exporter;
+require List::Util; # List::Util loads the XS
+
+$VERSION = $VERSION = $List::Util::VERSION;
+@ISA = qw(Exporter);
+@EXPORT_OK = qw(blessed dualvar reftype weaken isweak tainted readonly);
+
+sub export_fail {
+  if (grep { /^(weaken|isweak)$/ } @_ ) {
+    require Carp;
+    Carp::croak("Weak references are not implemented in the version of perl");
+  }
+  if (grep { /^dualvar$/ } @_ ) {
+    require Carp;
+    Carp::croak("dualvar is only avaliable with the XS version");
+  }
+  
+  @_;
+}
+
+eval <<'ESQ' unless defined &dualvar;
+
+push @EXPORT_FAIL, qw(weaken isweak dualvar);
+
+# The code beyond here is only used if the XS is not installed
+
+# Hope nobody defines a sub by this name
+sub UNIVERSAL::a_sub_not_likely_to_be_here { ref($_[0]) }
+
+sub blessed ($) {
+  local($@, $SIG{__DIE__}, $SIG{__WARN__});
+  length(ref($_[0]))
+    ? eval { $_[0]->a_sub_not_likely_to_be_here }
+    : undef
+}
+
+sub reftype ($) {
+  local($@, $SIG{__DIE__}, $SIG{__WARN__});
+  my $r = shift;
+  my $t;
+
+  length($t = ref($r)) or return undef;
+
+  # This eval will fail if the reference is not blessed
+  eval { $r->a_sub_not_likely_to_be_here; 1 }
+    ? do {
+      $t = eval {
+         # we have a GLOB or an IO. Stringify a GLOB gives it's name
+         my $q = *$r;
+         $q =~ /^\*/ ? "GLOB" : "IO";
+       }
+       or do {
+         # OK, if we don't have a GLOB what parts of
+         # a glob will it populate.
+         # NOTE: A glob always has a SCALAR
+         local *glob = $r;
+         defined *glob{ARRAY} && "ARRAY"
+         or defined *glob{HASH} && "HASH"
+         or defined *glob{CODE} && "CODE"
+         or length(ref(${$r})) ? "REF" : "SCALAR";
+       }
+    }
+    : $t
+}
+
+sub tainted {
+  local($@, $SIG{__DIE__}, $SIG{__WARN__});
+  local $^W = 0;
+  eval { kill 0 * $_[0] };
+  $@ =~ /^Insecure/;
+}
+
+sub readonly {
+  return 0 if tied($_[0]) || (ref(\($_[0])) ne "SCALAR");
+
+  local($@, $SIG{__DIE__}, $SIG{__WARN__});
+  my $tmp = $_[0];
+
+  !eval { $_[0] = $tmp; 1 };
+}
+
+ESQ
+
+1;
+
+__END__
+
+=head1 NAME
+
+Scalar::Util - A selection of general-utility scalar subroutines
+
+=head1 SYNOPSIS
+
+    use Scalar::Util qw(blessed dualvar reftype weaken isweak);
+
+=head1 DESCRIPTION
+
+C<Scalar::Util> contains a selection of subroutines that people have
+expressed would be nice to have in the perl core, but the usage would
+not really be high enough to warrant the use of a keyword, and the size
+so small such that being individual extensions would be wasteful.
+
+By default C<Scalar::Util> does not export any subroutines. The
+subroutines defined are
+
+=over 4
+
+=item blessed EXPR
+
+If EXPR evaluates to a blessed reference the name of the package
+that it is blessed into is returned. Otherwise C<undef> is returned.
+
+=item dualvar NUM, STRING
+
+Returns a scalar that has the value NUM in a numeric context and the
+value STRING in a string context.
+
+    $foo = dualvar 10, "Hello";
+    $num = $foo + 2;                   # 12
+    $str = $foo . " world";            # Hello world
+
+=item isweak EXPR
+
+If EXPR is a scalar which is a weak reference the result is true.
+
+=item reftype EXPR
+
+If EXPR evaluates to a reference the type of the variable referenced
+is returned. Otherwise C<undef> is returned.
+
+=item weaken REF
+
+REF will be turned into a weak reference. This means that it will not
+hold a reference count on the object it references. Also when the reference
+count on that object reaches zero, REF will be set to undef.
+
+This is useful for keeping copies of references , but you don't want to
+prevent the object being DESTROY-ed at it's usual time.
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright (c) 1997-2000 Graham Barr <gbarr@pobox.com>. All rights reserved.
+This program is free software; you can redistribute it and/or modify it 
+under the same terms as Perl itself.
+
+except weaken and isweak which are
+
+Copyright (c) 1999 Tuomas J. Lukka <lukka@iki.fi>. All rights reserved.
+This program is free software; you can redistribute it and/or modify it
+under the same terms as perl itself.
+
+=head1 BLATANT PLUG
+
+The weaken and isweak subroutines in this module and the patch to the core Perl
+were written in connection  with the APress book `Tuomas J. Lukka's Definitive
+Guide to Object-Oriented Programming in Perl', to avoid explaining why certain
+things would have to be done in cumbersome ways.
+
+=cut
index 0bc152b..11848db 100644 (file)
@@ -1,21 +1,35 @@
 package Time::HiRes;
 
 use strict;
-use vars qw($VERSION @ISA @EXPORT @EXPORT_OK @EXPORT_FAIL);
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $AUTOLOAD);
 
 require Exporter;
-require DynaLoader;
+use XSLoader;
 
-@ISA = qw(Exporter DynaLoader);
+@ISA = qw(Exporter);
 
 @EXPORT = qw( );
-@EXPORT_OK = qw (usleep sleep ualarm alarm gettimeofday time tv_interval);
-
-$VERSION = do{my@r=q$Revision: 1.20 $=~/\d+/g;sprintf '%02d.'.'%02d'x$#r,@r};
-
-bootstrap Time::HiRes $VERSION;
+@EXPORT_OK = qw (usleep sleep ualarm alarm gettimeofday time tv_interval
+                getitimer setitimer ITIMER_REAL ITIMER_VIRTUAL ITIMER_PROF);
+
+$VERSION = '1.21';
+
+sub AUTOLOAD {
+    my $constname;
+    ($constname= $AUTOLOAD) =~ s/.*:://;
+    my $val = constant($constname, @_ ? $_[0] : 0);
+    if ($!) {
+       my ($pack,$file,$line) = caller;
+       die "Your vendor has not defined Time::HiRes macro $constname, used at $file line $line.\n";
+    }
+    {
+       no strict 'refs';
+       *$AUTOLOAD = sub { $val };
+    }
+    goto &$AUTOLOAD;
+}
 
-@EXPORT_FAIL = grep { ! defined &$_ } @EXPORT_OK;
+XSLoader::load 'Time::HiRes', $VERSION;
 
 # Preloaded methods go here.
 
@@ -26,14 +40,6 @@ sub tv_interval {
     (${$b}[0] - ${$a}[0]) + ((${$b}[1] - ${$a}[1]) / 1_000_000);
 }
 
-# I'm only supplying this because the version of it in 5.003's Export.pm
-# is buggy (it doesn't shift off the class name).
-
-sub export_fail {
-    my $self = shift;
-    @_;
-}
-
 # Autoload methods go after =cut, and are processed by the autosplit program.
 
 1;
@@ -60,11 +66,18 @@ Time::HiRes - High resolution ualarm, usleep, and gettimeofday
   $elapsed = tv_interval ( $t0 );
 
   use Time::HiRes qw ( time alarm sleep );
+
   $now_fractions = time;
   sleep ($floating_seconds);
   alarm ($floating_seconds);
   alarm ($floating_seconds, $floating_interval);
 
+  use Time::HiRes qw( setitimer getitimer
+                     ITIMER_REAL ITIMER_VIRTUAL ITIMER_PROF );
+
+  setitimer ($which, $floating_seconds, $floating_interval );
+  getitimer ($which);
+
 =head1 DESCRIPTION
 
 The C<Time::HiRes> module implements a Perl interface to the usleep, ualarm,
@@ -75,12 +88,12 @@ the underlying gettimeofday, usleep, and ualarm calls.
 If your system lacks gettimeofday(2) you don't get gettimeofday() or the
 one-arg form of tv_interval().  If you don't have usleep(3) or select(2)
 you don't get usleep() or sleep().  If your system don't have ualarm(3)
-or setitimer(2) you don't
-get ualarm() or alarm().  If you try to import an unimplemented function
-in the C<use> statement it will fail at compile time.
+or setitimer(2) you don't get ualarm() or alarm().
+If you try to import an unimplemented function in the C<use> statement
+it will fail at compile time.
 
-The following functions can be imported from this module.  No
-functions are exported by default.
+The following functions can be imported from this module.
+No functions are exported by default.
 
 =over 4
 
@@ -126,6 +139,52 @@ is optional and will be 0 if unspecified, resulting in alarm-like
 behaviour.  This function can be imported, resulting in a nice drop-in
 replacement for the C<alarm> provided with perl, see the EXAMPLES below.
 
+=item setitimer ( $which, $floating_seconds [, $interval_floating_seconds ] )
+
+Start up an interval timer: after a certain time, a signal is arrives,
+and more may keep arriving at certain intervals.  To disable a timer,
+use time of zero.  If interval is set to zero (or unspecified), the
+timer is disabled after the next delivered signal.
+
+Use of interval timers may interfere with alarm(), sleep(), and usleep().
+In standard-speak the "interaction is unspecified", which means that
+I<anything> may happen: it may work, it may not.
+
+In scalar context, the remaining time in the timer is returned.
+
+In list context, both the remaining time and the interval are returned.
+
+There are three interval timers: the $which can be ITIMER_REAL,
+ITIMER_VIRTUAL, or ITIMER_PROF.
+
+ITIMER_REAL results in alarm()-like behavior.  Time is counted in
+I<real time>, that is, wallclock time.  SIGALRM is delivered when
+the timer expires.
+
+ITIMER_VIRTUAL counts time in (process) I<virtual time>, that is, only
+when the process is running.  In multiprocessing/user/CPU systems this
+may be much less than real time.  (This time is also known as the
+I<user time>.)  SIGVTALRM is delivered when the timer expires.
+
+ITIMER_PROF counts time when either the process virtual time or when
+the operating system is running on behalf of the process (such as
+I/O).  (This time is also known as the I<system time>.)  (Collectively
+these times are also known as the I<CPU time>.)  SIGPROF is delivered
+when the timer expires.  SIGPROF can interrupt system calls.
+
+The semantics of interval timers for multithreaded programs are
+system-specific, and some systems may support additional interval
+timers.  See your setitimer() documentation.
+
+=item getitimer ( $which )
+
+Return the remaining time in the interval timer specified by $which.
+
+In scalar context, the remaining time is returned.
+
+In list context, both the remaining time and the interval are returned.
+The interval is always what you put in using setitimer().
+
 =back
 
 =head1 EXAMPLES
@@ -166,6 +225,14 @@ replacement for the C<alarm> provided with perl, see the EXAMPLES below.
   sleep (2.5);
   alarm (10.6666666);
 
+  # Arm an interval timer to go off first at 10 seconds and
+  # after that every 2.5 seconds, in process virtual time
+
+  use Time::HiRes qw ( setitimer ITIMER_VIRTUAL time );
+
+  $SIG{VTLARM} = sub { print time, "\n" };
+  setitimer(ITIMER_VIRTUAL, 10, 2.5);
+
 =head1 C API
 
 In addition to the perl API described above, a C API is available for
index 043b3e3..2100375 100644 (file)
@@ -13,6 +13,46 @@ extern "C" {
 }
 #endif
 
+static IV
+constant(char *name, int arg)
+{
+    errno = 0;
+    switch (*name) {
+    case 'I':
+      if (strEQ(name, "ITIMER_REAL"))
+#ifdef ITIMER_REAL
+       return ITIMER_REAL;
+#else
+       goto not_there;
+#endif
+      if (strEQ(name, "ITIMER_REALPROF"))
+#ifdef ITIMER_REALPROF
+       return ITIMER_REALPROF;
+#else
+       goto not_there;
+#endif
+      if (strEQ(name, "ITIMER_VIRTUAL"))
+#ifdef ITIMER_VIRTUAL
+       return ITIMER_VIRTUAL;
+#else
+       goto not_there;
+#endif
+      if (strEQ(name, "ITIMER_PROF"))
+#ifdef ITIMER_PROF
+       return ITIMER_PROF;
+#else
+       goto not_there;
+#endif
+      break;
+    }
+    errno = EINVAL;
+    return 0;
+
+not_there:
+    errno = ENOENT;
+    return 0;
+}
+
 #if !defined(HAS_GETTIMEOFDAY) && defined(WIN32)
 #define HAS_GETTIMEOFDAY
 
@@ -166,7 +206,7 @@ myU2time(UV *ret)
   ret[1] = Tp.tv_usec;
 }
 
-static double
+static NV
 myNVtime()
 {
   struct timeval Tp;
@@ -187,6 +227,11 @@ BOOT:
   hv_store(PL_modglobal, "Time::U2time", 12, newSViv((IV) myU2time), 0);
 #endif
 
+IV
+constant(name, arg)
+       char *          name
+       int             arg
+
 #ifdef HAS_USLEEP
 
 void
@@ -195,7 +240,7 @@ usleep(useconds)
 
 void
 sleep(fseconds)
-        double fseconds 
+        NV fseconds 
        CODE:
        int useconds = fseconds * 1000000;
        usleep (useconds);
@@ -211,8 +256,8 @@ ualarm(useconds,interval=0)
 
 int
 alarm(fseconds,finterval=0)
-       double fseconds
-       double finterval
+       NV fseconds
+       NV finterval
        PREINIT:
        int useconds, uinterval;
        CODE:
@@ -240,7 +285,7 @@ gettimeofday()
              PUSHs(sv_2mortal(newSVnv(Tp.tv_sec + (Tp.tv_usec / 1000000.0))));
         }
 
-double
+NV
 time()
         PREINIT:
         struct timeval Tp;
@@ -253,6 +298,51 @@ time()
 
 #endif
 
+#if defined(HAS_GETITIMER) && defined(HAS_SETITIMER)
+
+#define TV2NV(tv) ((NV)((tv).tv_sec) + 0.000001 * (NV)((tv).tv_usec))
+
+void
+setitimer(which, seconds, interval = 0)
+       int which
+       NV seconds
+       NV interval
+    PREINIT:
+       struct itimerval newit;
+       struct itimerval oldit;
+    PPCODE:
+       newit.it_value.tv_sec  = seconds;
+       newit.it_value.tv_usec =
+         (seconds  - (NV)newit.it_value.tv_sec)    * 1000000.0;
+       newit.it_interval.tv_sec  = interval;
+       newit.it_interval.tv_usec =
+         (interval - (NV)newit.it_interval.tv_sec) * 1000000.0;
+       if (setitimer(which, &newit, &oldit) == 0) {
+         EXTEND(sp, 1);
+         PUSHs(sv_2mortal(newSVnv(TV2NV(oldit.it_value))));
+         if (GIMME == G_ARRAY) {
+           EXTEND(sp, 1);
+           PUSHs(sv_2mortal(newSVnv(TV2NV(oldit.it_interval))));
+         }
+       }
+
+void
+getitimer(which)
+       int which
+    PREINIT:
+       struct itimerval nowit;
+    PPCODE:
+       if (getitimer(which, &nowit) == 0) {
+         EXTEND(sp, 1);
+         PUSHs(sv_2mortal(newSVnv(TV2NV(nowit.it_value))));
+         if (GIMME == G_ARRAY) {
+           EXTEND(sp, 1);
+           PUSHs(sv_2mortal(newSVnv(TV2NV(nowit.it_interval))));
+         }
+       }
+
+#endif
+
 # $Id: HiRes.xs,v 1.11 1999/03/16 02:27:38 wegscd Exp wegscd $
 
 # $Log: HiRes.xs,v $
diff --git a/gv.c b/gv.c
index 8351613..117667c 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -1081,7 +1081,12 @@ Perl_gv_check(pTHX_ HV *stash)
                 * module, don't bother warning */
                if (file
                    && PERL_FILE_IS_ABSOLUTE(file)
-                   && (instr(file, "/lib/") || instr(file, ".pm")))
+#ifdef MACOS_TRADITIONAL
+                   && (instr(file, ":lib:")
+#else
+                   && (instr(file, "/lib/")
+#endif
+                   || instr(file, ".pm")))
                {
                    continue;
                }
index 57b8c86..6e5de81 100644 (file)
@@ -546,7 +546,7 @@ struct's constructor.
 
 =head1 Author and Modification History
 
-Modified by Casey Tweten, 2000-11-08, v0.59.
+Modified by Casey West, 2000-11-08, v0.59.
 
     Added the ability for compile time class creation.
 
index 1305318..e3fd897 100644 (file)
@@ -218,11 +218,11 @@ sub require_version {
     my($self, $wanted) = @_;
     my $pkg = ref $self || $self;
     my $version = ${"${pkg}::VERSION"};
-    if (!$version or $version < $wanted) {
-       $version ||= "(undef)";
+    if (!defined $version or $version < $wanted) {
+       $version = defined $version ? $version : "(undef)";
            # %INC contains slashes, but $pkg contains double-colons.
        my $file = (map {s,::,/,g; $INC{$_}} "$pkg.pm")[0];
-       $file &&= " ($file)";
+       $file = defined $file ? " ($file)" : '';
        require Carp;
        Carp::croak("$pkg $wanted required--this is only version $version$file")
     }
index c496aa0..0a1b549 100644 (file)
@@ -120,7 +120,6 @@ sub install {
            return unless -f _;
            return if $_ eq ".exists";
            my $targetdir  = MY->catdir($targetroot, $File::Find::dir);
-           my $origfile   = $_;
            my $targetfile = MY->catfile($targetdir, $_);
 
            my $diff = 0;
@@ -156,7 +155,7 @@ sub install {
            } else {
                inc_uninstall($_,$File::Find::dir,$verbose,0); # nonono set to 0
            }
-           $packlist->{$origfile}++;
+           $packlist->{$targetfile}++;
 
        }, ".");
        chdir($cwd) or Carp::croak("Couldn't chdir to $cwd: $!");
index b7ff815..12cb5e0 100644 (file)
@@ -8,7 +8,28 @@ use ExtUtils::MakeMaker;
 use Config;
 use File::Find;
 use File::Basename;
-our $VERSION = '0.02';
+our $VERSION = '0.03';
+
+my $DOSISH = ($^O =~ /^(MSWin\d\d|os2|dos|mint)$/);
+
+sub _is_prefix
+{
+my ($self, $path, $prefix) = @_;
+if (substr($path, 0, length($prefix)) eq $prefix)
+   {
+   return(1);
+   }
+if ($DOSISH)
+   {
+   $path =~ s|\\|/|g;
+   $prefix =~ s|\\|/|g;
+   if ($path =~ m{^\Q$prefix\E}i)
+      {
+      return(1);
+      }
+   }
+return(0);
+}
 
 sub _is_type($$$)
 {
@@ -16,22 +37,18 @@ my ($self, $path, $type) = @_;
 return(1) if ($type eq "all");
 if ($type eq "doc")
    {
-   return(substr($path, 0, length($Config{installman1dir}))
-              eq $Config{installman1dir}
+   return($self->_is_prefix($path, $Config{installman1dir})
           ||
-          substr($path, 0, length($Config{installman3dir}))
-              eq $Config{installman3dir}
+          $self->_is_prefix($path, $Config{installman3dir})
           ? 1 : 0)
    }
 if ($type eq "prog")
    {
-   return(substr($path, 0, length($Config{prefix})) eq $Config{prefix}
+   return($self->_is_prefix($path, $Config{prefix})
           &&
-          substr($path, 0, length($Config{installman1dir}))
-             ne $Config{installman1dir}
+          !$self->_is_prefix($path, $Config{installman1dir})
           &&
-          substr($path, 0, length($Config{installman3dir}))
-              ne $Config{installman3dir}
+          !$self->_is_prefix($path, $Config{installman3dir})
           ? 1 : 0);
    }
 return(0);
@@ -43,7 +60,7 @@ my ($self, $path, @under) = @_;
 $under[0] = "" if (! @under);
 foreach my $dir (@under)
    {
-   return(1) if (substr($path, 0, length($dir)) eq $dir);
+   return(1) if ($self->_is_prefix($path, $dir));
    }
 return(0);
 }
@@ -54,21 +71,32 @@ my ($class) = @_;
 $class = ref($class) || $class;
 my $self = {};
 
+my $installarchlib = $Config{installarchlib};
+my $archlib = $Config{archlib};
+my $sitearch = $Config{sitearch};
+
+if ($DOSISH)
+   {
+   $installarchlib =~ s|\\|/|g;
+   $archlib =~ s|\\|/|g;
+   $sitearch =~ s|\\|/|g;
+   }
+
 # Read the core packlist
 $self->{Perl}{packlist} =
-   ExtUtils::Packlist->new("$Config{installarchlib}/.packlist");
+   ExtUtils::Packlist->new("$installarchlib/.packlist");
 $self->{Perl}{version} = $Config{version};
 
 # Read the module packlists
 my $sub = sub
    {
    # Only process module .packlists
-   return if ($_) ne ".packlist" || $File::Find::dir eq $Config{installarchlib};
+   return if ($_) ne ".packlist" || $File::Find::dir eq $installarchlib;
 
    # Hack of the leading bits of the paths & convert to a module name
    my $module = $File::Find::name;
-   $module =~ s!$Config{archlib}/auto/(.*)/.packlist!$1!s;
-   $module =~ s!$Config{sitearch}/auto/(.*)/.packlist!$1!s;
+   $module =~ s!\Q$archlib\E/auto/(.*)/.packlist!$1!s;
+   $module =~ s!\Q$sitearch\E/auto/(.*)/.packlist!$1!s;
    my $modfile = "$module.pm";
    $module =~ s!/!::!g;
 
@@ -87,7 +115,7 @@ my $sub = sub
    # Read the .packlist
    $self->{$module}{packlist} = ExtUtils::Packlist->new($File::Find::name);
    };
-find($sub, $Config{archlib}, $Config{sitearch});
+find($sub, $archlib, $sitearch);
 
 return(bless($self, $class));
 }
index b3c6b97..5ab3508 100644 (file)
@@ -1,6 +1,7 @@
 package Net::Ping;
 
 # Current maintainer: colinm@cpan.org (Colin McMillen)
+#              stream protocol: bronson@trestle.com (Scott Bronson)
 #
 # Original author:   mose@ccsn.edu (Russell Mosemann)
 #
@@ -23,7 +24,7 @@ use Carp;
 
 @ISA = qw(Exporter);
 @EXPORT = qw(pingecho);
-$VERSION = 2.03;
+$VERSION = 2.04;
 
 # Constants
 
@@ -70,8 +71,8 @@ sub new
     bless($self, $class);
 
     $proto = $def_proto unless $proto;          # Determine the protocol
-    croak('Protocol for ping must be "icmp", "tcp", "udp", or "external"')
-        unless $proto =~ m/^(tcp|udp|icmp|external)$/;
+    croak('Protocol for ping must be "icmp", "udp", "tcp", "stream", or "external"')
+        unless $proto =~ m/^(icmp|udp|tcp|stream|external)$/;
     $self->{"proto"} = $proto;
 
     $timeout = $def_timeout unless $timeout;    # Determine the timeout
@@ -114,7 +115,7 @@ sub new
         socket($self->{"fh"}, &PF_INET(), &SOCK_RAW(), $self->{"proto_num"}) ||
             croak("icmp socket error - $!");
     }
-    elsif ($self->{"proto"} eq "tcp")           # Just a file handle for now
+    elsif ($self->{"proto"} eq "tcp" || $self->{"proto"} eq "stream")
     {
         $self->{"proto_num"} = (getprotobyname('tcp'))[2] ||
             croak("Can't get tcp protocol by name");
@@ -154,6 +155,7 @@ sub ping
     return $self->ping_udp($ip, $timeout)      if $self->{"proto"} eq "udp";
     return $self->ping_icmp($ip, $timeout)     if $self->{"proto"} eq "icmp";
     return $self->ping_tcp($ip, $timeout)      if $self->{"proto"} eq "tcp";
+    return $self->ping_stream($ip, $timeout)   if $self->{"proto"} eq "stream";
 
     croak("Unknown protocol \"$self->{proto}\" in ping()");
 }
@@ -283,96 +285,10 @@ sub checksum
     return(~(($chk >> 16) + $chk) & 0xffff);    # Again and complement
 }
 
-# Description:  Perform a tcp echo ping.  Since a tcp connection is
-# host specific, we have to open and close each connection here.  We
-# can't just leave a socket open.  Because of the robust nature of
-# tcp, it will take a while before it gives up trying to establish a
-# connection.  Therefore, we use select() on a non-blocking socket to
-# check against our timeout. No data bytes are actually
-# sent since the successful establishment of a connection is proof
-# enough of the reachability of the remote host.  Also, tcp is
-# expensive and doesn't need our help to add to the overhead.
-
-sub ping_tcp
-{
-  my ($self,
-      $ip,                # Packed IP number of the host
-      $timeout            # Seconds after which ping times out
-     ) = @_;
-  my ($saddr,             # sockaddr_in with port and ip
-      $rin,               # Used in select()
-      $ret                # The return value
-     );
-
-  socket($self->{"fh"}, &PF_INET(), &SOCK_STREAM(), $self->{"proto_num"}) ||
-    croak("tcp socket error - $!");
-
-  $saddr = sockaddr_in($self->{"port_num"}, $ip);
-
-  $ret = 0;               # Default to unreachable
-
-  # Buggy Winsock API doesn't allow us to use non-blocking connect()
-  # calls. Hence, if our OS is Windows, we need to create a new process
-  # to run a blocking connect attempt, and kill it after the timeout has
-  # passed.
-  if ($^O =~ /win32/i)
-  {
-      my ($child, $ret, $pid, $time);
-      my $host = inet_ntoa($ip);
-
-      # The code we will be executing in our new process.
-      my $code = '"use Net::Ping; $p = Net::Ping->new(\'tcp\'); ';
-      $code .= 'exit($p->_ping_tcp_win(' . $host . '))"';
-
-      # Call the process.
-      $pid = system(1, "perl", "-e", $code);
-
-      # Import the POSIX version of <sys/wait.h>
-      require POSIX;
-      import POSIX qw(:sys_wait_h);
-
-      # Get the current time; will be used to tell if we've timed out.
-      $time = time;
-
-      # Wait for the child to return or for the timeout to expire.
-      do {
-         $child = waitpid($pid, &WNOHANG);
-          $ret = $?;
-      } until time > ($time + $timeout) or $child;
-
-      # Return an appropriate value; 0 if the child didn't return,
-      # the return value of the child otherwise.
-      return $ret >> 8 if $child;
-
-      kill $pid;
-      return 0;
-  }
-
-  # If our OS isn't Windows, do this stuff instead...
-  else
-  {
-      # Try a non-blocking TCP connect to the remote echo port.
-      # Our call to select() below will stop after the timeout has
-      # passed or set the return value to true if the connection
-      # succeeds in time.
-      $self->{"fh"}->blocking(0);
-      connect($self->{"fh"}, $saddr);
-
-      $rin = "";
-      vec($rin, fileno($self->{"fh"}), 1) = 1;
-      $ret = 1 if select($rin, undef, undef, $timeout);
-
-      # Close our filehandle, restore it to its default state (i.e. blocking),
-      # and return our result.
-      $self->{"fh"}->blocking(1);
-      $self->{"fh"}->close();
-  }
-  return($ret);
-}
-
 # Warning: this method may generate false positives.
 # It is meant to be a private method and should only
 # be invoked by ping_tcp() if $^O =~ /win32/i.
+
 sub _ping_tcp_win
 {
     my ($self,
@@ -401,6 +317,218 @@ sub _ping_tcp_win
     return $ret;
 }
 
+# Buggy Winsock API doesn't allow us to use non-blocking connect()
+# calls. Hence, if our OS is Windows, we need to create a new process
+# to run a blocking connect attempt, and kill it after the timeout has
+# passed.  Unfortunately, this won't work with the stream protocol.
+
+sub ping_tcp_win32
+{
+    my ($self,
+        $ip,                # Packed IP number of the host
+        $timeout            # Seconds after which open times out
+        ) = @_;
+
+    socket($self->{"fh"}, &PF_INET(), &SOCK_STREAM(), $self->{"proto_num"}) ||
+      croak("tcp socket error - $!");
+
+    my $saddr = sockaddr_in($self->{"port_num"}, $ip);
+
+       my ($child, $ret, $pid, $time);
+       my $host = inet_ntoa($ip);
+
+       # The code we will be executing in our new process.
+       my $code = '"use Net::Ping; $p = Net::Ping->new(\'tcp\'); ';
+       $code .= 'exit($p->_ping_tcp_win(' . $host . '))"';
+
+       # Call the process.
+       $pid = system(1, "perl", "-e", $code);
+
+       # Import the POSIX version of <sys/wait.h>
+       require POSIX;
+       import POSIX qw(:sys_wait_h);
+
+       # Get the current time; will be used to tell if we've timed out.
+       $time = time;
+
+       # Wait for the child to return or for the timeout to expire.
+       do {
+               $child = waitpid($pid, &WNOHANG);
+               $ret = $?;
+       } until time > ($time + $timeout) or $child;
+
+       # Return an appropriate value; 0 if the child didn't return,
+       # the return value of the child otherwise.
+       return $ret >> 8 if $child;
+
+       kill $pid;
+       return 0;
+}
+
+# This writes the given string to the socket and then reads it
+# back.  It returns 1 on success, 0 on failure.
+sub tcp_echo
+{
+       my $self = shift;
+       my $timeout = shift;
+       my $pingstring = shift;
+
+       my $ret = undef;
+       my $time = time;
+       my $wrstr = $pingstring;
+       my $rdstr = "";
+
+    eval <<'EOM';
+       do {
+               my $rin = "";
+               vec($rin, $self->{"fh"}->fileno(), 1) = 1;
+
+               my $rout = undef;
+               if($wrstr) {
+                       $rout = "";
+                       vec($rout, $self->{"fh"}->fileno(), 1) = 1;
+               }
+
+               if(select($rin, $rout, undef, ($time + $timeout) - time())) {
+
+                       if($rout && vec($rout,$self->{"fh"}->fileno(),1)) {
+                               my $num = syswrite($self->{"fh"}, $wrstr);
+                               if($num) {
+                                       # If it was a partial write, update and try again.
+                                       $wrstr = substr($wrstr,$num);
+                               } else {
+                                       # There was an error.
+                                       $ret = 0;
+                               }
+                       }
+
+                       if(vec($rin,$self->{"fh"}->fileno(),1)) {
+                               my $reply;
+                               if(sysread($self->{"fh"},$reply,length($pingstring)-length($rdstr))) {
+                                       $rdstr .= $reply;
+                                       $ret = 1 if $rdstr eq $pingstring;
+                               } else {
+                                       # There was an error.
+                                       $ret = 0;
+                               }
+                       }
+
+               }
+       } until time() > ($time + $timeout) || defined($ret);
+EOM
+
+       return $ret;
+}
+
+sub tcp_connect
+{
+    my ($self,
+        $ip,                # Packed IP number of the host
+        $timeout            # Seconds after which open times out
+        ) = @_;
+
+       # Should we go back to using blocking IO and alarms to implement
+       # the stream protocol on win32?
+    croak "no nonblocking io -- can't stream ping on win32"
+               if ($^O =~ /win32/i);
+
+       $self->{"ip"} = $ip;
+
+    socket($self->{"fh"}, &PF_INET(), &SOCK_STREAM(), $self->{"proto_num"}) ||
+      croak("tcp socket error - $!");
+
+    my $saddr = sockaddr_in($self->{"port_num"}, $ip);
+    my $ret = 0;
+
+       # Try a non-blocking TCP connect to the remote echo port.
+       # Our call to select() below will stop after the timeout has
+       # passed or set the return value to true if the connection
+       # succeeds in time.
+       $self->{"fh"}->blocking(0);
+       connect($self->{"fh"}, $saddr);
+
+       # This replaces the breakage where we were listening on a
+       # socket that would never produce any data.  This works, but
+       # it's now quite a bit heavier than the old Net::Ping.  I'd
+       # like to see it reverted.
+       return $self->tcp_echo($timeout, "ping!\n");
+}
+
+# Description:  Perform a tcp echo ping.  Since a tcp connection is
+# host specific, we have to open and close each connection here.  We
+# can't just leave a socket open.  Because of the robust nature of
+# tcp, it will take a while before it gives up trying to establish a
+# connection.  Therefore, we use select() on a non-blocking socket to
+# check against our timeout. No data bytes are actually
+# sent since the successful establishment of a connection is proof
+# enough of the reachability of the remote host.  Also, tcp is
+# expensive and doesn't need our help to add to the overhead.
+
+sub ping_tcp
+{
+    my ($self,
+        $ip,                # Packed IP number of the host
+        $timeout            # Seconds after which ping times out
+       ) = @_;
+
+       my $ret;
+
+       # tcp_connect won't work on win32, so special-case it if need be.
+    if ($^O =~ /win32/i) {
+               $ret = $self->ping_tcp_win32($ip, $timeout);
+       } else {
+       $ret = $self->tcp_connect($ip, $timeout);
+       $self->{"fh"}->close();
+       }
+
+    return $ret;
+}
+
+# Description: Perform a stream ping.  If the tcp connection isn't
+# already open, it opens it.  It then sends some data and waits for
+# a reply.  It leaves the stream open on exit.
+
+sub ping_stream
+{
+    my ($self,
+        $ip,                # Packed IP number of the host
+        $timeout            # Seconds after which ping times out
+        ) = @_;
+
+    my $pingstring = "ping!\n";   # The data we exchange with the server
+
+    # Open the stream if it's not already open
+    if(!defined $self->{"fh"}->fileno()) {
+        $self->tcp_connect($ip, $timeout) or return 0;
+    }
+
+    croak "tried to switch servers while stream pinging"
+       if $self->{"ip"} ne $ip;
+
+    return $self->tcp_echo($timeout, "pingschwingping!\n");
+}
+
+# Description: opens the stream.  You would do this if you want to
+# separate the overhead of opening the stream from the first ping.
+
+sub open
+{
+   my ($self,
+       $ip,                # Packed IP number of the host
+        $timeout            # Seconds after which open times out
+       ) = @_;
+
+   $timeout = $self->{"timeout"} unless $timeout;
+
+   if($self->{"proto"} eq "stream") {
+       if(defined($self->{"fh"}->fileno())) {
+           croak("socket is already open");
+       } else {
+           $self->tcp_connect($ip, $timeout);
+       }
+   }
+}
+
 # Description:  Perform a udp echo ping.  Construct a message of
 # at least the one-byte sequence number and any additional data bytes.
 # Send the message out and wait for a message to come back.  If we
@@ -527,39 +655,64 @@ hosts on a network.  A ping object is first created with optional
 parameters, a variable number of hosts may be pinged multiple
 times and then the connection is closed.
 
-You may choose one of four different protocols to use for the
-ping. The "udp" protocol is the default. Note that a live remote host
-may still fail to be pingable by one or more of these protocols. For
-example, www.microsoft.com is generally alive but not pingable.
+Ping supports five ping protocols, each with its own strengths
+and weaknesses.  The "udp" protocol is the default.  A host
+may be configured to respond to only a few of these protocols,
+or even none at all.  For example, www.microsoft.com is generally
+alive but not pingable.
 
-With the "tcp" protocol the ping() method attempts to establish a
-connection to the remote host's echo port.  If the connection is
-successfully established, the remote host is considered reachable.  No
-data is actually echoed.  This protocol does not require any special
-privileges but has higher overhead than the other two protocols.
+=over 4
+
+=item icmp
+
+The C<ping()> method sends an icmp echo message to the remote host
+(this is what the UNIX ping program does).
+If the echoed message is received from the remote host and
+the echoed information is correct, the remote host is considered
+reachable.  Specifying this protocol requires that the program
+be run as root or that the program be setuid to root.
 
-Specifying the "udp" protocol causes the ping() method to send a udp
+=item udp
+
+The C<ping()> method sends a udp
 packet to the remote host's echo port.  If the echoed packet is
 received from the remote host and the received packet contains the
 same data as the packet that was sent, the remote host is considered
 reachable.  This protocol does not require any special privileges.
 
-It should be borne in mind that, for both udp ping, a host
+It should be borne in mind that, for both udp and tcp ping, a host
 will be reported as unreachable if it is not running the
 appropriate echo service.  For Unix-like systems see L<inetd(8)> for
 more information.
 
-If the "icmp" protocol is specified, the ping() method sends an icmp
-echo message to the remote host, which is what the UNIX ping program
-does.  If the echoed message is received from the remote host and
-the echoed information is correct, the remote host is considered
-reachable.  Specifying the "icmp" protocol requires that the program
-be run as root or that the program be setuid to root.
+=item tcp
 
-If the "external" protocol is specified, the ping() method attempts to
-use the C<Net::Ping::External> module to ping the remote host.
-C<Net::Ping::External> interfaces with your system's default C<ping>
-utility to perform the ping, and generally produces relatively
+The C<ping()> method attempts to establish a
+connection to the remote host's echo port.  If the connection is
+successfully established, the remote host is considered reachable.
+Once the connection is made, it is torn down immediately -- no data
+is actually echoed.  This protocol does not require any special
+privileges but has highest overhead of the protocols.
+
+=item stream
+
+This is just like the tcp protocol, except that once it establishes
+the tcp connection, it keeps it up.  Each subsequent ping
+request re-uses the existing connection.  stream
+provides better performance than tcp since the connection
+doesn't need to be created and torn down with every ping.  It is
+also the only protocol that will recognize that the original host is
+gone, even if it is immediately replaced by an
+identical host responding in exactly the same way.  The drawback
+is that you can only ping one host per Ping instance.  You will get
+an error if you neglect to call C<close()> before trying to ping
+a different network device.
+
+=item external
+
+The ping() method attempts to use the C<Net::Ping::External> module to ping
+the remote host.  C<Net::Ping::External> interfaces with your system's default
+L<ping(8)> utility to perform the ping, and generally produces relatively
 accurate results. If C<Net::Ping::External> if not installed on your
 system, specifying the "external" protocol will result in an error.
 
@@ -594,6 +747,17 @@ there is a problem with the IP number, undef is returned.  Otherwise,
 1 is returned if the host is reachable and 0 if it is not.  For all
 practical purposes, undef and 0 and can be treated as the same case.
 
+=item $p->open($host);
+
+When you are using the stream protocol, this call pre-opens the
+tcp socket.  It's only necessary to do this if you want to
+provide a different timeout when creating the connection, or
+remove the overhead of establishing the connection from the
+first ping.  If you don't call C<open()>, the connection is
+automatically openeed the first time C<ping()> is called.
+This call simply does nothing if you are using any protocol other
+than stream.
+
 =item $p->close();
 
 Close the network connection for this ping object.  The network
@@ -622,9 +786,8 @@ to implement a small wait (e.g. 25ms or more) between each ping to
 avoid flooding your network with packets.
 
 The icmp protocol requires that the program be run as root or that it
-be setuid to root.  The tcp and udp protocols do not require special
-privileges, but not all network devices implement the echo protocol
-for tcp or udp.
+be setuid to root.  The other protocols do not require special
+privileges, but not all network devices implement tcp or udp echo.
 
 Local hosts should normally respond to pings within milliseconds.
 However, on a very congested network it may take up to 3 seconds or
@@ -633,7 +796,9 @@ is set too low under these conditions, it will appear that the remote
 host is not reachable (which is almost the truth).
 
 Reachability doesn't necessarily mean that the remote host is actually
-functioning beyond its ability to echo packets.
+functioning beyond its ability to echo packets.  tcp is slightly better
+at indicating the health of a system than icmp because it uses more
+of the networking stack to respond.
 
 Because of a lack of anything better, this module uses its own
 routines to pack and unpack ICMP packets.  It would be better for a
index c2f522c..44318d2 100644 (file)
@@ -196,6 +196,6 @@ Larry Wall
 
 Changes by Jenda@Krynicky.cz and Dave Cottle <d.cottle@csc.canterbury.ac.nz>
 
-Changes and bug fixes by Casey Tweten <crt@kiski.net>
+Changes and bug fixes by Casey West <casey@geeknest.com>
 
 =cut
index 1e07a68..ffa8791 100644 (file)
@@ -314,8 +314,8 @@ C<CONSTANT =E<gt> 'value'>.
 Tom Phoenix, E<lt>F<rootbeer@redcat.com>E<gt>, with help from
 many other folks.
 
-Multiple constant declarations at once added by Casey Tweten,
-E<lt>F<crt@kiski.net>E<gt>.
+Multiple constant declarations at once added by Casey West,
+E<lt>F<casey@geeknest.com>E<gt>.
 
 =head1 COPYRIGHT
 
index 402127a..0885e67 100644 (file)
@@ -61,9 +61,8 @@ Enabling the C<utf8> pragma has the following effects:
 Bytes in the source text that have their high-bit set will be treated
 as being part of a literal UTF-8 character.  This includes most literals
 such as identifiers, string constants, constant regular expression patterns
-and package names.  On EBCDIC platforms, characters in the C1 control group 
-and the Latin 1 character set are treated as being part of a literal
-UTF-EBCDIC character.
+and package names.  On EBCDIC platforms characters in the Latin 1 
+character set are treated as being part of a literal UTF-EBCDIC character.
 
 =item *
 
diff --git a/op.c b/op.c
index aa0b1e7..6cd2f9a 100644 (file)
--- a/op.c
+++ b/op.c
@@ -5870,6 +5870,7 @@ Perl_ck_glob(pTHX_ OP *o)
        gv = gv_fetchpv("CORE::GLOBAL::glob", FALSE, SVt_PVCV);
        glob_gv = gv_fetchpv("File::Glob::csh_glob", FALSE, SVt_PVCV);
        GvCV(gv) = GvCV(glob_gv);
+       SvREFCNT_inc((SV*)GvCV(gv));
        GvIMPORTED_CV_on(gv);
        LEAVE;
     }
index 8e15a82..bf565d0 100644 (file)
@@ -70,6 +70,7 @@
 #if !defined(PERL_PATCHLEVEL_H_IMPLICIT) && !defined(LOCAL_PATCH_COUNT)
 static char    *local_patches[] = {
         NULL
+       ,"DEVEL9717"
        ,NULL
 };
 
index 12ea2f3..ccfe139 100644 (file)
@@ -6,7 +6,8 @@ perlebcdic - Considerations for running Perl on EBCDIC platforms
 
 An exploration of some of the issues facing Perl programmers
 on EBCDIC based computers.  We do not cover localization, 
-internationalization, or multi byte character set issues (yet).
+internationalization, or multi byte character set issues other
+than some discussion of UTF-8 and UTF-EBCDIC.
 
 Portions that are still incomplete are marked with XXX.
 
@@ -54,7 +55,7 @@ also known as CCSID 819 (or sometimes 0819 or even 00819).
 
 =head2 EBCDIC
 
-The Extended Binary Coded Decimal Interchange Code  refers to a 
+The Extended Binary Coded Decimal Interchange Code refers to a 
 large collection of slightly different single and multi byte 
 coded character sets that are different from ASCII or ISO 8859-1 
 and typically run on host computers.  The EBCDIC encodings derive 
@@ -88,14 +89,21 @@ in 237 places, in other words they agree on only 19 code point values.
 
 Character code set ID 1047 is also a mapping of the ASCII plus 
 Latin-1 characters (i.e. ISO 8859-1) to an EBCDIC set.  1047 is 
-used under Unix System Services for OS/390, and OpenEdition for VM/ESA. 
-CCSID 1047 differs from CCSID 0037 in eight places.
+used under Unix System Services for OS/390 or z/OS, and OpenEdition 
+for VM/ESA.  CCSID 1047 differs from CCSID 0037 in eight places.
 
 =head2 POSIX-BC
 
 The EBCDIC code page in use on Siemens' BS2000 system is distinct from
 1047 and 0037.  It is identified below as the POSIX-BC set.
 
+=head2 Unicode and UTF
+
+UTF is a Unicode Transformation Format.  UTF-8 is a Unicode conforming
+representation of the Unicode standard that looks very much like ASCII.
+UTF-EBCDIC is an attempt to represent Unicode characters in an EBCDIC
+transparent manner.
+
 =head1 SINGLE OCTET TABLES
 
 The following tables list the ASCII and Latin 1 ordered sets including
@@ -103,7 +111,7 @@ the subsets: C0 controls (0..31), ASCII graphics (32..7e), delete (7f),
 C1 controls (80..9f), and Latin-1 (a.k.a. ISO 8859-1) (a0..ff).  In the 
 table non-printing control character names as well as the Latin 1 
 extensions to ASCII have been labelled with character names roughly 
-corresponding to I<The Unicode Standard, Version 2.0> albeit with 
+corresponding to I<The Unicode Standard, Version 3.0> albeit with 
 substitutions such as s/LATIN// and s/VULGAR// in all cases, 
 s/CAPITAL LETTER// in some cases, and s/SMALL LETTER ([A-Z])/\l$1/ 
 in some other cases (the C<charnames> pragma names unfortunately do 
@@ -123,294 +131,342 @@ work with a pod2_other_format translation) through:
 =back
 
     perl -ne 'if(/(.{33})(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/)' \
-     -e '{printf("%s%-9o%-9o%-9o%-9o\n",$1,$2,$3,$4,$5)}' perlebcdic.pod
+     -e '{printf("%s%-9o%-9o%-9o%o\n",$1,$2,$3,$4,$5)}' perlebcdic.pod
+
+If you want to retain the UTF-x code points then in script form you
+might want to write:
+
+=over 4
+
+=item recipe 1
+
+=back
+
+    open(FH,"<perlebcdic.pod") or die "Could not open perlebcdic.pod: $!";
+    while (<FH>) {
+        if (/(.{33})(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\.?(\d*)\s+(\d+)\.?(\d*)/)  {
+            if ($7 ne '' && $9 ne '') {
+                printf("%s%-9o%-9o%-9o%-9o%-3o.%-5o%-3o.%o\n",$1,$2,$3,$4,$5,$6,$7,$8,$9);
+            }
+            elsif ($7 ne '') {
+                printf("%s%-9o%-9o%-9o%-9o%-3o.%-5o%o\n",$1,$2,$3,$4,$5,$6,$7,$8);
+            }
+            else {
+                printf("%s%-9o%-9o%-9o%-9o%-9o%o\n",$1,$2,$3,$4,$5,$6,$8);
+            }
+        }
+    }
 
 If you would rather see this table listing hexadecimal values then
 run the table through:
 
 =over 4
 
-=item recipe 1
+=item recipe 2
 
 =back
 
     perl -ne 'if(/(.{33})(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/)' \
-     -e '{printf("%s%-9X%-9X%-9X%-9X\n",$1,$2,$3,$4,$5)}' perlebcdic.pod
-
-
-                                 8859-1
-    chr                          0819     0037     1047     POSIX-BC
-    ----------------------------------------------------------------
-    <NULL>                       0        0        0        0 
-    <START OF HEADING>           1        1        1        1
-    <START OF TEXT>              2        2        2        2
-    <END OF TEXT>                3        3        3        3
-    <END OF TRANSMISSION>        4        55       55       55
-    <ENQUIRY>                    5        45       45       45
-    <ACKNOWLEDGE>                6        46       46       46
-    <BELL>                       7        47       47       47
-    <BACKSPACE>                  8        22       22       22
-    <HORIZONTAL TABULATION>      9        5        5        5
-    <LINE FEED>                  10       37       21       21  ***
-    <VERTICAL TABULATION>        11       11       11       11
-    <FORM FEED>                  12       12       12       12
-    <CARRIAGE RETURN>            13       13       13       13
-    <SHIFT OUT>                  14       14       14       14
-    <SHIFT IN>                   15       15       15       15
-    <DATA LINK ESCAPE>           16       16       16       16
-    <DEVICE CONTROL ONE>         17       17       17       17
-    <DEVICE CONTROL TWO>         18       18       18       18
-    <DEVICE CONTROL THREE>       19       19       19       19
-    <DEVICE CONTROL FOUR>        20       60       60       60
-    <NEGATIVE ACKNOWLEDGE>       21       61       61       61
-    <SYNCHRONOUS IDLE>           22       50       50       50
-    <END OF TRANSMISSION BLOCK>  23       38       38       38
-    <CANCEL>                     24       24       24       24
-    <END OF MEDIUM>              25       25       25       25
-    <SUBSTITUTE>                 26       63       63       63
-    <ESCAPE>                     27       39       39       39
-    <FILE SEPARATOR>             28       28       28       28
-    <GROUP SEPARATOR>            29       29       29       29
-    <RECORD SEPARATOR>           30       30       30       30
-    <UNIT SEPARATOR>             31       31       31       31
-    <SPACE>                      32       64       64       64
-    !                            33       90       90       90
-    "                            34       127      127      127
-    #                            35       123      123      123
-    $                            36       91       91       91
-    %                            37       108      108      108
-    &                            38       80       80       80
-    '                            39       125      125      125
-    (                            40       77       77       77
-    )                            41       93       93       93
-    *                            42       92       92       92
-    +                            43       78       78       78
-    ,                            44       107      107      107
-    -                            45       96       96       96
-    .                            46       75       75       75
-    /                            47       97       97       97
-    0                            48       240      240      240
-    1                            49       241      241      241
-    2                            50       242      242      242
-    3                            51       243      243      243
-    4                            52       244      244      244
-    5                            53       245      245      245
-    6                            54       246      246      246
-    7                            55       247      247      247
-    8                            56       248      248      248
-    9                            57       249      249      249
-    :                            58       122      122      122
-    ;                            59       94       94       94
-    <                            60       76       76       76
-    =                            61       126      126      126
-    >                            62       110      110      110
-    ?                            63       111      111      111
-    @                            64       124      124      124
-    A                            65       193      193      193
-    B                            66       194      194      194
-    C                            67       195      195      195
-    D                            68       196      196      196
-    E                            69       197      197      197
-    F                            70       198      198      198
-    G                            71       199      199      199
-    H                            72       200      200      200
-    I                            73       201      201      201
-    J                            74       209      209      209
-    K                            75       210      210      210
-    L                            76       211      211      211
-    M                            77       212      212      212
-    N                            78       213      213      213
-    O                            79       214      214      214
-    P                            80       215      215      215
-    Q                            81       216      216      216
-    R                            82       217      217      217
-    S                            83       226      226      226
-    T                            84       227      227      227
-    U                            85       228      228      228
-    V                            86       229      229      229
-    W                            87       230      230      230
-    X                            88       231      231      231
-    Y                            89       232      232      232
-    Z                            90       233      233      233
-    [                            91       186      173      187 *** ###
-    \                            92       224      224      188 ### 
-    ]                            93       187      189      189 ***
-    ^                            94       176      95       106 *** ###
-    _                            95       109      109      109
-    `                            96       121      121      74  ###
-    a                            97       129      129      129
-    b                            98       130      130      130
-    c                            99       131      131      131
-    d                            100      132      132      132
-    e                            101      133      133      133
-    f                            102      134      134      134
-    g                            103      135      135      135
-    h                            104      136      136      136
-    i                            105      137      137      137
-    j                            106      145      145      145
-    k                            107      146      146      146
-    l                            108      147      147      147
-    m                            109      148      148      148
-    n                            110      149      149      149
-    o                            111      150      150      150
-    p                            112      151      151      151
-    q                            113      152      152      152
-    r                            114      153      153      153
-    s                            115      162      162      162
-    t                            116      163      163      163
-    u                            117      164      164      164
-    v                            118      165      165      165
-    w                            119      166      166      166
-    x                            120      167      167      167
-    y                            121      168      168      168
-    z                            122      169      169      169
-    {                            123      192      192      251 ###
-    |                            124      79       79       79
-    }                            125      208      208      253 ###
-    ~                            126      161      161      255 ###
-    <DELETE>                     127      7        7        7
-    <C1 0>                       128      32       32       32
-    <C1 1>                       129      33       33       33
-    <C1 2>                       130      34       34       34
-    <C1 3>                       131      35       35       35
-    <C1 4>                       132      36       36       36
-    <C1 5>                       133      21       37       37  ***
-    <C1 6>                       134      6        6        6
-    <C1 7>                       135      23       23       23
-    <C1 8>                       136      40       40       40
-    <C1 9>                       137      41       41       41
-    <C1 10>                      138      42       42       42
-    <C1 11>                      139      43       43       43
-    <C1 12>                      140      44       44       44
-    <C1 13>                      141      9        9        9
-    <C1 14>                      142      10       10       10
-    <C1 15>                      143      27       27       27
-    <C1 16>                      144      48       48       48
-    <C1 17>                      145      49       49       49
-    <C1 18>                      146      26       26       26
-    <C1 19>                      147      51       51       51
-    <C1 20>                      148      52       52       52
-    <C1 21>                      149      53       53       53
-    <C1 22>                      150      54       54       54
-    <C1 23>                      151      8        8        8
-    <C1 24>                      152      56       56       56
-    <C1 25>                      153      57       57       57
-    <C1 26>                      154      58       58       58
-    <C1 27>                      155      59       59       59
-    <C1 28>                      156      4        4        4
-    <C1 29>                      157      20       20       20
-    <C1 30>                      158      62       62       62
-    <C1 31>                      159      255      255      95  ###
-    <NON-BREAKING SPACE>         160      65       65       65
-    <INVERTED EXCLAMATION MARK>  161      170      170      170
-    <CENT SIGN>                  162      74       74       176 ###
-    <POUND SIGN>                 163      177      177      177
-    <CURRENCY SIGN>              164      159      159      159
-    <YEN SIGN>                   165      178      178      178
-    <BROKEN BAR>                 166      106      106      208 ###
-    <SECTION SIGN>               167      181      181      181
-    <DIAERESIS>                  168      189      187      121 *** ###
-    <COPYRIGHT SIGN>             169      180      180      180
-    <FEMININE ORDINAL INDICATOR> 170      154      154      154
-    <LEFT POINTING GUILLEMET>    171      138      138      138
-    <NOT SIGN>                   172      95       176      186 *** ###       
-    <SOFT HYPHEN>                173      202      202      202
-    <REGISTERED TRADE MARK SIGN> 174      175      175      175
-    <MACRON>                     175      188      188      161 ###
-    <DEGREE SIGN>                176      144      144      144
-    <PLUS-OR-MINUS SIGN>         177      143      143      143
-    <SUPERSCRIPT TWO>            178      234      234      234
-    <SUPERSCRIPT THREE>          179      250      250      250
-    <ACUTE ACCENT>               180      190      190      190
-    <MICRO SIGN>                 181      160      160      160
-    <PARAGRAPH SIGN>             182      182      182      182
-    <MIDDLE DOT>                 183      179      179      179
-    <CEDILLA>                    184      157      157      157
-    <SUPERSCRIPT ONE>            185      218      218      218
-    <MASC. ORDINAL INDICATOR>    186      155      155      155
-    <RIGHT POINTING GUILLEMET>   187      139      139      139
-    <FRACTION ONE QUARTER>       188      183      183      183
-    <FRACTION ONE HALF>          189      184      184      184
-    <FRACTION THREE QUARTERS>    190      185      185      185
-    <INVERTED QUESTION MARK>     191      171      171      171
-    <A WITH GRAVE>               192      100      100      100
-    <A WITH ACUTE>               193      101      101      101
-    <A WITH CIRCUMFLEX>          194      98       98       98
-    <A WITH TILDE>               195      102      102      102
-    <A WITH DIAERESIS>           196      99       99       99
-    <A WITH RING ABOVE>          197      103      103      103
-    <CAPITAL LIGATURE AE>        198      158      158      158
-    <C WITH CEDILLA>             199      104      104      104
-    <E WITH GRAVE>               200      116      116      116
-    <E WITH ACUTE>               201      113      113      113
-    <E WITH CIRCUMFLEX>          202      114      114      114
-    <E WITH DIAERESIS>           203      115      115      115
-    <I WITH GRAVE>               204      120      120      120
-    <I WITH ACUTE>               205      117      117      117
-    <I WITH CIRCUMFLEX>          206      118      118      118
-    <I WITH DIAERESIS>           207      119      119      119
-    <CAPITAL LETTER ETH>         208      172      172      172
-    <N WITH TILDE>               209      105      105      105
-    <O WITH GRAVE>               210      237      237      237
-    <O WITH ACUTE>               211      238      238      238
-    <O WITH CIRCUMFLEX>          212      235      235      235
-    <O WITH TILDE>               213      239      239      239
-    <O WITH DIAERESIS>           214      236      236      236
-    <MULTIPLICATION SIGN>        215      191      191      191
-    <O WITH STROKE>              216      128      128      128
-    <U WITH GRAVE>               217      253      253      224 ###
-    <U WITH ACUTE>               218      254      254      254
-    <U WITH CIRCUMFLEX>          219      251      251      221 ###
-    <U WITH DIAERESIS>           220      252      252      252
-    <Y WITH ACUTE>               221      173      186      173 *** ###
-    <CAPITAL LETTER THORN>       222      174      174      174
-    <SMALL LETTER SHARP S>       223      89       89       89
-    <a WITH GRAVE>               224      68       68       68
-    <a WITH ACUTE>               225      69       69       69
-    <a WITH CIRCUMFLEX>          226      66       66       66
-    <a WITH TILDE>               227      70       70       70
-    <a WITH DIAERESIS>           228      67       67       67
-    <a WITH RING ABOVE>          229      71       71       71
-    <SMALL LIGATURE ae>          230      156      156      156
-    <c WITH CEDILLA>             231      72       72       72
-    <e WITH GRAVE>               232      84       84       84
-    <e WITH ACUTE>               233      81       81       81
-    <e WITH CIRCUMFLEX>          234      82       82       82
-    <e WITH DIAERESIS>           235      83       83       83
-    <i WITH GRAVE>               236      88       88       88
-    <i WITH ACUTE>               237      85       85       85
-    <i WITH CIRCUMFLEX>          238      86       86       86
-    <i WITH DIAERESIS>           239      87       87       87
-    <SMALL LETTER eth>           240      140      140      140
-    <n WITH TILDE>               241      73       73       73
-    <o WITH GRAVE>               242      205      205      205
-    <o WITH ACUTE>               243      206      206      206
-    <o WITH CIRCUMFLEX>          244      203      203      203
-    <o WITH TILDE>               245      207      207      207
-    <o WITH DIAERESIS>           246      204      204      204
-    <DIVISION SIGN>              247      225      225      225
-    <o WITH STROKE>              248      112      112      112
-    <u WITH GRAVE>               249      221      221      192 ###
-    <u WITH ACUTE>               250      222      222      222
-    <u WITH CIRCUMFLEX>          251      219      219      219
-    <u WITH DIAERESIS>           252      220      220      220
-    <y WITH ACUTE>               253      141      141      141
-    <SMALL LETTER thorn>         254      142      142      142
-    <y WITH DIAERESIS>           255      223      223      223
+     -e '{printf("%s%-9X%-9X%-9X%X\n",$1,$2,$3,$4,$5)}' perlebcdic.pod
+
+Or, in order to retain the UTF-x code points in hexadecimal:
+
+=over 4
+
+=item recipe 3
+
+=back
+
+    open(FH,"<perlebcdic.pod") or die "Could not open perlebcdic.pod: $!";
+    while (<FH>) {
+        if (/(.{33})(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\.?(\d*)\s+(\d+)\.?(\d*)/)  {
+            if ($7 ne '' && $9 ne '') {
+                printf("%s%-9X%-9X%-9X%-9X%-2X.%-6X%-2X.%X\n",$1,$2,$3,$4,$5,$6,$7,$8,$9);
+            }
+            elsif ($7 ne '') {
+                printf("%s%-9X%-9X%-9X%-9X%-2X.%-6X%X\n",$1,$2,$3,$4,$5,$6,$7,$8);
+            }
+            else {
+                printf("%s%-9X%-9X%-9X%-9X%-9X%X\n",$1,$2,$3,$4,$5,$6,$8);
+            }
+        }
+    }
+
+
+                                                                     incomp-  incomp-
+                                 8859-1                              lete     lete
+    chr                          0819     0037     1047     POSIX-BC UTF-8    UTF-EBCDIC
+    ------------------------------------------------------------------------------------
+    <NULL>                       0        0        0        0        0        0 
+    <START OF HEADING>           1        1        1        1        1        1
+    <START OF TEXT>              2        2        2        2        2        2
+    <END OF TEXT>                3        3        3        3        3        3
+    <END OF TRANSMISSION>        4        55       55       55       4        55 
+    <ENQUIRY>                    5        45       45       45       5        45 
+    <ACKNOWLEDGE>                6        46       46       46       6        46 
+    <BELL>                       7        47       47       47       7        47 
+    <BACKSPACE>                  8        22       22       22       8        22 
+    <HORIZONTAL TABULATION>      9        5        5        5        9        5 
+    <LINE FEED>                  10       37       21       21       10       21       ***
+    <VERTICAL TABULATION>        11       11       11       11       11       11
+    <FORM FEED>                  12       12       12       12       12       12
+    <CARRIAGE RETURN>            13       13       13       13       13       13
+    <SHIFT OUT>                  14       14       14       14       14       14
+    <SHIFT IN>                   15       15       15       15       15       15
+    <DATA LINK ESCAPE>           16       16       16       16       16       16
+    <DEVICE CONTROL ONE>         17       17       17       17       17       17
+    <DEVICE CONTROL TWO>         18       18       18       18       18       18
+    <DEVICE CONTROL THREE>       19       19       19       19       19       19
+    <DEVICE CONTROL FOUR>        20       60       60       60       20       60
+    <NEGATIVE ACKNOWLEDGE>       21       61       61       61       21       61
+    <SYNCHRONOUS IDLE>           22       50       50       50       22       50
+    <END OF TRANSMISSION BLOCK>  23       38       38       38       23       38
+    <CANCEL>                     24       24       24       24       24       24
+    <END OF MEDIUM>              25       25       25       25       25       25
+    <SUBSTITUTE>                 26       63       63       63       26       63
+    <ESCAPE>                     27       39       39       39       27       39
+    <FILE SEPARATOR>             28       28       28       28       28       28
+    <GROUP SEPARATOR>            29       29       29       29       29       29
+    <RECORD SEPARATOR>           30       30       30       30       30       30
+    <UNIT SEPARATOR>             31       31       31       31       31       31
+    <SPACE>                      32       64       64       64       32       64
+    !                            33       90       90       90       33       90
+    "                            34       127      127      127      34       127
+    #                            35       123      123      123      35       123
+    $                            36       91       91       91       36       91
+    %                            37       108      108      108      37       108
+    &                            38       80       80       80       38       80
+    '                            39       125      125      125      39       125
+    (                            40       77       77       77       40       77
+    )                            41       93       93       93       41       93
+    *                            42       92       92       92       42       92
+    +                            43       78       78       78       43       78
+    ,                            44       107      107      107      44       107
+    -                            45       96       96       96       45       96
+    .                            46       75       75       75       46       75
+    /                            47       97       97       97       47       97
+    0                            48       240      240      240      48       240
+    1                            49       241      241      241      49       241
+    2                            50       242      242      242      50       242
+    3                            51       243      243      243      51       243
+    4                            52       244      244      244      52       244
+    5                            53       245      245      245      53       245
+    6                            54       246      246      246      54       246
+    7                            55       247      247      247      55       247
+    8                            56       248      248      248      56       248
+    9                            57       249      249      249      57       249
+    :                            58       122      122      122      58       122
+    ;                            59       94       94       94       59       94
+    <                            60       76       76       76       60       76
+    =                            61       126      126      126      61       126
+    >                            62       110      110      110      62       110
+    ?                            63       111      111      111      63       111
+    @                            64       124      124      124      64       124
+    A                            65       193      193      193      65       193
+    B                            66       194      194      194      66       194
+    C                            67       195      195      195      67       195
+    D                            68       196      196      196      68       196
+    E                            69       197      197      197      69       197
+    F                            70       198      198      198      70       198
+    G                            71       199      199      199      71       199
+    H                            72       200      200      200      72       200
+    I                            73       201      201      201      73       201
+    J                            74       209      209      209      74       209
+    K                            75       210      210      210      75       210
+    L                            76       211      211      211      76       211
+    M                            77       212      212      212      77       212
+    N                            78       213      213      213      78       213
+    O                            79       214      214      214      79       214
+    P                            80       215      215      215      80       215
+    Q                            81       216      216      216      81       216
+    R                            82       217      217      217      82       217
+    S                            83       226      226      226      83       226
+    T                            84       227      227      227      84       227
+    U                            85       228      228      228      85       228
+    V                            86       229      229      229      86       229
+    W                            87       230      230      230      87       230
+    X                            88       231      231      231      88       231
+    Y                            89       232      232      232      89       232
+    Z                            90       233      233      233      90       233
+    [                            91       186      173      187      91       173      *** ###
+    \                            92       224      224      188      92       224      ### 
+    ]                            93       187      189      189      93       189      ***
+    ^                            94       176      95       106      94       95       *** ###
+    _                            95       109      109      109      95       109
+    `                            96       121      121      74       96       121      ###
+    a                            97       129      129      129      97       129
+    b                            98       130      130      130      98       130
+    c                            99       131      131      131      99       131
+    d                            100      132      132      132      100      132
+    e                            101      133      133      133      101      133
+    f                            102      134      134      134      102      134
+    g                            103      135      135      135      103      135
+    h                            104      136      136      136      104      136
+    i                            105      137      137      137      105      137
+    j                            106      145      145      145      106      145
+    k                            107      146      146      146      107      146
+    l                            108      147      147      147      108      147
+    m                            109      148      148      148      109      148
+    n                            110      149      149      149      110      149
+    o                            111      150      150      150      111      150
+    p                            112      151      151      151      112      151
+    q                            113      152      152      152      113      152
+    r                            114      153      153      153      114      153
+    s                            115      162      162      162      115      162
+    t                            116      163      163      163      116      163
+    u                            117      164      164      164      117      164
+    v                            118      165      165      165      118      165
+    w                            119      166      166      166      119      166
+    x                            120      167      167      167      120      167
+    y                            121      168      168      168      121      168
+    z                            122      169      169      169      122      169
+    {                            123      192      192      251      123      192      ###
+    |                            124      79       79       79       124      79
+    }                            125      208      208      253      125      208      ###
+    ~                            126      161      161      255      126      161      ###
+    <DELETE>                     127      7        7        7        127      7
+    <C1 0>                       128      32       32       32       194.128  32
+    <C1 1>                       129      33       33       33       194.129  33
+    <C1 2>                       130      34       34       34       194.130  34
+    <C1 3>                       131      35       35       35       194.131  35
+    <C1 4>                       132      36       36       36       194.132  36
+    <C1 5>                       133      21       37       37       194.133  37       ***
+    <C1 6>                       134      6        6        6        194.134  6
+    <C1 7>                       135      23       23       23       194.135  23
+    <C1 8>                       136      40       40       40       194.136  40
+    <C1 9>                       137      41       41       41       194.137  41
+    <C1 10>                      138      42       42       42       194.138  42
+    <C1 11>                      139      43       43       43       194.139  43
+    <C1 12>                      140      44       44       44       194.140  44
+    <C1 13>                      141      9        9        9        194.141  9
+    <C1 14>                      142      10       10       10       194.142  10
+    <C1 15>                      143      27       27       27       194.143  27
+    <C1 16>                      144      48       48       48       194.144  48
+    <C1 17>                      145      49       49       49       194.145  49
+    <C1 18>                      146      26       26       26       194.146  26
+    <C1 19>                      147      51       51       51       194.147  51
+    <C1 20>                      148      52       52       52       194.148  52
+    <C1 21>                      149      53       53       53       194.149  53
+    <C1 22>                      150      54       54       54       194.150  54
+    <C1 23>                      151      8        8        8        194.151  8
+    <C1 24>                      152      56       56       56       194.152  56
+    <C1 25>                      153      57       57       57       194.153  57
+    <C1 26>                      154      58       58       58       194.154  58
+    <C1 27>                      155      59       59       59       194.155  59
+    <C1 28>                      156      4        4        4        194.156  4
+    <C1 29>                      157      20       20       20       194.157  20
+    <C1 30>                      158      62       62       62       194.158  62
+    <C1 31>                      159      255      255      95       194.159  255      ###
+    <NON-BREAKING SPACE>         160      65       65       65       194.160  128.65
+    <INVERTED EXCLAMATION MARK>  161      170      170      170      194.161  128.66
+    <CENT SIGN>                  162      74       74       176      194.162  128.67   ###
+    <POUND SIGN>                 163      177      177      177      194.163  128.68
+    <CURRENCY SIGN>              164      159      159      159      194.164  128.69
+    <YEN SIGN>                   165      178      178      178      194.165  128.70
+    <BROKEN BAR>                 166      106      106      208      194.166  128.71   ###
+    <SECTION SIGN>               167      181      181      181      194.167  128.72
+    <DIAERESIS>                  168      189      187      121      194.168  128.73   *** ###
+    <COPYRIGHT SIGN>             169      180      180      180      194.169  128.74
+    <FEMININE ORDINAL INDICATOR> 170      154      154      154      194.170  128.81
+    <LEFT POINTING GUILLEMET>    171      138      138      138      194.171  128.82
+    <NOT SIGN>                   172      95       176      186      194.172  128.83   *** ###
+    <SOFT HYPHEN>                173      202      202      202      194.173  128.84
+    <REGISTERED TRADE MARK SIGN> 174      175      175      175      194.174  128.85
+    <MACRON>                     175      188      188      161      194.175  128.86   ###
+    <DEGREE SIGN>                176      144      144      144      194.176  128.87
+    <PLUS-OR-MINUS SIGN>         177      143      143      143      194.177  128.88
+    <SUPERSCRIPT TWO>            178      234      234      234      194.178  128.89
+    <SUPERSCRIPT THREE>          179      250      250      250      194.179  128.98
+    <ACUTE ACCENT>               180      190      190      190      194.180  128.99
+    <MICRO SIGN>                 181      160      160      160      194.181  128.100
+    <PARAGRAPH SIGN>             182      182      182      182      194.182  128.101
+    <MIDDLE DOT>                 183      179      179      179      194.183  128.102
+    <CEDILLA>                    184      157      157      157      194.184  128.103
+    <SUPERSCRIPT ONE>            185      218      218      218      194.185  128.104
+    <MASC. ORDINAL INDICATOR>    186      155      155      155      194.186  128.105
+    <RIGHT POINTING GUILLEMET>   187      139      139      139      194.187  128.106
+    <FRACTION ONE QUARTER>       188      183      183      183      194.188  128.112
+    <FRACTION ONE HALF>          189      184      184      184      194.189  128.113
+    <FRACTION THREE QUARTERS>    190      185      185      185      194.190  128.114
+    <INVERTED QUESTION MARK>     191      171      171      171      194.191  128.115
+    <A WITH GRAVE>               192      100      100      100      195.128  138.65
+    <A WITH ACUTE>               193      101      101      101      195.129  138.66
+    <A WITH CIRCUMFLEX>          194      98       98       98       195.130  138.67
+    <A WITH TILDE>               195      102      102      102      195.131  138.68
+    <A WITH DIAERESIS>           196      99       99       99       195.132  138.69
+    <A WITH RING ABOVE>          197      103      103      103      195.133  138.70
+    <CAPITAL LIGATURE AE>        198      158      158      158      195.134  138.71
+    <C WITH CEDILLA>             199      104      104      104      195.135  138.72
+    <E WITH GRAVE>               200      116      116      116      195.136  138.73
+    <E WITH ACUTE>               201      113      113      113      195.137  138.74
+    <E WITH CIRCUMFLEX>          202      114      114      114      195.138  138.81
+    <E WITH DIAERESIS>           203      115      115      115      195.139  138.82
+    <I WITH GRAVE>               204      120      120      120      195.140  138.83
+    <I WITH ACUTE>               205      117      117      117      195.141  138.84
+    <I WITH CIRCUMFLEX>          206      118      118      118      195.142  138.85
+    <I WITH DIAERESIS>           207      119      119      119      195.143  138.86
+    <CAPITAL LETTER ETH>         208      172      172      172      195.144  138.87
+    <N WITH TILDE>               209      105      105      105      195.145  138.88
+    <O WITH GRAVE>               210      237      237      237      195.146  138.89
+    <O WITH ACUTE>               211      238      238      238      195.147  138.98
+    <O WITH CIRCUMFLEX>          212      235      235      235      195.148  138.99
+    <O WITH TILDE>               213      239      239      239      195.149  138.100
+    <O WITH DIAERESIS>           214      236      236      236      195.150  138.101
+    <MULTIPLICATION SIGN>        215      191      191      191      195.151  138.102
+    <O WITH STROKE>              216      128      128      128      195.152  138.103
+    <U WITH GRAVE>               217      253      253      224      195.153  138.104  ###
+    <U WITH ACUTE>               218      254      254      254      195.154  138.105
+    <U WITH CIRCUMFLEX>          219      251      251      221      195.155  138.106  ###
+    <U WITH DIAERESIS>           220      252      252      252      195.156  138.112
+    <Y WITH ACUTE>               221      173      186      173      195.157  138.113  *** ###
+    <CAPITAL LETTER THORN>       222      174      174      174      195.158  138.114
+    <SMALL LETTER SHARP S>       223      89       89       89       195.159  138.115
+    <a WITH GRAVE>               224      68       68       68       195.160  139.65
+    <a WITH ACUTE>               225      69       69       69       195.161  139.66
+    <a WITH CIRCUMFLEX>          226      66       66       66       195.162  139.67
+    <a WITH TILDE>               227      70       70       70       195.163  139.68
+    <a WITH DIAERESIS>           228      67       67       67       195.164  139.69
+    <a WITH RING ABOVE>          229      71       71       71       195.165  139.70
+    <SMALL LIGATURE ae>          230      156      156      156      195.166  139.71
+    <c WITH CEDILLA>             231      72       72       72       195.167  139.72
+    <e WITH GRAVE>               232      84       84       84       195.168  139.73
+    <e WITH ACUTE>               233      81       81       81       195.169  139.74
+    <e WITH CIRCUMFLEX>          234      82       82       82       195.170  139.81
+    <e WITH DIAERESIS>           235      83       83       83       195.171  139.82
+    <i WITH GRAVE>               236      88       88       88       195.172  139.83
+    <i WITH ACUTE>               237      85       85       85       195.173  139.84
+    <i WITH CIRCUMFLEX>          238      86       86       86       195.174  139.85
+    <i WITH DIAERESIS>           239      87       87       87       195.175  139.86
+    <SMALL LETTER eth>           240      140      140      140      195.176  139.87
+    <n WITH TILDE>               241      73       73       73       195.177  139.88
+    <o WITH GRAVE>               242      205      205      205      195.178  139.89
+    <o WITH ACUTE>               243      206      206      206      195.179  139.98
+    <o WITH CIRCUMFLEX>          244      203      203      203      195.180  139.99
+    <o WITH TILDE>               245      207      207      207      195.181  139.100
+    <o WITH DIAERESIS>           246      204      204      204      195.182  139.101
+    <DIVISION SIGN>              247      225      225      225      195.183  139.102
+    <o WITH STROKE>              248      112      112      112      195.184  139.103
+    <u WITH GRAVE>               249      221      221      192      195.185  139.104  ###
+    <u WITH ACUTE>               250      222      222      222      195.186  139.105
+    <u WITH CIRCUMFLEX>          251      219      219      219      195.187  139.106
+    <u WITH DIAERESIS>           252      220      220      220      195.188  139.112
+    <y WITH ACUTE>               253      141      141      141      195.189  139.113
+    <SMALL LETTER thorn>         254      142      142      142      195.190  139.114
+    <y WITH DIAERESIS>           255      223      223      223      195.191  139.115
 
 If you would rather see the above table in CCSID 0037 order rather than
 ASCII + Latin-1 order then run the table through:
 
 =over 4
 
-=item recipe 2
+=item recipe 4
 
 =back
 
     perl -ne 'if(/.{33}\d{1,3}\s{6,8}\d{1,3}\s{6,8}\d{1,3}\s{6,8}\d{1,3}/)'\
      -e '{push(@l,$_)}' \
      -e 'END{print map{$_->[0]}' \
-     -e '          sort{$a->[1] <=> $b->[1]}' \ 
+     -e '          sort{$a->[1] <=> $b->[1]}' \
      -e '          map{[$_,substr($_,42,3)]}@l;}' perlebcdic.pod
 
 If you would rather see it in CCSID 1047 order then change the digit
@@ -418,14 +474,14 @@ If you would rather see it in CCSID 1047 order then change the digit
 
 =over 4
 
-=item recipe 3
+=item recipe 5
 
 =back
 
     perl -ne 'if(/.{33}\d{1,3}\s{6,8}\d{1,3}\s{6,8}\d{1,3}\s{6,8}\d{1,3}/)'\
      -e '{push(@l,$_)}' \
      -e 'END{print map{$_->[0]}' \
-     -e '          sort{$a->[1] <=> $b->[1]}' \ 
+     -e '          sort{$a->[1] <=> $b->[1]}' \
      -e '          map{[$_,substr($_,51,3)]}@l;}' perlebcdic.pod
 
 If you would rather see it in POSIX-BC order then change the digit
@@ -433,14 +489,14 @@ If you would rather see it in POSIX-BC order then change the digit
 
 =over 4
 
-=item recipe 4
+=item recipe 6
 
 =back
 
     perl -ne 'if(/.{33}\d{1,3}\s{6,8}\d{1,3}\s{6,8}\d{1,3}\s{6,8}\d{1,3}/)'\
      -e '{push(@l,$_)}' \
      -e 'END{print map{$_->[0]}' \
-     -e '          sort{$a->[1] <=> $b->[1]}' \ 
+     -e '          sort{$a->[1] <=> $b->[1]}' \
      -e '          map{[$_,substr($_,60,3)]}@l;}' perlebcdic.pod
 
 
@@ -541,22 +597,22 @@ XPG operability often implies the presence of an I<iconv> utility
 available from the shell or from the C library.  Consult your system's
 documentation for information on iconv.
 
-On OS/390 see the iconv(1) man page.  One way to invoke the iconv 
+On OS/390 or z/OS see the iconv(1) man page.  One way to invoke the iconv 
 shell utility from within perl would be to:
 
-    # OS/390 example
+    # OS/390 or z/OS example
     $ascii_data = `echo '$ebcdic_data'| iconv -f IBM-1047 -t ISO8859-1`
 
 or the inverse map:
 
-    # OS/390 example
+    # OS/390 or z/OS example
     $ebcdic_data = `echo '$ascii_data'| iconv -f ISO8859-1 -t IBM-1047`
 
 For other perl based conversion options see the Convert::* modules on CPAN.
 
 =head2 C RTL
 
-The OS/390 C run time library provides _atoe() and _etoa() functions.
+The OS/390 and z/OS C run time libraries provide _atoe() and _etoa() functions.
 
 =head1 OPERATOR DIFFERENCES
 
@@ -675,8 +731,8 @@ recommend something similar to:
     print "Content-type:\ttext/html\015\012\015\012"; 
     # this may be wrong on EBCDIC
 
-Under the IBM OS/390 USS Web Server for example you should instead
-write that as:
+Under the IBM OS/390 USS Web Server or WebSphere on z/OS for example 
+you should instead write that as:
 
     print "Content-type:\ttext/html\r\n\r\n"; # OK for DGW et alia
 
@@ -909,7 +965,7 @@ connection.
 This strategy can employ a network connection.  As such
 it would be computationally expensive.
 
-=head1 TRANFORMATION FORMATS
+=head1 TRANSFORMATION FORMATS
 
 There are a variety of ways of transforming data with an intra character set 
 mapping that serve a variety of purposes.  Sorting was discussed in the 
@@ -1073,7 +1129,7 @@ omitted for brevity):
     $string =~ s/=([0-9A-Fa-f][0-9A-Fa-f])/chr $a2e[hex $1]/ge;
     $string =~ s/=[\n\r]+$//;
 
-=head2 Caesarian cyphers
+=head2 Caesarian ciphers
 
 The practice of shifting an alphabet one or more characters for encipherment
 dates back thousands of years and was explicitly detailed by Gaius Julius
@@ -1100,6 +1156,9 @@ In one-liner form:
 
 =head1 Hashing order and checksums
 
+To the extent that it is possible to write code that depends on 
+hashing order there may be differences between hashes as stored
+on an ASCII based machine and hashes stored on an EBCDIC based machine.
 XXX
 
 =head1 I18N AND L10N
@@ -1110,7 +1169,11 @@ and discussed under the L<perlebcdic/OS ISSUES> section below.
 
 =head1 MULTI OCTET CHARACTER SETS
 
-Multi byte EBCDIC code pages; Unicode, UTF-8, UTF-EBCDIC, XXX.
+Perl may work with an internal UTF-EBCDIC encoding form for wide characters 
+on EBCDIC platforms in a manner analogous to the way that it works with 
+the UTF-8 internal encoding form on ASCII based platforms.
+
+Legacy multi byte EBCDIC code pages XXX.
 
 =head1 OS ISSUES
 
@@ -1129,7 +1192,7 @@ XXX.
 
 =back
 
-=head2 OS/390 
+=head2 OS/390, z/OS
 
 Perl runs under Unix Systems Services or USS.
 
@@ -1152,15 +1215,16 @@ or:
 
 See also the OS390::Stdio module on CPAN.
 
-=item OS/390 iconv
+=item OS/390, z/OS iconv
 
 B<iconv> is supported as both a shell utility and a C RTL routine.
 See also the iconv(1) and iconv(3) manual pages.
 
 =item locales
 
-On OS/390 see L<locale> for information on locales.  The L10N files
-are in F</usr/nls/locale>.  $Config{d_setlocale} is 'define' on OS/390.
+On OS/390 or z/OS see L<locale> for information on locales.  The L10N files
+are in F</usr/nls/locale>.  $Config{d_setlocale} is 'define' on OS/390
+or z/OS.
 
 =back
 
@@ -1180,17 +1244,15 @@ was known to strip accented characters to their unaccented counterparts
 while attempting to view this document through the B<pod2man> program 
 (for example, you may see a plain C<y> rather than one with a diaeresis 
 as in E<yuml>).  Another nroff truncated the resultant man page at
-the first occurence of 8 bit characters.
+the first occurrence of 8 bit characters.
 
 Not all shells will allow multiple C<-e> string arguments to perl to
-be concatenated together properly as recipes 2, 3, and 4 might seem
-to imply.
-
-Perl does not yet work with any Unicode features on EBCDIC platforms.
+be concatenated together properly as recipes 0, 2, 4, 5, and 6 might 
+seem to imply.
 
 =head1 SEE ALSO
 
-L<perllocale>, L<perlfunc>.
+L<perllocale>, L<perlfunc>, L<perlunicode>, L<utf8>.
 
 =head1 REFERENCES
 
@@ -1204,10 +1266,7 @@ http://www.wps.com/texts/codes/
 B<ASCII: American Standard Code for Information Infiltration> Tom Jennings,
 September 1999.
 
-B<The Unicode Standard Version 2.0> The Unicode Consortium, 
-ISBN 0-201-48345-9, Addison Wesley Developers Press, July 1996. 
-
-B<The Unicode Standard Version 3.0> The Unicode Consortium, Lisa Moore ed., 
+B<The Unicode Standard, Version 3.0> The Unicode Consortium, Lisa Moore ed., 
 ISBN 0-201-61633-5, Addison Wesley Developers Press, February 2000. 
 
 B<CDRA: IBM - Character Data Representation Architecture - 
@@ -1221,6 +1280,13 @@ B<Codes, Ciphers, and Other Cryptic and Clandestine Communication>
 Fred B. Wrixon, ISBN 1-57912-040-7, Black Dog & Leventhal Publishers,
 1998.
 
+http://www.bobbemer.com/P-BIT.HTM
+B<IBM - EBCDIC and the P-bit; The biggest Computer Goof Ever> Robert Bemer.
+
+=head1 HISTORY
+
+15 April 2001: added UTF-8 and UTF-EBCDIC to main table, pvhp.
+
 =head1 AUTHOR
 
 Peter Prymmer pvhp@best.com wrote this in 1999 and 2000 
index 1bba005..38128b9 100644 (file)
@@ -1081,4 +1081,4 @@ TIEHANDLE by Sven Verdoolaege <F<skimo@dns.ufsia.ac.be>> and Doug MacEachern <F<
 
 UNTIE by Nick Ing-Simmons <F<nick@ing-simmons.net>>
 
-Tying Arrays by Casey Tweten <F<crt@kiski.net>>
+Tying Arrays by Casey West <F<casey@geeknest.com>>
index b30b25f..d2fcbff 100644 (file)
@@ -2031,11 +2031,13 @@ to enable a few features
 
 =item POSIX-BC
 
+=item Unicode and UTF
+
 =back
 
 =item SINGLE OCTET TABLES
 
-recipe 0, recipe 1, recipe 2, recipe 3, recipe 4
+recipe 0, recipe 1, recipe 2, recipe 3, recipe 4, recipe 5, recipe 6
 
 =item IDENTIFYING CHARACTER CODE SETS
 
@@ -2075,7 +2077,7 @@ chr(), ord(), pack(), print(), printf(), sort(), sprintf(), unpack()
 
 =back
 
-=item TRANFORMATION FORMATS
+=item TRANSFORMATION FORMATS
 
 =over 4
 
@@ -2085,7 +2087,7 @@ chr(), ord(), pack(), print(), printf(), sort(), sprintf(), unpack()
 
 =item Quoted-Printable encoding and decoding
 
-=item Caesarian cyphers
+=item Caesarian ciphers
 
 =back
 
@@ -2103,9 +2105,9 @@ chr(), ord(), pack(), print(), printf(), sort(), sprintf(), unpack()
 
 IFS access
 
-=item OS/390 
+=item OS/390, z/OS
 
-chcp, dataset access, OS/390 iconv, locales
+chcp, dataset access, OS/390, z/OS iconv, locales
 
 =item VM/ESA?
 
@@ -2119,6 +2121,8 @@ chcp, dataset access, OS/390 iconv, locales
 
 =item REFERENCES
 
+=item HISTORY
+
 =item AUTHOR
 
 =back
@@ -9888,9 +9892,9 @@ C<untaint_pattern>, C<untaint_skip>
 
 =item DESCRIPTION
 
-C<GLOB_ERR>, C<GLOB_MARK>, C<GLOB_NOCASE>, C<GLOB_NOCHECK>, C<GLOB_NOSORT>,
-C<GLOB_BRACE>, C<GLOB_NOMAGIC>, C<GLOB_QUOTE>, C<GLOB_TILDE>, C<GLOB_CSH>,
-C<GLOB_ALPHASORT>
+C<GLOB_ERR>, C<GLOB_LIMIT>, C<GLOB_MARK>, C<GLOB_NOCASE>, C<GLOB_NOCHECK>,
+C<GLOB_NOSORT>, C<GLOB_BRACE>, C<GLOB_NOMAGIC>, C<GLOB_QUOTE>,
+C<GLOB_TILDE>, C<GLOB_CSH>, C<GLOB_ALPHASORT>
 
 =item DIAGNOSTICS
 
@@ -11154,6 +11158,58 @@ set ( NAME => VALUE [, NAME => VALUE ...] ), setall ( VALUES ), setval ( N
 
 =back
 
+=head2 List::Util - A selection of general-utility list subroutines
+
+=over 4
+
+=item SYNOPSIS
+
+=item DESCRIPTION
+
+first BLOCK LIST, max LIST, maxstr LIST, min LIST, minstr LIST, reduce
+BLOCK LIST, sum LIST
+
+=item SUGGESTED ADDITIONS
+
+=item COPYRIGHT
+
+=back
+
+=head2 List::Utilib::List::Util, List::Util - A selection of
+general-utility list subroutines
+
+=over 4
+
+=item SYNOPSIS
+
+=item DESCRIPTION
+
+first BLOCK LIST, max LIST, maxstr LIST, min LIST, minstr LIST, reduce
+BLOCK LIST, sum LIST
+
+=item SUGGESTED ADDITIONS
+
+=item COPYRIGHT
+
+=back
+
+=head2 List::Utilib::Scalar::Util, Scalar::Util - A selection of
+general-utility scalar subroutines
+
+=over 4
+
+=item SYNOPSIS
+
+=item DESCRIPTION
+
+blessed EXPR, dualvar NUM, STRING, isweak EXPR, reftype EXPR, weaken REF
+
+=item COPYRIGHT
+
+=item BLATANT PLUG
+
+=back
+
 =head2 Locale::Constants - constants for Locale codes
 
 =over 4
@@ -11532,12 +11588,14 @@ C<O_RDONLY>, C<O_WRONLY>, C<O_RDWR>
 
 =item DESCRIPTION
 
+icmp, udp, tcp, stream, external
+
 =over 4
 
 =item Functions
 
 Net::Ping->new([$proto [, $def_timeout [, $bytes]]]);, $p->ping($host [,
-$timeout]);, $p->close();, pingecho($host [, $timeout]);
+$timeout]);, $p->open($host);, $p->close();, pingecho($host [, $timeout]);
 
 =back
 
@@ -13077,6 +13135,22 @@ Memory, CPU, Snooping, Signals, State Changes
 
 =back
 
+=head2 Scalar::Util - A selection of general-utility scalar subroutines
+
+=over 4
+
+=item SYNOPSIS
+
+=item DESCRIPTION
+
+blessed EXPR, dualvar NUM, STRING, isweak EXPR, reftype EXPR, weaken REF
+
+=item COPYRIGHT
+
+=item BLATANT PLUG
+
+=back
+
 =head2 Search::Dict, look - search for key in dictionary file
 
 =over 4
@@ -13773,6 +13847,32 @@ TIESCALAR classname, LIST, FETCH this, STORE this, value, DESTROY this
 
 =back
 
+=head2 Time::HiRes - High resolution ualarm, usleep, and gettimeofday
+
+=over 4
+
+=item SYNOPSIS
+
+=item DESCRIPTION
+
+gettimeofday (), usleep ( $useconds ), ualarm ( $useconds [,
+$interval_useconds ] ), tv_interval ( $ref_to_gettimeofday [,
+$ref_to_later_gettimeofday] ), time (), sleep ( $floating_seconds ), alarm
+( $floating_seconds [, $interval_floating_seconds ] ), setitimer ( $which,
+$floating_seconds [, $interval_floating_seconds ] ), getitimer ( $which )
+
+=item EXAMPLES
+
+=item C API
+
+=item AUTHORS
+
+=item REVISION
+
+=item COPYRIGHT
+
+=back
+
 =head2 Time::Local - efficiently compute time from local and GMT time
 
 =over 4
@@ -13787,6 +13887,59 @@ TIESCALAR classname, LIST, FETCH this, STORE this, value, DESTROY this
 
 =back
 
+=head2 Time::Piece - Object Oriented time objects
+
+=over 4
+
+=item SYNOPSIS
+
+=item DESCRIPTION
+
+=item USAGE
+
+=over 4
+
+=item Local Locales
+
+=item Date Calculations
+
+=item Date Comparisons
+
+=item Global Overriding
+
+=back
+
+=item AUTHOR
+
+=over 4
+
+=item License
+
+=item Bugs
+
+=back
+
+=back
+
+=head2 Time::Piece::Seconds, Time::Seconds - a simple API to convert
+seconds to other date values
+
+=over 4
+
+=item SYNOPSIS
+
+=item DESCRIPTION
+
+=item METHODS
+
+=item AUTHOR
+
+=item LICENSE
+
+=item Bugs
+
+=back
+
 =head2 Time::gmtime - by-name interface to Perl's built-in gmtime()
 function
 
index 1ddaf25..831ad08 100644 (file)
@@ -105,21 +105,29 @@ else {
 }
 
 if ($Config{d_symlink}) {
-    my @dirs = split " " => $Config{libpth};
-    my $target = pop @dirs;
-    symlink $target => "linktest";
-    mkdir "pteerslt";
-    chdir "pteerslt";
-    my $rel = "../../t/linktest";
-
-    my $abs_path      = Cwd::abs_path($rel);
-    my $fast_abs_path = Cwd::fast_abs_path($rel);
-    print +($abs_path      eq $target ? "" : "not "), "ok 13\n";
-    print +($fast_abs_path eq $target ? "" : "not "), "ok 14\n";
-
-    chdir "..";
-    rmdir "pteerslt";
-    unlink "linktest";
+    my @dirs = grep(! -l $_ => (split " " => $Config{libpth}));
+    if (@dirs) {
+       my $target = pop @dirs;
+       symlink $target => "linktest";
+       mkdir "pteerslt";
+       chdir "pteerslt";
+       my $rel = "../../t/linktest";
+       
+       my $abs_path      = Cwd::abs_path($rel);
+       my $fast_abs_path = Cwd::fast_abs_path($rel);
+       print "# abs_path      $abs_path\n";
+       print "# fast_abs_path $fast_abs_path\n";
+       print "# target        $target\n";
+       print +($abs_path      eq $target ? "" : "not "), "ok 13\n";
+       print +($fast_abs_path eq $target ? "" : "not "), "ok 14\n";
+       
+       chdir "..";
+       rmdir "pteerslt";
+       unlink "linktest";
+    } else {
+       print "ok 13 # skipped\n";
+       print "ok 14 # skipped\n";
+    }
 } else {
     print "ok 13 # skipped\n";
     print "ok 14 # skipped\n";
diff --git a/t/lib/exporter.t b/t/lib/exporter.t
new file mode 100644 (file)
index 0000000..d5c4073
--- /dev/null
@@ -0,0 +1,145 @@
+#!./perl
+
+BEGIN {
+    chdir 't' if -d 't';
+    @INC = '../lib';
+}
+
+# Utility testing functions.
+my $test_num = 1;
+sub ok ($;$) {
+    my($test, $name) = @_;
+    print "not " unless $test;
+    print "ok $test_num";
+    print " - $name" if defined $name;
+    print "\n";
+    $test_num++;
+}
+
+
+my $loaded;
+BEGIN { $| = 1; $^W = 1; }
+END {print "not ok $test_num\n" unless $loaded;}
+print "1..$Total_tests\n";
+use Exporter;
+$loaded = 1;
+ok(1, 'compile');
+
+
+BEGIN {
+    # Methods which Exporter says it implements.
+    @Exporter_Methods = qw(import
+                           export_to_level
+                           require_version
+                           export_fail
+                          );
+}
+
+BEGIN { $Total_tests = 14 + @Exporter_Methods }
+
+package Testing;
+require Exporter;
+@ISA = qw(Exporter);
+
+# Make sure Testing can do everything its supposed to.
+foreach my $meth (@::Exporter_Methods) {
+    ::ok( Testing->can($meth), "subclass can $meth()" );
+}
+
+%EXPORT_TAGS = (
+                This => [qw(stuff %left)],
+                That => [qw(Above the @wailing)],
+                tray => [qw(Fasten $seatbelt)],
+               );
+@EXPORT    = qw(lifejacket);
+@EXPORT_OK = qw(under &your $seat);
+$VERSION = '1.05';
+
+::ok( Testing->require_version(1.05),   'require_version()' );
+eval { Testing->require_version(1.11); 1 };
+::ok( $@,                               'require_version() fail' );
+::ok( Testing->require_version(0),      'require_version(0)' );
+
+sub lifejacket  { 'lifejacket'  }
+sub stuff       { 'stuff'       }
+sub Above       { 'Above'       }
+sub the         { 'the'         }
+sub Fasten      { 'Fasten'      }
+sub your        { 'your'        }
+sub under       { 'under'       }
+use vars qw($seatbelt $seat @wailing %left);
+$seatbelt = 'seatbelt';
+$seat     = 'seat';
+@wailing = qw(AHHHHHH);
+%left = ( left => "right" );
+
+
+Exporter::export_ok_tags;
+
+my %tags     = map { $_ => 1 } map { @$_ } values %EXPORT_TAGS;
+my %exportok = map { $_ => 1 } @EXPORT_OK;
+my $ok = 1;
+foreach my $tag (keys %tags) {
+    $ok = exists $exportok{$tag};
+}
+::ok( $ok, 'export_ok_tags()' );
+
+
+package Foo;
+Testing->import;
+
+::ok( defined &lifejacket,      'simple import' );
+
+
+package Bar;
+my @imports = qw($seatbelt &Above stuff @wailing %left);
+Testing->import(@imports);
+
+::ok( (!grep { eval "!defined $_" } map({ /^\w/ ? "&$_" : $_ } @imports)),
+      'import by symbols' );
+
+
+package Yar;
+my @tags = qw(:This :tray);
+Testing->import(@tags);
+
+::ok( (!grep { eval "!defined $_" } map { /^\w/ ? "&$_" : $_ }
+             map { @$_ } @{$Testing::EXPORT_TAGS{@tags}}),
+      'import by tags' );
+
+
+package Arrr;
+Testing->import(qw(!lifejacket));
+
+::ok( !defined &lifejacket,     'deny import by !' );
+
+
+package Mars;
+Testing->import('/e/');
+
+::ok( (!grep { eval "!defined $_" } map { /^\w/ ? "&$_" : $_ }
+            grep { /e/ } @Testing::EXPORT, @Testing::EXPORT_OK),
+      'import by regex');
+
+
+package Venus;
+Testing->import('!/e/');
+
+::ok( (!grep { eval "defined $_" } map { /^\w/ ? "&$_" : $_ }
+            grep { /e/ } @Testing::EXPORT, @Testing::EXPORT_OK),
+      'deny import by regex');
+::ok( !defined &lifejacket, 'further denial' );
+
+
+package More::Testing;
+@ISA = qw(Exporter);
+$VERSION = 0;
+eval { More::Testing->require_version(0); 1 };
+::ok(!$@,       'require_version(0) and $VERSION = 0');
+
+
+package Yet::More::Testing;
+@ISA = qw(Exporter);
+$VERSION = 0;
+eval { Yet::More::Testing->require_version(10); 1 };
+::ok($@ !~ /\(undef\)/,       'require_version(10) and $VERSION = 0');
index 50c20f0..cc741e7 100644 (file)
@@ -3,7 +3,7 @@ BEGIN {
     @INC = '../lib';
 }
 
-BEGIN { $| = 1; print "1..17\n"; }
+BEGIN { $| = 1; print "1..19\n"; }
 
 END {print "not ok 1\n" unless $loaded;}
 
@@ -23,6 +23,8 @@ import Time::HiRes 'gettimeofday'     if $have_gettimeofday;
 import Time::HiRes 'usleep'            if $have_usleep;
 import Time::HiRes 'ualarm'            if $have_ualarm;
 
+use Config;
+
 sub skip {
     map { print "ok $_ (skipped)\n" } @_;
 }
@@ -159,18 +161,56 @@ unless (defined &Time::HiRes::gettimeofday
     $SIG{ALRM} = "tick";
     while ($i)
     {
-       alarm(2.5);
+       alarm(0.3);
        select (undef, undef, undef, 10);
-       print "# Select returned! ", Time::HiRes::tv_interval ($r), "\n";
+       print "# Select returned! $i ", Time::HiRes::tv_interval ($r), "\n";
     }
 
     sub tick
     {
-       print "# Tick! ", Time::HiRes::tv_interval ($r), "\n";
        $i--;
+       print "# Tick! $i ", Time::HiRes::tv_interval ($r), "\n";
     }
     $SIG{ALRM} = 'DEFAULT';
 
     print "ok 17\n";
 }
 
+unless (defined &Time::HiRes::setitimer
+       && defined &Time::HiRes::getitimer
+       && exists &Time::HiRes::ITIMER_VIRTUAL
+       && $Config{d_select}) {
+    for (18..19) {
+       print "ok $_ # Skip: no virtual interval timers\n";
+    }
+} else {
+    use Time::HiRes qw (setitimer getitimer ITIMER_VIRTUAL);
+
+    my $i = 3;
+    my $r = [Time::HiRes::gettimeofday];
+
+    $SIG{VTALRM} = sub {
+       $i ? $i-- : setitimer(ITIMER_VIRTUAL, 0);
+       print "# Tick! $i ", Time::HiRes::tv_interval($r), "\n";
+    }; 
+
+    print "# setitimer: ", join(" ", setitimer(ITIMER_VIRTUAL, 0.5, 0.4)), "\n";
+
+    # Assume interval timer granularity of 0.05 seconds.  Too bold?
+    print "not " unless abs(getitimer(ITIMER_VIRTUAL) / 0.5) - 1 < 0.1;
+    print "ok 18\n";
+
+    print "# getitimer: ", join(" ", getitimer(ITIMER_VIRTUAL)), "\n";
+
+    while (getitimer(ITIMER_VIRTUAL)) {
+       my $j; $j++ for 1..1000; # Can't be unbreakable, must test getitimer().
+    }
+
+    print "# getitimer: ", join(" ", getitimer(ITIMER_VIRTUAL)), "\n";
+
+    print "not " unless getitimer(ITIMER_VIRTUAL) == 0;
+    print "ok 19\n";
+
+    $SIG{VTALRM} = 'DEFAULT';
+}
+
diff --git a/t/lib/u-blessed.t b/t/lib/u-blessed.t
new file mode 100755 (executable)
index 0000000..d70e023
--- /dev/null
@@ -0,0 +1,34 @@
+BEGIN {
+       chdir 't' if -d 't';
+       @INC = '../lib';
+}
+
+use Scalar::Util qw(blessed);
+use vars qw($t $y $x);
+
+print "1..7\n";
+
+print "not " if blessed(1);
+print "ok 1\n";
+
+print "not " if blessed('A');
+print "ok 2\n";
+
+print "not " if blessed({});
+print "ok 3\n";
+
+print "not " if blessed([]);
+print "ok 4\n";
+
+$y = \$t;
+
+print "not " if blessed($y);
+print "ok 5\n";
+
+$x = bless [], "ABC";
+
+print "not " unless blessed($x);
+print "ok 6\n";
+
+print "not " unless blessed($x) eq 'ABC';
+print "ok 7\n";
diff --git a/t/lib/u-dualvar.t b/t/lib/u-dualvar.t
new file mode 100755 (executable)
index 0000000..acee8ad
--- /dev/null
@@ -0,0 +1,41 @@
+BEGIN {
+       chdir 't' if -d 't';
+       @INC = '../lib';
+}
+
+BEGIN {
+  require Scalar::Util;
+
+  if (grep { /dualvar/ } @Scalar::Util::EXPORT_FAIL) {
+    print "1..0\n";
+    exit;
+  }
+}
+
+use Scalar::Util qw(dualvar);
+
+print "1..6\n";
+
+$var = dualvar 2.2,"string";
+
+print "not " unless $var == 2.2;
+print "ok 1\n";
+
+print "not " unless $var eq "string";
+print "ok 2\n";
+
+$var2 = $var;
+
+$var++;
+
+print "not " unless $var == 3.2;
+print "ok 3\n";
+
+print "not " unless $var ne "string";
+print "ok 4\n";
+
+print "not " unless $var2 == 2.2;
+print "ok 5\n";
+
+print "not " unless $var2 eq "string";
+print "ok 6\n";
diff --git a/t/lib/u-first.t b/t/lib/u-first.t
new file mode 100755 (executable)
index 0000000..71f3de4
--- /dev/null
@@ -0,0 +1,20 @@
+BEGIN {
+       chdir 't' if -d 't';
+       @INC = '../lib';
+}
+
+use List::Util qw(first);
+
+print "1..4\n";
+
+print "not " unless defined &first;
+print "ok 1\n";
+
+print "not " unless 9 == first { 8 == ($_ - 1) } 9,4,5,6;
+print "ok 2\n";
+
+print "not " if defined(first { 0 } 1,2,3,4);
+print "ok 3\n";
+
+print "not " if defined(first { 0 });
+print "ok 4\n";
diff --git a/t/lib/u-max.t b/t/lib/u-max.t
new file mode 100755 (executable)
index 0000000..f4873bd
--- /dev/null
@@ -0,0 +1,25 @@
+BEGIN {
+       chdir 't' if -d 't';
+       @INC = '../lib';
+}
+
+use List::Util qw(max);
+
+print "1..5\n";
+
+print "not " unless defined &max;
+print "ok 1\n";
+
+print "not " unless max(1) == 1;
+print "ok 2\n";
+
+print "not " unless max(1,2) == 2;
+print "ok 3\n";
+
+print "not " unless max(2,1) == 2;
+print "ok 4\n";
+
+my @a = map { rand() } 1 .. 20;
+my @b = sort { $a <=> $b } @a;
+print "not " unless max(@a) == $b[-1];
+print "ok 5\n";
diff --git a/t/lib/u-maxstr.t b/t/lib/u-maxstr.t
new file mode 100755 (executable)
index 0000000..7964613
--- /dev/null
@@ -0,0 +1,25 @@
+BEGIN {
+       chdir 't' if -d 't';
+       @INC = '../lib';
+}
+
+use List::Util qw(maxstr);
+
+print "1..5\n";
+
+print "not " unless defined &maxstr;
+print "ok 1\n";
+
+print "not " unless maxstr('a') eq 'a';
+print "ok 2\n";
+
+print "not " unless maxstr('a','b') eq 'b';
+print "ok 3\n";
+
+print "not " unless maxstr('B','A') eq 'B';
+print "ok 4\n";
+
+my @a = map { pack("u", pack("C*",map { int(rand(256))} (0..int(rand(10) + 2)))) } 0 .. 20;
+my @b = sort { $a cmp $b } @a;
+print "not " unless maxstr(@a) eq $b[-1];
+print "ok 5\n";
diff --git a/t/lib/u-min.t b/t/lib/u-min.t
new file mode 100755 (executable)
index 0000000..124d88a
--- /dev/null
@@ -0,0 +1,25 @@
+BEGIN {
+       chdir 't' if -d 't';
+       @INC = '../lib';
+}
+
+use List::Util qw(min);
+
+print "1..5\n";
+
+print "not " unless defined &min;
+print "ok 1\n";
+
+print "not " unless min(9) == 9;
+print "ok 2\n";
+
+print "not " unless min(1,2) == 1;
+print "ok 3\n";
+
+print "not " unless min(2,1) == 1;
+print "ok 4\n";
+
+my @a = map { rand() } 1 .. 20;
+my @b = sort { $a <=> $b } @a;
+print "not " unless min(@a) == $b[0];
+print "ok 5\n";
diff --git a/t/lib/u-minstr.t b/t/lib/u-minstr.t
new file mode 100755 (executable)
index 0000000..12dc2fb
--- /dev/null
@@ -0,0 +1,25 @@
+BEGIN {
+       chdir 't' if -d 't';
+       @INC = '../lib';
+}
+
+use List::Util qw(minstr);
+
+print "1..5\n";
+
+print "not " unless defined &minstr;
+print "ok 1\n";
+
+print "not " unless minstr('a') eq 'a';
+print "ok 2\n";
+
+print "not " unless minstr('a','b') eq 'a';
+print "ok 3\n";
+
+print "not " unless minstr('B','A') eq 'A';
+print "ok 4\n";
+
+my @a = map { pack("u", pack("C*",map { int(rand(256))} (0..int(rand(10) + 2)))) } 0 .. 20;
+my @b = sort { $a cmp $b } @a;
+print "not " unless minstr(@a) eq $b[0];
+print "ok 5\n";
diff --git a/t/lib/u-readonly.t b/t/lib/u-readonly.t
new file mode 100644 (file)
index 0000000..5079725
--- /dev/null
@@ -0,0 +1,41 @@
+BEGIN {
+       chdir 't' if -d 't';
+       @INC = '../lib';
+}
+
+use Scalar::Util qw(readonly);
+
+print "1..9\n";
+
+print "not " unless readonly(1);
+print "ok 1\n";
+
+my $var = 2;
+
+print "not " if readonly($var);
+print "ok 2\n";
+
+print "not " unless $var == 2;
+print "ok 3\n";
+
+print "not " unless readonly("fred");
+print "ok 4\n";
+
+$var = "fred";
+
+print "not " if readonly($var);
+print "ok 5\n";
+
+print "not " unless $var eq "fred";
+print "ok 6\n";
+
+$var = \2;
+
+print "not " if readonly($var);
+print "ok 7\n";
+
+print "not " unless readonly($$var);
+print "ok 8\n";
+
+print "not " if readonly(*STDOUT);
+print "ok 9\n";
diff --git a/t/lib/u-reduce.t b/t/lib/u-reduce.t
new file mode 100755 (executable)
index 0000000..d00dea1
--- /dev/null
@@ -0,0 +1,25 @@
+BEGIN {
+       chdir 't' if -d 't';
+       @INC = '../lib';
+}
+
+use List::Util qw(reduce min);
+
+print "1..5\n";
+
+print "not " if defined reduce {};
+print "ok 1\n";
+
+print "not " unless 9 == reduce { $a / $b } 756,3,7,4;
+print "ok 2\n";
+
+print "not " unless 9 == reduce { $a / $b } 9;
+print "ok 3\n";
+
+@a = map { rand } 0 .. 20;
+print "not " unless min(@a) == reduce { $a < $b ? $a : $b } @a;
+print "ok 4\n";
+
+@a = map { pack("C", int(rand(256))) } 0 .. 20;
+print "not " unless join("",@a) eq reduce { $a . $b } @a;
+print "ok 5\n";
diff --git a/t/lib/u-reftype.t b/t/lib/u-reftype.t
new file mode 100755 (executable)
index 0000000..06f9ffb
--- /dev/null
@@ -0,0 +1,50 @@
+BEGIN {
+       chdir 't' if -d 't';
+       @INC = '../lib';
+}
+
+use Scalar::Util qw(reftype);
+use vars qw($t $y $x *F);
+use Symbol qw(gensym);
+
+# Ensure we do not trigger and tied methods
+tie *F, 'MyTie';
+
+@test = (
+ [ undef, 1],
+ [ undef, 'A'],
+ [ HASH => {} ],
+ [ ARRAY => [] ],
+ [ SCALAR => \$t ],
+ [ REF    => \(\$t) ],
+ [ GLOB   => \*F ],
+ [ GLOB   => gensym ],
+ [ CODE   => sub {} ],
+# [ IO => *STDIN{IO} ] the internal sv_reftype returns UNKNOWN
+);
+
+print "1..", @test*4, "\n";
+
+my $i = 1;
+foreach $test (@test) {
+  my($type,$what) = @$test;
+  my $pack;
+  foreach $pack (undef,"ABC","0",undef) {
+    print "# $what\n";
+    my $res = reftype($what);
+    printf "# %s - %s\n", map { defined($_) ? $_ : 'undef' } $type,$res;
+    print "not " if $type ? $res ne $type : defined($res);
+    bless $what, $pack if $type && defined $pack;
+    print "ok ",$i++,"\n";
+  }
+}
+
+package MyTie;
+
+sub TIEHANDLE { bless {} }
+sub DESTROY {}
+
+sub AUTOLOAD {
+  warn "$AUTOLOAD called";
+  exit 1; # May be in an eval
+}
diff --git a/t/lib/u-sum.t b/t/lib/u-sum.t
new file mode 100755 (executable)
index 0000000..9c1c7cb
--- /dev/null
@@ -0,0 +1,18 @@
+BEGIN {
+       chdir 't' if -d 't';
+       @INC = '../lib';
+}
+
+use List::Util qw(sum);
+
+print "1..3\n";
+
+print "not " if defined sum;
+print "ok 1\n";
+
+print "not " unless sum(9) == 9;
+print "ok 2\n";
+
+print "not " unless sum(1,2,3,4) == 10;
+print "ok 3\n";
+
diff --git a/t/lib/u-tainted.t b/t/lib/u-tainted.t
new file mode 100644 (file)
index 0000000..c38cf1a
--- /dev/null
@@ -0,0 +1,33 @@
+#!./perl -T
+
+BEGIN {
+       chdir 't' if -d 't';
+       @INC = '../lib';
+}
+
+use lib qw(blib/lib blib/arch);
+use Scalar::Util qw(tainted);
+use Config;
+
+print "1..5\n";
+
+print "not " if tainted(1);
+print "ok 1\n";
+
+my $var = 2;
+
+print "not " if tainted($var);
+print "ok 2\n";
+
+my $key = (keys %ENV)[0];
+
+$var = $ENV{$key};
+
+print "not " unless tainted($var);
+print "ok 3\n";
+
+print "not " unless tainted($ENV{$key});
+print "ok 4\n";
+
+print "not " if @ARGV and not tainted($ARGV[0]);
+print "ok 5\n";
diff --git a/t/lib/u-weak.t b/t/lib/u-weak.t
new file mode 100755 (executable)
index 0000000..bab6197
--- /dev/null
@@ -0,0 +1,201 @@
+BEGIN {
+       chdir 't' if -d 't';
+       @INC = '../lib';
+}
+
+BEGIN {
+  $|=1;
+  require Scalar::Util;
+  if (grep { /weaken/ } @Scalar::Util::EXPORT_FAIL) {
+    print("1..0\n");
+    exit;
+  }
+
+  $DEBUG = 0;
+
+  if ($DEBUG && eval { require Devel::Peek } ) {
+    Devel::Peek->import('Dump');
+  }
+  else {
+    *Dump = sub {};
+  }
+}
+
+use Scalar::Util qw(weaken isweak);
+print "1..17\n";
+
+######################### End of black magic.
+
+$cnt = 0;
+
+sub ok {
+       ++$cnt;
+       if($_[0]) { print "ok $cnt\n"; } else {print "not ok $cnt\n"; }
+}
+
+$| = 1;
+
+if(1) {
+
+my ($y,$z);
+
+#
+# Case 1: two references, one is weakened, the other is then undef'ed.
+#
+
+{
+       my $x = "foo";
+       $y = \$x;
+       $z = \$x;
+}
+print "# START:\n";
+Dump($y); Dump($z);
+
+ok( $y ne "" and $z ne "" );
+weaken($y);
+
+print "# WEAK:\n";
+Dump($y); Dump($z);
+
+ok( $y ne "" and $z ne "" );
+undef($z);
+
+print "# UNDZ:\n";
+Dump($y); Dump($z);
+
+ok( not (defined($y) and defined($z)) );
+undef($y);
+
+print "# UNDY:\n";
+Dump($y); Dump($z);
+
+ok( not (defined($y) and defined($z)) );
+
+print "# FIN:\n";
+Dump($y); Dump($z);
+
+# exit(0);
+
+# }
+# {
+
+# 
+# Case 2: one reference, which is weakened
+#
+
+# kill 5,$$;
+
+print "# CASE 2:\n";
+
+{
+       my $x = "foo";
+       $y = \$x;
+}
+
+ok( $y ne "" );
+print "# BW: \n";
+Dump($y);
+weaken($y);
+print "# AW: \n";
+Dump($y);
+ok( not defined $y  );
+
+print "# EXITBLOCK\n";
+}
+
+# exit(0);
+
+# 
+# Case 3: a circular structure
+#
+
+# kill 5, $$;
+
+$flag = 0;
+{
+       my $y = bless {}, Dest;
+       Dump($y);
+       print "# 1: $y\n";
+       $y->{Self} = $y;
+       Dump($y);
+       print "# 2: $y\n";
+       $y->{Flag} = \$flag;
+       print "# 3: $y\n";
+       weaken($y->{Self});
+       print "# WKED\n";
+       ok( $y ne "" );
+       print "# VALS: HASH ",$y,"   SELF ",\$y->{Self},"  Y ",\$y, 
+               "    FLAG: ",\$y->{Flag},"\n";
+       print "# VPRINT\n";
+}
+print "# OUT $flag\n";
+ok( $flag == 1 );
+
+print "# AFTER\n";
+
+undef $flag;
+
+print "# FLAGU\n";
+
+#
+# Case 4: a more complicated circular structure
+#
+
+$flag = 0;
+{
+       my $y = bless {}, Dest;
+       my $x = bless {}, Dest;
+       $x->{Ref} = $y;
+       $y->{Ref} = $x;
+       $x->{Flag} = \$flag;
+       $y->{Flag} = \$flag;
+       weaken($x->{Ref});
+}
+ok( $flag == 2 );
+
+#
+# Case 5: deleting a weakref before the other one
+#
+
+{
+       my $x = "foo";
+       $y = \$x;
+       $z = \$x;
+}
+
+print "# CASE5\n";
+Dump($y);
+
+weaken($y);
+Dump($y);
+undef($y);
+
+ok( not defined $y);
+ok($z ne "");
+
+
+#
+# Case 6: test isweakref
+#
+
+$a = 5;
+ok(!isweak($a));
+$b = \$a;
+ok(!isweak($b));
+weaken($b);
+ok(isweak($b));
+$b = \$a;
+ok(!isweak($b));
+
+$x = {};
+weaken($x->{Y} = \$a);
+ok(isweak($x->{Y}));
+ok(!isweak($x->{Z}));
+
+
+package Dest;
+
+sub DESTROY {
+       print "# INCFLAG\n";
+       ${$_[0]{Flag}} ++;
+}
index a7416f2..2ed9df1 100644 (file)
@@ -31,7 +31,7 @@
 #
 #  -- .robin. <robin@kitsite.com>  2001-03-13
 
-print "1..39\n";
+print "1..41\n";
 
 my $ok;
 
@@ -923,3 +923,24 @@ TEST39: {
     }
 }
 print ($ok ? "ok 39\n" : "not ok 39\n");
+
+
+### Test that loop control is dynamicly scoped.
+
+sub test_last_label { last TEST40 }
+
+TEST40: {
+    $ok = 1;
+    test_last_label();
+    $ok = 0;
+}
+print ($ok ? "ok 40\n" : "not ok 40\n");
+
+sub test_last { last }
+
+TEST41: {
+    $ok = 1;
+    test_last();
+    $ok = 0;
+}
+print ($ok ? "ok 41\n" : "not ok 41\n");
index e2c7500..591f039 100644 (file)
@@ -27,7 +27,7 @@ else
 my $files = 0;
 foreach my $file (@w_files) {
 
-    next if /(~|\.orig|,v)$/;
+    next if $file =~ /(~|\.orig|,v)$/;
 
     open F, "<$file" or die "Cannot open $file: $!\n" ;
     my $line = 0;
diff --git a/utf8.c b/utf8.c
index 25cd0fd..785047e 100644 (file)
--- a/utf8.c
+++ b/utf8.c
@@ -27,7 +27,7 @@
 /* Unicode support */
 
 /*
-=for apidoc A|U8*|uvuni_to_utf8|U8 *d|UV uv
+=for apidoc A|U8 *|uvuni_to_utf8|U8 *d|UV uv
 
 Adds the UTF8 representation of the Unicode codepoint C<uv> to the end
 of the string C<d>; C<d> should be have at least C<UTF8_MAXLEN+1> free
@@ -141,7 +141,8 @@ character.  Note that an INVARIANT (i.e. ASCII) character is a valid UTF-8 chara
 The actual number of bytes in the UTF-8 character will be returned if
 it is valid, otherwise 0.
 
-=cut */
+=cut
+*/
 STRLEN
 Perl_is_utf8_char(pTHX_ U8 *s)
 {
@@ -236,10 +237,11 @@ the strict UTF-8 encoding (see F<utf8.h>).
 
 Most code should use utf8_to_uvchr() rather than call this directly.
 
-=cut */
+=cut
+*/
 
 UV
-Perl_utf8n_to_uvuni(pTHX_ U8* s, STRLEN curlen, STRLEN* retlen, U32 flags)
+Perl_utf8n_to_uvuni(pTHX_ U8 *s, STRLEN curlen, STRLEN *retlen, U32 flags)
 {
     UV uv = *s, ouv;
     STRLEN len = 1;
@@ -439,7 +441,7 @@ malformed:
 }
 
 /*
-=for apidoc A|U8* s|utf8_to_uvchr|STRLEN *retlen
+=for apidoc A|UV|utf8_to_uvchr|U8 *s|STRLEN *retlen
 
 Returns the native character value of the first character in the string C<s>
 which is assumed to be in UTF8 encoding; C<retlen> will be set to the
@@ -452,13 +454,13 @@ returned and retlen is set, if possible, to -1.
 */
 
 UV
-Perl_utf8_to_uvchr(pTHX_ U8* s, STRLEN* retlen)
+Perl_utf8_to_uvchr(pTHX_ U8 *s, STRLEN *retlen)
 {
     return Perl_utf8n_to_uvchr(aTHX_ s, UTF8_MAXLEN, retlen, 0);
 }
 
 /*
-=for apidoc A|U8* s|utf8_to_uvuni|STRLEN *retlen
+=for apidoc A|UV|utf8_to_uvuni|U8 *s|STRLEN *retlen
 
 Returns the Unicode code point of the first character in the string C<s>
 which is assumed to be in UTF8 encoding; C<retlen> will be set to the
@@ -474,14 +476,14 @@ returned and retlen is set, if possible, to -1.
 */
 
 UV
-Perl_utf8_to_uvuni(pTHX_ U8* s, STRLEN* retlen)
+Perl_utf8_to_uvuni(pTHX_ U8 *s, STRLEN *retlen)
 {
     /* Call the low level routine asking for checks */
     return Perl_utf8n_to_uvuni(aTHX_ s, UTF8_MAXLEN, retlen, 0);
 }
 
 /*
-=for apidoc A|STRLEN|utf8_length|U8* s|U8 *e
+=for apidoc A|STRLEN|utf8_length|U8 *s|U8 *e
 
 Return the length of the UTF-8 char encoded string C<s> in characters.
 Stops at C<e> (inclusive).  If C<e E<lt> s> or if the scan would end
@@ -491,7 +493,7 @@ up past C<e>, croaks.
 */
 
 STRLEN
-Perl_utf8_length(pTHX_ U8* s, U8* e)
+Perl_utf8_length(pTHX_ U8 *s, U8 *e)
 {
     STRLEN len = 0;
 
@@ -522,7 +524,8 @@ and C<b>.
 WARNING: use only if you *know* that the pointers point inside the
 same UTF-8 buffer.
 
-=cut */
+=cut
+*/
 
 IV
 Perl_utf8_distance(pTHX_ U8 *a, U8 *b)
@@ -558,7 +561,7 @@ Perl_utf8_distance(pTHX_ U8 *a, U8 *b)
 }
 
 /*
-=for apidoc A|U8*|utf8_hop|U8 *s|I32 off
+=for apidoc A|U8 *|utf8_hop|U8 *s|I32 off
 
 Return the UTF-8 pointer C<s> displaced by C<off> characters, either
 forward or backward.
@@ -567,7 +570,8 @@ WARNING: do not use the following unless you *know* C<off> is within
 the UTF-8 data pointed to by C<s> *and* that on entry C<s> is aligned
 on the first byte of character or just after the last byte of a character.
 
-=cut */
+=cut
+*/
 
 U8 *
 Perl_utf8_hop(pTHX_ U8 *s, I32 off)
@@ -602,7 +606,7 @@ Returns zero on failure, setting C<len> to -1.
 */
 
 U8 *
-Perl_utf8_to_bytes(pTHX_ U8* s, STRLEN *len)
+Perl_utf8_to_bytes(pTHX_ U8 *s, STRLEN *len)
 {
     U8 *send;
     U8 *d;
@@ -641,10 +645,11 @@ length.  Returns the original string if no conversion occurs, C<len>
 is unchanged. Do nothing if C<is_utf8> points to 0. Sets C<is_utf8> to
 0 if C<s> is converted or contains all 7bit characters.
 
-=cut */
+=cut
+*/
 
 U8 *
-Perl_bytes_from_utf8(pTHX_ U8* s, STRLEN *len, bool *is_utf8)
+Perl_bytes_from_utf8(pTHX_ U8 *s, STRLEN *len, bool *is_utf8)
 {
     U8 *d;
     U8 *start = s;
@@ -695,7 +700,7 @@ reflect the new length.
 */
 
 U8*
-Perl_bytes_to_utf8(pTHX_ U8* s, STRLEN *len)
+Perl_bytes_to_utf8(pTHX_ U8 *s, STRLEN *len)
 {
     U8 *send;
     U8 *d;
@@ -1390,7 +1395,7 @@ Perl_swash_fetch(pTHX_ SV *sv, U8 *ptr)
 
 
 /*
-=for apidoc A|U8*|uvchr_to_utf8|U8 *d|UV uv
+=for apidoc A|U8 *|uvchr_to_utf8|U8 *d|UV uv
 
 Adds the UTF8 representation of the Native codepoint C<uv> to the end
 of the string C<d>; C<d> should be have at least C<UTF8_MAXLEN+1> free
@@ -1418,7 +1423,7 @@ Perl_uvchr_to_utf8(pTHX_ U8 *d, UV uv)
 
 
 /*
-=for apidoc A|U8* s|utf8n_to_uvchr|STRLEN curlen, STRLEN *retlen, U32 flags
+=for apidoc A|UV|utf8n_to_uvchr|U8 *s|STRLEN curlen|STRLEN *retlen|U32 flags
 
 Returns the native character value of the first character in the string C<s>
 which is assumed to be in UTF8 encoding; C<retlen> will be set to the
@@ -1433,7 +1438,7 @@ Allows length and flags to be passed to low level routine.
 */
 #undef Perl_utf8n_to_uvchr
 UV
-Perl_utf8n_to_uvchr(pTHX_ U8* s, STRLEN curlen, STRLEN* retlen, U32 flags)
+Perl_utf8n_to_uvchr(pTHX_ U8 *s, STRLEN curlen, STRLEN *retlen, U32 flags)
 {
     UV uv = Perl_utf8n_to_uvuni(aTHX_ s, curlen, retlen, flags);
     return UNI_TO_NATIVE(uv);
index 51e8d78..b1379bf 100644 (file)
@@ -57,12 +57,14 @@ dprofpp - display perl profile data
 
 =head1 SYNOPSIS
 
-dprofpp [B<-a>|B<-z>|B<-l>|B<-v>|B<-U>] [B<-s>|B<-r>|B<-u>] [B<-q>] [B<-F>] [B<-I|-E>] [B<-O cnt>] [B<-A>] [B<-R>] [B<-S>] [B<-g subroutine>] [profile]
-
+dprofpp [B<-a>|B<-z>|B<-l>|B<-v>|B<-U>] [B<-d>] [B<-s>|B<-r>|B<-u>] [B<-q>] [B<-F>] [B<-I|-E>] [B<-O cnt>] [B<-A>] [B<-R>] [B<-S>] [B<-g subroutine>] [B<-G> <regexp> [B<-P>]] [B<-f> <regexp>] [profile]
+  
 dprofpp B<-T> [B<-F>] [B<-g subroutine>] [profile]
 
 dprofpp B<-t> [B<-F>] [B<-g subroutine>] [profile]
 
+dprofpp B<-G> <regexp> [B<-P>] [profile]
 dprofpp B<-p script> [B<-Q>] [other opts]
 
 dprofpp B<-V> [profile]
@@ -147,6 +149,10 @@ Average time (in seconds) spent in each call of this routine
 
 Sort alphabetically by subroutine names.
 
+=item B<-d>
+
+Reverse whatever sort is used
+
 =item B<-A>
 
 Count timing for autoloaded subroutine as timing for C<*::AUTOLOAD>.
@@ -258,6 +264,25 @@ should show you which subroutines are using the most time.
 
 Ignore subroutines except C<subroutine> and whatever is called from it.
 
+=item B<-G> <regexp>
+
+Aggregate "Group" all calls matching the pattern together.
+For example this can be used to group all calls of a set of packages
+
+  -G "(package1::)|(package2::)|(package3::)"
+
+or to group subroutines by name:
+
+  -G "getNum"
+
+=item B<-P>
+
+Used with -G to aggregate "Pull"  together all calls that did not match -G.
+
+=item B<-f> <regexp>
+
+Filter all calls matching the pattern.
+
 =back
 
 =head1 ENVIRONMENT
@@ -297,7 +322,7 @@ use Getopt::Std 'getopts';
 use Config '%Config';
 
 Setup: {
-       my $options = 'O:g:lzaAvuTtqrRsUFEIp:QVS';
+       my $options = 'O:g:G:Pf:dlzaAvuTtqrRsUFEIp:QVS';
 
        $Monfile = 'tmon.out';
        if( exists $ENV{DPROFPP_OPTS} ){
@@ -340,6 +365,11 @@ Setup: {
 # -g subr      count only those who are SUBR or called from SUBR
 # -S           Create statistics for all the depths
 
+# -G           Group all calls matching the pattern together.
+# -P           Used with -G to pull all other calls together.
+# -f           Filter all calls mathcing the pattern.
+# -d           Reverse sort
+
        if( defined $opt_V ){
                my $fh = 'main::fh';
                print "$0 version: $VERSION\n";
@@ -357,6 +387,10 @@ Setup: {
        $sort = 'by_calls' if defined $opt_l;
        $sort = 'by_alpha' if defined $opt_a;
        $sort = 'by_avgcpu' if defined $opt_v;
+       
+       if(defined $opt_d){
+               $sort = "r".$sort;
+       }
        $incl_excl = 'Exclusive';
        $incl_excl = 'Inclusive' if defined $opt_I;
        $whichtime = 'User+System';
@@ -412,6 +446,23 @@ Main: {
 
        parsestack( $fh, $names, $calls, $times, $ctimes, $idkeys );
 
+       #filter calls
+       if( $opt_f ){
+               for(my $i = 0;$i < @$idkeys - 2;){
+                       $key = $$idkeys[$i];
+                       if($key =~ /$opt_f/){
+                               splice(@$idkeys, $i, 1);
+                               $runtime -= $$times{$key};
+                               next;
+                       }
+                       $i++;
+               }
+       }
+
+       if( $opt_G ){
+               group($names, $calls, $times, $ctimes, $idkeys );
+       }
+
        settime( \$runtime, $hz ) unless $opt_g;
 
        exit(0) if $opt_T || $opt_t;
@@ -430,6 +481,49 @@ Main: {
                 $deep_times);
 }
 
+sub group{
+       my ($names, $calls, $times, $ctimes, $idkeys ) = @_;
+               print "Option G Grouping: [$opt_G]\n";
+               # create entries to store grouping
+               $$names{$opt_G} = $opt_G;
+               $$calls{$opt_G} = 0;
+               $$times{$opt_G} = 0;
+               $$ctimes{$opt_G} = 0;
+               $$idkeys[@$idkeys] = $opt_G;
+               # Sum calls for the grouping
+
+               my $other = "other";
+               if($opt_P){
+                       $$names{$other} = $other;
+                       $$calls{$other} = 0;
+                       $$times{$other} = 0;
+                       $$ctimes{$other} = 0;
+                       $$idkeys[@$idkeys] = $other;
+               }
+
+               for(my $i = 0;$i < @$idkeys - 2;){
+                       $key = $$idkeys[$i];
+                       if($key =~ /$opt_G/){
+                               $$calls{$opt_G} += $$calls{$key};
+                               $$times{$opt_G} += $$times{$key};
+                               $$ctimes{$opt_G} += $$ctimes{$key};
+                               splice(@$idkeys, $i, 1);
+                               next;
+                       }else{
+                               if($opt_P){
+                                       $$calls{$other} += $$calls{$key};
+                                       $$times{$other} += $$times{$key};
+                                       $$ctimes{$other} += $$ctimes{$key};
+                                       splice(@$idkeys, $i, 1);
+                                       next;
+                               }
+                       }
+                       $i++;
+               }
+               print "Grouping [$opt_G] Calls: [$$calls{$opt_G}]\n".
+                         "Grouping [$opt_G] Times: [$$times{$opt_G}]\n".
+                         "Grouping [$opt_G] IncTimes: [$$ctimes{$opt_G}]\n";
+}
 
 # Sets $runtime to user, system, real, or user+system time.  The
 # result is given in seconds.
@@ -563,6 +657,7 @@ sub add_to_tree {
   pop @$curdeep_times;
 }
 
+
 sub parsestack {
        my( $fh, $names, $calls, $times, $ctimes, $idkeys ) = @_;
        my( $dir, $name );
@@ -734,7 +829,7 @@ sub exitstamp {
        if( ! defined $x ){
                die "Garbled profile, missing an enter time stamp";
        }
-       if( $x->[0] ne $name ){
+       if( $x->[0] ne $name and $opt_G and ($name =~ /$opt_G/)){
          if ($x->[0] =~ /::AUTOLOAD$/) {
            if ($opt_A) {
              $name = $x->[0];
@@ -814,6 +909,12 @@ sub by_ctime { $ctimes->{$b} <=> $ctimes->{$a} }
 sub by_calls { $calls->{$b} <=> $calls->{$a} }
 sub by_alpha { $names->{$a} cmp $names->{$b} }
 sub by_avgcpu { $persecs->{$b} <=> $persecs->{$a} }
+# Reversed
+sub rby_time { $times->{$a} <=> $times->{$b} }
+sub rby_ctime { $ctimes->{$a} <=> $ctimes->{$b} }
+sub rby_calls { $calls->{$a} <=> $calls->{$b} }
+sub rby_alpha { $names->{$b} cmp $names->{$a} }
+sub rby_avgcpu { $persecs->{$a} <=> $persecs->{$b} }
 
 
 format CSTAT_top =
@@ -836,3 +937,4 @@ $pcnt, $secs, $csecs, $ncalls, $percall, $cpercall, $name
 close OUT or die "Can't close $file: $!";
 chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
 exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';
+