[inseparable changes from patch from perl5.003_11 to perl5.003_12]
Perl 5 Porters [Thu, 19 Dec 1996 04:44:00 +0000 (16:44 +1200)]
 CORE LANGUAGE CHANGES

Subject: Support C<delete @hash{@keys}>
From: Chip Salzenberg <chip@atlantic.net>
Files: op.c op.h opcode.pl pod/perldiag.pod pod/perlfunc.pod pp.c t/op/delete.t

Subject: Autovivify scalars
From: Chip Salzenberg <chip@atlantic.net>
Files: dump.c op.c op.h pp.c pp_hot.c

 DOCUMENTATION

Subject: Update pods: perldelta -> perlnews, perli18n -> perllocale
From: Tom Christiansen <tchrist@perl.com>
Files: MANIFEST pod/perl.pod pod/perldelta.pod pod/perli18n.pod pod/perlnews.pod

Subject: perltoot.pod
Date: Mon, 09 Dec 1996 07:44:10 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Files: MANIFEST pod/perltoot.pod
Msg-ID: <199612091444.HAA09947@toy.perl.com>

    (applied based on p5p patch as commit 32e22efaa9ec59b73a208b6c532a0b435e2c6462)

Subject: Perlguts, version 25
Date: Fri, 6 Dec 96 11:40:27 PST
From: Jeff Okamoto <okamoto@hpcc123.corp.hp.com>
Files: pod/perlguts.pod

    private-msgid: <199612061940.AA055461228@hpcc123.corp.hp.com>

Subject: pod patches for English errors
Date: Mon, 09 Dec 1996 13:33:11 -0800
From: Steve Kelem <steve.kelem@xilinx.com>
Files: pod/*.pod
Msg-ID: <24616.850167191@castor>

    (applied based on p5p patch as commit 0135f10892ed8a21c4dbd1fca21fbcc365df99dd)

Subject: Misc doc updates
Date: Sat, 14 Dec 1996 18:56:33 -0700
From: Tom Christiansen <tchrist@mox.perl.com>
Files: pod/*

    Subject: Re: perldelta.pod

    Here are some diffs to the _11 pods.  I forgot to add perldelta to
    perl.pod though.

    And *PLEASE* fix the Artistic License so it no longer has the bogus
    "whomever" misdeclined in the nominative case:

        under the copyright of this Package, but belong to whomever generated
        them, and may be sold commercially, and may be aggregated with this

    It should obviously be "whoever".

    p5p-msgid: <199612150156.SAA12506@mox.perl.com>

 OTHER CORE CHANGES

Subject: Allow assignment to empty array values during foreach()
From: Chip Salzenberg <chip@atlantic.net>
Files: cop.h global.sym mg.c op.c perl.h pp_hot.c proto.h sv.c

Subject: Fix nested closures
From: Chip Salzenberg <chip@atlantic.net>
Files: op.c opcode.pl pp.c pp_ctl.c pp_hot.c

Subject: Fix core dump on auto-vivification
From: Chip Salzenberg <chip@atlantic.net>
Files: pp_hot.c

Subject: Fix core dump on C<open $undef_var, "X">
From: Chip Salzenberg <chip@atlantic.net>
Files: pp_sys.c

Subject: Fix -T/-B on globs and globrefs
From: Chip Salzenberg <chip@atlantic.net>
Files: pp_sys.c

Subject: Fix memory management of $`, $&, and $'
From: Chip Salzenberg <chip@atlantic.net>
Files: pp_hot.c regexec.c

Subject: Fix paren matching during backtracking
From: Chip Salzenberg <chip@atlantic.net>
Files: regexec.c

Subject: Fix memory leak and std{in,out,err} death in perl_{con,de}str
From: Chip Salzenberg <chip@atlantic.net>
Files: miniperlmain.c perl.c perl.h sv.c

Subject: Discard garbage bytes at end of prototype()
From: Chip Salzenberg <chip@atlantic.net>
Files: pp.c

Subject: Fix local($pack::{foo})
From: Chip Salzenberg <chip@atlantic.net>
Files: global.sym pp.c pp_hot.c proto.h scope.c

Subject: Disable warn, die, and parse hooks _before_ global destruction
From: Chip Salzenberg <chip@atlantic.net>
Files: perl.c

Subject: Re: Bug in formline
Date: Sun, 08 Dec 1996 14:58:32 -0500
From: Gurusamy Sarathy <gsar@engin.umich.edu>
Files: pp_ctl.c
Msg-ID: <199612081958.OAA26025@aatma.engin.umich.edu>

    (applied based on p5p patch as commit b386bda18108ba86d0b76ebe2d8745eafa80f39e)

Subject: Fix C<@a = ($a,$b,$c,$d) = (1,2)>
From: Chip Salzenberg <chip@atlantic.net>
Files: pp_hot.c

Subject: Properly support and document newRV{,_inc,_noinc}
From: Chip Salzenberg <chip@atlantic.net>
Files: global.sym pod/perlguts.pod sv.c sv.h

Subject: Allow lvalue pos inside recursive function
From: Chip Salzenberg <chip@atlantic.net>
Files: op.c pp.c pp_ctl.c pp_hot.c

 PORTABILITY

Subject: Make $privlib contents compatible with 5.003
From: Chip Salzenberg <chip@atlantic.net>
Files: INSTALL ext/Opcode/Safe.pm installperl lib/FileHandle.pm lib/Test/Harness.pm

Subject: Support $bincompat3 config variable; update metaconfig units
From: Chip Salzenberg <chip@atlantic.net>
Files: Configure MANIFEST compat3.sym config_h.SH embed.pl global.sym old_embed.pl old_global.sym old_perl_exp.SH perl_exp.SH

Subject: Look for gettimeofday() in Configure
Date: Wed, 11 Dec 1996 15:49:57 +0100
From: John Hughes <john@AtlanTech.COM>
Files: Configure config_H config_h.SH pp.c

    Subject: perl5.003_11, Should base use of gettimeofday on HAS_GETTIMEOFDAY, not I_SYS_TIME

    I've been installing perl5.003_11 on a SCO system that has the TCP/IP runtime
    installed but not the TCP/IP development system.

    Unfortunately the <sys/time.h> include file is included in the TCP/IP runtime
    while libsocket.a is in the development system.

    This means that pp.c decides to use "gettimeofday" because <sys/time.h> is
    present but I can't link the perl that gets compiled.

    So, here's a patch to base the use of "gettimeofday" on "HAS_GETTIMEOFDAY"
    instead of "I_SYS_TIME".  I also took the liberty of removing the special
    case for plan9 (I assume plan9 has <sys/time.h> but no gettimeofday.  Am I
    right?).

    p5p-msgid: <01BBE77A.F6F37F80@malvinas.AtlanTech.COM>

Subject: Make $startperl a relative path if people want portable scrip
From: Chip Salzenberg <chip@atlantic.net>
Files: Configure

Subject: Homogenize use of "eval exec" hack
From: Chip Salzenberg <chip@atlantic.net>
Files: Porting/Glossary eg/README eg/nih eg/sysvipc/ipcmsg eg/sysvipc/ipcsem eg/sysvipc/ipcshm lib/diagnostics.pm makeaperl.SH pod/checkpods.PL pod/perlrun.pod pod/pod2html.PL pod/pod2latex.PL pod/pod2man.PL pod/pod2text.PL utils/c2ph.PL utils/h2ph.PL utils/h2xs.PL utils/perlbug.PL utils/perldoc.PL utils/pl2pm.PL x2p/a2py.c x2p/find2perl.PL x2p/s2p.PL

Subject: LynxOS support
Date: Thu, 12 Dec 1996 09:25:00 PST
From: Greg Seibert <seibert@Lynx.COM>
Files: Configure MANIFEST hints/lynxos.sh t/op/stat.t
Msg-ID: <m0vYEsY-0000IZC@kzinti.lynx.com>

    (applied based on p5p patch as commit 6693373533b15e559fd8f0f1877e5e6ec15483cc)

Subject: Re: db-recno.t failures with _11 on Freebsd 2.1-stable
Date: 11 Dec 1996 18:58:56 -0500
From: Roderick Schertler <roderick@gate.net>
Files: INSTALL hints/freebsd.sh
Msg-ID: <pzohg0r5tr.fsf@eeyore.ibcinc.com>

    (applied based on p5p patch as commit 10e40321ee752c58e3407b204c74c8049894cb51)

Subject: VMS patches to 5.003_11
Date: Mon, 09 Dec 1996 23:16:10 -0500 (EST)
From: Charles Bailey <bailey@HMIVAX.HUMGEN.UPENN.EDU>
Files: MANIFEST regexec.c t/lib/filehand.t util.c vms/*

    private-msgid: <01ICTR32LCZG001A1D@hmivax.humgen.upenn.edu>

 TESTING

Subject: recurse recurse recurse ...
Date: Mon, 9 Dec 1996 23:44:27 +0200 (EET)
From: Jarkko Hietaniemi <jhi@cc.hut.fi>
Files: MANIFEST t/op/recurse.t

    private-msgid: <199612092144.XAA29025@alpha.hut.fi>

 UTILITIES, LIBRARY, AND EXTENSIONS

Subject: Add CPAN and Net::FTP
From: Chip Salzenberg <chip@atlantic.net>
Files: MANIFEST lib/CPAN.pm lib/CPAN/FirstTime.pm lib/CPAN/Nox.pm lib/Net/FTP.pm lib/Net/Netrc.pm lib/Net/Socket.pm pod/perlmod.pod

Subject: Add File::Compare
Date: Mon, 16 Dec 1996 18:44:59 GMT
From: Nick Ing-Simmons <nik@tiuk.ti.com>
Files: MANIFEST lib/File/Compare.pm pod/perlmod.pod
Msg-ID: <199612161844.SAA02152@pluto>

    (applied based on p5p patch as commit ec971c5c328aca84fb827f69f2cc1dc3be81f830)

Subject: Add Tie::RefHash
Date: Sun, 15 Dec 1996 18:58:08 -0500
From: Gurusamy Sarathy <gsar@engin.umich.edu>
Files: MANIFEST lib/Tie/RefHash.pm pod/perlmod.pod
Msg-ID: <199612152358.SAA28665@aatma.engin.umich.edu>

    (applied based on p5p patch as commit 9a079709134ebbf4c935cc8752fdb564e5c82b94)

Subject: Put "splain" in utils.
From: Chip Salzenberg <chip@atlantic.net>
Files: Makefile.SH installperl utils/Makefile utils/splain.PL

Subject: Some h2ph fixes
Date: Fri, 13 Dec 1996 11:34:12 -0800
From: Jeff Okamoto <okamoto@hpcc123.corp.hp.com>
Files: utils/h2ph.PL

    Here is a message regarding changes to h2ph that should probably be folded
    into the 5.004 release.

    p5p-msgid: <199612131934.AA289845652@hpcc123.corp.hp.com>

134 files changed:
Artistic
Changes
Configure
INSTALL
MANIFEST
Makefile.SH
Porting/Glossary
compat3.sym [new file with mode: 0644]
config_H
config_h.SH
cop.h
dump.c
eg/README
eg/nih
eg/sysvipc/ipcmsg
eg/sysvipc/ipcsem
eg/sysvipc/ipcshm
emacs/cperl-mode.el
embed.h
embed.pl
ext/IO/lib/IO/Handle.pm
ext/Opcode/Safe.pm
ext/POSIX/POSIX.xs
global.sym
hints/freebsd.sh
hints/lynxos.sh [new file with mode: 0644]
installperl
lib/CPAN.pm [new file with mode: 0644]
lib/CPAN/FirstTime.pm [new file with mode: 0644]
lib/CPAN/Nox.pm [new file with mode: 0644]
lib/Fatal.pm
lib/File/Compare.pm [new file with mode: 0644]
lib/FileHandle.pm
lib/Getopt/Long.pm
lib/Net/FTP.pm [new file with mode: 0644]
lib/Net/Netrc.pm [new file with mode: 0644]
lib/Net/Socket.pm [new file with mode: 0644]
lib/Test/Harness.pm
lib/Tie/RefHash.pm [new file with mode: 0644]
lib/blib.pm
lib/diagnostics.pm
makeaperl.SH
malloc.c
mg.c
miniperlmain.c
op.c
op.h
opcode.h
opcode.pl
patchlevel.h
perl.c
perl.h
perl_exp.SH
perly.c
perly.c.diff
perly.y
pod/checkpods.PL
pod/perl.pod
pod/perlapio.pod
pod/perlbot.pod
pod/perlcall.pod
pod/perldata.pod
pod/perldebug.pod
pod/perldiag.pod
pod/perldsc.pod
pod/perlembed.pod
pod/perlform.pod
pod/perlfunc.pod
pod/perlguts.pod
pod/perllocale.pod [new file with mode: 0644]
pod/perllol.pod
pod/perlmod.pod
pod/perlnews.pod [new file with mode: 0644]
pod/perlobj.pod
pod/perlop.pod
pod/perlpod.pod
pod/perlre.pod
pod/perlref.pod
pod/perlrun.pod
pod/perlsec.pod
pod/perlstyle.pod
pod/perlsub.pod
pod/perlsyn.pod
pod/perltie.pod
pod/perltoc.pod
pod/perltoot.pod [new file with mode: 0644]
pod/perltrap.pod
pod/perlvar.pod
pod/perlxs.pod
pod/perlxstut.pod
pod/pod2html.PL
pod/pod2latex.PL
pod/pod2man.PL
pod/pod2text.PL
pp.c
pp_ctl.c
pp_hot.c
pp_sys.c
proto.h
regexec.c
scope.c
sv.c
sv.h
t/lib/filehand.t
t/op/delete.t
t/op/recurse.t
t/op/stat.t
util.c
utils/Makefile
utils/c2ph.PL
utils/h2ph.PL
utils/h2xs.PL
utils/perlbug.PL
utils/perldoc.PL
utils/pl2pm.PL
utils/splain.PL [new file with mode: 0644]
vms/Makefile
vms/descrip.mms
vms/ext/DCLsym/0README.txt [new file with mode: 0644]
vms/ext/DCLsym/DCLsym.pm [new file with mode: 0644]
vms/ext/DCLsym/DCLsym.xs [new file with mode: 0644]
vms/ext/DCLsym/Makefile.PL [new file with mode: 0644]
vms/ext/DCLsym/test.pl [new file with mode: 0644]
vms/ext/Stdio/Stdio.pm
vms/ext/Stdio/Stdio.xs
vms/ext/Stdio/test.pl
vms/genopt.com
vms/perly_c.vms
vms/perly_h.vms
vms/vms.c
vms/vmsish.h
x2p/a2py.c
x2p/find2perl.PL
x2p/s2p.PL

index 11f4d82..5f22124 100644 (file)
--- a/Artistic
+++ b/Artistic
@@ -97,7 +97,7 @@ interpreter is so embedded.
 
 6. The scripts and library files supplied as input to or produced as
 output from the programs of this Package do not automatically fall
-under the copyright of this Package, but belong to whomever generated
+under the copyright of this Package, but belong to whoever generated
 them, and may be sold commercially, and may be aggregated with this
 Package.  If such scripts or library files are aggregated with this
 Package via the so-called "undump" or "unexec" methods of producing a
diff --git a/Changes b/Changes
index 51d876d..dff8dff 100644 (file)
--- a/Changes
+++ b/Changes
@@ -8,6 +8,281 @@ or in the .../src/5/0/unsupported directory for sub-version
 releases.)
 
 ----------------
+Version 5.003_12
+----------------
+
+This patch is huge.  A multitude of bug fixes, new modules (especially
+CPAN and Net::FTP), a couple of new Configure variables, updated
+docs...  it's a long list.  And speaking of lists, here's a list of
+the more significant changes in 5.003_12:
+
+ CORE LANGUAGE CHANGES
+
+  Title:  "Support C<delete @hash{@keys}>"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  op.c op.h opcode.pl pod/perldiag.pod pod/perlfunc.pod pp.c
+          t/op/delete.t
+
+  Title:  "Autovivify scalars"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  dump.c op.c op.h pp.c pp_hot.c
+
+  Title:  "Allow any word, including keyword, as label"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  toke.c
+
+ OTHER CORE CHANGES
+
+  Title:  "Allow assignment to empty array values during foreach()"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  cop.h global.sym mg.c op.c perl.h pp_hot.c proto.h sv.c
+
+  Title:  "Fix nested closures"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  op.c opcode.pl pp.c pp_ctl.c pp_hot.c
+
+  Title:  "Fix core dump on auto-vivification"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  pp_hot.c
+
+  Title:  "Fix core dump on C<open $undef_var, "X">"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  pp_sys.c
+
+  Title:  "Fix -T/-B on globs and globrefs"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  pp_sys.c
+
+  Title:  "Fix memory management of $`, $&, and $'"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  pp_hot.c regexec.c
+
+  Title:  "Fix paren matching during backtracking"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  regexec.c
+
+  Title:  "Fix memory leak and std{in,out,err} death in perl_{con,de}str
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  miniperlmain.c perl.c perl.h sv.c
+
+  Title:  "Discard garbage bytes at end of prototype()"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  pp.c
+
+  Title:  "Fix local($pack::{foo})"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  global.sym pp.c pp_hot.c proto.h scope.c
+
+  Title:  "Fix for AmigaOS - inplace operation"
+   From:  "Norbert Pueschel" <pueschel@imsdd.meb.uni-bonn.de>
+ Msg-ID:  <77724601@Armageddon.meb.uni-bonn.de>
+   Date:  Sun, 08 Dec 1996 15:33:00 +0100
+  Files:  doio.c
+
+  Title:  "Disable warn, die, and parse hooks _before_ global destruction
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  perl.c
+
+  Title:  "Re: Bug in formline "
+   From:  Gurusamy Sarathy <gsar@engin.umich.edu>
+ Msg-ID:  <199612081958.OAA26025@aatma.engin.umich.edu>
+   Date:  Sun, 08 Dec 1996 14:58:32 -0500
+  Files:  pp_ctl.c
+
+  Title:  "Fix C<@a = ($a,$b,$c,$d) = (1,2)>"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  pp_hot.c
+
+  Title:  "Fix %ENV assignment when environment starts out empty"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  hv.c
+
+  Title:  "Properly support and document newRV{,_inc,_noinc}"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  global.sym pod/perlguts.pod sv.c sv.h
+
+  Title:  "Support SvREADONLY on arrays"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  av.c
+
+  Title:  "Allow lvalue pos inside recursive function"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  op.c pp.c pp_ctl.c pp_hot.c
+
+ PORTABILITY
+
+  Title:  "Eliminate PerlIO warnings when setting cnt to -1"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  perlio.c
+
+  Title:  "Make $privlib contents compatible with 5.003"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  INSTALL ext/Opcode/Safe.pm installperl lib/FileHandle.pm
+          lib/Test/Harness.pm
+
+  Title:  "Support $bincompat3 config variable; update metaconfig units"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  Configure MANIFEST compat3.sym config_h.SH embed.pl global.sym
+          old_embed.pl old_global.sym old_perl_exp.SH perl_exp.SH
+
+  Title:  "Look for gettimeofday() in Configure"
+   From:  John Hughes <john@AtlanTech.COM>
+ Msg-ID:  <01BBE77A.F6F37F80@malvinas.AtlanTech.COM>
+   Date:  Wed, 11 Dec 1996 15:49:57 +0100
+  Files:  Configure config_H config_h.SH pp.c
+
+  Title:  "Make $startperl a relative path if people want portable scrip
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  Configure
+
+  Title:  "Homogenize use of "eval exec" hack"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  Porting/Glossary eg/README eg/nih eg/sysvipc/ipcmsg
+          eg/sysvipc/ipcsem eg/sysvipc/ipcshm lib/diagnostics.pm
+          makeaperl.SH pod/checkpods.PL pod/perlrun.pod
+          pod/pod2html.PL pod/pod2latex.PL pod/pod2man.PL
+          pod/pod2text.PL utils/c2ph.PL utils/h2ph.PL utils/h2xs.PL
+          utils/perlbug.PL utils/perldoc.PL utils/pl2pm.PL x2p/a2py.c
+          x2p/find2perl.PL x2p/s2p.PL
+
+  Title:  "LynxOS support"
+   From:  seibert@Lynx.COM (Greg Seibert)
+ Msg-ID:  <m0vYEsY-0000IZC@kzinti.lynx.com>
+   Date:  Thu, 12 Dec 1996 09:25:00 PST
+  Files:  Configure MANIFEST hints/lynxos.sh t/op/stat.t
+
+  Title:  "In Linux hints, set suidsafe=no and dosuid=yes"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  hints/linux.sh
+
+  Title:  "5.003_11 on UnixWare 2.1.1 - Only one small UnixWare buglet"
+   From:  aburlison@cix.compulink.co.uk (Alan Burlison)
+ Msg-ID:  <memo.453720@cix.compulink.co.uk>
+   Date:  Wed, 11 Dec 96 18:34 GMT0
+  Files:  hints/svr4.sh
+
+  Title:  "Re: db-recno.t failures with _11 on Freebsd 2.1-stable"
+   From:  Roderick Schertler <roderick@gate.net>
+ Msg-ID:  <pzohg0r5tr.fsf@eeyore.ibcinc.com>
+   Date:  11 Dec 1996 18:58:56 -0500
+  Files:  INSTALL hints/freebsd.sh
+
+  Title:  "OS/2 updates from Ilya"
+   From:  Ilya Zakharevich <ilya@math.ohio-state.edu>
+  Files:  README.os2 os2/Changes os2/Makefile.SHs os2/os2.c os2/os2ish.h
+
+  Title:  "VMS patches to 5.003_11"
+   From:  Charles Bailey <bailey@HMIVAX.HUMGEN.UPENN.EDU>
+ Msg-ID:  <01ICTR32LCZG001A1D@hmivax.humgen.upenn.edu>
+   Date:  Mon, 09 Dec 1996 23:16:10 -0500 (EST)
+  Files:  MANIFEST regexec.c t/lib/filehand.t util.c vms/*
+
+ TESTING
+
+  Title:  "recurse recurse recurse ..."
+   From:  Jarkko Hietaniemi <jhi@cc.hut.fi>
+ Msg-ID:  <199612092144.XAA29025@alpha.hut.fi>
+   Date:  Mon, 9 Dec 1996 23:44:27 +0200 (EET)
+  Files:  MANIFEST t/op/recurse.t
+
+ UTILITIES, LIBRARY, AND EXTENSIONS
+
+  Title:  "Add CPAN and Net::FTP"
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  MANIFEST lib/CPAN.pm lib/CPAN/FirstTime.pm lib/CPAN/Nox.pm
+          lib/Net/FTP.pm lib/Net/Netrc.pm lib/Net/Socket.pm
+          pod/perlmod.pod
+
+  Title:  "Please update Text::Wrap and Text::Tabs"
+   From:  David Muir Sharnoff <muir@idiom.com>
+ Msg-ID:  <199612180659.WAA24957@idiom.com>
+   Date:  Tue, 17 Dec 1996 22:59:59 -0800 (PST)
+  Files:  lib/Text/Tabs.pm lib/Text/Wrap.pm
+
+  Title:  "Add File::Compare"
+   From:  Nick Ing-Simmons <nik@tiuk.ti.com>
+ Msg-ID:  <199612161844.SAA02152@pluto>
+   Date:  Mon, 16 Dec 1996 18:44:59 GMT
+  Files:  MANIFEST lib/File/Compare.pm pod/perlmod.pod
+
+  Title:  "Add Tie::RefHash"
+   From:  Gurusamy Sarathy <gsar@engin.umich.edu>
+ Msg-ID:  <199612152358.SAA28665@aatma.engin.umich.edu>
+   Date:  Sun, 15 Dec 1996 18:58:08 -0500
+  Files:  MANIFEST lib/Tie/RefHash.pm pod/perlmod.pod
+
+  Title:  "Put "splain" in utils."
+   From:  Chip Salzenberg <chip@atlantic.net>
+  Files:  Makefile.SH installperl utils/Makefile utils/splain.PL
+
+  Title:  "Some h2ph fixes"
+   From:  Jeff Okamoto <okamoto@hpcc123.corp.hp.com>
+ Msg-ID:  <199612131934.AA289845652@hpcc123.corp.hp.com>
+   Date:  Fri, 13 Dec 1996 11:34:12 -0800
+  Files:  utils/h2ph.PL
+
+  Title:  "xsubpp patch to add #line"
+   From:  nick@ni-s.u-net.com (Nick Ing-Simmons)
+ Msg-ID:  <199612162153.VAA03590@ni-s.u-net.com>
+   Date:  Mon, 16 Dec 1996 21:53:56 GMT
+  Files:  lib/ExtUtils/xsubpp
+
+  Title:  "Re: Proposed addition to File::Copy: move"
+   From:  Charles Bailey <bailey@HMIVAX.HUMGEN.UPENN.EDU>
+ Msg-ID:  <01ICZBN0LRC8001A1D@hmivax.humgen.upenn.edu>
+   Date:  Sat, 14 Dec 1996 00:27:29 -0500 (EST)
+  Files:  lib/File/Copy.pm t/lib/filecopy.t
+
+  Title:  "DB_File 1.09 patch"
+   From:  pmarquess@bfsec.bt.co.uk (Paul Marquess)
+ Msg-ID:  <9612181037.AA10123@claudius.bfsec.bt.co.uk>
+   Date:  Wed, 18 Dec 96 10:37:58 GMT
+  Files:  ext/DB_File/DB_File.pm ext/DB_File/DB_File.xs
+
+  Title:  "Debugger update"
+   From:  Ilya Zakharevich <ilya@math.ohio-state.edu>
+ Msg-ID:  <199612111038.FAA24363@monk.mps.ohio-state.edu>
+   Date:  Wed, 11 Dec 1996 05:38:28 -0500 (EST)
+  Files:  lib/perl5db.pl
+
+ DOCUMENTATION
+
+  Title:  "Update pods: perldelta -> perlnews, perli18n -> perllocale"
+   From:  Tom Christiansen and Dominic Dunlop
+  Files:  MANIFEST pod/perl.pod pod/perldelta.pod pod/perli18n.pod
+          pod/perlnews.pod
+
+  Title:  "perltoot.pod"
+   From:  Tom Christiansen <tchrist@mox.perl.com>
+ Msg-ID:  <199612091444.HAA09947@toy.perl.com>
+   Date:  Mon, 09 Dec 1996 07:44:10 -0700
+  Files:  MANIFEST pod/perltoot.pod
+
+  Title:  "Perlguts, version 25"
+   From:  Jeff Okamoto <okamoto@hpcc123.corp.hp.com>
+ Msg-ID:  <199612061940.AA055461228@hpcc123.corp.hp.com>
+   Date:  Fri, 6 Dec 96 11:40:27 PST
+  Files:  pod/perlguts.pod
+
+  Title:  "pod/perlipc.pod patch"
+   From:  d-lewart@uiuc.edu (Daniel S. Lewart)
+ Msg-ID:  <199612090910.CAA20906@mox.perl.com>
+   Date:  Mon, 9 Dec 96 3:10:02 CST
+  Files:  pod/perlipc.pod
+
+  Title:  "pod patches for English errors"
+   From:  Steve Kelem <steve.kelem@xilinx.com>
+ Msg-ID:  <24616.850167191@castor>
+   Date:  Mon, 09 Dec 1996 13:33:11 -0800
+  Files:  pod/*.pod
+
+  Title:  "Misc doc updates"
+   From:  Tom Christiansen <tchrist@mox.perl.com>
+ Msg-ID:  <199612150156.SAA12506@mox.perl.com>
+   Date:  Sat, 14 Dec 1996 18:56:33 -0700
+  Files:  pod/*
+
+----------------
 Version 5.003_11
 ----------------
 
index f9bb490..c8ee9f6 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -20,7 +20,7 @@
 
 # $Id: Head.U,v 3.0.1.8 1995/07/25 13:40:02 ram Exp $
 #
-# Generated on Thu Oct 10 15:08:34 EDT 1996 [metaconfig 3.0 PL60]
+# Generated on Tue Dec 17 14:33:33 EST 1996 [metaconfig 3.0 PL60]
 
 cat >/tmp/c1$$ <<EOF
 ARGGGHHHH!!!!!
@@ -227,6 +227,8 @@ baserev=''
 bin=''
 binexp=''
 installbin=''
+bincompat3=''
+d_bincompat3=''
 byteorder=''
 cc=''
 gccversion=''
@@ -284,6 +286,8 @@ d_flexfnam=''
 d_flock=''
 d_fork=''
 d_fsetpos=''
+d_ftime=''
+d_gettimeod=''
 d_Gconvert=''
 d_getgrps=''
 d_gethent=''
@@ -773,7 +777,7 @@ case "$sh" in
 '')    cat <<EOM >&2
 $me:  Fatal Error:  I can't find a Bourne Shell anywhere.  
 Usually it's in /bin/sh.  How did you even get this far?
-Please contact me (Andy Dougherty) at doughera@lafcol.lafayette.edu and 
+Please contact me (Chip Salzenberg) at chip@atlantic.net and 
 we'll try to straigten this all out.
 EOM
        exit 1
@@ -849,11 +853,11 @@ cat >>extract <<'EOS'
 CONFIG=true
 echo "Doing variable substitutions on .SH files..."
 if test -f MANIFEST; then
-       shlist=`awk '!/^old_/ {print $1}' <MANIFEST | grep '\.SH$'`
+       shlist=`awk '{print $1}' <MANIFEST | grep '\.SH'`
        : Pick up possible extension manifests.
        for dir in ext/* ; do
                if test -f $dir/MANIFEST; then
-                       xxx=`awk '!/^old_/ {print $1}' < $dir/MANIFEST | 
+                       xxx=`awk '{print $1}' < $dir/MANIFEST | 
                                sed -n "/\.SH$/ s@^@$dir/@p"`
                        shlist="$shlist $xxx"
                fi
@@ -861,7 +865,7 @@ if test -f MANIFEST; then
        set x $shlist
 else
        echo "(Looking for .SH files under the current directory.)"
-       set x `find . -name "*.SH" -print | grep -v '/old_'`
+       set x `find . -name "*.SH" -print`
 fi
 shift
 case $# in
@@ -1141,7 +1145,7 @@ THIS PACKAGE SEEMS TO BE INCOMPLETE.
 You have the option of continuing the configuration process, despite the
 distinct possibility that your kit is damaged, by typing 'y'es.  If you
 do, don't blame me if something goes wrong.  I advise you to type 'n'o
-and contact the author (doughera@lafcol.lafayette.edu).
+and contact the author (chip@atlantic.net).
 
 EOM
                echo $n "Continue? [n] $c" >&4
@@ -1341,7 +1345,7 @@ Much effort has been expended to ensure that this shell script will run on any
 Unix system.  If despite that it blows up on yours, your best bet is to edit
 Configure and run it again.  If you can't run Configure for some reason,
 you'll have to generate a config.sh file by hand.  Whatever problems you
-have, let me (doughera@lafcol.lafayette.edu) know how I blew it.
+have, let me (chip@atlantic.net) know how I blew it.
 
 This installation script affects things in two ways:
 
@@ -1631,13 +1635,14 @@ EOM
        cd hints; ls -C *.sh | $sed 's/\.sh/   /g' >&4
        dflt=''
        : Half the following guesses are probably wrong... If you have better
-       : tests or hints, please send them to doughera@lafcol.lafayette.edu
+       : tests or hints, please send them to chip@atlantic.net
        : The metaconfig authors would also appreciate a copy...
        $test -f /irix && osname=irix
        $test -f /xenix && osname=sco_xenix
        $test -f /dynix && osname=dynix
        $test -f /dnix && osname=dnix
-       $test -f /unicos && osname=unicos && osvers=`$uname -r`
+       $test -f /lynx.os && osname=lynxos
+       $test -f /unicos && osname=unicos && osvers=`$uname -r`
        $test -f /bin/mips && /bin/mips && osname=mips
        $test -d /NextApps && set X `hostinfo | grep 'NeXT Mach.*:' | \
                $sed -e 's/://' -e 's/\./_/'` && osname=next && osvers=$4
@@ -1781,7 +1786,7 @@ EOM
                $2) case "$osname" in
                        *isc*) ;;
                        *freebsd*) ;;
-                       svr*)
+                       svr*)
                                : svr4.x or possibly later
                                case "svr$3" in 
                                ${osname}*)
@@ -2020,7 +2025,8 @@ if xxx=`./loc arch blurfl $pth`; $test -f "$xxx"; then
        tarch=`arch`"-$osname"
 elif xxx=`./loc uname blurfl $pth`; $test -f "$xxx" ; then
        if uname -m > tmparch 2>&1 ; then
-               tarch=`$sed -e 's/ /_/g' -e 's/_*$//' -e 's/$/'"-$osname/" tmparch`
+               tarch=`$sed -e 's/ *$//' -e 's/ /_/g'
+                       -e 's/$/'"-$osname/" tmparch`
        else
                tarch="$osname"
        fi
@@ -2418,7 +2424,7 @@ else
 fi
 
 : set the base revision
-baserev=5.0
+baserev=5
 
 : get the patchlevel
 echo " "
@@ -2430,7 +2436,12 @@ else
        patchlevel=0
        subversion=0
 fi
-$echo $n "(You have $package $baserev patchlevel $patchlevel" $c
+$echo $n "(You have $package" $c
+case "$package" in
+"*$baserev")   ;;
+*)             $echo $n " $baserev" $c ;;
+esac
+$echo $n " patchlevel $patchlevel" $c
 test 0 -eq "$subversion" || $echo $n " subversion $subversion" $c
 echo ".)"
 
@@ -2523,6 +2534,33 @@ $undef$define) . ./whoa; eval "$var=\$tu";;
 *) eval "$var=$val";;
 esac'
 
+$cat <<EOM
+
+Perl 5.004 can be compiled for binary compatibility with 5.003.
+If you decide to do so, you will be able to continue using any
+extensions that were compiled for Perl 5.003.  However, binary
+compatibility forces Perl to expose some of its internal symbols
+in the same way that 5.003 did.  So you may have symbol conflicts
+if you embed a binary-compatible Perl in other programs.
+
+EOM
+case "$d_bincompat3" in
+"$undef") dflt=n ;;
+*) dflt=y ;;
+esac
+rp='Binary compatibility with Perl 5.003?'
+. ./myread
+case "$ans" in
+y*) val="$define" ;;
+*)  val="$undef" ;;
+esac
+set d_bincompat3
+eval $setvar
+case "$d_bincompat3" in
+"$define") bincompat3=y ;;
+*) bincompat3=n ;;
+esac
+
 : make some quick guesses about what we are up against
 echo " "
 $echo $n "Hmm...  $c"
@@ -3219,6 +3257,25 @@ none) libpth=' ';;
 *) libpth="$ans";;
 esac
 
+: Define several unixisms. Hints files or command line options
+: can be used to override them.
+case "$ar" in
+'') ar='ar';;
+esac
+case "$lib_ext" in
+'') lib_ext='.a';;
+esac
+case "$obj_ext" in
+'') obj_ext='.o';;
+esac
+case "$path_sep" in
+'') path_sep=':';;
+esac
+: Which makefile gets called first.  This is used by make depend.
+case "$firstmakefile" in
+'') firstmakefile='makefile';;
+esac
+
 : compute shared library extension
 case "$so" in
 '')
@@ -3241,11 +3298,6 @@ rp='What is the file extension used for shared libraries?'
 . ./myread
 so="$ans"
 
-: If no lib_ext yet, assume '.a'.
-case "$lib_ext" in
-'') lib_ext='.a';;
-esac
-
 : Looking for optional libraries
 echo " "
 echo "Checking for optional libraries..." >&4
@@ -3270,25 +3322,25 @@ for thislib in $libswanted; do
                *"-l$thislib "*);;
                *) dflt="$dflt -l$thislib";;
                esac
-       elif xxx=`./loc lib$thislib${lib_ext} X $libpth`; $test -f "$xxx"; then
+       elif xxx=`./loc lib$thislib$lib_ext X $libpth`; $test -f "$xxx"; then
                echo "Found -l$thislib."
                case " $dflt " in
                *"-l$thislib "*);;
                *) dflt="$dflt -l$thislib";;
                esac
-       elif xxx=`./loc $thislib${lib_ext} X $libpth`; $test -f "$xxx"; then
+       elif xxx=`./loc $thislib$lib_ext X $libpth`; $test -f "$xxx"; then
                echo "Found -l$thislib."
                case " $dflt " in
                *"-l$thislib "*);;
                *) dflt="$dflt -l$thislib";;
                esac
-       elif xxx=`./loc lib${thislib}_s${lib_ext} X $libpth`; $test -f "$xxx"; then
+       elif xxx=`./loc lib${thislib}_s$lib_ext X $libpth`; $test -f "$xxx"; then
                echo "Found -l${thislib}_s."
                case " $dflt " in
                *"-l$thislib "*);;
                *) dflt="$dflt -l${thislib}_s";;
                esac
-       elif xxx=`./loc Slib$thislib${lib_ext} X $xlibpth`; $test -f "$xxx"; then
+       elif xxx=`./loc Slib$thislib$lib_ext X $xlibpth`; $test -f "$xxx"; then
                echo "Found -l$thislib."
                case " $dflt " in
                *"-l$thislib "*);;
@@ -3546,7 +3598,6 @@ if ./osf1; then
 else
        set signal.h LANGUAGE_C; eval $inctest
 fi
-set signal.h NO_PROTOTYPE; eval $inctest
 set signal.h _NO_PROTO; eval $inctest
 
 case "$hint" in
@@ -3839,7 +3890,7 @@ echo " "
 case "$libc" in
 '') libc=unknown
        case "$libs" in
-       *-lc_s*) libc=`./loc libc_s${lib_ext} $libc $libpth`
+       *-lc_s*) libc=`./loc libc_s$lib_ext $libc $libpth`
        esac
        ;;
 esac
@@ -3857,15 +3908,13 @@ case "$libs" in
                        :
                elif try=`./loc lib$thislib.$so X $libpth`; $test -f "$try"; then
                        :
-               elif try=`./loc lib$thislib${lib_ext} X $libpth`; $test -f "$try"; then
-                       :
-               elif try=`./loc $thislib${lib_ext} X $libpth`; $test -f "$try"; then
+               elif try=`./loc lib$thislib$lib_ext X $libpth`; $test -f "$try"; then
                        :
                elif try=`./loc lib$thislib X $libpth`; $test -f "$try"; then
                        :
                elif try=`./loc $thislib X $libpth`; $test -f "$try"; then
                        :
-               elif try=`./loc Slib$thislib${lib_ext} X $xlibpth`; $test -f "$try"; then
+               elif try=`./loc Slib$thislib$lib_ext X $xlibpth`; $test -f "$try"; then
                        :
                else
                        try=''
@@ -3896,7 +3945,7 @@ unknown)
                eval set \$$#
        done
        $test -r $1 || set /usr/ccs/lib/libc.$so
-       $test -r $1 || set /lib/libsys_s.a
+       $test -r $1 || set /lib/libsys_s$lib_ext
        ;;
 *)
        set blurfl
@@ -3915,25 +3964,25 @@ elif $test -r /lib/libc && $test -r /lib/clib; then
        fi
 elif $test -r "$libc" || (test -h "$libc") >/dev/null 2>&1; then
        echo "Your C library seems to be in $libc, as you said before."
-elif $test -r $incpath/usr/lib/libc${lib_ext}; then
-       libc=$incpath/usr/lib/libc${lib_ext};
+elif $test -r $incpath/usr/lib/libc$lib_ext; then
+       libc=$incpath/usr/lib/libc$lib_ext;
        echo "Your C library seems to be in $libc.  That's fine."
-elif $test -r /lib/libc${lib_ext}; then
-       libc=/lib/libc${lib_ext};
+elif $test -r /lib/libc$lib_ext; then
+       libc=/lib/libc$lib_ext;
        echo "Your C library seems to be in $libc.  You're normal."
 else
-       if tans=`./loc libc${lib_ext} blurfl/dyick $libpth`; $test -r "$tans"; then
+       if tans=`./loc libc$lib_ext blurfl/dyick $libpth`; $test -r "$tans"; then
                :
        elif tans=`./loc libc blurfl/dyick $libpth`; $test -r "$tans"; then
                libnames="$libnames "`./loc clib blurfl/dyick $libpth`
        elif tans=`./loc clib blurfl/dyick $libpth`; $test -r "$tans"; then
                :
-       elif tans=`./loc Slibc${lib_ext} blurfl/dyick $xlibpth`; $test -r "$tans"; then
+       elif tans=`./loc Slibc$lib_ext blurfl/dyick $xlibpth`; $test -r "$tans"; then
                :
-       elif tans=`./loc Mlibc${lib_ext} blurfl/dyick $xlibpth`; $test -r "$tans"; then
+       elif tans=`./loc Mlibc$lib_ext blurfl/dyick $xlibpth`; $test -r "$tans"; then
                :
        else
-               tans=`./loc Llibc${lib_ext} blurfl/dyick $xlibpth`
+               tans=`./loc Llibc$lib_ext blurfl/dyick $xlibpth`
        fi
        if $test -r "$tans"; then
                echo "Your C library seems to be in $tans, of all places."
@@ -4087,22 +4136,6 @@ fi
 esac
 $rm -f libnames libpath
 
-: Define several unixisms. Hints files or command line options
-: can be used to override them.
-case "$ar" in
-'') ar='ar';;
-esac
-case "$obj_ext" in
-'') obj_ext='.o';;
-esac
-case "$path_sep" in
-'') path_sep=':';;
-esac
-: Which makefile gets called first.  This is used by make depend.
-case "$firstmakefile" in
-'') firstmakefile='makefile';;
-esac
-
 : determine filename position in cpp output
 echo " "
 echo "Computing filename position in cpp output for #include directives..." >&4
@@ -4608,7 +4641,7 @@ case "$shrpdir" in
 *)     $cat >&4 <<EOM
 WARNING:  Use of the shrpdir variable for the installation location of
 the shared $libperl is not supported.  It was never documented and
-will not work in this version.  Let me (doughera@lafcol.lafayette.edu)
+will not work in this version.  Let me (chip@atlantic.net)
 know of any problems this may cause.
 
 EOM
@@ -5216,6 +5249,63 @@ rp='Perl administrator e-mail address'
 . ./myread
 perladmin="$ans"
 
+: figure out how to guarantee perl startup
+case "$startperl" in
+'')
+       case "$sharpbang" in
+       *!)
+               $cat <<EOH
+
+I can use the #! construct to start perl on your system. This will
+make startup of perl scripts faster, but may cause problems if you
+want to share those scripts and perl is not in a standard place
+($binexp/perl) on all your platforms. The alternative is to force
+a shell by starting the script with a single ':' character.
+
+EOH
+               dflt="$binexp/perl"
+               rp='What shall I put after the #! to start up perl ("none" to not use #!)?'
+               . ./myread
+               case "$ans" in
+               none) startperl=": # use perl";;
+               *) startperl="#!$ans";;
+               esac
+               ;;
+       *) startperl=": # use perl"
+               ;;
+       esac
+       ;;
+esac
+echo "I'll use $startperl to start perl scripts."
+
+: figure best path for perl in scripts
+case "$perlpath" in
+'')
+       perlpath="$binexp/perl"
+       case "$startperl" in
+       *!*) ;;
+       *)
+               $cat <<EOH
+
+I will use the "eval 'exec'" idiom to start Perl on your system.
+I can use the full path of your Perl binary for this purpose, but
+doing so may cause problems if you want to share those scripts and
+Perl is not always in a standard place ($binexp/perl).
+
+EOH
+               dflt="$binexp/perl"
+               rp="What path shall I use in \"eval 'exec'\"?"
+               . ./myread
+               perlpath="$ans"
+               ;;
+       esac
+       ;;
+esac
+case "$startperl" in
+*!*)   ;;
+*)     echo "I'll use $perlpath in \"eval 'exec'\"" ;;
+esac
+
 : determine where public executable scripts go
 set scriptdir scriptdir
 eval $prefixit
@@ -5269,40 +5359,6 @@ else
        installscript="$scriptdirexp"
 fi
 
-: determine perl absolute location
-case "$perlpath" in
-'')    perlpath=$binexp/perl ;;
-esac
-
-: figure out how to guarantee perl startup
-case "$startperl" in
-'')
-       case "$sharpbang" in
-       *!)
-               $cat <<EOH
-
-I can use the #! construct to start perl on your system. This will
-make startup of perl scripts faster, but may cause problems if you
-want to share those scripts and perl is not in a standard place
-($perlpath) on all your platforms. The alternative is to force
-a shell by starting the script with a single ':' character.
-
-EOH
-               dflt=$perlpath
-               rp='What shall I put after the #! to start up perl ("none" to not use #!)?'
-               . ./myread
-               case "$ans" in
-               none) startperl=": # use perl";;
-               *) startperl="#!$ans";;
-               esac
-               ;;
-       *) startperl=": # use perl"
-               ;;
-       esac
-       ;;
-esac
-echo "I'll use $startperl to start perl scripts."
-
 cat <<EOM
 
 Previous version of $package used the standard IO mechanisms as defined in
@@ -5911,19 +5967,19 @@ if set crypt val -f d_crypt; eval $csym; $val; then
        val="$define"
        cryptlib=''
 else
-       cryptlib=`./loc Slibcrypt${lib_ext} "" $xlibpth`
+       cryptlib=`./loc Slibcrypt$lib_ext "" $xlibpth`
        if $test -z "$cryptlib"; then
-               cryptlib=`./loc Mlibcrypt${lib_ext} "" $xlibpth`
+               cryptlib=`./loc Mlibcrypt$lib_ext "" $xlibpth`
        else
                cryptlib=-lcrypt
        fi
        if $test -z "$cryptlib"; then
-               cryptlib=`./loc Llibcrypt${lib_ext} "" $xlibpth`
+               cryptlib=`./loc Llibcrypt$lib_ext "" $xlibpth`
        else
                cryptlib=-lcrypt
        fi
        if $test -z "$cryptlib"; then
-               cryptlib=`./loc libcrypt${lib_ext} "" $libpth`
+               cryptlib=`./loc libcrypt$lib_ext "" $libpth`
        else
                cryptlib=-lcrypt
        fi
@@ -6126,23 +6182,23 @@ main()
 #endif
     handle = dlopen("./dyna.$dlext", mode) ;
     if (handle == NULL) {
-        printf ("1\n") ;
-        fflush (stdout) ;
-           exit(0);
+       printf ("1\n") ;
+       fflush (stdout) ;
+       exit(0);
     }
     symbol = dlsym(handle, "fred") ;
     if (symbol == NULL) {
-               /* try putting a leading underscore */
-        symbol = dlsym(handle, "_fred") ;
-        if (symbol == NULL) {
-            printf ("2\n") ;
-            fflush (stdout) ;
-               exit(0);
-               }
-        printf ("3\n") ;
+       /* try putting a leading underscore */
+       symbol = dlsym(handle, "_fred") ;
+       if (symbol == NULL) {
+           printf ("2\n") ;
+           fflush (stdout) ;
+           exit(0);
+       }
+       printf ("3\n") ;
     }
     else
-        printf ("4\n") ;
+       printf ("4\n") ;
     fflush (stdout) ;
     exit(0);
 }
@@ -6460,6 +6516,25 @@ eval $inlibc
 set getpriority d_getprior
 eval $inlibc
 
+: see if gettimeofday or ftime exists
+set gettimeofday d_gettimeod
+eval $inlibc
+case "$d_gettimeod" in
+"$undef")
+       set ftime d_ftime 
+       eval $inlibc
+       ;;
+*)
+       val="$undef"; set d_ftime; eval $setvar
+       ;;
+esac
+case "$d_gettimeod$d_ftime" in
+"$undef$undef")
+       echo " "
+       echo 'No ftime() nor gettimeofday() -- timing may be less accurate.' >&4
+       ;;
+esac
+
 : see if this is a netinet/in.h or sys/in.h system
 set netinet/in.h i_niin sys/in.h i_sysin
 eval $inhdr
@@ -7048,7 +7123,7 @@ val="$undef"
 case "$d_memcmp" in
 "$define")
        echo " "
-       echo "Checking to see if memcmp() can compare relative magnitude..." >&4
+       echo "Checking to see if your memcmp() can compare relative magnitude..." >&4
        $cat >foo.c <<EOCP
 #$i_memory I_MEMORY
 #$i_stdlib I_STDLIB
@@ -7390,10 +7465,10 @@ else
                : we will have to assume that it supports the 4.2 BSD interface
                d_oldsock="$undef"
        else
-               echo "You don't have Berkeley networking in libc${lib_ext}..." >&4
-               if test -f /usr/lib/libnet${lib_ext}; then
-                       ( (nm $nm_opt /usr/lib/libnet${lib_ext} | eval $nm_extract) ||  \
-                       ar t /usr/lib/libnet${lib_ext}) 2>/dev/null >> libc.list
+               echo "You don't have Berkeley networking in libc$lib_ext..." >&4
+               if test -f /usr/lib/libnet$lib_ext; then
+                       ( (nm $nm_opt /usr/lib/libnet$lib_ext | eval $nm_extract) ||  \
+                       ar t /usr/lib/libnet$lib_ext) 2>/dev/null >> libc.list
                        if $contains socket libc.list >/dev/null 2>&1; then
                        echo "...but the Wollongong group seems to have hacked it in." >&4
                                socketlib="-lnet"
@@ -7406,7 +7481,7 @@ else
                                        d_oldsock="$define"
                                fi
                        else
-                               echo "or even in libnet${lib_ext}, which is peculiar." >&4
+                               echo "or even in libnet$lib_ext, which is peculiar." >&4
                                d_socket="$undef"
                                d_oldsock="$undef"
                        fi
@@ -8480,14 +8555,14 @@ EOP
 $cc $ccflags -c bar1.c >/dev/null 2>&1
 $cc $ccflags -c bar2.c >/dev/null 2>&1
 $cc $ccflags -c foo.c >/dev/null 2>&1
-ar rc bar${lib_ext} bar2.o bar1.o >/dev/null 2>&1
-if $cc $ccflags $ldflags -o foobar foo.o bar${lib_ext} $libs > /dev/null 2>&1 &&
+ar rc bar$lib_ext bar2.o bar1.o >/dev/null 2>&1
+if $cc $ccflags $ldflags -o foobar foo.o bar$lib_ext $libs > /dev/null 2>&1 &&
        ./foobar >/dev/null 2>&1; then
        echo "ar appears to generate random libraries itself."
        orderlib=false
        ranlib=":"
-elif ar ts bar${lib_ext} >/dev/null 2>&1 &&
-       $cc $ccflags $ldflags -o foobar foo.o bar${lib_ext} $libs > /dev/null 2>&1 &&
+elif ar ts bar$lib_ext >/dev/null 2>&1 &&
+       $cc $ccflags $ldflags -o foobar foo.o bar$lib_ext $libs > /dev/null 2>&1 &&
        ./foobar >/dev/null 2>&1; then
                echo "a table of contents needs to be added with 'ar ts'."
                orderlib=false
@@ -8960,7 +9035,7 @@ main()
 }
 EOM
 echo " "
-if $cc $ccflags $ldflags -o ssize ssize.c > /dev/null 2>&1  &&
+if $cc $ccflags $ldflags -o ssize ssize.c $libs > /dev/null 2>&1  &&
                ./ssize > /dev/null 2>&1 ; then
        ssizetype=`./ssize`
        echo "I'll be using $ssizetype for functions returning a byte count." >&4
@@ -9530,23 +9605,22 @@ known_extensions=''
 : some additional extensions into the source tree and expect them
 : to be built.
 for xxx in * ; do
-       case "$xxx" in
-       DynaLoader) ;;
-       *)
-               if $test -f $xxx/$xxx.xs; then
-                       known_extensions="$known_extensions $xxx"
-               else
-                       if $test -d $xxx; then
-                               cd $xxx
-                               for yyy in * ; do
-                                       if $test -f $yyy/$yyy.xs; then
-                                               known_extensions="$known_extensions $xxx/$yyy"
-                                       fi
-                               done
-                               cd ..
-                       fi
-               fi ;;
-       esac
+    case "$xxx" in
+    DynaLoader) ;;
+    *) if $test -f $xxx/$xxx.xs; then
+           known_extensions="$known_extensions $xxx"
+       else
+           if $test -d $xxx; then
+               cd $xxx
+               for yyy in * ; do
+                   if $test -f $yyy/$yyy.xs; then
+                       known_extensions="$known_extensions $xxx/$yyy"
+                   fi
+               done
+               cd ..
+           fi
+       fi ;;
+    esac
 done
 set X $known_extensions
 shift
@@ -9759,6 +9833,7 @@ awk='$awk'
 baserev='$baserev'
 bash='$bash'
 bin='$bin'
+bincompat3='$bincompat3'
 binexp='$binexp'
 bison='$bison'
 byacc='$byacc'
@@ -9798,6 +9873,7 @@ d_archlib='$d_archlib'
 d_attribut='$d_attribut'
 d_bcmp='$d_bcmp'
 d_bcopy='$d_bcopy'
+d_bincompat3='$d_bincompat3'
 d_bsd='$d_bsd'
 d_bsdgetpgrp='$d_bsdgetpgrp'
 d_bsdpgrp='$d_bsdpgrp'
@@ -9836,6 +9912,7 @@ d_flock='$d_flock'
 d_fork='$d_fork'
 d_fpathconf='$d_fpathconf'
 d_fsetpos='$d_fsetpos'
+d_ftime='$d_ftime'
 d_getgrps='$d_getgrps'
 d_gethent='$d_gethent'
 d_gethname='$d_gethname'
@@ -9845,6 +9922,7 @@ d_getpgrp2='$d_getpgrp2'
 d_getpgrp='$d_getpgrp'
 d_getppid='$d_getppid'
 d_getprior='$d_getprior'
+d_gettimeod='$d_gettimeod'
 d_gnulibc='$d_gnulibc'
 d_htonl='$d_htonl'
 d_index='$d_index'
diff --git a/INSTALL b/INSTALL
index 325509b..b629682 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -125,12 +125,12 @@ you can use the Configure command line option -Uusedl.
 By default, Configure will offer to build every extension which appears
 to be supported.  For example, Configure will offer to build GDBM_File
 only if it is able to find the gdbm library.  (See examples below.)
-DynaLoader, Fcntl, FileHandle and IO are always built by default.
-Configure does not contain code to test for POSIX compliance, so POSIX
-is always built by default as well.  If you wish to skip POSIX, you can
-set the Configure variable useposix=false either in a hint file or from
-the Configure command line.  Similarly, the Opcode extension is always
-built by default, but you can skip it by setting the Configure variable
+DynaLoader, Fcntl, and IO are always built by default.  Configure does
+not contain code to test for POSIX compliance, so POSIX is always built
+by default as well.  If you wish to skip POSIX, you can set the
+Configure variable useposix=false either in a hint file or from the
+Configure command line.  Similarly, the Opcode extension is always built
+by default, but you can skip it by setting the Configure variable
 useopcode=false either in a hint file for from the command line.
 
 Even if you do not have dynamic loading, you must still build the
@@ -143,7 +143,6 @@ to turn off each extension:
     DB_File            i_db
     DynaLoader         (Must always be included as a static extension)
     Fcntl              (Always included by default)
-    FileHandle         (Always included by default)
     GDBM_File          i_gdbm
     IO                 (Always included by default)
     NDBM_File          i_ndbm
@@ -885,6 +884,11 @@ If you get syntax errors on '(', try -DCRIPPLED_CC.
 
 Machines with half-implemented dbm routines will need to #undef I_ODBM
 
+db-recno failure on tests 51, 53 and 55:  Old versions of the DB library
+(including the DB library which comes with FreeBSD 2.1) had broken
+handling of recno databases with modified bval settings.  Upgrade your
+DB library or OS.
+
 =back
 
 =head1 make test
index 6c267a1..ce57721 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -4,8 +4,8 @@ Changes5.000            Differences from perl4.
 Changes5.001           Differences from 5.000.
 Changes5.002           Differences from 5.001.
 Changes5.003           Differences from 5.002.
-configure              Crude emulation of GNU configure
 Configure              Portability tool
+configure              Crude emulation of GNU configure
 Copying                        The GNU General Public License
 EXTERN.h               Included before foreign .h files
 INSTALL                        Detailed installation instructions.
@@ -23,6 +23,7 @@ XSUB.h                        Include file for extension subroutines
 av.c                   Array value code
 av.h                   Array value header
 cflags.SH              A script that emits C compilation flags per file
+compat3.sym            List of symbols for binary-compatibility with 5.003
 config_H               Sample config.h
 config_h.SH            Produces config.h
 configpm               Produces lib/Config.pm
@@ -225,6 +226,7 @@ hints/irix_6_2.sh   Hints for named architecture
 hints/isc.sh           Hints for named architecture
 hints/isc_2.sh         Hints for named architecture
 hints/linux.sh         Hints for named architecture
+hints/lynxos.sh                Hints for named architecture
 hints/machten.sh       Hints for named architecture
 hints/machten_2.sh     Hints for named architecture
 hints/mips.sh          Hints for named architecture
@@ -269,6 +271,9 @@ lib/AnyDBM_File.pm  Perl module to emulate dbmopen
 lib/AutoLoader.pm      Autoloader base class
 lib/AutoSplit.pm       A module to split up autoload functions
 lib/Benchmark.pm       A module to time pieces of code and such
+lib/CPAN.pm            Interface to Comprehensive Perl Archive Network
+lib/CPAN/FirstTime.pm  Utility for creating CPAN config files
+lib/CPAN/Nox.pm                Runs CPAN while avoiding compiled extensions
 lib/Carp.pm            Error message base class
 lib/Class/Template.pm  Structure/member template builder; makes nested types
 lib/Cwd.pm             Various cwd routines (getcwd, fastcwd, chdir)
@@ -293,6 +298,7 @@ lib/ExtUtils/xsubpp         External subroutine preprocessor
 lib/Fatal.pm           Make do-or-die equivalents of functions
 lib/File/Basename.pm   A module to emulate the basename program
 lib/File/CheckTree.pm  Perl module supporting wholesale file mode validation
+lib/File/Compare.pm    Emulation of cmp command
 lib/File/Copy.pm       Emulation of cp command
 lib/File/Find.pm       Routines to do a find
 lib/File/Path.pm       A module to do things like `mkdir -p' and `rm -r'
@@ -308,7 +314,10 @@ lib/IPC/Open3.pm   Open a three-ended pipe!
 lib/Math/BigFloat.pm   An arbitrary precision floating-point arithmetic package
 lib/Math/BigInt.pm     An arbitrary precision integer arithmetic package
 lib/Math/Complex.pm    A Complex package
+lib/Net/FTP.pm         File Transfer Protocol client
+lib/Net/Netrc.pm       Parser for ".netrc" file a la Berkeley UNIX
 lib/Net/Ping.pm                Ping methods
+lib/Net/Socket.pm      Support class for Net::FTP
 lib/Net/hostent.pm     Object-oriented wrapper around CORE::gethost*
 lib/Net/netent.pm      Object-oriented wrapper around CORE::getnet*
 lib/Net/protoent.pm    Object-oriented wrapper around CORE::getproto*
@@ -332,6 +341,7 @@ lib/Text/Soundex.pm Perl module to implement Soundex
 lib/Text/Tabs.pm       Do expand and unexpand
 lib/Text/Wrap.pm       Paragraph formatter
 lib/Tie/Hash.pm                Base class for tied hashes
+lib/Tie/RefHash.pm     Base class for tied hashes with references as keys
 lib/Tie/Scalar.pm      Base class for tied scalars
 lib/Tie/SubstrHash.pm  Compact hash for known key, value and table size
 lib/Time/Local.pm      Reverse translation of localtime, gmtime
@@ -379,7 +389,6 @@ lib/perl5db.pl              Perl debugging routines
 lib/pwd.pl             Routines to keep track of PWD environment variable
 lib/shellwords.pl      Perl library to split into words with shell quoting
 lib/sigtrap.pm         For trapping an abort and giving traceback
-lib/splain             Standalone program to print verbose diagnostics.
 lib/stat.pl            Perl library supporting stat function
 lib/strict.pm          For "use strict"
 lib/subs.pm            Declare overriding subs
@@ -400,9 +409,6 @@ miniperlmain.c              Basic perl w/o dynamic loading or extensions
 mv-if-diff             Script to mv a file if it changed
 myconfig               Prints summary of the current configuration
 nostdio.h              Cause compile error on stdio calls
-old_embed.pl           Produces embed.h using old_global.sym
-old_global.sym         Old list of symbols to hide when embedded
-old_perl_exp.SH                Creates old list of exported symbols for AIX.
 op.c                   Opcode syntax tree code
 op.h                   Opcode syntax tree header
 opcode.h               Automatically generated opcode header
@@ -494,10 +500,11 @@ pod/perlembed.pod Embedding info
 pod/perlform.pod       Format info
 pod/perlfunc.pod       Function info
 pod/perlguts.pod       Internals info
-pod/perli18n.pod       I18N info
 pod/perlipc.pod                IPC info
-pod/perllol.pod                How to use lists of lists.
+pod/perllocale.pod     Locale support info
+pod/perllol.pod                How to use lists of lists
 pod/perlmod.pod                Module info
+pod/perlnews.pod       News of changes since last version
 pod/perlobj.pod                Object info
 pod/perlop.pod         Operator info
 pod/perlovl.pod                Overloading info
@@ -511,6 +518,7 @@ pod/perlsub.pod             Subroutine info
 pod/perlsyn.pod                Syntax info
 pod/perltie.pod                Tieing an object class into a simple variable
 pod/perltoc.pod                Table of Contents info
+pod/perltoot.pod       Tom's object-oriented tutorial
 pod/perltrap.pod       Trap info
 pod/perlvar.pod                Variable info
 pod/perlxs.pod         XS api info
@@ -655,9 +663,10 @@ t/op/push.t                See if push and pop work
 t/op/quotemeta.t       See if quotemeta works
 t/op/rand.t            See if rand works
 t/op/range.t           See if .. works
-t/op/re_tests          Input file for op.regexp
+t/op/re_tests          Regular expressions for regexp.t
 t/op/read.t            See if read() works
 t/op/readdir.t         See if readdir() works
+t/op/recurse.t         See if deep recursion works
 t/op/ref.t             See if refs and objects work
 t/op/regexp.t          See if regular expressions work
 t/op/repeat.t          See if x operator works
@@ -676,7 +685,6 @@ t/op/undef.t                See if undef works
 t/op/unshift.t         See if unshift works
 t/op/vec.t             See if vectors work
 t/op/write.t           See if write works
-t/re_tests             Regular expressions for regexp.t
 taint.c                        Tainting code
 toke.c                 The tokener
 universal.c            The default UNIVERSAL package methods
@@ -690,9 +698,15 @@ utils/h2xs.PL              Program to make .xs files from C header files
 utils/perlbug.PL       A simple tool to submit a bug report
 utils/perldoc.PL       A simple tool to find & display perl's documentation
 utils/pl2pm.PL         A pl to pm translator
+utils/splain.PL                Stand-alone version of diagnostics.pm
 vms/Makefile           VMS port
 vms/config.vms         default config.h for VMS
 vms/descrip.mms                MM[SK] description file for build
+vms/ext/DCLsym/0README.txt     ReadMe file for VMS::DCLsym
+vms/ext/DCLsym/DCLsym.pm       Perl access to CLI symbols
+vms/ext/DCLsym/DCLsym.xs       Perl access to CLI symbols
+vms/ext/DCLsym/Makefile.PL     MakeMaker driver for VMS::DCLsym
+vms/ext/DCLsym/test.pl regression tests for VMS::DCLsym
 vms/ext/Filespec.pm    VMS-Unix file syntax interconversion
 vms/ext/Stdio/0README.txt      ReadMe file for VMS::Stdio
 vms/ext/Stdio/Makefile.PL      MakeMaker driver for VMS::Stdio
index 81d6589..db3b776 100755 (executable)
@@ -243,7 +243,7 @@ $(LIBPERL): $& perl$(OBJ_EXT) $(obj)
        case "$useshrplib" in
        true)
                $spitshell >>Makefile <<'!NO!SUBS!'
-       $(LD) $(LDDLFLAGS) -o $@ perl$(OBJ_EXT) $(obj)
+       $(LD) $(LDDLFLAGS) -o $@ perl$(OBJ_EXT) $(obj) $(libs)
 !NO!SUBS!
                ;;
        *)
index 4cd0099..da02084 100644 (file)
@@ -1318,7 +1318,7 @@ startperl (startperl.U):
        script to make sure (hopefully) that it runs with perl and not some
        shell. Of course, that leading line must be followed by the classical
        perl idiom:
-               eval 'exec perl -S $0 "$@"'
+               eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
                        if $running_under_some_shell;
        to guarantee perl startup should the shell execute the script. Note
        that this magic incatation is not understood by csh.
diff --git a/compat3.sym b/compat3.sym
new file mode 100644 (file)
index 0000000..db53dd6
--- /dev/null
@@ -0,0 +1,46 @@
+# Global symbols that should handled differently when Perl 5.004 is
+# compiled for binary compatibility with version 5.003.
+
+# Variables from "interp.sym" that _should_ be hidden.
+
+curcop
+curcopdb
+envgv
+siggv
+tainting
+
+# Variables from "global.sym" that should _not_ be hidden.
+
+Error
+block_type
+comppad_name_floor
+debug
+nice_chunk
+nice_chunk_size
+no_myglob
+no_symref
+no_wrongref
+pad_reset_pending
+padix_floor
+regflags
+warn_uninit
+
+# Functions from "global.sym" that should _not_ be hidden.
+
+SvIV
+SvNV
+SvTRUE
+SvUV
+boot_core_UNIVERSAL
+do_undump
+safecalloc
+safefree
+safemalloc
+saferealloc
+safexcalloc
+safexfree
+safexmalloc
+safexrealloc
+save_iv
+sv_pvn
+yydestruct
index 6146ce8..11e9033 100644 (file)
--- a/config_H
+++ b/config_H
  */
 #define HAS_FSETPOS    /**/
 
+/* HAS_GETTIMEOFDAY:
+ *     This symbol, if defined, indicates that the gettimeofday() system
+ *     call is available for a sub-second accuracy clock. Usually, the file
+ *     <sys/resource.h> needs to be included (see I_SYS_RESOURCE).
+ *     The type "Timeval" should be used to refer to "struct timeval".
+ */
+/*#define HAS_GETTIMEOFDAY     / **/
+#ifdef HAS_GETTIMEOFDAY
+#define Timeval struct timeval /* Structure used by gettimeofday() */
+#endif
+
 /* HAS_GETGROUPS:
  *     This symbol, if defined, indicates that the getgroups() routine is
  *     available to get the list of process groups.  If unavailable, multiple
 /*#define HAS_SAFE_MEMCPY      / **/
 
 /* HAS_SANE_MEMCMP:
- *     This symbol, if defined, indicates that the memcmp() routine is
- *     available to compare memory blocks for relative magnitude. If this
- *     symbol is not defined, and if HAS_MEMCMP is defined, then memcmp()
- *     may be used only to compare memory blocks for equality.
+ *     This symbol, if defined, indicates that the memcmp routine is available
+ *     and can be used to compare relative magnitudes of chars with their high
+ *     bits set.  If it is not defined, roll your own version.
  */
 /*#define HAS_SANE_MEMCMP      / **/
 
 #define ARCHLIB "/opt/perl/lib/i86pc-solaris/5.00305"          /**/
 #define ARCHLIB_EXP "/opt/perl/lib/i86pc-solaris/5.00305"              /**/
 
+/* BINCOMPAT3:
+ *     This symbol, if defined, indicates that Perl 5.004 should be
+ *     binary-compatible with Perl 5.003.
+ */
+#define BINCOMPAT3             /**/
+
 /* BYTEORDER:
  *     This symbol holds the hexadecimal constant defined in byteorder,
  *     i.e. 0x1234 or 0x4321, etc...
index d2ff19c..dd73771 100755 (executable)
@@ -269,6 +269,17 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un-
  */
 #$d_fsetpos HAS_FSETPOS        /**/
 
+/* HAS_GETTIMEOFDAY:
+ *     This symbol, if defined, indicates that the gettimeofday() system
+ *     call is available for a sub-second accuracy clock. Usually, the file
+ *     <sys/resource.h> needs to be included (see I_SYS_RESOURCE).
+ *     The type "Timeval" should be used to refer to "struct timeval".
+ */
+#$d_gettimeod HAS_GETTIMEOFDAY /**/
+#ifdef HAS_GETTIMEOFDAY
+#define Timeval struct timeval /* Structure used by gettimeofday() */
+#endif
+
 /* HAS_GETGROUPS:
  *     This symbol, if defined, indicates that the getgroups() routine is
  *     available to get the list of process groups.  If unavailable, multiple
@@ -551,10 +562,9 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un-
 #$d_safemcpy HAS_SAFE_MEMCPY   /**/
 
 /* HAS_SANE_MEMCMP:
- *     This symbol, if defined, indicates that the memcmp() routine is
- *     available to compare memory blocks for relative magnitude. If this
- *     symbol is not defined, and if HAS_MEMCMP is defined, then memcmp()
- *     may be used only to compare memory blocks for equality.
+ *     This symbol, if defined, indicates that the memcmp routine is available
+ *     and can be used to compare relative magnitudes of chars with their high
+ *     bits set.  If it is not defined, roll your own version.
  */
 #$d_sanemcmp HAS_SANE_MEMCMP   /**/
 
@@ -810,19 +820,19 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un-
 
 /* HAS_STRTOD:
  *     This symbol, if defined, indicates that the strtod routine is
- *     available to translate strings to doubles.
+ *     available to provide better numeric string conversion than atof().
  */
 #$d_strtod HAS_STRTOD  /**/
 
 /* HAS_STRTOL:
- *     This symbol, if defined, indicates that the strtol routine is
- *     available to translate strings to integers.
+ *     This symbol, if defined, indicates that the strtol routine is available
+ *     to provide better numeric string conversion than atoi() and friends.
  */
 #$d_strtol HAS_STRTOL  /**/
 
 /* HAS_STRTOUL:
  *     This symbol, if defined, indicates that the strtoul routine is
- *     available to translate strings to integers.
+ *     available to provide conversion of strings to unsigned long.
  */
 #$d_strtoul HAS_STRTOUL        /**/
 
@@ -1376,6 +1386,12 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un-
 #$d_archlib ARCHLIB "$archlib"         /**/
 #$d_archlib ARCHLIB_EXP "$archlibexp"          /**/
 
+/* BINCOMPAT3:
+ *     This symbol, if defined, indicates that Perl 5.004 should be
+ *     binary-compatible with Perl 5.003.
+ */
+#$d_bincompat3 BINCOMPAT3                      /**/
+
 /* BYTEORDER:
  *     This symbol holds the hexadecimal constant defined in byteorder,
  *     i.e. 0x1234 or 0x4321, etc...
diff --git a/cop.h b/cop.h
index 6aa32df..299873b 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -93,6 +93,7 @@ struct block_loop {
     OP *       last_op;
     SV **      itervar;
     SV *       itersave;
+    SV *       iterlval;
     AV *       iterary;
     I32                iterix;
 };
@@ -103,12 +104,14 @@ struct block_loop {
        cx->blk_loop.redo_op = cLOOP->op_redoop;                        \
        cx->blk_loop.next_op = cLOOP->op_nextop;                        \
        cx->blk_loop.last_op = cLOOP->op_lastop;                        \
+       cx->blk_loop.iterlval = Nullsv;                                 \
        cx->blk_loop.itervar = ivar;                                    \
        if (ivar)                                                       \
            cx->blk_loop.itersave = *cx->blk_loop.itervar;
 
 #define POPLOOP(cx)                                                    \
-       newsp           = stack_base + cx->blk_loop.resetsp;
+       newsp           = stack_base + cx->blk_loop.resetsp;            \
+       SvREFCNT_dec(cx->blk_loop.iterlval)
 
 /* context common to subroutines, evals and loops */
 struct block {
diff --git a/dump.c b/dump.c
index 064641f..c0749b8 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -189,10 +189,17 @@ register OP *op;
                (void)strcat(buf,"AMPER,");
            if (op->op_private & OPpENTERSUB_DB)
                (void)strcat(buf,"DB,");
-           if (op->op_private & OPpDEREF_AV)
-               (void)strcat(buf,"AV,");
-           if (op->op_private & OPpDEREF_HV)
-               (void)strcat(buf,"HV,");
+           switch (op->op_private & OPpDEREF) {
+           case OPpDEREF_SV:
+               (void)strcat(buf, "SV,");
+               break;
+           case OPpDEREF_AV:
+               (void)strcat(buf, "AV,");
+               break;
+           case OPpDEREF_HV:
+               (void)strcat(buf, "HV,");
+               break;
+           }
            if (op->op_private & HINT_STRICT_REFS)
                (void)strcat(buf,"STRICT_REFS,");
        }
index 87cfc33..15eb655 100644 (file)
--- a/eg/README
+++ b/eg/README
@@ -13,7 +13,7 @@ of a system to check on and report various kinds of anomalies.
 If you machine doesn't support #!, the first thing you'll want to do is
 replace the #! with a couple of lines that look like this:
 
-       eval "exec /usr/bin/perl -S $0 $*"
+       eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
                if $running_under_some_shell;
 
 being sure to include any flags that were on the #! line.  A supplied script
diff --git a/eg/nih b/eg/nih
index 2066f4b..4475c49 100644 (file)
--- a/eg/nih
+++ b/eg/nih
@@ -1,4 +1,4 @@
-eval "exec /usr/bin/perl -Spi.bak $0 $*"
+eval 'exec /usr/bin/perl -Spi.bak $0 ${1+"$@"}'
        if $running_under_some_shell;
 
 # $RCSfile: nih,v $$Revision: 4.1 $$Date: 92/08/07 17:20:27 $
@@ -6,5 +6,6 @@ eval "exec /usr/bin/perl -Spi.bak $0 $*"
 # This script makes #! scripts directly executable on machines that don't
 # support #!.  It edits in place any scripts mentioned on the command line.
 
-s|^#!(.*)|#!$1\neval "exec $1 -S \$0 \$*"\n\tif \$running_under_some_shell;|
+s[^#!(.*)]
+ [#!$1\neval 'exec $1 -S \$0 \${1+"\$@"}'\n\tif \$running_under_some_shell;]
        if $. == 1;
index 317e027..646d8b6 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
-       if 0;
+       if $running_under_some_shell;
 
 require 'sys/ipc.ph';
 require 'sys/msg.ph';
index d72a2dd..4d871b9 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
-       if 0;
+       if $running_under_some_shell;
 
 require 'sys/ipc.ph';
 require 'sys/msg.ph';
index d40e46b..ecc1ba4 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
-       if 0;
+       if $running_under_some_shell;
 
 require 'sys/ipc.ph';
 require 'sys/shm.ph';
index ba4a863..6fa07ad 100644 (file)
@@ -32,7 +32,7 @@
 ;;; Corrections made by Ilya Zakharevich ilya@math.mps.ohio-state.edu
 ;;; XEmacs changes by Peter Arius arius@informatik.uni-erlangen.de
 
-;; $Id: cperl-mode.el,v 1.29 1996/11/18 23:10:26 ilya Exp ilya $
+;; $Id: cperl-mode.el,v 1.31+ 1996/12/09 08:03:14 ilya Exp ilya $
 
 ;;; To use this mode put the following into your .emacs file:
 
 ;;; in your .emacs file. (Emacs rulers do not consider it politically
 ;;; correct to make whistles enabled by default.)
 
+;;; DO NOT FORGET to read micro-docs. (available from `Perl' menu). <<<<<<
+;;; or as help on variables `cperl-tips', `cperl-problems',         <<<<<<
+;;; `cperl-non-problems'.                                           <<<<<<
+
 ;;; Additional useful commands to put into your .emacs file:
 
 ;; (setq auto-mode-alist
 ;;;  Minor updates to `cperl-short-docs'.
 ;;;  Will not consider <<= as start of here-doc.
 
+;;;; After 1.29
+;;;  Added an extra advice to look into Micro-docs. ;-).
+;;;  Enclosing of region when you press a closing parenth is regulated by
+;;;  `cperl-electric-parens-string'.
+;;;  Minor updates to `cperl-short-docs'.
+;;;  `initialize-new-tags-table' called only if present (Does this help
+;;;     with generation of tags under XEmacs?).
+;;;  When creating/updating tag files, new info is written at the old place,
+;;;     or at the end (is this a wanted behaviour? I need this in perl build directory).
+
+;;;; After 1.30
+;;;  All the keywords from keywords.pl included (maybe with dummy explanation).
+;;;  No auto-help inside strings, comment, here-docs, formats, and pods.
+;;;  Shrinkwrapping of info, regulated by `cperl-max-help-size'.
+;;;  Info on variables as well.
+;;;  Recognision of HERE-DOCS improved yet more.
+;;;  Autonewline works on `}' without warnings.
+;;;  Autohelp works again on $_[0].
+
+;;;; After 1.31
+;;;  perl-descr.el found its author - hi, Johan!
+
 (defvar cperl-extra-newline-before-brace nil
   "*Non-nil means that if, elsif, while, until, else, for, foreach
 and do constructs look like:
@@ -388,7 +414,7 @@ Can be overwritten by `cperl-hairy' if nil.")
   "*Non-nil (and non-null) means { after $ in CPerl buffers should be preceeded by ` '.
 Can be overwritten by `cperl-hairy' if nil.")
 
-(defvar cperl-electric-parens-string "({[<"
+(defvar cperl-electric-parens-string "({[]})<"
   "*String of parentheses that should be electric in CPerl.")
 
 (defvar cperl-electric-parens nil
@@ -455,6 +481,12 @@ You can always make lookup from menu or using \\[cperl-find-pods-heres].")
   "*Not-nil means add backreferences to generated `imenu's.
 May require patched `imenu' and `imenu-go'.")
 
+(defvar cperl-max-help-size 66
+  "*Non-nil means shrink-wrapping of info-buffer allowed up to these percents.")
+
+(defvar cperl-shrink-wrap-info-frame t
+  "*Non-nil means shrink-wrapping of info-buffer-frame allowed.")
+
 (defvar cperl-info-page "perl"
   "Name of the info page containing perl docs.
 Older version of this page was called `perl5', newer `perl'.")
@@ -548,6 +580,10 @@ will not break indentation, but
        1 if ( s#//#/# );
 will.
 
+By similar reasons
+       s\"abc\"def\";
+will confuse CPerl a lot.
+
 If you still get wrong indentation in situation that you think the
 code should be able to parse, try:
 
@@ -1194,10 +1230,10 @@ char is \"{\", insert extra newline before only if
                   (if cperl-auto-newline 
                       (progn (cperl-indent-line) (newline) t) nil)))
          (progn
-           (if cperl-auto-newline
-               (setq insertpos (point)))
            (insert last-command-char)
            (cperl-indent-line)
+           (if cperl-auto-newline
+               (setq insertpos (1- (point))))
            (if (and cperl-auto-newline (null only-before))
                (progn
                  (newline)
@@ -1282,6 +1318,9 @@ If not, or if we are not at the end of marking range, would self-insert."
   (interactive "P")
   (let ((beg (save-excursion (beginning-of-line) (point)))
        (other-end (if (and cperl-electric-parens-mark
+                           (cperl-val 'cperl-electric-parens)
+                           (memq last-command-char
+                                 (append cperl-electric-parens-string nil))
                            (cperl-mark-active) 
                            (< (mark) (point)))
                       (mark) 
@@ -2137,9 +2176,20 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
               "\\(\\`\n?\\|\n\n\\)=" 
               "\\|"
               ;; One extra () before this:
-              "<<\\(\\([\"'`]\\)\\([^\"'`\n]*\\)\\3\\|\\(\\([a-zA-Z_][a-zA-Z_0-9]*\\)?\\)[^=]\\)" ; [^=] to avoid <<=.
+              "<<" 
+                "\\(" 
+                ;; First variant "BLAH" or just ``.
+                   "\\([\"'`]\\)"
+                   "\\([^\"'`\n]*\\)"
+                   "\\3"
+                "\\|"
+                ;; Second variant: Identifier or empty
+                  "\\(\\([a-zA-Z_][a-zA-Z_0-9]*\\)?\\)"
+                  ;; Check that we do not have <<= or << 30 or << $blah.
+                  "\\([^= \t$@%&]\\|[ \t]+[^ \t\n0-9$@%&]\\)"
+                "\\)"
               "\\|"
-              ;; 1+5 extra () before this:
+              ;; 1+6 extra () before this:
               "^[ \t]*format[ \t]*\\([a-zA-Z0-9_]+\\)?[ \t]*=[ \t]*$")))
     (unwind-protect
        (progn
@@ -2240,12 +2290,12 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
                        (t (message "End of here-document `%s' not found." tag)))))
               ;; format
               (t
-               ;; 1+5=6 extra () before this:
+               ;; 1+6=7 extra () before this:
                ;; "^[ \t]*format[ \t]*\\([a-zA-Z0-9_]+\\)?[ \t]*=[ \t]*$")))
                (setq b (point)
-                     name (if (match-beginning 7) ; 6 + 1
-                              (buffer-substring (match-beginning 7) ; 6 + 1
-                                                (match-end 7)) ; 6 + 1
+                     name (if (match-beginning 8) ; 7 + 1
+                              (buffer-substring (match-beginning 8) ; 7 + 1
+                                                (match-end 8)) ; 7 + 1
                             ""))
                (setq argument nil)
                (if cperl-pod-here-fontify 
@@ -3295,34 +3345,52 @@ Available styles are GNU, K&R, BSD and Whitesmith."
   (let ((perl-dbg-flags "-wc"))
     (mode-compile)))
 
-(defun cperl-info-buffer ()
-  ;; Returns buffer with documentation. Creates if missing
-  (let ((info (get-buffer "*info-perl*")))
+(defun cperl-info-buffer (type)
+  ;; Returns buffer with documentation. Creates if missing.
+  ;; If TYPE, this vars buffer.
+  ;; Special care is taken to not stomp over an existing info buffer
+  (let* ((bname (if type "*info-perl-var*" "*info-perl*"))
+        (info (get-buffer bname))
+        (oldbuf (get-buffer "*info*")))
     (if info info
       (save-window-excursion
        ;; Get Info running
        (require 'info)
+       (cond (oldbuf
+              (set-buffer oldbuf)
+              (rename-buffer "*info-perl-tmp*")))
        (save-window-excursion
          (info))
-       (Info-find-node cperl-info-page "perlfunc")
+       (Info-find-node cperl-info-page (if type "perlvar" "perlfunc"))
        (set-buffer "*info*")
-       (rename-buffer "*info-perl*")
+       (rename-buffer bname)
+       (cond (oldbuf
+              (set-buffer "*info-perl-tmp*")
+              (rename-buffer "*info*")
+              (set-buffer bname)))
+       (make-variable-buffer-local 'window-min-height)
+       (setq window-min-height 2)
        (current-buffer)))))
 
 (defun cperl-word-at-point (&optional p)
   ;; Returns the word at point or at P.
   (save-excursion
     (if p (goto-char p))
-    (require 'etags)
-    (funcall (or (and (boundp 'find-tag-default-function)
-                     find-tag-default-function)
-                (get major-mode 'find-tag-default-function)
-                ;; XEmacs 19.12 has `find-tag-default-hook'; it is
-                ;; automatically used within `find-tag-default':
-                'find-tag-default))))
+    (or (cperl-word-at-point-hard)
+       (progn
+         (require 'etags)
+         (funcall (or (and (boundp 'find-tag-default-function)
+                           find-tag-default-function)
+                      (get major-mode 'find-tag-default-function)
+                      ;; XEmacs 19.12 has `find-tag-default-hook'; it is
+                      ;; automatically used within `find-tag-default':
+                      'find-tag-default))))))
 
 (defun cperl-info-on-command (command)
-  "Shows documentation for Perl command in other window."
+  "Shows documentation for Perl command in other window.
+If perl-info buffer is shown in some frame, uses this frame.
+Customized by setting variables `cperl-shrink-wrap-info-frame',
+`cperl-max-help-size'."
   (interactive 
    (let* ((default (cperl-word-at-point))
          (read (read-string 
@@ -3334,21 +3402,72 @@ Available styles are GNU, K&R, BSD and Whitesmith."
 
   (let ((buffer (current-buffer))
        (cmd-desc (concat "^" (regexp-quote command) "[^a-zA-Z_0-9]")) ; "tr///"
-       pos)
+       pos isvar height iniheight frheight buf win fr1 fr2 iniwin not-loner
+       max-height char-height buf-list)
     (if (string-match "^-[a-zA-Z]$" command)
        (setq cmd-desc "^-X[ \t\n]"))
-    (set-buffer (cperl-info-buffer))
+    (setq isvar (string-match "^[$@%]" command)
+         buf (cperl-info-buffer isvar)
+         iniwin (selected-window)
+         fr1 (window-frame iniwin))
+    (set-buffer buf)
     (beginning-of-buffer)
-    (re-search-forward "^-X[ \t\n]")
-    (forward-line -1)
+    (or isvar 
+       (progn (re-search-forward "^-X[ \t\n]")
+              (forward-line -1)))
     (if (re-search-forward cmd-desc nil t)
        (progn
-         (setq pos (progn (beginning-of-line)
-                          (point)))
-         (pop-to-buffer (cperl-info-buffer))
+         ;; Go back to beginning of the group (ex, for qq)
+         (if (re-search-backward "^[ \t\n\f]")
+             (forward-line 1))
+         (beginning-of-line)
+         ;; Get some of 
+         (setq pos (point)
+               buf-list (list buf "*info-perl-var*" "*info-perl*"))
+         (while (and (not win) buf-list)
+           (setq win (get-buffer-window (car buf-list) t))
+           (setq buf-list (cdr buf-list)))
+         (or (not win)
+             (eq (window-buffer win) buf)
+             (set-window-buffer win buf))
+         (and win (setq fr2 (window-frame win)))
+         (if (or (not fr2) (eq fr1 fr2))
+             (pop-to-buffer buf)
+           (special-display-popup-frame buf) ; Make it visible
+           (select-window win))
+         (goto-char pos)               ; Needed (?!).
+         ;; Resize
+         (setq iniheight (window-height)
+               frheight (frame-height)
+               not-loner (< iniheight (1- frheight))) ; Are not alone
+         (cond ((if not-loner cperl-max-help-size 
+                  cperl-shrink-wrap-info-frame)
+                (setq height 
+                      (+ 2 
+                         (count-lines 
+                          pos 
+                          (save-excursion
+                            (if (re-search-forward
+                                 "^[ \t][^\n]*\n+\\([^ \t\n\f]\\|\\'\\)" nil t)
+                                (match-beginning 0) (point-max)))))
+                      max-height 
+                      (if not-loner
+                          (/ (* (- frheight 3) cperl-max-help-size) 100)
+                        (setq char-height (frame-char-height))
+                        ;; Non-functioning under OS/2:
+                        (if (eq char-height 1) (setq char-height 18))
+                        ;; Title, menubar, + 2 for slack
+                        (- (/ (x-display-pixel-height) char-height) 4)
+                        ))
+                (if (> height max-height) (setq height max-height))
+                ;;(message "was %s doing %s" iniheight height)
+                (if not-loner
+                    (enlarge-window (- height iniheight))
+                  (set-frame-height (window-frame win) (1+ height)))))
          (set-window-start (selected-window) pos))
       (message "No entry for %s found." command))
-    (pop-to-buffer buffer)))
+    ;;(pop-to-buffer buffer)
+    (select-window iniwin)))
 
 (defun cperl-info-on-current-command ()
   "Shows documentation for Perl command at point in other window."
@@ -3373,7 +3492,7 @@ Available styles are GNU, K&R, BSD and Whitesmith."
         imenu-extract-index-name-function 
         (index-item (save-restriction
                       (save-window-excursion
-                        (set-buffer (cperl-info-buffer))
+                        (set-buffer (cperl-info-buffer nil))
                         (setq imenu-create-index-function 
                               'imenu-default-create-index-function
                               imenu-prev-index-position-function
@@ -3660,7 +3779,7 @@ in subdirectories too."
        )
        (t
        (setq xs (string-match "\\.xs$" file))
-       (cond ((eq erase 'ignore) nil)
+       (cond ((eq erase 'ignore) (goto-char (point-max)))
              (erase (erase-buffer))
              (t
               (goto-char 1)
@@ -3671,12 +3790,13 @@ in subdirectories too."
                                    (progn 
                                      (forward-char 1)
                                      (search-forward "\f\n" nil 'toend)
-                                     (point)))
-                    (goto-char 1)))))
+                                     (point))))
+                (goto-char (point-max)))))
        (insert (cperl-find-tags file xs))))
       (if inbuffer nil         ; Delegate to the caller
        (save-buffer 0)         ; No backup
-       (initialize-new-tags-table)))))
+       (if (fboundp 'initialize-new-tags-table) ; Do we need something special in XEmacs?
+           (initialize-new-tags-table))))))
 
 (defvar cperl-tags-hier-regexp-list
   "^\\(\\(package\\)\\>\\|sub\\>[^\n]+::\\|[a-zA-Z_][a-zA-Z_0-9:]*(\C-?[^\n]+::\\|[ \t]*BOOT:\C-?[^\n]+::\\)")
@@ -3971,11 +4091,12 @@ Currently it is tuned to C and Perl syntax."
   ;;(concat "\\("
   (mapconcat
    'identity
-   '("[$@%*&][0-9a-zA-Z_:]+"           ; Usual variable
+   '("[$@%*&][0-9a-zA-Z_:]+\\([ \t]*[[{]\\)?"          ; Usual variable
      "[$@]\\^[a-zA-Z]"                 ; Special variable
      "[$@][^ \n\t]"                    ; Special variable
      "-[a-zA-Z]"                       ; File test
      "\\\\[a-zA-Z0]"                   ; Special chars
+     "^=[a-z][a-zA-Z0-9_]*"            ; Pod sections
      "[-!&*+,-./<=>?\\\\^|~]+"         ; Operator
      "[a-zA-Z_0-9:]+"                  ; symbol or number
      "x="
@@ -3989,6 +4110,58 @@ Currently it is tuned to C and Perl syntax."
   "Matches places in the buffer we can find help for.")
 
 (defvar cperl-message-on-help-error t)
+(defvar cperl-help-from-timer nil)
+
+(defun cperl-word-at-point-hard ()
+  ;; Does not save-excursion
+  ;; Get to the something meaningful
+  (or (eobp) (eolp) (forward-char 1))
+  (re-search-backward "[-a-zA-Z0-9_:!&*+,-./<=>?\\\\^|~$%@]" 
+                     (save-excursion (beginning-of-line) (point))
+                     'to-beg)
+  ;;  (cond
+  ;;   ((or (eobp) (looking-at "[][ \t\n{}();,]")) ; Not at a symbol
+  ;;    (skip-chars-backward " \n\t\r({[]});,")
+  ;;    (or (bobp) (backward-char 1))))
+  ;; Try to backtrace
+  (cond
+   ((looking-at "[a-zA-Z0-9_:]")       ; symbol
+    (skip-chars-backward "[a-zA-Z0-9_:]")
+    (cond 
+     ((and (eq (preceding-char) ?^)    ; $^I
+          (eq (char-after (- (point) 2)) ?\$))
+      (forward-char -2))
+     ((memq (preceding-char) (append "*$@%&\\" nil)) ; *glob
+      (forward-char -1))
+     ((and (eq (preceding-char) ?\=)
+          (eq (current-column) 1))
+      (forward-char -1)))              ; =head1
+    (if (and (eq (preceding-char) ?\<)
+            (looking-at "\\$?[a-zA-Z0-9_:]+>")) ; <FH>
+       (forward-char -1)))
+   ((and (looking-at "=") (eq (preceding-char) ?x)) ; x=
+    (forward-char -1))
+   ((and (looking-at "\\^") (eq (preceding-char) ?\$)) ; $^I
+    (forward-char -1))
+   ((looking-at "[-!&*+,-./<=>?\\\\^|~]")
+    (skip-chars-backward "[-!&*+,-./<=>?\\\\^|~]")
+    (cond
+     ((and (eq (preceding-char) ?\$)
+          (not (eq (char-after (- (point) 2)) ?\$))) ; $-
+      (forward-char -1))
+     ((and (eq (following-char) ?\>)
+          (string-match "[a-zA-Z0-9_]" (char-to-string (preceding-char)))
+          (save-excursion
+            (forward-sexp -1)
+            (and (eq (preceding-char) ?\<)
+                 (looking-at "\\$?[a-zA-Z0-9_:]+>")))) ; <FH>
+      (search-backward "<"))))
+   ((and (eq (following-char) ?\$)
+        (eq (preceding-char) ?\<)
+        (looking-at "\\$?[a-zA-Z0-9_:]+>")) ; <$fh>
+    (forward-char -1)))
+  (if (looking-at cperl-have-help-regexp)
+      (buffer-substring (match-beginning 0) (match-end 0))))
 
 (defun cperl-get-help ()
   "Get one-line docs on the symbol at the point.
@@ -3996,56 +4169,19 @@ The data for these docs is a little bit obsolete and may be in fact longer
 than a line. Your contribution to update/shorten it is appreciated."
   (interactive)
   (save-excursion
-    ;; Get to the something meaningful
-    (or (eobp) (eolp) (forward-char 1))
-    (re-search-backward "[-a-zA-Z0-9_:!&*+,-./<=>?\\\\^|~$%@]" 
-                       (save-excursion (beginning-of-line) (point))
-                       'to-beg)
-    ;;  (cond
-    ;;   ((or (eobp) (looking-at "[][ \t\n{}();,]")) ; Not at a symbol
-    ;;    (skip-chars-backward " \n\t\r({[]});,")
-    ;;    (or (bobp) (backward-char 1))))
-    ;; Try to backtrace
-    (cond
-     ((looking-at "[a-zA-Z0-9_:]")     ; symbol
-      (skip-chars-backward "[a-zA-Z0-9_:]")
-      (cond 
-       ((and (eq (preceding-char) ?^)  ; $^I
-            (eq (char-after (- (point) 2)) ?\$))
-       (forward-char -2))
-       ((memq (preceding-char) (append "*$@%&\\" nil)) ; *glob
-       (forward-char -1)))
-      (if (and (eq (preceding-char) ?\<)
-              (looking-at "\\$?[a-zA-Z0-9_:]+>")) ; <FH>
-         (forward-char -1)))
-     ((and (looking-at "=") (eq (preceding-char) ?x)) ; x=
-      (forward-char -1))
-     ((and (looking-at "\\^") (eq (preceding-char) ?\$)) ; $^I
-      (forward-char -1))
-     ((looking-at "[-!&*+,-./<=>?\\\\^|~]")
-      (skip-chars-backward "[-!&*+,-./<=>?\\\\^|~]")
-      (cond
-       ((and (eq (preceding-char) ?\$)
-              (not (eq (char-after (- (point) 2)) ?\$))) ; $-
-         (forward-char -1))
-       ((and (eq (following-char) ?\>)
-            (string-match "[a-zA-Z0-9_]" (char-to-string (preceding-char)))
-            (save-excursion
-              (forward-sexp -1)
-              (and (eq (preceding-char) ?\<)
-                   (looking-at "\\$?[a-zA-Z0-9_:]+>")))) ; <FH>
-       (search-backward "<"))))
-     ((and (eq (following-char) ?\$)
-          (eq (preceding-char) ?\<)
-          (looking-at "\\$?[a-zA-Z0-9_:]+>")) ; <$fh>
-      (forward-char -1)))
-    ;;(or (eobp) (forward-char 1))
-    (if (looking-at cperl-have-help-regexp)
-       (cperl-describe-perl-symbol 
-        (buffer-substring (match-beginning 0) (match-end 0)))
-      (if cperl-message-on-help-error
-         (message "Nothing found for %s..." 
-                  (buffer-substring (point) (+ 5 (point))))))))
+    (let ((word (cperl-word-at-point-hard)))
+      (if word
+         (if (and cperl-help-from-timer ; Bail out if not in mainland
+                  (not (string-match "^#!\\|\\\\\\|^=" word)) ; Show help even in comments/strings.
+                  (or (memq (get-text-property (point) 'face)
+                            '(font-lock-comment-face font-lock-string-face))
+                      (memq (get-text-property (point) 'syntax-type)
+                            '(pod here-doc format))))
+             nil
+           (cperl-describe-perl-symbol word))
+       (if cperl-message-on-help-error
+           (message "Nothing found for %s..." 
+                    (buffer-substring (point) (+ 5 (point)))))))))
 
 ;;; Stolen from perl-descr.el by Johan Vromans:
 
@@ -4054,46 +4190,27 @@ than a line. Your contribution to update/shorten it is appreciated."
 
 (defun cperl-describe-perl-symbol (val)
   "Display the documentation of symbol at point, a Perl operator."
-  ;; We suppose that the current position is at the start of the symbol
-  ;; when we convert $_[5] to @_
-  (let (;;(fn (perl-symbol-at-point))
-       (enable-recursive-minibuffers t)
-       ;;val 
+  (let ((enable-recursive-minibuffers t)
        args-file regexp)
-    ;;  (interactive
-    ;;    (let ((fn (perl-symbol-at-point))
-    ;;   (enable-recursive-minibuffers t)
-    ;;   val args-file regexp)
-    ;;      (setq val (read-from-minibuffer
-    ;;           (if fn
-    ;;               (format "Symbol (default %s): " fn)
-    ;;             "Symbol: ")))
-    ;;      (if (string= val "")
-    ;;   (setq val fn))
     (cond
        ((string-match "^[&*][a-zA-Z_]" val)
         (setq val (concat (substring val 0 1) "NAME")))
-       ((looking-at "[$@][a-zA-Z_:0-9]+\\([[{]\\)")
-        (if (= ?\[ (char-after (match-beginning 1)))
-             (setq val (concat "@" (substring val 1)))
-           (setq val (concat "%" (substring val 1)))))
-       ((and (string= val "x") (looking-at "x="))
+       ((string-match "^[$@]\\([a-zA-Z_:0-9]+\\)[ \t]*\\[" val)
+        (setq val (concat "@" (substring val 1 (match-end 1)))))
+       ((string-match "^[$@]\\([a-zA-Z_:0-9]+\\)[ \t]*{" val)
+        (setq val (concat "%" (substring val 1 (match-end 1)))))
+       ((and (string= val "x") (string-match "^x=" val))
         (setq val "x="))
        ((string-match "^\\$[\C-a-\C-z]" val)
         (setq val (concat "$^" (char-to-string (+ ?A -1 (aref val 1))))))
-       ((and (string= "<" val) (looking-at "<\\$?[a-zA-Z0-9_:]+>"))
+        ((string-match "^CORE::" val)
+        (setq val "CORE::"))
+        ((string-match "^SUPER::" val)
+        (setq val "SUPER::"))
+       ((and (string= "<" val) (string-match "^<\\$?[a-zA-Z0-9_:]+>" val))
         (setq val "<NAME>")))
-;;;    (if (string-match "^[&*][a-zA-Z_]" val)
-;;;    (setq val (concat (substring val 0 1) "NAME"))
-;;;      (if (looking-at "[$@][a-zA-Z_:0-9]+\\([[{]\\)")
-;;;      (if (= ?\[ (char-after (match-beginning 1)))
-;;;          (setq val (concat "@" (substring val 1)))
-;;;        (setq val (concat "%" (substring val 1))))
-;;;    (if (and (string= val "x") (looking-at "x="))
-;;;        (setq val "x=")
-;;;      (if (looking-at "[$@][a-zA-Z_:0-9]")
-;;;          ))))
-    (setq regexp (concat "^" "\\([^a-zA-Z0-9_:]+[ \t]\\)?"
+    (setq regexp (concat "^" 
+                        "\\([^a-zA-Z0-9_:]+[ \t]+\\)?"
                         (regexp-quote val) 
                         "\\([ \t([/]\\|$\\)"))
 
@@ -4114,14 +4231,15 @@ than a line. Your contribution to update/shorten it is appreciated."
             (message "No definition for %s" val)))))))
 
 (defvar cperl-short-docs "Ignore my value"
+  ;; Perl4 version was written by Johan Vromans (jvromans@squirrel.nl)
   "# based on '@(#)@ perl-descr.el 1.9 - describe-perl-symbol' [Perl 5]
-!      Logical negation.       
-!=     Numeric inequality.
-!~     Search pattern, substitution, or translation (negated).
+! ...  Logical negation.       
+... != ...     Numeric inequality.
+... !~ ...     Search pattern, substitution, or translation (negated).
 $!     In numeric context: errno. In a string context: error string.
 $\"    The separator which joins elements of arrays interpolated in strings.
 $#     The output format for printed numbers. Initial value is %.20g.
-$$     The process number of the perl running this script. Altered (in the child process) by fork().
+$$     Process number of this script. Changes in the fork()ed child process.
 $%     The current page number of the currently selected output channel.
 
        The following variables are always local to the current block:
@@ -4147,9 +4265,9 @@ $,        The output field separator for the print operator.
 $-     The number of lines left on the page.
 $.     The current input line number of the last filehandle that was read.
 $/     The input record separator, newline by default.
-$0     The name of the file containing the perl script being executed. May be set
-$:     The set of characters after which a string may be broken to fill continuation fields (starting with ^) in a format.
-$;     The subscript separator for multi-dimensional array emulation. Default is \"\\034\".
+$0     Name of the file containing the perl script being executed. May be set.
+$:     String may be broken after these characters to fill ^-lines in a format.
+$;     Subscript separator for multi-dim array emulation. Default \"\\034\".
 $<     The real uid of this process.
 $=     The page length of the current output channel. Default is 60 lines.
 $>     The effective uid of this process.
@@ -4173,28 +4291,28 @@ $^T     The time the script was started. Used by -A/-M/-C file tests.
 $^W    True if warnings are requested (perl -w flag).
 $^X    The name under which perl was invoked (argv[0] in C-speech).
 $_     The default input and pattern-searching space.
-$|     Flag for auto-flush after write/print on the currently selected output channel. Default is 0. 
+$|     Auto-flush after write/print on the current output channel? Default 0. 
 $~     The name of the current report format.
-%      Modulo division.
-%=     Modulo division assignment.
+... % ...      Modulo division.
+... %= ...     Modulo division assignment.
 %ENV   Contains the current environment.
 %INC   List of files that have been require-d or do-ne.
 %SIG   Used to set signal handlers for various signals.
-&      Bitwise and.
-&&     Logical and.
-&&=    Logical and assignment.
-&=     Bitwise and assignment.
-*      Multiplication.
-**     Exponentiation.
-*NAME  Refers to all objects represented by NAME. *NAM1 = *NAM2 makes NAM1 a reference to NAM2.
+... & ...      Bitwise and.
+... && ...     Logical and.
+... &&= ...    Logical and assignment.
+... &= ...     Bitwise and assignment.
+... * ...      Multiplication.
+... ** ...     Exponentiation.
+*NAME  Glob: all objects refered by NAME. *NAM1 = *NAM2 aliases NAM1 to NAM2.
 &NAME(arg0, ...)       Subroutine call. Arguments go to @_.
-+      Addition.
-++     Auto-increment (magical on strings).
-+=     Addition assignment.
+... + ...      Addition.               +EXPR   Makes EXPR into scalar context.
+++     Auto-increment (magical on strings).    ++EXPR  EXPR++
+... += ...     Addition assignment.
 ,      Comma operator.
--      Subtraction.
---     Auto-decrement.
--=     Subtraction assignment.
+... - ...      Subtraction.
+--     Auto-decrement (NOT magical on strings).        --EXPR  EXPR--
+... -= ...     Subtraction assignment.
 -A     Access time in days since script started.
 -B     File is a non-text (binary) file.
 -C     Inode change time in days since script started.
@@ -4225,54 +4343,54 @@ $~      The name of the current report format.
 .      Concatenate strings.
 ..     Alternation, also range operator.
 .=     Concatenate assignment strings
-/      Division.       /PATTERN/ioxsmg Pattern match
-/=     Division assignment.
+... / ...      Division.       /PATTERN/ioxsmg Pattern match
+... /= ...     Division assignment.
 /PATTERN/ioxsmg        Pattern match.
-<      Numeric less than.      <pattern>       Glob.   See <NAME>, <> as well.
+... < ...      Numeric less than.      <pattern>       Glob.   See <NAME>, <> as well.
 <NAME> Reads line from filehandle NAME. NAME must be bareword/dollar-bareword.
 <pattern>      Glob. (Unless pattern is bareword/dollar-bareword - see <NAME>)
 <>     Reads line from union of files in @ARGV (= command line) and STDIN.
-<<     Bitwise shift left.     <<      start of HERE-DOCUMENT.
-<=     Numeric less than or equal to.
-<=>    Numeric compare.
-=      Assignment.
-==     Numeric equality.
-=~     Search pattern, substitution, or translation
->      Numeric greater than.
->=     Numeric greater than or equal to.
->>     Bitwise shift right.
->>=    Bitwise shift right assignment.
-? :    Alternation (if-then-else) operator.    ?PAT? Backwards pattern match.
-?PATTERN?      Backwards pattern match.
+... << ...     Bitwise shift left.     <<      start of HERE-DOCUMENT.
+... <= ...     Numeric less than or equal to.
+... <=> ...    Numeric compare.
+... = ...      Assignment.
+... == ...     Numeric equality.
+... =~ ...     Search pattern, substitution, or translation
+... > ...      Numeric greater than.
+... >= ...     Numeric greater than or equal to.
+... >> ...     Bitwise shift right.
+... >>= ...    Bitwise shift right assignment.
+... ? ... : ...        Condition=if-then-else operator.   ?PAT? One-time pattern match.
+?PATTERN?      One-time pattern match.
 @ARGV  Command line arguments (not including the command name - see $0).
 @INC   List of places to look for perl scripts during do/include/use.
 @_     Parameter array for subroutines. Also used by split unless in array context.
 \\     Creates a reference to whatever follows, like \$var.
 \\0    Octal char, e.g. \\033.
 \\E    Case modification terminator. See \\Q, \\L, and \\U.
-\\L    Lowercase until \\E .
-\\U    Upcase until \\E .
-\\Q    Quote metacharacters until \\E .
+\\L    Lowercase until \\E . See also \l, lc.
+\\U    Upcase until \\E . See also \u, uc.
+\\Q    Quote metacharacters until \\E . See also quotemeta.
 \\a    Alarm character (octal 007).
 \\b    Backspace character (octal 010).
 \\c    Control character, e.g. \\c[ .
 \\e    Escape character (octal 033).
 \\f    Formfeed character (octal 014).
-\\l    Lowercase of next character. See also \\L and \\u,
+\\l    Lowercase the next character. See also \\L and \\u, lcfirst,
 \\n    Newline character (octal 012).
 \\r    Return character (octal 015).
 \\t    Tab character (octal 011).
-\\u    Upcase  of next character. See also \\U and \\l,
+\\u    Upcase the next character. See also \\U and \\l, ucfirst,
 \\x    Hex character, e.g. \\x1b.
-^      Bitwise exclusive or.
-__END__        End of program source.
-__DATA__       End of program source.
+^ ...  Bitwise exclusive or.
+__END__        Ends program source.
+__DATA__       Ends program source.
 __FILE__       Current (source) filename.
 __LINE__       Current line in current source.
 ARGV   Default multi-file input filehandle. <ARGV> is a synonym for <>.
 ARGVOUT        Output filehandle with -i flag.
-BEGIN { block }        Immediately executed (during compilation) piece of code.
-END { block }  Pseudo-subroutine executed after the script finishes.
+BEGIN { ... }  Immediately executed (during compilation) piece of code.
+END { ... }    Pseudo-subroutine executed after the script finishes.
 DATA   Input filehandle for what follows after __END__ or __DATA__.
 accept(NEWSOCKET,GENERICSOCKET)
 alarm(SECONDS)
@@ -4287,20 +4405,20 @@ chown(LIST)
 chroot(FILENAME)
 close(FILEHANDLE)
 closedir(DIRHANDLE)
-cmp    String compare.
+... cmp ...    String compare.
 connect(SOCKET,NAME)
 continue of { block } continue { block }. Is executed after `next' or at end.
 cos(EXPR)
 crypt(PLAINTEXT,SALT)
-dbmclose(ASSOC_ARRAY)
-dbmopen(ASSOC,DBNAME,MODE)
+dbmclose(%HASH)
+dbmopen(%HASH,DBNAME,MODE)
 defined(EXPR)
-delete($ASSOC{KEY})
+delete($HASH{KEY})
 die(LIST)
 do { ... }|SUBR while|until EXPR       executes at least once
 do(EXPR|SUBR([LIST]))
 dump LABEL
-each(ASSOC_ARRAY)
+each(%HASH)
 endgrent
 endhostent
 endnetent
@@ -4308,7 +4426,7 @@ endprotoent
 endpwent
 endservent
 eof[([FILEHANDLE])]
-eq     String equality.
+... eq ...     String equality.
 eval(EXPR) or eval { BLOCK }
 exec(LIST)
 exit(EXPR)
@@ -4319,7 +4437,7 @@ flock(FILEHANDLE,OPERATION)
 for (EXPR;EXPR;EXPR) { ... }
 foreach [VAR] (@ARRAY) { ... }
 fork
-ge     String greater than or equal.
+... ge ...     String greater than or equal.
 getc[(FILEHANDLE)]
 getgrent
 getgrgid(GID)
@@ -4349,17 +4467,17 @@ getsockopt(SOCKET,LEVEL,OPTNAME)
 gmtime(EXPR)
 goto LABEL
 grep(EXPR,LIST)
-gt     String greater than.
+... gt ...     String greater than.
 hex(EXPR)
 if (EXPR) { ... } [ elsif (EXPR) { ... } ... ] [ else { ... } ] or EXPR if EXPR
 index(STR,SUBSTR[,OFFSET])
 int(EXPR)
 ioctl(FILEHANDLE,FUNCTION,SCALAR)
 join(EXPR,LIST)
-keys(ASSOC_ARRAY)
+keys(%HASH)
 kill(LIST)
 last [LABEL]
-le     String less than or equal.
+... le ...     String less than or equal.
 length(EXPR)
 link(OLDFILE,NEWFILE)
 listen(SOCKET,QUEUESIZE)
@@ -4367,7 +4485,7 @@ local(LIST)
 localtime(EXPR)
 log(EXPR)
 lstat(EXPR|FILEHANDLE|VAR)
-lt     String less than.
+... lt ...     String less than.
 m/PATTERN/iogsmx
 mkdir(FILENAME,MODE)
 msgctl(ID,CMD,ARG)
@@ -4375,14 +4493,14 @@ msgget(KEY,FLAGS)
 msgrcv(ID,VAR,SIZE,TYPE.FLAGS)
 msgsnd(ID,MSG,FLAGS)
 my VAR or my (VAR1,...)        Introduces a lexical variable ($VAR, @ARR, or %HASH).
-ne     String inequality.
+... ne ...     String inequality.
 next [LABEL]
 oct(EXPR)
 open(FILEHANDLE[,EXPR])
 opendir(DIRHANDLE,EXPR)
 ord(EXPR)
 pack(TEMPLATE,LIST)
-package        Introduces package context.
+package NAME   Introduces package context.
 pipe(READHANDLE,WRITEHANDLE)
 pop(ARRAY)
 print [FILEHANDLE] [(LIST)]
@@ -4441,7 +4559,7 @@ sqrt(EXPR)
 srand(EXPR)
 stat(EXPR|FILEHANDLE|VAR)
 study[(SCALAR)]
-sub [NAME [(format)]] { BODY } or      sub [NAME [(format)]];
+sub [NAME [(format)]] { BODY } sub NAME [(format)];    sub [(format)] {...}
 substr(EXPR,OFFSET[,LEN])
 symlink(OLDFILE,NEWFILE)
 syscall(LIST)
@@ -4460,23 +4578,73 @@ unless (EXPR) { ... } [ else { ... } ] or EXPR unless EXPR
 unlink(LIST)
 unpack(TEMPLATE,EXPR)
 unshift(ARRAY,LIST)
-until (EXPR) { ... } or EXPR until EXPR
+until (EXPR) { ... }                                   EXPR until EXPR
 utime(LIST)
-values(ASSOC_ARRAY)
+values(%HASH)
 vec(EXPR,OFFSET,BITS)
 wait
 waitpid(PID,FLAGS)
 wantarray
 warn(LIST)
-while  (EXPR) { ... } or EXPR while EXPR
+while  (EXPR) { ... }                                  EXPR while EXPR
 write[(EXPR|FILEHANDLE)]
-x      Repeat string or array.
-x=     Repetition assignment.
+... x ...      Repeat string or array.
+x= ... Repetition assignment.
 y/SEARCHLIST/REPLACEMENTLIST/
-|      Bitwise or.
-||     Logical or.
-~      Unary bitwise complement.
+... | ...      Bitwise or.
+... || ...     Logical or.
+~ ...          Unary bitwise complement.
 #!     OS interpreter indicator. If contains `perl', used for options, and -x.
+AUTOLOAD {...} Shorthand for `sub AUTOLOAD {...}'.
+CORE::         Prefix to access builtin function if imported sub obscures it.
+SUPER::                Prefix to lookup for a method in @ISA classes.
+DESTROY                Shorthand for `sub DESTROY {...}'.
+... EQ ...     Obsolete synonym of `eq'.
+... GE ...     Obsolete synonym of `ge'.
+... GT ...     Obsolete synonym of `gt'.
+... LE ...     Obsolete synonym of `le'.
+... LT ...     Obsolete synonym of `lt'.
+... NE ...     Obsolete synonym of `ne'.
+abs [ EXPR ]   absolute value
+... and ...            Low-precedence synonym for &&.
+bless REFERENCE [, PACKAGE]    Makes reference into an object of a package.
+chomp          Docs missing
+chr            Docs missing
+else           Part of if/unless {BLOCK} elsif {BLOCK} else {BLOCK}.
+elsif          Part of if/unless {BLOCK} elsif {BLOCK} else {BLOCK}.
+exists $HASH{KEY}      True if the key exists.
+format         Docs missing
+formline       Docs missing
+glob EXPR      Synonym of <EXPR>.
+lc [ EXPR ]    Returns lowercased EXPR.
+lcfirst [ EXPR ]       Returns EXPR with lower-cased first letter.
+map            Docs missing
+no PACKAGE [SYMBOL1, ...]  Partial reverse for `use'. Runs `unimport' method.
+... not ...            Low-precedence synonym for ! - negation.
+... or ...             Low-precedence synonym for ||.
+pos STRING    Set/Get end-position of the last match over this string, see \\G.
+quotemeta [ EXPR ]     Quote metacharacters.
+qw             Docs missing
+readline FH    Synonym of <FH>.
+readpipe CMD   Synonym of `CMD`.
+ref [ EXPR ]   Type of EXPR when dereferenced.
+sysopen                Docs missing
+tie            Docs missing
+tied           Docs missing
+uc [ EXPR ]    Returns upcased EXPR.
+ucfirst [ EXPR ]       Returns EXPR with upcased first letter.
+untie          Docs missing
+use PACKAGE [SYMBOL1, ...]  Compile-time `require' with consequent `import'.
+... xor ...            Low-precedence synonym for exclusive or.
+prototype \&SUB        Returns prototype of the function given a reference.
+=head1         Top-level heading.
+=head2         Second-level heading.
+=head3         Third-level heading (is there such?).
+=over [ NUMBER ]       Start list.
+=item [ TITLE ]                Start new item in the list.
+=back          End list.
+=cut           Switch from POD to Perl.
+=pod           Switch from Perl to POD.
 ")
 
 (defun cperl-switch-to-doc-buffer ()
@@ -4522,7 +4690,7 @@ y/SEARCHLIST/REPLACEMENTLIST/
 
       (defun cperl-get-help-defer ()
        (if (not (eq major-mode 'perl-mode)) nil
-         (let ((cperl-message-on-help-error nil))
+         (let ((cperl-message-on-help-error nil) (cperl-help-from-timer t))
            (cperl-get-help)
            (setq cperl-help-shown t))))
       (cperl-lazy-install)))
diff --git a/embed.h b/embed.h
index da0c709..82cb97f 100644 (file)
--- a/embed.h
+++ b/embed.h
@@ -1,6 +1,6 @@
 /* !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!! 
-   This file is built by embed.pl from global.sym and interp.sym.
-   Any changes made here will be lost 
+   This file is built by embed.pl from global.sym, interp.sym,
+   and compat3.sym.  Any changes made here will be lost!
 */
 
 /* (Doing namespace management portably in C is really gross.) */
 #  define EMBED 1 
 #endif
 
+/* Hide global symbols? */
+
 #ifdef EMBED
 
-/* globals we need to hide from the world */
-#define AMG_names      Perl_AMG_names
-#define Error          Perl_Error
-#define He             Perl_He
-#define No             Perl_No
-#define Sv             Perl_Sv
-#define Xpv            Perl_Xpv
-#define Yes            Perl_Yes
-#define abs_amg                Perl_abs_amg
-#define add_amg                Perl_add_amg
-#define add_ass_amg    Perl_add_ass_amg
-#define additem                Perl_additem
+#define AMG_names              Perl_AMG_names
+#define Gv_AMupdate            Perl_Gv_AMupdate
+#define No                     Perl_No
+#define Sv                     Perl_Sv
+#define Xpv                    Perl_Xpv
+#define Yes                    Perl_Yes
+#define abs_amg                        Perl_abs_amg
+#define add_amg                        Perl_add_amg
+#define add_ass_amg            Perl_add_ass_amg
+#define additem                        Perl_additem
+#define amagic_call            Perl_amagic_call
 #define amagic_generation      Perl_amagic_generation
-#define an             Perl_an
-#define atan2_amg      Perl_atan2_amg
-#define band_amg       Perl_band_amg
-#define block_type     Perl_block_type
-#define bool__amg      Perl_bool__amg
-#define bor_amg                Perl_bor_amg
-#define buf            Perl_buf
-#define bufend         Perl_bufend
-#define bufptr         Perl_bufptr
-#define bxor_amg       Perl_bxor_amg
-#define check          Perl_check
-#define collation_ix   Perl_collation_ix
-#define collation_name Perl_collation_name
+#define an                     Perl_an
+#define append_elem            Perl_append_elem
+#define append_list            Perl_append_list
+#define apply                  Perl_apply
+#define assertref              Perl_assertref
+#define atan2_amg              Perl_atan2_amg
+#define av_clear               Perl_av_clear
+#define av_extend              Perl_av_extend
+#define av_fake                        Perl_av_fake
+#define av_fetch               Perl_av_fetch
+#define av_fill                        Perl_av_fill
+#define av_len                 Perl_av_len
+#define av_make                        Perl_av_make
+#define av_pop                 Perl_av_pop
+#define av_push                        Perl_av_push
+#define av_shift               Perl_av_shift
+#define av_store               Perl_av_store
+#define av_undef               Perl_av_undef
+#define av_unshift             Perl_av_unshift
+#define band_amg               Perl_band_amg
+#define bind_match             Perl_bind_match
+#define block_end              Perl_block_end
+#define block_start            Perl_block_start
+#define bool__amg              Perl_bool__amg
+#define bor_amg                        Perl_bor_amg
+#define buf                    Perl_buf
+#define bufend                 Perl_bufend
+#define bufptr                 Perl_bufptr
+#define bxor_amg               Perl_bxor_amg
+#define calllist               Perl_calllist
+#define cando                  Perl_cando
+#define cast_ulong             Perl_cast_ulong
+#define check                  Perl_check
+#define check_uni              Perl_check_uni
+#define checkcomma             Perl_checkcomma
+#define ck_aelem               Perl_ck_aelem
+#define ck_bitop               Perl_ck_bitop
+#define ck_concat              Perl_ck_concat
+#define ck_delete              Perl_ck_delete
+#define ck_eof                 Perl_ck_eof
+#define ck_eval                        Perl_ck_eval
+#define ck_exec                        Perl_ck_exec
+#define ck_ftst                        Perl_ck_ftst
+#define ck_fun                 Perl_ck_fun
+#define ck_fun_locale          Perl_ck_fun_locale
+#define ck_glob                        Perl_ck_glob
+#define ck_grep                        Perl_ck_grep
+#define ck_gvconst             Perl_ck_gvconst
+#define ck_index               Perl_ck_index
+#define ck_lengthconst         Perl_ck_lengthconst
+#define ck_lfun                        Perl_ck_lfun
+#define ck_listiob             Perl_ck_listiob
+#define ck_match               Perl_ck_match
+#define ck_null                        Perl_ck_null
+#define ck_repeat              Perl_ck_repeat
+#define ck_require             Perl_ck_require
+#define ck_retarget            Perl_ck_retarget
+#define ck_rfun                        Perl_ck_rfun
+#define ck_rvconst             Perl_ck_rvconst
+#define ck_scmp                        Perl_ck_scmp
+#define ck_select              Perl_ck_select
+#define ck_shift               Perl_ck_shift
+#define ck_sort                        Perl_ck_sort
+#define ck_spair               Perl_ck_spair
+#define ck_split               Perl_ck_split
+#define ck_subr                        Perl_ck_subr
+#define ck_svconst             Perl_ck_svconst
+#define ck_trunc               Perl_ck_trunc
+#define collation_ix           Perl_collation_ix
+#define collation_name         Perl_collation_name
 #define collation_standard     Perl_collation_standard
-#define collxfrm_base  Perl_collxfrm_base
-#define collxfrm_mult  Perl_collxfrm_mult
-#define compcv         Perl_compcv
-#define compiling      Perl_compiling
-#define compl_amg      Perl_compl_amg
-#define comppad                Perl_comppad
-#define comppad_name   Perl_comppad_name
+#define collxfrm_base          Perl_collxfrm_base
+#define collxfrm_mult          Perl_collxfrm_mult
+#define compcv                 Perl_compcv
+#define compiling              Perl_compiling
+#define compl_amg              Perl_compl_amg
+#define comppad                        Perl_comppad
+#define comppad_name           Perl_comppad_name
 #define comppad_name_fill      Perl_comppad_name_fill
-#define comppad_name_floor     Perl_comppad_name_floor
-#define concat_amg     Perl_concat_amg
-#define concat_ass_amg Perl_concat_ass_amg
-#define cop_seqmax     Perl_cop_seqmax
-#define cos_amg                Perl_cos_amg
-#define cryptseen      Perl_cryptseen
-#define cshlen         Perl_cshlen
-#define cshname                Perl_cshname
-#define curinterp      Perl_curinterp
-#define curpad         Perl_curpad
-#define cv_const_sv    Perl_cv_const_sv
-#define dc             Perl_dc
-#define debug          Perl_debug
-#define dec_amg                Perl_dec_amg
-#define di             Perl_di
-#define div_amg                Perl_div_amg
-#define div_ass_amg    Perl_div_ass_amg
-#define do_undump      Perl_do_undump
-#define ds             Perl_ds
-#define egid           Perl_egid
-#define eq_amg         Perl_eq_amg
-#define error_count    Perl_error_count
-#define euid           Perl_euid
-#define evalseq                Perl_evalseq
-#define exp_amg                Perl_exp_amg
-#define expect         Perl_expect
-#define expectterm     Perl_expectterm
-#define fallback_amg   Perl_fallback_amg
-#define filter_add     Perl_filter_add
-#define filter_del     Perl_filter_del
-#define filter_read    Perl_filter_read
-#define fold           Perl_fold
-#define fold_locale    Perl_fold_locale
-#define freq           Perl_freq
-#define ge_amg         Perl_ge_amg
-#define gid            Perl_gid
-#define gt_amg         Perl_gt_amg
-#define hexdigit       Perl_hexdigit
-#define hints          Perl_hints
-#define in_my          Perl_in_my
-#define inc_amg                Perl_inc_amg
-#define io_close       Perl_io_close
-#define know_next      Perl_know_next
-#define last_lop       Perl_last_lop
-#define last_lop_op    Perl_last_lop_op
-#define last_uni       Perl_last_uni
-#define le_amg         Perl_le_amg
-#define lex_brackets   Perl_lex_brackets
-#define lex_brackstack Perl_lex_brackstack
-#define lex_casemods   Perl_lex_casemods
-#define lex_casestack  Perl_lex_casestack
-#define lex_defer      Perl_lex_defer
-#define lex_dojoin     Perl_lex_dojoin
-#define lex_expect     Perl_lex_expect
-#define lex_fakebrack  Perl_lex_fakebrack
-#define lex_formbrack  Perl_lex_formbrack
-#define lex_inpat      Perl_lex_inpat
-#define lex_inwhat     Perl_lex_inwhat
-#define lex_op         Perl_lex_op
-#define lex_repl       Perl_lex_repl
-#define lex_starts     Perl_lex_starts
-#define lex_state      Perl_lex_state
-#define lex_stuff      Perl_lex_stuff
-#define linestr                Perl_linestr
-#define log_amg                Perl_log_amg
-#define lshift_amg     Perl_lshift_amg
-#define lshift_ass_amg Perl_lshift_ass_amg
-#define lt_amg         Perl_lt_amg
-#define markstack      Perl_markstack
-#define markstack_max  Perl_markstack_max
-#define markstack_ptr  Perl_markstack_ptr
-#define max_intro_pending      Perl_max_intro_pending
-#define maxo           Perl_maxo
-#define min_intro_pending      Perl_min_intro_pending
-#define mod_amg                Perl_mod_amg
-#define mod_ass_amg    Perl_mod_ass_amg
-#define mult_amg       Perl_mult_amg
-#define mult_ass_amg   Perl_mult_ass_amg
-#define multi_close    Perl_multi_close
-#define multi_end      Perl_multi_end
-#define multi_open     Perl_multi_open
-#define multi_start    Perl_multi_start
-#define na             Perl_na
-#define ncmp_amg       Perl_ncmp_amg
-#define ne_amg         Perl_ne_amg
-#define neg_amg                Perl_neg_amg
-#define nexttoke       Perl_nexttoke
-#define nexttype       Perl_nexttype
-#define nexttype       Perl_nexttype
-#define nextval                Perl_nextval
-#define nextval                Perl_nextval
-#define nice_chunk     Perl_nice_chunk
-#define nice_chunk_size        Perl_nice_chunk_size
-#define no_aelem       Perl_no_aelem
-#define no_dir_func    Perl_no_dir_func
-#define no_func                Perl_no_func
-#define no_helem       Perl_no_helem
-#define no_mem         Perl_no_mem
-#define no_modify      Perl_no_modify
-#define no_myglob      Perl_no_myglob
-#define no_security    Perl_no_security
-#define no_sock_func   Perl_no_sock_func
-#define no_symref      Perl_no_symref
-#define no_usym                Perl_no_usym
-#define no_wrongref    Perl_no_wrongref
-#define nointrp                Perl_nointrp
-#define nomem          Perl_nomem
-#define nomemok                Perl_nomemok
-#define nomethod_amg   Perl_nomethod_amg
-#define not_amg                Perl_not_amg
-#define numeric_local  Perl_numeric_local
-#define numeric_name   Perl_numeric_name
-#define numeric_standard       Perl_numeric_standard
-#define numer_amg      Perl_numer_amg
-#define oldbufptr      Perl_oldbufptr
-#define oldoldbufptr   Perl_oldoldbufptr
-#define op             Perl_op
-#define op_desc                Perl_op_desc
-#define op_name                Perl_op_name
-#define op_seqmax      Perl_op_seqmax
-#define opargs         Perl_opargs
-#define origalen       Perl_origalen
-#define origenviron    Perl_origenviron
-#define osname         Perl_osname
-#define pad_reset_pending      Perl_pad_reset_pending
-#define padix          Perl_padix
-#define padix_floor    Perl_padix_floor
-#define patleave       Perl_patleave
-#define pow_amg                Perl_pow_amg
-#define pow_ass_amg    Perl_pow_ass_amg
-#define ppaddr         Perl_ppaddr
-#define profiledata    Perl_profiledata
-#define provide_ref    Perl_provide_ref
-#define psig_name      Perl_psig_name
-#define psig_ptr       Perl_psig_ptr
-#define qrt_amg                Perl_qrt_amg
-#define rcsid          Perl_rcsid
-#define reall_srchlen  Perl_reall_srchlen
-#define regarglen      Perl_regarglen
-#define regbol         Perl_regbol
-#define regcode                Perl_regcode
-#define regdummy       Perl_regdummy
-#define regendp                Perl_regendp
-#define regeol         Perl_regeol
-#define regflags       Perl_regflags
-#define reginput       Perl_reginput
-#define regkind                Perl_regkind
-#define reglastparen   Perl_reglastparen
-#define regmyendp      Perl_regmyendp
-#define regmyp_size    Perl_regmyp_size
-#define regmystartp    Perl_regmystartp
-#define regnarrate     Perl_regnarrate
-#define regnaughty     Perl_regnaughty
-#define regnpar                Perl_regnpar
-#define regparse       Perl_regparse
-#define regprecomp     Perl_regprecomp
-#define regprev                Perl_regprev
-#define regsawback     Perl_regsawback
-#define regsize                Perl_regsize
-#define regstartp      Perl_regstartp
-#define regtill                Perl_regtill
-#define regxend                Perl_regxend
-#define repeat_amg     Perl_repeat_amg
-#define repeat_ass_amg Perl_repeat_ass_amg
-#define retstack       Perl_retstack
-#define retstack_ix    Perl_retstack_ix
-#define retstack_max   Perl_retstack_max
-#define rsfp           Perl_rsfp
-#define rsfp_filters   Perl_rsfp_filters
-#define rshift_amg     Perl_rshift_amg
-#define rshift_ass_amg Perl_rshift_ass_amg
-#define save_iv                Perl_save_iv
-#define save_pptr      Perl_save_pptr
-#define savestack      Perl_savestack
-#define savestack_ix   Perl_savestack_ix
-#define savestack_max  Perl_savestack_max
-#define saw_return     Perl_saw_return
-#define scmp_amg       Perl_scmp_amg
-#define scopestack     Perl_scopestack
-#define scopestack_ix  Perl_scopestack_ix
-#define scopestack_max Perl_scopestack_max
-#define scrgv          Perl_scrgv
-#define seq_amg                Perl_seq_amg
-#define sge_amg                Perl_sge_amg
-#define sgt_amg                Perl_sgt_amg
-#define sh_path                Perl_sh_path
-#define sig_name       Perl_sig_name
-#define sig_num                Perl_sig_num
-#define sighandler     Perl_sighandler
-#define simple         Perl_simple
-#define sin_amg                Perl_sin_amg
-#define sle_amg                Perl_sle_amg
-#define slt_amg                Perl_slt_amg
-#define sne_amg                Perl_sne_amg
-#define stack_base     Perl_stack_base
-#define stack_max      Perl_stack_max
-#define stack_sp       Perl_stack_sp
-#define statbuf                Perl_statbuf
-#define string_amg     Perl_string_amg
-#define sub_generation Perl_sub_generation
-#define subline                Perl_subline
-#define subname                Perl_subname
-#define subtr_amg      Perl_subtr_amg
-#define subtr_ass_amg  Perl_subtr_ass_amg
-#define sv_no          Perl_sv_no
-#define sv_undef       Perl_sv_undef
-#define sv_yes         Perl_sv_yes
-#define thisexpr       Perl_thisexpr
-#define timesbuf       Perl_timesbuf
-#define tokenbuf       Perl_tokenbuf
-#define uid            Perl_uid
-#define varies         Perl_varies
-#define vert           Perl_vert
-#define vtbl_amagic    Perl_vtbl_amagic
-#define vtbl_amagicelem        Perl_vtbl_amagicelem
-#define vtbl_arylen    Perl_vtbl_arylen
-#define vtbl_bm                Perl_vtbl_bm
-#define vtbl_collxfrm  Perl_vtbl_collxfrm
-#define vtbl_dbline    Perl_vtbl_dbline
-#define vtbl_env       Perl_vtbl_env
-#define vtbl_envelem   Perl_vtbl_envelem
-#define vtbl_fm                Perl_vtbl_fm
-#define vtbl_glob      Perl_vtbl_glob
-#define vtbl_isa       Perl_vtbl_isa
-#define vtbl_isaelem   Perl_vtbl_isaelem
-#define vtbl_mglob     Perl_vtbl_mglob
-#define vtbl_nkeys     Perl_vtbl_nkeys
-#define vtbl_pack      Perl_vtbl_pack
-#define vtbl_packelem  Perl_vtbl_packelem
-#define vtbl_pos       Perl_vtbl_pos
-#define vtbl_sig       Perl_vtbl_sig
-#define vtbl_sigelem   Perl_vtbl_sigelem
-#define vtbl_substr    Perl_vtbl_substr
-#define vtbl_sv                Perl_vtbl_sv
-#define vtbl_taint     Perl_vtbl_taint
-#define vtbl_uvar      Perl_vtbl_uvar
-#define vtbl_vec       Perl_vtbl_vec
-#define warn_nl                Perl_warn_nl
-#define warn_nosemi    Perl_warn_nosemi
-#define warn_reserved  Perl_warn_reserved
-#define warn_uninit    Perl_warn_uninit
-#define watchaddr      Perl_watchaddr
-#define watchok                Perl_watchok
-#define yychar         Perl_yychar
-#define yycheck                Perl_yycheck
-#define yydebug                Perl_yydebug
-#define yydefred       Perl_yydefred
-#define yydgoto                Perl_yydgoto
-#define yyerrflag      Perl_yyerrflag
-#define yygindex       Perl_yygindex
-#define yylen          Perl_yylen
-#define yylhs          Perl_yylhs
-#define yylval         Perl_yylval
-#define yyname         Perl_yyname
-#define yynerrs                Perl_yynerrs
-#define yyrindex       Perl_yyrindex
-#define yyrule         Perl_yyrule
-#define yysindex       Perl_yysindex
-#define yytable                Perl_yytable
-#define yyval          Perl_yyval
-#define Gv_AMupdate    Perl_Gv_AMupdate
-#define SvTRUE         Perl_SvTRUE
-#define SvIV           Perl_SvIV
-#define SvUV           Perl_SvUV
-#define SvNV           Perl_SvNV
-#define amagic_call    Perl_amagic_call
-#define append_elem    Perl_append_elem
-#define append_list    Perl_append_list
-#define apply          Perl_apply
-#define assertref      Perl_assertref
-#define av_clear       Perl_av_clear
-#define av_extend      Perl_av_extend
-#define av_fake                Perl_av_fake
-#define av_fetch       Perl_av_fetch
-#define av_fill                Perl_av_fill
-#define av_len         Perl_av_len
-#define av_make                Perl_av_make
-#define av_pop         Perl_av_pop
-#define av_push                Perl_av_push
-#define av_shift       Perl_av_shift
-#define av_store       Perl_av_store
-#define av_undef       Perl_av_undef
-#define av_unshift     Perl_av_unshift
-#define bind_match     Perl_bind_match
-#define block_end      Perl_block_end
-#define block_start    Perl_block_start
-#define boot_core_UNIVERSAL    Perl_boot_core_UNIVERSAL
-#define calllist       Perl_calllist
-#define cando          Perl_cando
-#define cast_ulong     Perl_cast_ulong
-#define check_uni      Perl_check_uni
-#define checkcomma     Perl_checkcomma
-#define ck_aelem       Perl_ck_aelem
-#define ck_bitop       Perl_ck_bitop
-#define ck_concat      Perl_ck_concat
-#define ck_delete      Perl_ck_delete
-#define ck_eof         Perl_ck_eof
-#define ck_eval                Perl_ck_eval
-#define ck_exec                Perl_ck_exec
-#define ck_ftst                Perl_ck_ftst
-#define ck_fun         Perl_ck_fun
-#define ck_fun_locale  Perl_ck_fun_locale
-#define ck_glob                Perl_ck_glob
-#define ck_grep                Perl_ck_grep
-#define ck_gvconst     Perl_ck_gvconst
-#define ck_index       Perl_ck_index
-#define ck_lengthconst Perl_ck_lengthconst
-#define ck_lfun                Perl_ck_lfun
-#define ck_listiob     Perl_ck_listiob
-#define ck_match       Perl_ck_match
-#define ck_null                Perl_ck_null
-#define ck_repeat      Perl_ck_repeat
-#define ck_require     Perl_ck_require
-#define ck_retarget    Perl_ck_retarget
-#define ck_rfun                Perl_ck_rfun
-#define ck_rvconst     Perl_ck_rvconst
-#define ck_scmp                Perl_ck_scmp
-#define ck_select      Perl_ck_select
-#define ck_shift       Perl_ck_shift
-#define ck_sort                Perl_ck_sort
-#define ck_spair       Perl_ck_spair
-#define ck_split       Perl_ck_split
-#define ck_subr                Perl_ck_subr
-#define ck_svconst     Perl_ck_svconst
-#define ck_trunc       Perl_ck_trunc
-#define convert                Perl_convert
-#define cpytill                Perl_cpytill
-#define croak          Perl_croak
-#define cv_clone       Perl_cv_clone
-#define cv_undef       Perl_cv_undef
-#define cx_dump                Perl_cx_dump
-#define cxinc          Perl_cxinc
-#define deb            Perl_deb
-#define deb_growlevel  Perl_deb_growlevel
-#define debop          Perl_debop
-#define debprofdump    Perl_debprofdump
-#define debstack       Perl_debstack
-#define debstackptrs   Perl_debstackptrs
-#define deprecate      Perl_deprecate
-#define die            Perl_die
-#define die_where      Perl_die_where
-#define do_aexec       Perl_do_aexec
-#define do_chomp       Perl_do_chomp
-#define do_chop                Perl_do_chop
-#define do_close       Perl_do_close
-#define do_eof         Perl_do_eof
-#define do_exec                Perl_do_exec
-#define do_execfree    Perl_do_execfree
-#define do_ipcctl      Perl_do_ipcctl
-#define do_ipcget      Perl_do_ipcget
-#define do_join                Perl_do_join
-#define do_kv          Perl_do_kv
-#define do_msgrcv      Perl_do_msgrcv
-#define do_msgsnd      Perl_do_msgsnd
-#define do_open                Perl_do_open
-#define do_pipe                Perl_do_pipe
-#define do_print       Perl_do_print
-#define do_readline    Perl_do_readline
-#define do_seek                Perl_do_seek
-#define do_semop       Perl_do_semop
-#define do_shmio       Perl_do_shmio
-#define do_sprintf     Perl_do_sprintf
-#define do_tell                Perl_do_tell
-#define do_trans       Perl_do_trans
-#define do_vecset      Perl_do_vecset
-#define do_vop         Perl_do_vop
-#define doeval         Perl_doeval
-#define dofindlabel    Perl_dofindlabel
-#define dopoptoeval    Perl_dopoptoeval
-#define dounwind       Perl_dounwind
-#define dowantarray    Perl_dowantarray
-#define dump_all       Perl_dump_all
-#define dump_eval      Perl_dump_eval
-#define dump_fds       Perl_dump_fds
-#define dump_form      Perl_dump_form
-#define dump_gv                Perl_dump_gv
-#define dump_mstats    Perl_dump_mstats
-#define dump_op                Perl_dump_op
-#define dump_packsubs  Perl_dump_packsubs
-#define dump_pm                Perl_dump_pm
-#define dump_sub       Perl_dump_sub
-#define fbm_compile    Perl_fbm_compile
-#define fbm_instr      Perl_fbm_instr
-#define fetch_gv       Perl_fetch_gv
-#define fetch_io       Perl_fetch_io
-#define filter_add     Perl_filter_add
-#define filter_del     Perl_filter_del
-#define filter_read    Perl_filter_read
-#define fold_constants Perl_fold_constants
-#define force_ident    Perl_force_ident
-#define force_list     Perl_force_list
-#define force_next     Perl_force_next
-#define force_word     Perl_force_word
-#define free_tmps      Perl_free_tmps
+#define concat_amg             Perl_concat_amg
+#define concat_ass_amg         Perl_concat_ass_amg
+#define convert                        Perl_convert
+#define cop_seqmax             Perl_cop_seqmax
+#define cos_amg                        Perl_cos_amg
+#define cpytill                        Perl_cpytill
+#define croak                  Perl_croak
+#define cryptseen              Perl_cryptseen
+#define cshlen                 Perl_cshlen
+#define cshname                        Perl_cshname
+#define curinterp              Perl_curinterp
+#define curpad                 Perl_curpad
+#define cv_clone               Perl_cv_clone
+#define cv_const_sv            Perl_cv_const_sv
+#define cv_undef               Perl_cv_undef
+#define cx_dump                        Perl_cx_dump
+#define cxinc                  Perl_cxinc
+#define dc                     Perl_dc
+#define deb                    Perl_deb
+#define deb_growlevel          Perl_deb_growlevel
+#define debop                  Perl_debop
+#define debprofdump            Perl_debprofdump
+#define debstack               Perl_debstack
+#define debstackptrs           Perl_debstackptrs
+#define dec_amg                        Perl_dec_amg
+#define deprecate              Perl_deprecate
+#define di                     Perl_di
+#define die                    Perl_die
+#define die_where              Perl_die_where
+#define div_amg                        Perl_div_amg
+#define div_ass_amg            Perl_div_ass_amg
+#define do_aexec               Perl_do_aexec
+#define do_chomp               Perl_do_chomp
+#define do_chop                        Perl_do_chop
+#define do_close               Perl_do_close
+#define do_eof                 Perl_do_eof
+#define do_exec                        Perl_do_exec
+#define do_execfree            Perl_do_execfree
+#define do_ipcctl              Perl_do_ipcctl
+#define do_ipcget              Perl_do_ipcget
+#define do_join                        Perl_do_join
+#define do_kv                  Perl_do_kv
+#define do_msgrcv              Perl_do_msgrcv
+#define do_msgsnd              Perl_do_msgsnd
+#define do_open                        Perl_do_open
+#define do_pipe                        Perl_do_pipe
+#define do_print               Perl_do_print
+#define do_readline            Perl_do_readline
+#define do_seek                        Perl_do_seek
+#define do_semop               Perl_do_semop
+#define do_shmio               Perl_do_shmio
+#define do_sprintf             Perl_do_sprintf
+#define do_tell                        Perl_do_tell
+#define do_trans               Perl_do_trans
+#define do_vecset              Perl_do_vecset
+#define do_vop                 Perl_do_vop
+#define doeval                 Perl_doeval
+#define dofindlabel            Perl_dofindlabel
+#define dopoptoeval            Perl_dopoptoeval
+#define dounwind               Perl_dounwind
+#define dowantarray            Perl_dowantarray
+#define ds                     Perl_ds
+#define dump_all               Perl_dump_all
+#define dump_eval              Perl_dump_eval
+#define dump_fds               Perl_dump_fds
+#define dump_form              Perl_dump_form
+#define dump_gv                        Perl_dump_gv
+#define dump_mstats            Perl_dump_mstats
+#define dump_op                        Perl_dump_op
+#define dump_packsubs          Perl_dump_packsubs
+#define dump_pm                        Perl_dump_pm
+#define dump_sub               Perl_dump_sub
+#define egid                   Perl_egid
+#define eq_amg                 Perl_eq_amg
+#define error_count            Perl_error_count
+#define euid                   Perl_euid
+#define evalseq                        Perl_evalseq
+#define exp_amg                        Perl_exp_amg
+#define expect                 Perl_expect
+#define expectterm             Perl_expectterm
+#define fallback_amg           Perl_fallback_amg
+#define fbm_compile            Perl_fbm_compile
+#define fbm_instr              Perl_fbm_instr
+#define fetch_gv               Perl_fetch_gv
+#define fetch_io               Perl_fetch_io
+#define filter_add             Perl_filter_add
+#define filter_del             Perl_filter_del
+#define filter_read            Perl_filter_read
+#define fold                   Perl_fold
+#define fold_constants         Perl_fold_constants
+#define fold_locale            Perl_fold_locale
+#define force_ident            Perl_force_ident
+#define force_list             Perl_force_list
+#define force_next             Perl_force_next
+#define force_word             Perl_force_word
+#define free_tmps              Perl_free_tmps
+#define freq                   Perl_freq
+#define ge_amg                 Perl_ge_amg
 #define gen_constant_list      Perl_gen_constant_list
-#define gp_free                Perl_gp_free
-#define gp_ref         Perl_gp_ref
-#define gv_AVadd       Perl_gv_AVadd
-#define gv_HVadd       Perl_gv_HVadd
-#define gv_IOadd       Perl_gv_IOadd
-#define gv_check       Perl_gv_check
-#define gv_efullname   Perl_gv_efullname
-#define gv_efullname3  Perl_gv_efullname3
-#define gv_fetchfile   Perl_gv_fetchfile
-#define gv_fetchmeth   Perl_gv_fetchmeth
-#define gv_fetchmethod Perl_gv_fetchmethod
-#define gv_fetchpv     Perl_gv_fetchpv
-#define gv_fullname    Perl_gv_fullname
-#define gv_fullname3   Perl_gv_fullname3
-#define gv_init                Perl_gv_init
-#define gv_stashpv     Perl_gv_stashpv
-#define gv_stashpvn    Perl_gv_stashpvn
-#define gv_stashsv     Perl_gv_stashsv
-#define he_delayfree   Perl_he_delayfree
-#define he_free                Perl_he_free
-#define he_root                Perl_he_root
-#define hoistmust      Perl_hoistmust
-#define hv_clear       Perl_hv_clear
-#define hv_delete      Perl_hv_delete
-#define hv_delete_ent  Perl_hv_delete_ent
-#define hv_exists      Perl_hv_exists
-#define hv_exists_ent  Perl_hv_exists_ent
-#define hv_fetch       Perl_hv_fetch
-#define hv_fetch_ent   Perl_hv_fetch_ent
-#define hv_iterinit    Perl_hv_iterinit
-#define hv_iterkey     Perl_hv_iterkey
-#define hv_iterkeysv   Perl_hv_iterkeysv
-#define hv_iternext    Perl_hv_iternext
-#define hv_iternextsv  Perl_hv_iternextsv
-#define hv_iterval     Perl_hv_iterval
-#define hv_ksplit      Perl_hv_ksplit
-#define hv_magic       Perl_hv_magic
-#define hv_stashpv     Perl_hv_stashpv
-#define hv_store       Perl_hv_store
-#define hv_store_ent   Perl_hv_store_ent
-#define hv_undef       Perl_hv_undef
-#define ibcmp          Perl_ibcmp
-#define ibcmp_locale   Perl_ibcmp_locale
-#define ingroup                Perl_ingroup
-#define instr          Perl_instr
-#define intro_my       Perl_intro_my
-#define intuit_more    Perl_intuit_more
-#define invert         Perl_invert
-#define jmaybe         Perl_jmaybe
-#define keyword                Perl_keyword
-#define leave_scope    Perl_leave_scope
-#define lex_end                Perl_lex_end
-#define lex_start      Perl_lex_start
-#define linklist       Perl_linklist
-#define list           Perl_list
-#define listkids       Perl_listkids
-#define localize       Perl_localize
+#define gid                    Perl_gid
+#define gp_free                        Perl_gp_free
+#define gp_ref                 Perl_gp_ref
+#define gt_amg                 Perl_gt_amg
+#define gv_AVadd               Perl_gv_AVadd
+#define gv_HVadd               Perl_gv_HVadd
+#define gv_IOadd               Perl_gv_IOadd
+#define gv_check               Perl_gv_check
+#define gv_efullname           Perl_gv_efullname
+#define gv_efullname3          Perl_gv_efullname3
+#define gv_fetchfile           Perl_gv_fetchfile
+#define gv_fetchmeth           Perl_gv_fetchmeth
+#define gv_fetchmethod         Perl_gv_fetchmethod
+#define gv_fetchpv             Perl_gv_fetchpv
+#define gv_fullname            Perl_gv_fullname
+#define gv_fullname3           Perl_gv_fullname3
+#define gv_init                        Perl_gv_init
+#define gv_stashpv             Perl_gv_stashpv
+#define gv_stashpvn            Perl_gv_stashpvn
+#define gv_stashsv             Perl_gv_stashsv
+#define he_delayfree           Perl_he_delayfree
+#define he_free                        Perl_he_free
+#define he_root                        Perl_he_root
+#define hexdigit               Perl_hexdigit
+#define hints                  Perl_hints
+#define hoistmust              Perl_hoistmust
+#define hv_clear               Perl_hv_clear
+#define hv_delete              Perl_hv_delete
+#define hv_delete_ent          Perl_hv_delete_ent
+#define hv_exists              Perl_hv_exists
+#define hv_exists_ent          Perl_hv_exists_ent
+#define hv_fetch               Perl_hv_fetch
+#define hv_fetch_ent           Perl_hv_fetch_ent
+#define hv_iterinit            Perl_hv_iterinit
+#define hv_iterkey             Perl_hv_iterkey
+#define hv_iterkeysv           Perl_hv_iterkeysv
+#define hv_iternext            Perl_hv_iternext
+#define hv_iternextsv          Perl_hv_iternextsv
+#define hv_iterval             Perl_hv_iterval
+#define hv_ksplit              Perl_hv_ksplit
+#define hv_magic               Perl_hv_magic
+#define hv_stashpv             Perl_hv_stashpv
+#define hv_store               Perl_hv_store
+#define hv_store_ent           Perl_hv_store_ent
+#define hv_undef               Perl_hv_undef
+#define ibcmp                  Perl_ibcmp
+#define ibcmp_locale           Perl_ibcmp_locale
+#define in_my                  Perl_in_my
+#define inc_amg                        Perl_inc_amg
+#define ingroup                        Perl_ingroup
+#define instr                  Perl_instr
+#define intro_my               Perl_intro_my
+#define intuit_more            Perl_intuit_more
+#define invert                 Perl_invert
+#define io_close               Perl_io_close
+#define jmaybe                 Perl_jmaybe
+#define keyword                        Perl_keyword
+#define know_next              Perl_know_next
+#define last_lop               Perl_last_lop
+#define last_lop_op            Perl_last_lop_op
+#define last_uni               Perl_last_uni
+#define le_amg                 Perl_le_amg
+#define leave_scope            Perl_leave_scope
+#define lex_brackets           Perl_lex_brackets
+#define lex_brackstack         Perl_lex_brackstack
+#define lex_casemods           Perl_lex_casemods
+#define lex_casestack          Perl_lex_casestack
+#define lex_defer              Perl_lex_defer
+#define lex_dojoin             Perl_lex_dojoin
+#define lex_end                        Perl_lex_end
+#define lex_expect             Perl_lex_expect
+#define lex_fakebrack          Perl_lex_fakebrack
+#define lex_formbrack          Perl_lex_formbrack
+#define lex_inpat              Perl_lex_inpat
+#define lex_inwhat             Perl_lex_inwhat
+#define lex_op                 Perl_lex_op
+#define lex_repl               Perl_lex_repl
+#define lex_start              Perl_lex_start
+#define lex_starts             Perl_lex_starts
+#define lex_state              Perl_lex_state
+#define lex_stuff              Perl_lex_stuff
+#define linestr                        Perl_linestr
+#define linklist               Perl_linklist
+#define list                   Perl_list
+#define listkids               Perl_listkids
+#define localize               Perl_localize
+#define log_amg                        Perl_log_amg
 #define looks_like_number      Perl_looks_like_number
-#define magic_clearenv Perl_magic_clearenv
-#define magic_clearpack        Perl_magic_clearpack
-#define magic_clearsig Perl_magic_clearsig
+#define lshift_amg             Perl_lshift_amg
+#define lshift_ass_amg         Perl_lshift_ass_amg
+#define lt_amg                 Perl_lt_amg
+#define magic_clearenv         Perl_magic_clearenv
+#define magic_clearpack                Perl_magic_clearpack
+#define magic_clearsig         Perl_magic_clearsig
 #define magic_existspack       Perl_magic_existspack
-#define magic_get      Perl_magic_get
-#define magic_getarylen        Perl_magic_getarylen
-#define magic_getglob  Perl_magic_getglob
-#define magic_getpack  Perl_magic_getpack
-#define magic_getpos   Perl_magic_getpos
-#define magic_getsig   Perl_magic_getsig
-#define magic_gettaint Perl_magic_gettaint
-#define magic_getuvar  Perl_magic_getuvar
-#define magic_len      Perl_magic_len
-#define magic_nextpack Perl_magic_nextpack
-#define magic_set      Perl_magic_set
-#define magic_setamagic        Perl_magic_setamagic
-#define magic_setarylen        Perl_magic_setarylen
-#define magic_setbm    Perl_magic_setbm
+#define magic_freevivary       Perl_magic_freevivary
+#define magic_get              Perl_magic_get
+#define magic_getarylen                Perl_magic_getarylen
+#define magic_getglob          Perl_magic_getglob
+#define magic_getpack          Perl_magic_getpack
+#define magic_getpos           Perl_magic_getpos
+#define magic_getsig           Perl_magic_getsig
+#define magic_gettaint         Perl_magic_gettaint
+#define magic_getuvar          Perl_magic_getuvar
+#define magic_len              Perl_magic_len
+#define magic_nextpack         Perl_magic_nextpack
+#define magic_set              Perl_magic_set
+#define magic_setamagic                Perl_magic_setamagic
+#define magic_setarylen                Perl_magic_setarylen
+#define magic_setbm            Perl_magic_setbm
 #define magic_setcollxfrm      Perl_magic_setcollxfrm
-#define magic_setdbline        Perl_magic_setdbline
-#define magic_setenv   Perl_magic_setenv
-#define magic_setfm    Perl_magic_setfm
-#define magic_setglob  Perl_magic_setglob
-#define magic_setisa   Perl_magic_setisa
-#define magic_setmglob Perl_magic_setmglob
-#define magic_setnkeys Perl_magic_setnkeys
-#define magic_setpack  Perl_magic_setpack
-#define magic_setpos   Perl_magic_setpos
-#define magic_setsig   Perl_magic_setsig
-#define magic_setsubstr        Perl_magic_setsubstr
-#define magic_settaint Perl_magic_settaint
-#define magic_setuvar  Perl_magic_setuvar
-#define magic_setvec   Perl_magic_setvec
-#define magic_wipepack Perl_magic_wipepack
-#define magicname      Perl_magicname
-#define markstack_grow Perl_markstack_grow
-#define mem_collxfrm   Perl_mem_collxfrm
-#define mess           Perl_mess
-#define mg_clear       Perl_mg_clear
-#define mg_copy                Perl_mg_copy
-#define mg_find                Perl_mg_find
-#define mg_free                Perl_mg_free
-#define mg_get         Perl_mg_get
-#define mg_len         Perl_mg_len
-#define mg_magical     Perl_mg_magical
-#define mg_set         Perl_mg_set
-#define mod            Perl_mod
-#define modkids                Perl_modkids
-#define moreswitches   Perl_moreswitches
-#define mstats         Perl_mstats
-#define my             Perl_my
-#define my_bcopy       Perl_my_bcopy
-#define my_bzero       Perl_my_bzero
-#define my_chsize      Perl_my_chsize
-#define my_exit                Perl_my_exit
-#define my_htonl       Perl_my_htonl
-#define my_lstat       Perl_my_lstat
-#define my_memcmp      Perl_my_memcmp
-#define my_ntohl       Perl_my_ntohl
-#define my_pclose      Perl_my_pclose
-#define my_popen       Perl_my_popen
-#define my_setenv      Perl_my_setenv
-#define my_stat                Perl_my_stat
-#define my_swap                Perl_my_swap
-#define my_unexec      Perl_my_unexec
-#define newANONHASH    Perl_newANONHASH
-#define newANONLIST    Perl_newANONLIST
-#define newANONSUB     Perl_newANONSUB
-#define newASSIGNOP    Perl_newASSIGNOP
-#define newAV          Perl_newAV
-#define newAVREF       Perl_newAVREF
-#define newBINOP       Perl_newBINOP
-#define newCONDOP      Perl_newCONDOP
-#define newCVREF       Perl_newCVREF
-#define newFORM                Perl_newFORM
-#define newFOROP       Perl_newFOROP
-#define newGVOP                Perl_newGVOP
-#define newGVREF       Perl_newGVREF
-#define newGVgen       Perl_newGVgen
-#define newHV          Perl_newHV
-#define newHVREF       Perl_newHVREF
-#define newIO          Perl_newIO
-#define newLISTOP      Perl_newLISTOP
-#define newLOGOP       Perl_newLOGOP
-#define newLOOPEX      Perl_newLOOPEX
-#define newLOOPOP      Perl_newLOOPOP
-#define newNULLLIST    Perl_newNULLLIST
-#define newOP          Perl_newOP
-#define newPMOP                Perl_newPMOP
-#define newPROG                Perl_newPROG
-#define newPVOP                Perl_newPVOP
-#define newRANGE       Perl_newRANGE
-#define newRV          Perl_newRV
-#define newSLICEOP     Perl_newSLICEOP
-#define newSTATEOP     Perl_newSTATEOP
-#define newSUB         Perl_newSUB
-#define newSV          Perl_newSV
-#define newSVOP                Perl_newSVOP
-#define newSVREF       Perl_newSVREF
-#define newSViv                Perl_newSViv
-#define newSVnv                Perl_newSVnv
-#define newSVpv                Perl_newSVpv
-#define newSVrv                Perl_newSVrv
-#define newSVsv                Perl_newSVsv
-#define newUNOP                Perl_newUNOP
-#define newWHILEOP     Perl_newWHILEOP
-#define newXS          Perl_newXS
-#define newXSUB                Perl_newXSUB
-#define nextargv       Perl_nextargv
-#define ninstr         Perl_ninstr
-#define no_fh_allowed  Perl_no_fh_allowed
-#define no_op          Perl_no_op
-#define oopsAV         Perl_oopsAV
-#define oopsCV         Perl_oopsCV
-#define oopsHV         Perl_oopsHV
-#define op_free                Perl_op_free
-#define package                Perl_package
-#define pad_alloc      Perl_pad_alloc
-#define pad_allocmy    Perl_pad_allocmy
-#define pad_findmy     Perl_pad_findmy
-#define pad_free       Perl_pad_free
-#define pad_leavemy    Perl_pad_leavemy
-#define pad_reset      Perl_pad_reset
-#define pad_sv         Perl_pad_sv
-#define pad_swipe      Perl_pad_swipe
-#define peep           Perl_peep
-#define pidgone                Perl_pidgone
-#define pmflag         Perl_pmflag
-#define pmruntime      Perl_pmruntime
-#define pmtrans                Perl_pmtrans
-#define pop_return     Perl_pop_return
-#define pop_scope      Perl_pop_scope
-#define pp_aassign     Perl_pp_aassign
-#define pp_abs         Perl_pp_abs
-#define pp_accept      Perl_pp_accept
-#define pp_add         Perl_pp_add
-#define pp_aelem       Perl_pp_aelem
-#define pp_aelemfast   Perl_pp_aelemfast
-#define pp_alarm       Perl_pp_alarm
-#define pp_and         Perl_pp_and
-#define pp_andassign   Perl_pp_andassign
-#define pp_anoncode    Perl_pp_anoncode
-#define pp_anonhash    Perl_pp_anonhash
-#define pp_anonlist    Perl_pp_anonlist
-#define pp_aslice      Perl_pp_aslice
-#define pp_atan2       Perl_pp_atan2
-#define pp_av2arylen   Perl_pp_av2arylen
-#define pp_backtick    Perl_pp_backtick
-#define pp_bind                Perl_pp_bind
-#define pp_binmode     Perl_pp_binmode
-#define pp_bit_and     Perl_pp_bit_and
-#define pp_bit_or      Perl_pp_bit_or
-#define pp_bit_xor     Perl_pp_bit_xor
-#define pp_bless       Perl_pp_bless
-#define pp_caller      Perl_pp_caller
-#define pp_chdir       Perl_pp_chdir
-#define pp_chmod       Perl_pp_chmod
-#define pp_chomp       Perl_pp_chomp
-#define pp_chop                Perl_pp_chop
-#define pp_chown       Perl_pp_chown
-#define pp_chr         Perl_pp_chr
-#define pp_chroot      Perl_pp_chroot
-#define pp_close       Perl_pp_close
-#define pp_closedir    Perl_pp_closedir
-#define pp_complement  Perl_pp_complement
-#define pp_concat      Perl_pp_concat
-#define pp_cond_expr   Perl_pp_cond_expr
-#define pp_connect     Perl_pp_connect
-#define pp_const       Perl_pp_const
-#define pp_cos         Perl_pp_cos
-#define pp_crypt       Perl_pp_crypt
-#define pp_cswitch     Perl_pp_cswitch
-#define pp_dbmclose    Perl_pp_dbmclose
-#define pp_dbmopen     Perl_pp_dbmopen
-#define pp_dbstate     Perl_pp_dbstate
-#define pp_defined     Perl_pp_defined
-#define pp_delete      Perl_pp_delete
-#define pp_die         Perl_pp_die
-#define pp_divide      Perl_pp_divide
-#define pp_dofile      Perl_pp_dofile
-#define pp_dump                Perl_pp_dump
-#define pp_each                Perl_pp_each
-#define pp_egrent      Perl_pp_egrent
-#define pp_ehostent    Perl_pp_ehostent
-#define pp_enetent     Perl_pp_enetent
-#define pp_enter       Perl_pp_enter
-#define pp_entereval   Perl_pp_entereval
-#define pp_enteriter   Perl_pp_enteriter
-#define pp_enterloop   Perl_pp_enterloop
-#define pp_entersub    Perl_pp_entersub
-#define pp_entersubr   Perl_pp_entersubr
-#define pp_entertry    Perl_pp_entertry
-#define pp_enterwrite  Perl_pp_enterwrite
-#define pp_eof         Perl_pp_eof
-#define pp_eprotoent   Perl_pp_eprotoent
-#define pp_epwent      Perl_pp_epwent
-#define pp_eq          Perl_pp_eq
-#define pp_eservent    Perl_pp_eservent
-#define pp_evalonce    Perl_pp_evalonce
-#define pp_exec                Perl_pp_exec
-#define pp_exists      Perl_pp_exists
-#define pp_exit                Perl_pp_exit
-#define pp_exp         Perl_pp_exp
-#define pp_fcntl       Perl_pp_fcntl
-#define pp_fileno      Perl_pp_fileno
-#define pp_flip                Perl_pp_flip
-#define pp_flock       Perl_pp_flock
-#define pp_flop                Perl_pp_flop
-#define pp_fork                Perl_pp_fork
-#define pp_formline    Perl_pp_formline
-#define pp_ftatime     Perl_pp_ftatime
-#define pp_ftbinary    Perl_pp_ftbinary
-#define pp_ftblk       Perl_pp_ftblk
-#define pp_ftchr       Perl_pp_ftchr
-#define pp_ftctime     Perl_pp_ftctime
-#define pp_ftdir       Perl_pp_ftdir
-#define pp_fteexec     Perl_pp_fteexec
-#define pp_fteowned    Perl_pp_fteowned
-#define pp_fteread     Perl_pp_fteread
-#define pp_ftewrite    Perl_pp_ftewrite
-#define pp_ftfile      Perl_pp_ftfile
-#define pp_ftis                Perl_pp_ftis
-#define pp_ftlink      Perl_pp_ftlink
-#define pp_ftmtime     Perl_pp_ftmtime
-#define pp_ftpipe      Perl_pp_ftpipe
-#define pp_ftrexec     Perl_pp_ftrexec
-#define pp_ftrowned    Perl_pp_ftrowned
-#define pp_ftrread     Perl_pp_ftrread
-#define pp_ftrwrite    Perl_pp_ftrwrite
-#define pp_ftsgid      Perl_pp_ftsgid
-#define pp_ftsize      Perl_pp_ftsize
-#define pp_ftsock      Perl_pp_ftsock
-#define pp_ftsuid      Perl_pp_ftsuid
-#define pp_ftsvtx      Perl_pp_ftsvtx
-#define pp_fttext      Perl_pp_fttext
-#define pp_fttty       Perl_pp_fttty
-#define pp_ftzero      Perl_pp_ftzero
-#define pp_ge          Perl_pp_ge
-#define pp_gelem       Perl_pp_gelem
-#define pp_getc                Perl_pp_getc
-#define pp_getlogin    Perl_pp_getlogin
-#define pp_getpeername Perl_pp_getpeername
-#define pp_getpgrp     Perl_pp_getpgrp
-#define pp_getppid     Perl_pp_getppid
-#define pp_getpriority Perl_pp_getpriority
-#define pp_getsockname Perl_pp_getsockname
-#define pp_ggrent      Perl_pp_ggrent
-#define pp_ggrgid      Perl_pp_ggrgid
-#define pp_ggrnam      Perl_pp_ggrnam
-#define pp_ghbyaddr    Perl_pp_ghbyaddr
-#define pp_ghbyname    Perl_pp_ghbyname
-#define pp_ghostent    Perl_pp_ghostent
-#define pp_glob                Perl_pp_glob
-#define pp_gmtime      Perl_pp_gmtime
-#define pp_gnbyaddr    Perl_pp_gnbyaddr
-#define pp_gnbyname    Perl_pp_gnbyname
-#define pp_gnetent     Perl_pp_gnetent
-#define pp_goto                Perl_pp_goto
-#define pp_gpbyname    Perl_pp_gpbyname
-#define pp_gpbynumber  Perl_pp_gpbynumber
-#define pp_gprotoent   Perl_pp_gprotoent
-#define pp_gpwent      Perl_pp_gpwent
-#define pp_gpwnam      Perl_pp_gpwnam
-#define pp_gpwuid      Perl_pp_gpwuid
-#define pp_grepstart   Perl_pp_grepstart
-#define pp_grepwhile   Perl_pp_grepwhile
-#define pp_gsbyname    Perl_pp_gsbyname
-#define pp_gsbyport    Perl_pp_gsbyport
-#define pp_gservent    Perl_pp_gservent
-#define pp_gsockopt    Perl_pp_gsockopt
-#define pp_gt          Perl_pp_gt
-#define pp_gv          Perl_pp_gv
-#define pp_gvsv                Perl_pp_gvsv
-#define pp_helem       Perl_pp_helem
-#define pp_hex         Perl_pp_hex
-#define pp_hslice      Perl_pp_hslice
-#define pp_i_add       Perl_pp_i_add
-#define pp_i_divide    Perl_pp_i_divide
-#define pp_i_eq                Perl_pp_i_eq
-#define pp_i_ge                Perl_pp_i_ge
-#define pp_i_gt                Perl_pp_i_gt
-#define pp_i_le                Perl_pp_i_le
-#define pp_i_lt                Perl_pp_i_lt
-#define pp_i_modulo    Perl_pp_i_modulo
-#define pp_i_multiply  Perl_pp_i_multiply
-#define pp_i_ncmp      Perl_pp_i_ncmp
-#define pp_i_ne                Perl_pp_i_ne
-#define pp_i_negate    Perl_pp_i_negate
-#define pp_i_subtract  Perl_pp_i_subtract
-#define pp_index       Perl_pp_index
-#define pp_indread     Perl_pp_indread
-#define pp_int         Perl_pp_int
-#define pp_interp      Perl_pp_interp
-#define pp_ioctl       Perl_pp_ioctl
-#define pp_iter                Perl_pp_iter
-#define pp_join                Perl_pp_join
-#define pp_keys                Perl_pp_keys
-#define pp_kill                Perl_pp_kill
-#define pp_last                Perl_pp_last
-#define pp_lc          Perl_pp_lc
-#define pp_lcfirst     Perl_pp_lcfirst
-#define pp_le          Perl_pp_le
-#define pp_leave       Perl_pp_leave
-#define pp_leaveeval   Perl_pp_leaveeval
-#define pp_leaveloop   Perl_pp_leaveloop
-#define pp_leavesub    Perl_pp_leavesub
-#define pp_leavetry    Perl_pp_leavetry
-#define pp_leavewrite  Perl_pp_leavewrite
-#define pp_left_shift  Perl_pp_left_shift
-#define pp_length      Perl_pp_length
-#define pp_lineseq     Perl_pp_lineseq
-#define pp_link                Perl_pp_link
-#define pp_list                Perl_pp_list
-#define pp_listen      Perl_pp_listen
-#define pp_localtime   Perl_pp_localtime
-#define pp_log         Perl_pp_log
-#define pp_lslice      Perl_pp_lslice
-#define pp_lstat       Perl_pp_lstat
-#define pp_lt          Perl_pp_lt
-#define pp_map         Perl_pp_map
-#define pp_mapstart    Perl_pp_mapstart
-#define pp_mapwhile    Perl_pp_mapwhile
-#define pp_match       Perl_pp_match
-#define pp_method      Perl_pp_method
-#define pp_mkdir       Perl_pp_mkdir
-#define pp_modulo      Perl_pp_modulo
-#define pp_msgctl      Perl_pp_msgctl
-#define pp_msgget      Perl_pp_msgget
-#define pp_msgrcv      Perl_pp_msgrcv
-#define pp_msgsnd      Perl_pp_msgsnd
-#define pp_multiply    Perl_pp_multiply
-#define pp_ncmp                Perl_pp_ncmp
-#define pp_ne          Perl_pp_ne
-#define pp_negate      Perl_pp_negate
-#define pp_next                Perl_pp_next
-#define pp_nextstate   Perl_pp_nextstate
-#define pp_not         Perl_pp_not
-#define pp_nswitch     Perl_pp_nswitch
-#define pp_null                Perl_pp_null
-#define pp_oct         Perl_pp_oct
-#define pp_open                Perl_pp_open
-#define pp_open_dir    Perl_pp_open_dir
-#define pp_or          Perl_pp_or
-#define pp_orassign    Perl_pp_orassign
-#define pp_ord         Perl_pp_ord
-#define pp_pack                Perl_pp_pack
-#define pp_padany      Perl_pp_padany
-#define pp_padav       Perl_pp_padav
-#define pp_padhv       Perl_pp_padhv
-#define pp_padsv       Perl_pp_padsv
-#define pp_pipe_op     Perl_pp_pipe_op
-#define pp_pop         Perl_pp_pop
-#define pp_pos         Perl_pp_pos
-#define pp_postdec     Perl_pp_postdec
-#define pp_postinc     Perl_pp_postinc
-#define pp_pow         Perl_pp_pow
-#define pp_predec      Perl_pp_predec
-#define pp_preinc      Perl_pp_preinc
-#define pp_print       Perl_pp_print
-#define pp_prototype   Perl_pp_prototype
-#define pp_prtf                Perl_pp_prtf
-#define pp_push                Perl_pp_push
-#define pp_pushmark    Perl_pp_pushmark
-#define pp_pushre      Perl_pp_pushre
-#define pp_quotemeta   Perl_pp_quotemeta
-#define pp_rand                Perl_pp_rand
-#define pp_range       Perl_pp_range
-#define pp_rcatline    Perl_pp_rcatline
-#define pp_read                Perl_pp_read
-#define pp_readdir     Perl_pp_readdir
-#define pp_readline    Perl_pp_readline
-#define pp_readlink    Perl_pp_readlink
-#define pp_recv                Perl_pp_recv
-#define pp_redo                Perl_pp_redo
-#define pp_ref         Perl_pp_ref
-#define pp_refgen      Perl_pp_refgen
-#define pp_regcmaybe   Perl_pp_regcmaybe
-#define pp_regcomp     Perl_pp_regcomp
-#define pp_rename      Perl_pp_rename
-#define pp_repeat      Perl_pp_repeat
-#define pp_require     Perl_pp_require
-#define pp_reset       Perl_pp_reset
-#define pp_return      Perl_pp_return
-#define pp_reverse     Perl_pp_reverse
-#define pp_rewinddir   Perl_pp_rewinddir
-#define pp_right_shift Perl_pp_right_shift
-#define pp_rindex      Perl_pp_rindex
-#define pp_rmdir       Perl_pp_rmdir
-#define pp_rv2av       Perl_pp_rv2av
-#define pp_rv2cv       Perl_pp_rv2cv
-#define pp_rv2gv       Perl_pp_rv2gv
-#define pp_rv2hv       Perl_pp_rv2hv
-#define pp_rv2sv       Perl_pp_rv2sv
-#define pp_sassign     Perl_pp_sassign
-#define pp_scalar      Perl_pp_scalar
-#define pp_schomp      Perl_pp_schomp
-#define pp_schop       Perl_pp_schop
-#define pp_scmp                Perl_pp_scmp
-#define pp_scope       Perl_pp_scope
-#define pp_seek                Perl_pp_seek
-#define pp_seekdir     Perl_pp_seekdir
-#define pp_select      Perl_pp_select
-#define pp_semctl      Perl_pp_semctl
-#define pp_semget      Perl_pp_semget
-#define pp_semop       Perl_pp_semop
-#define pp_send                Perl_pp_send
-#define pp_seq         Perl_pp_seq
-#define pp_setpgrp     Perl_pp_setpgrp
-#define pp_setpriority Perl_pp_setpriority
-#define pp_sge         Perl_pp_sge
-#define pp_sgrent      Perl_pp_sgrent
-#define pp_sgt         Perl_pp_sgt
-#define pp_shift       Perl_pp_shift
-#define pp_shmctl      Perl_pp_shmctl
-#define pp_shmget      Perl_pp_shmget
-#define pp_shmread     Perl_pp_shmread
-#define pp_shmwrite    Perl_pp_shmwrite
-#define pp_shostent    Perl_pp_shostent
-#define pp_shutdown    Perl_pp_shutdown
-#define pp_sin         Perl_pp_sin
-#define pp_sle         Perl_pp_sle
-#define pp_sleep       Perl_pp_sleep
-#define pp_slt         Perl_pp_slt
-#define pp_sne         Perl_pp_sne
-#define pp_snetent     Perl_pp_snetent
-#define pp_socket      Perl_pp_socket
-#define pp_sockpair    Perl_pp_sockpair
-#define pp_sort                Perl_pp_sort
-#define pp_splice      Perl_pp_splice
-#define pp_split       Perl_pp_split
-#define pp_sprintf     Perl_pp_sprintf
-#define pp_sprotoent   Perl_pp_sprotoent
-#define pp_spwent      Perl_pp_spwent
-#define pp_sqrt                Perl_pp_sqrt
-#define pp_srand       Perl_pp_srand
-#define pp_srefgen     Perl_pp_srefgen
-#define pp_sselect     Perl_pp_sselect
-#define pp_sservent    Perl_pp_sservent
-#define pp_ssockopt    Perl_pp_ssockopt
-#define pp_stat                Perl_pp_stat
-#define pp_stringify   Perl_pp_stringify
-#define pp_stub                Perl_pp_stub
-#define pp_study       Perl_pp_study
-#define pp_subst       Perl_pp_subst
-#define pp_substcont   Perl_pp_substcont
-#define pp_substr      Perl_pp_substr
-#define pp_subtract    Perl_pp_subtract
-#define pp_symlink     Perl_pp_symlink
-#define pp_syscall     Perl_pp_syscall
-#define pp_sysopen     Perl_pp_sysopen
-#define pp_sysread     Perl_pp_sysread
-#define pp_system      Perl_pp_system
-#define pp_syswrite    Perl_pp_syswrite
-#define pp_tell                Perl_pp_tell
-#define pp_telldir     Perl_pp_telldir
-#define pp_tie         Perl_pp_tie
-#define pp_tied                Perl_pp_tied
-#define pp_time                Perl_pp_time
-#define pp_tms         Perl_pp_tms
-#define pp_trans       Perl_pp_trans
-#define pp_truncate    Perl_pp_truncate
-#define pp_uc          Perl_pp_uc
-#define pp_ucfirst     Perl_pp_ucfirst
-#define pp_umask       Perl_pp_umask
-#define pp_undef       Perl_pp_undef
-#define pp_unlink      Perl_pp_unlink
-#define pp_unpack      Perl_pp_unpack
-#define pp_unshift     Perl_pp_unshift
-#define pp_unstack     Perl_pp_unstack
-#define pp_untie       Perl_pp_untie
-#define pp_utime       Perl_pp_utime
-#define pp_values      Perl_pp_values
-#define pp_vec         Perl_pp_vec
-#define pp_wait                Perl_pp_wait
-#define pp_waitpid     Perl_pp_waitpid
-#define pp_wantarray   Perl_pp_wantarray
-#define pp_warn                Perl_pp_warn
-#define pp_xor         Perl_pp_xor
-#define pregcomp       Perl_pregcomp
-#define pregexec       Perl_pregexec
-#define pregfree       Perl_pregfree
-#define prepend_elem   Perl_prepend_elem
-#define push_return    Perl_push_return
-#define push_scope     Perl_push_scope
-#define q              Perl_q
-#define ref            Perl_ref
-#define refkids                Perl_refkids
-#define regdump                Perl_regdump
-#define regnext                Perl_regnext
-#define regprop                Perl_regprop
-#define repeatcpy      Perl_repeatcpy
-#define rninstr                Perl_rninstr
-#define rsignal                Perl_rsignal
-#define rsignal_save   Perl_rsignal_save
-#define rsignal_state  Perl_rsignal_state
-#define rsignal_restore        Perl_rsignal_restore
-#define runops         Perl_runops
-#define safecalloc     Perl_safecalloc
-#define safemalloc     Perl_safemalloc
-#define safefree       Perl_safefree
-#define saferealloc    Perl_saferealloc
-#define safexcalloc    Perl_safexcalloc
-#define safexmalloc    Perl_safexmalloc
-#define safexfree      Perl_safexfree
-#define safexrealloc   Perl_safexrealloc
-#define same_dirent    Perl_same_dirent
-#define save_I16       Perl_save_I16
-#define save_I32       Perl_save_I32
-#define save_aptr      Perl_save_aptr
-#define save_ary       Perl_save_ary
-#define save_clearsv   Perl_save_clearsv
-#define save_delete    Perl_save_delete
-#define save_destructor        Perl_save_destructor
-#define save_freeop    Perl_save_freeop
-#define save_freepv    Perl_save_freepv
-#define save_freesv    Perl_save_freesv
-#define save_hash      Perl_save_hash
-#define save_hptr      Perl_save_hptr
-#define save_int       Perl_save_int
-#define save_item      Perl_save_item
-#define save_list      Perl_save_list
-#define save_long      Perl_save_long
-#define save_nogv      Perl_save_nogv
-#define save_pptr      Perl_save_pptr
-#define save_scalar    Perl_save_scalar
-#define save_sptr      Perl_save_sptr
-#define save_svref     Perl_save_svref
-#define savepv         Perl_savepv
-#define savepvn                Perl_savepvn
-#define savestack_grow Perl_savestack_grow
-#define sawparens      Perl_sawparens
-#define scalar         Perl_scalar
-#define scalarkids     Perl_scalarkids
-#define scalarseq      Perl_scalarseq
-#define scalarvoid     Perl_scalarvoid
-#define scan_const     Perl_scan_const
-#define scan_formline  Perl_scan_formline
-#define scan_heredoc   Perl_scan_heredoc
-#define scan_hex       Perl_scan_hex
-#define scan_ident     Perl_scan_ident
+#define magic_setdbline                Perl_magic_setdbline
+#define magic_setenv           Perl_magic_setenv
+#define magic_setfm            Perl_magic_setfm
+#define magic_setglob          Perl_magic_setglob
+#define magic_setisa           Perl_magic_setisa
+#define magic_setmglob         Perl_magic_setmglob
+#define magic_setnkeys         Perl_magic_setnkeys
+#define magic_setpack          Perl_magic_setpack
+#define magic_setpos           Perl_magic_setpos
+#define magic_setsig           Perl_magic_setsig
+#define magic_setsubstr                Perl_magic_setsubstr
+#define magic_settaint         Perl_magic_settaint
+#define magic_setuvar          Perl_magic_setuvar
+#define magic_setvec           Perl_magic_setvec
+#define magic_setvivary                Perl_magic_setvivary
+#define magic_wipepack         Perl_magic_wipepack
+#define magicname              Perl_magicname
+#define markstack              Perl_markstack
+#define markstack_grow         Perl_markstack_grow
+#define markstack_max          Perl_markstack_max
+#define markstack_ptr          Perl_markstack_ptr
+#define max_intro_pending      Perl_max_intro_pending
+#define maxo                   Perl_maxo
+#define mem_collxfrm           Perl_mem_collxfrm
+#define mess                   Perl_mess
+#define mg_clear               Perl_mg_clear
+#define mg_copy                        Perl_mg_copy
+#define mg_find                        Perl_mg_find
+#define mg_free                        Perl_mg_free
+#define mg_get                 Perl_mg_get
+#define mg_len                 Perl_mg_len
+#define mg_magical             Perl_mg_magical
+#define mg_set                 Perl_mg_set
+#define min_intro_pending      Perl_min_intro_pending
+#define mod                    Perl_mod
+#define mod_amg                        Perl_mod_amg
+#define mod_ass_amg            Perl_mod_ass_amg
+#define modkids                        Perl_modkids
+#define moreswitches           Perl_moreswitches
+#define mstats                 Perl_mstats
+#define mult_amg               Perl_mult_amg
+#define mult_ass_amg           Perl_mult_ass_amg
+#define multi_close            Perl_multi_close
+#define multi_end              Perl_multi_end
+#define multi_open             Perl_multi_open
+#define multi_start            Perl_multi_start
+#define my                     Perl_my
+#define my_bcopy               Perl_my_bcopy
+#define my_bzero               Perl_my_bzero
+#define my_chsize              Perl_my_chsize
+#define my_exit                        Perl_my_exit
+#define my_htonl               Perl_my_htonl
+#define my_lstat               Perl_my_lstat
+#define my_memcmp              Perl_my_memcmp
+#define my_ntohl               Perl_my_ntohl
+#define my_pclose              Perl_my_pclose
+#define my_popen               Perl_my_popen
+#define my_setenv              Perl_my_setenv
+#define my_stat                        Perl_my_stat
+#define my_swap                        Perl_my_swap
+#define my_unexec              Perl_my_unexec
+#define na                     Perl_na
+#define ncmp_amg               Perl_ncmp_amg
+#define ne_amg                 Perl_ne_amg
+#define neg_amg                        Perl_neg_amg
+#define newANONHASH            Perl_newANONHASH
+#define newANONLIST            Perl_newANONLIST
+#define newANONSUB             Perl_newANONSUB
+#define newASSIGNOP            Perl_newASSIGNOP
+#define newAV                  Perl_newAV
+#define newAVREF               Perl_newAVREF
+#define newBINOP               Perl_newBINOP
+#define newCONDOP              Perl_newCONDOP
+#define newCVREF               Perl_newCVREF
+#define newFORM                        Perl_newFORM
+#define newFOROP               Perl_newFOROP
+#define newGVOP                        Perl_newGVOP
+#define newGVREF               Perl_newGVREF
+#define newGVgen               Perl_newGVgen
+#define newHV                  Perl_newHV
+#define newHVREF               Perl_newHVREF
+#define newIO                  Perl_newIO
+#define newLISTOP              Perl_newLISTOP
+#define newLOGOP               Perl_newLOGOP
+#define newLOOPEX              Perl_newLOOPEX
+#define newLOOPOP              Perl_newLOOPOP
+#define newNULLLIST            Perl_newNULLLIST
+#define newOP                  Perl_newOP
+#define newPMOP                        Perl_newPMOP
+#define newPROG                        Perl_newPROG
+#define newPVOP                        Perl_newPVOP
+#define newRANGE               Perl_newRANGE
+#define newRV                  Perl_newRV
+#define newSLICEOP             Perl_newSLICEOP
+#define newSTATEOP             Perl_newSTATEOP
+#define newSUB                 Perl_newSUB
+#define newSV                  Perl_newSV
+#define newSVOP                        Perl_newSVOP
+#define newSVREF               Perl_newSVREF
+#define newSViv                        Perl_newSViv
+#define newSVnv                        Perl_newSVnv
+#define newSVpv                        Perl_newSVpv
+#define newSVrv                        Perl_newSVrv
+#define newSVsv                        Perl_newSVsv
+#define newUNOP                        Perl_newUNOP
+#define newWHILEOP             Perl_newWHILEOP
+#define newXS                  Perl_newXS
+#define newXSUB                        Perl_newXSUB
+#define nextargv               Perl_nextargv
+#define nexttoke               Perl_nexttoke
+#define nexttype               Perl_nexttype
+#define nextval                        Perl_nextval
+#define ninstr                 Perl_ninstr
+#define no_aelem               Perl_no_aelem
+#define no_dir_func            Perl_no_dir_func
+#define no_fh_allowed          Perl_no_fh_allowed
+#define no_func                        Perl_no_func
+#define no_helem               Perl_no_helem
+#define no_mem                 Perl_no_mem
+#define no_modify              Perl_no_modify
+#define no_op                  Perl_no_op
+#define no_security            Perl_no_security
+#define no_sock_func           Perl_no_sock_func
+#define no_usym                        Perl_no_usym
+#define nointrp                        Perl_nointrp
+#define nomem                  Perl_nomem
+#define nomemok                        Perl_nomemok
+#define nomethod_amg           Perl_nomethod_amg
+#define not_amg                        Perl_not_amg
+#define numer_amg              Perl_numer_amg
+#define numeric_local          Perl_numeric_local
+#define numeric_name           Perl_numeric_name
+#define numeric_standard       Perl_numeric_standard
+#define oldbufptr              Perl_oldbufptr
+#define oldoldbufptr           Perl_oldoldbufptr
+#define oopsAV                 Perl_oopsAV
+#define oopsCV                 Perl_oopsCV
+#define oopsHV                 Perl_oopsHV
+#define op                     Perl_op
+#define op_desc                        Perl_op_desc
+#define op_free                        Perl_op_free
+#define op_name                        Perl_op_name
+#define op_seqmax              Perl_op_seqmax
+#define opargs                 Perl_opargs
+#define origalen               Perl_origalen
+#define origenviron            Perl_origenviron
+#define osname                 Perl_osname
+#define package                        Perl_package
+#define pad_alloc              Perl_pad_alloc
+#define pad_allocmy            Perl_pad_allocmy
+#define pad_findmy             Perl_pad_findmy
+#define pad_free               Perl_pad_free
+#define pad_leavemy            Perl_pad_leavemy
+#define pad_reset              Perl_pad_reset
+#define pad_sv                 Perl_pad_sv
+#define pad_swipe              Perl_pad_swipe
+#define padix                  Perl_padix
+#define patleave               Perl_patleave
+#define peep                   Perl_peep
+#define pidgone                        Perl_pidgone
+#define pmflag                 Perl_pmflag
+#define pmruntime              Perl_pmruntime
+#define pmtrans                        Perl_pmtrans
+#define pop_return             Perl_pop_return
+#define pop_scope              Perl_pop_scope
+#define pow_amg                        Perl_pow_amg
+#define pow_ass_amg            Perl_pow_ass_amg
+#define pp_aassign             Perl_pp_aassign
+#define pp_abs                 Perl_pp_abs
+#define pp_accept              Perl_pp_accept
+#define pp_add                 Perl_pp_add
+#define pp_aelem               Perl_pp_aelem
+#define pp_aelemfast           Perl_pp_aelemfast
+#define pp_alarm               Perl_pp_alarm
+#define pp_and                 Perl_pp_and
+#define pp_andassign           Perl_pp_andassign
+#define pp_anoncode            Perl_pp_anoncode
+#define pp_anonhash            Perl_pp_anonhash
+#define pp_anonlist            Perl_pp_anonlist
+#define pp_aslice              Perl_pp_aslice
+#define pp_atan2               Perl_pp_atan2
+#define pp_av2arylen           Perl_pp_av2arylen
+#define pp_backtick            Perl_pp_backtick
+#define pp_bind                        Perl_pp_bind
+#define pp_binmode             Perl_pp_binmode
+#define pp_bit_and             Perl_pp_bit_and
+#define pp_bit_or              Perl_pp_bit_or
+#define pp_bit_xor             Perl_pp_bit_xor
+#define pp_bless               Perl_pp_bless
+#define pp_caller              Perl_pp_caller
+#define pp_chdir               Perl_pp_chdir
+#define pp_chmod               Perl_pp_chmod
+#define pp_chomp               Perl_pp_chomp
+#define pp_chop                        Perl_pp_chop
+#define pp_chown               Perl_pp_chown
+#define pp_chr                 Perl_pp_chr
+#define pp_chroot              Perl_pp_chroot
+#define pp_close               Perl_pp_close
+#define pp_closedir            Perl_pp_closedir
+#define pp_complement          Perl_pp_complement
+#define pp_concat              Perl_pp_concat
+#define pp_cond_expr           Perl_pp_cond_expr
+#define pp_connect             Perl_pp_connect
+#define pp_const               Perl_pp_const
+#define pp_cos                 Perl_pp_cos
+#define pp_crypt               Perl_pp_crypt
+#define pp_cswitch             Perl_pp_cswitch
+#define pp_dbmclose            Perl_pp_dbmclose
+#define pp_dbmopen             Perl_pp_dbmopen
+#define pp_dbstate             Perl_pp_dbstate
+#define pp_defined             Perl_pp_defined
+#define pp_delete              Perl_pp_delete
+#define pp_die                 Perl_pp_die
+#define pp_divide              Perl_pp_divide
+#define pp_dofile              Perl_pp_dofile
+#define pp_dump                        Perl_pp_dump
+#define pp_each                        Perl_pp_each
+#define pp_egrent              Perl_pp_egrent
+#define pp_ehostent            Perl_pp_ehostent
+#define pp_enetent             Perl_pp_enetent
+#define pp_enter               Perl_pp_enter
+#define pp_entereval           Perl_pp_entereval
+#define pp_enteriter           Perl_pp_enteriter
+#define pp_enterloop           Perl_pp_enterloop
+#define pp_entersub            Perl_pp_entersub
+#define pp_entersubr           Perl_pp_entersubr
+#define pp_entertry            Perl_pp_entertry
+#define pp_enterwrite          Perl_pp_enterwrite
+#define pp_eof                 Perl_pp_eof
+#define pp_eprotoent           Perl_pp_eprotoent
+#define pp_epwent              Perl_pp_epwent
+#define pp_eq                  Perl_pp_eq
+#define pp_eservent            Perl_pp_eservent
+#define pp_evalonce            Perl_pp_evalonce
+#define pp_exec                        Perl_pp_exec
+#define pp_exists              Perl_pp_exists
+#define pp_exit                        Perl_pp_exit
+#define pp_exp                 Perl_pp_exp
+#define pp_fcntl               Perl_pp_fcntl
+#define pp_fileno              Perl_pp_fileno
+#define pp_flip                        Perl_pp_flip
+#define pp_flock               Perl_pp_flock
+#define pp_flop                        Perl_pp_flop
+#define pp_fork                        Perl_pp_fork
+#define pp_formline            Perl_pp_formline
+#define pp_ftatime             Perl_pp_ftatime
+#define pp_ftbinary            Perl_pp_ftbinary
+#define pp_ftblk               Perl_pp_ftblk
+#define pp_ftchr               Perl_pp_ftchr
+#define pp_ftctime             Perl_pp_ftctime
+#define pp_ftdir               Perl_pp_ftdir
+#define pp_fteexec             Perl_pp_fteexec
+#define pp_fteowned            Perl_pp_fteowned
+#define pp_fteread             Perl_pp_fteread
+#define pp_ftewrite            Perl_pp_ftewrite
+#define pp_ftfile              Perl_pp_ftfile
+#define pp_ftis                        Perl_pp_ftis
+#define pp_ftlink              Perl_pp_ftlink
+#define pp_ftmtime             Perl_pp_ftmtime
+#define pp_ftpipe              Perl_pp_ftpipe
+#define pp_ftrexec             Perl_pp_ftrexec
+#define pp_ftrowned            Perl_pp_ftrowned
+#define pp_ftrread             Perl_pp_ftrread
+#define pp_ftrwrite            Perl_pp_ftrwrite
+#define pp_ftsgid              Perl_pp_ftsgid
+#define pp_ftsize              Perl_pp_ftsize
+#define pp_ftsock              Perl_pp_ftsock
+#define pp_ftsuid              Perl_pp_ftsuid
+#define pp_ftsvtx              Perl_pp_ftsvtx
+#define pp_fttext              Perl_pp_fttext
+#define pp_fttty               Perl_pp_fttty
+#define pp_ftzero              Perl_pp_ftzero
+#define pp_ge                  Perl_pp_ge
+#define pp_gelem               Perl_pp_gelem
+#define pp_getc                        Perl_pp_getc
+#define pp_getlogin            Perl_pp_getlogin
+#define pp_getpeername         Perl_pp_getpeername
+#define pp_getpgrp             Perl_pp_getpgrp
+#define pp_getppid             Perl_pp_getppid
+#define pp_getpriority         Perl_pp_getpriority
+#define pp_getsockname         Perl_pp_getsockname
+#define pp_ggrent              Perl_pp_ggrent
+#define pp_ggrgid              Perl_pp_ggrgid
+#define pp_ggrnam              Perl_pp_ggrnam
+#define pp_ghbyaddr            Perl_pp_ghbyaddr
+#define pp_ghbyname            Perl_pp_ghbyname
+#define pp_ghostent            Perl_pp_ghostent
+#define pp_glob                        Perl_pp_glob
+#define pp_gmtime              Perl_pp_gmtime
+#define pp_gnbyaddr            Perl_pp_gnbyaddr
+#define pp_gnbyname            Perl_pp_gnbyname
+#define pp_gnetent             Perl_pp_gnetent
+#define pp_goto                        Perl_pp_goto
+#define pp_gpbyname            Perl_pp_gpbyname
+#define pp_gpbynumber          Perl_pp_gpbynumber
+#define pp_gprotoent           Perl_pp_gprotoent
+#define pp_gpwent              Perl_pp_gpwent
+#define pp_gpwnam              Perl_pp_gpwnam
+#define pp_gpwuid              Perl_pp_gpwuid
+#define pp_grepstart           Perl_pp_grepstart
+#define pp_grepwhile           Perl_pp_grepwhile
+#define pp_gsbyname            Perl_pp_gsbyname
+#define pp_gsbyport            Perl_pp_gsbyport
+#define pp_gservent            Perl_pp_gservent
+#define pp_gsockopt            Perl_pp_gsockopt
+#define pp_gt                  Perl_pp_gt
+#define pp_gv                  Perl_pp_gv
+#define pp_gvsv                        Perl_pp_gvsv
+#define pp_helem               Perl_pp_helem
+#define pp_hex                 Perl_pp_hex
+#define pp_hslice              Perl_pp_hslice
+#define pp_i_add               Perl_pp_i_add
+#define pp_i_divide            Perl_pp_i_divide
+#define pp_i_eq                        Perl_pp_i_eq
+#define pp_i_ge                        Perl_pp_i_ge
+#define pp_i_gt                        Perl_pp_i_gt
+#define pp_i_le                        Perl_pp_i_le
+#define pp_i_lt                        Perl_pp_i_lt
+#define pp_i_modulo            Perl_pp_i_modulo
+#define pp_i_multiply          Perl_pp_i_multiply
+#define pp_i_ncmp              Perl_pp_i_ncmp
+#define pp_i_ne                        Perl_pp_i_ne
+#define pp_i_negate            Perl_pp_i_negate
+#define pp_i_subtract          Perl_pp_i_subtract
+#define pp_index               Perl_pp_index
+#define pp_indread             Perl_pp_indread
+#define pp_int                 Perl_pp_int
+#define pp_interp              Perl_pp_interp
+#define pp_ioctl               Perl_pp_ioctl
+#define pp_iter                        Perl_pp_iter
+#define pp_join                        Perl_pp_join
+#define pp_keys                        Perl_pp_keys
+#define pp_kill                        Perl_pp_kill
+#define pp_last                        Perl_pp_last
+#define pp_lc                  Perl_pp_lc
+#define pp_lcfirst             Perl_pp_lcfirst
+#define pp_le                  Perl_pp_le
+#define pp_leave               Perl_pp_leave
+#define pp_leaveeval           Perl_pp_leaveeval
+#define pp_leaveloop           Perl_pp_leaveloop
+#define pp_leavesub            Perl_pp_leavesub
+#define pp_leavetry            Perl_pp_leavetry
+#define pp_leavewrite          Perl_pp_leavewrite
+#define pp_left_shift          Perl_pp_left_shift
+#define pp_length              Perl_pp_length
+#define pp_lineseq             Perl_pp_lineseq
+#define pp_link                        Perl_pp_link
+#define pp_list                        Perl_pp_list
+#define pp_listen              Perl_pp_listen
+#define pp_localtime           Perl_pp_localtime
+#define pp_log                 Perl_pp_log
+#define pp_lslice              Perl_pp_lslice
+#define pp_lstat               Perl_pp_lstat
+#define pp_lt                  Perl_pp_lt
+#define pp_map                 Perl_pp_map
+#define pp_mapstart            Perl_pp_mapstart
+#define pp_mapwhile            Perl_pp_mapwhile
+#define pp_match               Perl_pp_match
+#define pp_method              Perl_pp_method
+#define pp_mkdir               Perl_pp_mkdir
+#define pp_modulo              Perl_pp_modulo
+#define pp_msgctl              Perl_pp_msgctl
+#define pp_msgget              Perl_pp_msgget
+#define pp_msgrcv              Perl_pp_msgrcv
+#define pp_msgsnd              Perl_pp_msgsnd
+#define pp_multiply            Perl_pp_multiply
+#define pp_ncmp                        Perl_pp_ncmp
+#define pp_ne                  Perl_pp_ne
+#define pp_negate              Perl_pp_negate
+#define pp_next                        Perl_pp_next
+#define pp_nextstate           Perl_pp_nextstate
+#define pp_not                 Perl_pp_not
+#define pp_nswitch             Perl_pp_nswitch
+#define pp_null                        Perl_pp_null
+#define pp_oct                 Perl_pp_oct
+#define pp_open                        Perl_pp_open
+#define pp_open_dir            Perl_pp_open_dir
+#define pp_or                  Perl_pp_or
+#define pp_orassign            Perl_pp_orassign
+#define pp_ord                 Perl_pp_ord
+#define pp_pack                        Perl_pp_pack
+#define pp_padany              Perl_pp_padany
+#define pp_padav               Perl_pp_padav
+#define pp_padhv               Perl_pp_padhv
+#define pp_padsv               Perl_pp_padsv
+#define pp_pipe_op             Perl_pp_pipe_op
+#define pp_pop                 Perl_pp_pop
+#define pp_pos                 Perl_pp_pos
+#define pp_postdec             Perl_pp_postdec
+#define pp_postinc             Perl_pp_postinc
+#define pp_pow                 Perl_pp_pow
+#define pp_predec              Perl_pp_predec
+#define pp_preinc              Perl_pp_preinc
+#define pp_print               Perl_pp_print
+#define pp_prototype           Perl_pp_prototype
+#define pp_prtf                        Perl_pp_prtf
+#define pp_push                        Perl_pp_push
+#define pp_pushmark            Perl_pp_pushmark
+#define pp_pushre              Perl_pp_pushre
+#define pp_quotemeta           Perl_pp_quotemeta
+#define pp_rand                        Perl_pp_rand
+#define pp_range               Perl_pp_range
+#define pp_rcatline            Perl_pp_rcatline
+#define pp_read                        Perl_pp_read
+#define pp_readdir             Perl_pp_readdir
+#define pp_readline            Perl_pp_readline
+#define pp_readlink            Perl_pp_readlink
+#define pp_recv                        Perl_pp_recv
+#define pp_redo                        Perl_pp_redo
+#define pp_ref                 Perl_pp_ref
+#define pp_refgen              Perl_pp_refgen
+#define pp_regcmaybe           Perl_pp_regcmaybe
+#define pp_regcomp             Perl_pp_regcomp
+#define pp_rename              Perl_pp_rename
+#define pp_repeat              Perl_pp_repeat
+#define pp_require             Perl_pp_require
+#define pp_reset               Perl_pp_reset
+#define pp_return              Perl_pp_return
+#define pp_reverse             Perl_pp_reverse
+#define pp_rewinddir           Perl_pp_rewinddir
+#define pp_right_shift         Perl_pp_right_shift
+#define pp_rindex              Perl_pp_rindex
+#define pp_rmdir               Perl_pp_rmdir
+#define pp_rv2av               Perl_pp_rv2av
+#define pp_rv2cv               Perl_pp_rv2cv
+#define pp_rv2gv               Perl_pp_rv2gv
+#define pp_rv2hv               Perl_pp_rv2hv
+#define pp_rv2sv               Perl_pp_rv2sv
+#define pp_sassign             Perl_pp_sassign
+#define pp_scalar              Perl_pp_scalar
+#define pp_schomp              Perl_pp_schomp
+#define pp_schop               Perl_pp_schop
+#define pp_scmp                        Perl_pp_scmp
+#define pp_scope               Perl_pp_scope
+#define pp_seek                        Perl_pp_seek
+#define pp_seekdir             Perl_pp_seekdir
+#define pp_select              Perl_pp_select
+#define pp_semctl              Perl_pp_semctl
+#define pp_semget              Perl_pp_semget
+#define pp_semop               Perl_pp_semop
+#define pp_send                        Perl_pp_send
+#define pp_seq                 Perl_pp_seq
+#define pp_setpgrp             Perl_pp_setpgrp
+#define pp_setpriority         Perl_pp_setpriority
+#define pp_sge                 Perl_pp_sge
+#define pp_sgrent              Perl_pp_sgrent
+#define pp_sgt                 Perl_pp_sgt
+#define pp_shift               Perl_pp_shift
+#define pp_shmctl              Perl_pp_shmctl
+#define pp_shmget              Perl_pp_shmget
+#define pp_shmread             Perl_pp_shmread
+#define pp_shmwrite            Perl_pp_shmwrite
+#define pp_shostent            Perl_pp_shostent
+#define pp_shutdown            Perl_pp_shutdown
+#define pp_sin                 Perl_pp_sin
+#define pp_sle                 Perl_pp_sle
+#define pp_sleep               Perl_pp_sleep
+#define pp_slt                 Perl_pp_slt
+#define pp_sne                 Perl_pp_sne
+#define pp_snetent             Perl_pp_snetent
+#define pp_socket              Perl_pp_socket
+#define pp_sockpair            Perl_pp_sockpair
+#define pp_sort                        Perl_pp_sort
+#define pp_splice              Perl_pp_splice
+#define pp_split               Perl_pp_split
+#define pp_sprintf             Perl_pp_sprintf
+#define pp_sprotoent           Perl_pp_sprotoent
+#define pp_spwent              Perl_pp_spwent
+#define pp_sqrt                        Perl_pp_sqrt
+#define pp_srand               Perl_pp_srand
+#define pp_srefgen             Perl_pp_srefgen
+#define pp_sselect             Perl_pp_sselect
+#define pp_sservent            Perl_pp_sservent
+#define pp_ssockopt            Perl_pp_ssockopt
+#define pp_stat                        Perl_pp_stat
+#define pp_stringify           Perl_pp_stringify
+#define pp_stub                        Perl_pp_stub
+#define pp_study               Perl_pp_study
+#define pp_subst               Perl_pp_subst
+#define pp_substcont           Perl_pp_substcont
+#define pp_substr              Perl_pp_substr
+#define pp_subtract            Perl_pp_subtract
+#define pp_symlink             Perl_pp_symlink
+#define pp_syscall             Perl_pp_syscall
+#define pp_sysopen             Perl_pp_sysopen
+#define pp_sysread             Perl_pp_sysread
+#define pp_system              Perl_pp_system
+#define pp_syswrite            Perl_pp_syswrite
+#define pp_tell                        Perl_pp_tell
+#define pp_telldir             Perl_pp_telldir
+#define pp_tie                 Perl_pp_tie
+#define pp_tied                        Perl_pp_tied
+#define pp_time                        Perl_pp_time
+#define pp_tms                 Perl_pp_tms
+#define pp_trans               Perl_pp_trans
+#define pp_truncate            Perl_pp_truncate
+#define pp_uc                  Perl_pp_uc
+#define pp_ucfirst             Perl_pp_ucfirst
+#define pp_umask               Perl_pp_umask
+#define pp_undef               Perl_pp_undef
+#define pp_unlink              Perl_pp_unlink
+#define pp_unpack              Perl_pp_unpack
+#define pp_unshift             Perl_pp_unshift
+#define pp_unstack             Perl_pp_unstack
+#define pp_untie               Perl_pp_untie
+#define pp_utime               Perl_pp_utime
+#define pp_values              Perl_pp_values
+#define pp_vec                 Perl_pp_vec
+#define pp_wait                        Perl_pp_wait
+#define pp_waitpid             Perl_pp_waitpid
+#define pp_wantarray           Perl_pp_wantarray
+#define pp_warn                        Perl_pp_warn
+#define pp_xor                 Perl_pp_xor
+#define ppaddr                 Perl_ppaddr
+#define pregcomp               Perl_pregcomp
+#define pregexec               Perl_pregexec
+#define pregfree               Perl_pregfree
+#define prepend_elem           Perl_prepend_elem
+#define profiledata            Perl_profiledata
+#define provide_ref            Perl_provide_ref
+#define psig_name              Perl_psig_name
+#define psig_ptr               Perl_psig_ptr
+#define push_return            Perl_push_return
+#define push_scope             Perl_push_scope
+#define q                      Perl_q
+#define qrt_amg                        Perl_qrt_amg
+#define rcsid                  Perl_rcsid
+#define reall_srchlen          Perl_reall_srchlen
+#define ref                    Perl_ref
+#define refkids                        Perl_refkids
+#define regarglen              Perl_regarglen
+#define regbol                 Perl_regbol
+#define regcode                        Perl_regcode
+#define regdummy               Perl_regdummy
+#define regdump                        Perl_regdump
+#define regendp                        Perl_regendp
+#define regeol                 Perl_regeol
+#define reginput               Perl_reginput
+#define regkind                        Perl_regkind
+#define reglastparen           Perl_reglastparen
+#define regmyendp              Perl_regmyendp
+#define regmyp_size            Perl_regmyp_size
+#define regmystartp            Perl_regmystartp
+#define regnarrate             Perl_regnarrate
+#define regnaughty             Perl_regnaughty
+#define regnext                        Perl_regnext
+#define regnpar                        Perl_regnpar
+#define regparse               Perl_regparse
+#define regprecomp             Perl_regprecomp
+#define regprev                        Perl_regprev
+#define regprop                        Perl_regprop
+#define regsawback             Perl_regsawback
+#define regsize                        Perl_regsize
+#define regstartp              Perl_regstartp
+#define regtill                        Perl_regtill
+#define regxend                        Perl_regxend
+#define repeat_amg             Perl_repeat_amg
+#define repeat_ass_amg         Perl_repeat_ass_amg
+#define repeatcpy              Perl_repeatcpy
+#define retstack               Perl_retstack
+#define retstack_ix            Perl_retstack_ix
+#define retstack_max           Perl_retstack_max
+#define rninstr                        Perl_rninstr
+#define rsfp                   Perl_rsfp
+#define rsfp_filters           Perl_rsfp_filters
+#define rshift_amg             Perl_rshift_amg
+#define rshift_ass_amg         Perl_rshift_ass_amg
+#define rsignal                        Perl_rsignal
+#define rsignal_restore                Perl_rsignal_restore
+#define rsignal_save           Perl_rsignal_save
+#define rsignal_state          Perl_rsignal_state
+#define runops                 Perl_runops
+#define same_dirent            Perl_same_dirent
+#define save_I16               Perl_save_I16
+#define save_I32               Perl_save_I32
+#define save_aptr              Perl_save_aptr
+#define save_ary               Perl_save_ary
+#define save_clearsv           Perl_save_clearsv
+#define save_delete            Perl_save_delete
+#define save_destructor                Perl_save_destructor
+#define save_freeop            Perl_save_freeop
+#define save_freepv            Perl_save_freepv
+#define save_freesv            Perl_save_freesv
+#define save_gp                        Perl_save_gp
+#define save_hash              Perl_save_hash
+#define save_hptr              Perl_save_hptr
+#define save_int               Perl_save_int
+#define save_item              Perl_save_item
+#define save_list              Perl_save_list
+#define save_long              Perl_save_long
+#define save_nogv              Perl_save_nogv
+#define save_pptr              Perl_save_pptr
+#define save_scalar            Perl_save_scalar
+#define save_sptr              Perl_save_sptr
+#define save_svref             Perl_save_svref
+#define savepv                 Perl_savepv
+#define savepvn                        Perl_savepvn
+#define savestack              Perl_savestack
+#define savestack_grow         Perl_savestack_grow
+#define savestack_ix           Perl_savestack_ix
+#define savestack_max          Perl_savestack_max
+#define saw_return             Perl_saw_return
+#define sawparens              Perl_sawparens
+#define scalar                 Perl_scalar
+#define scalarkids             Perl_scalarkids
+#define scalarseq              Perl_scalarseq
+#define scalarvoid             Perl_scalarvoid
+#define scan_const             Perl_scan_const
+#define scan_formline          Perl_scan_formline
+#define scan_heredoc           Perl_scan_heredoc
+#define scan_hex               Perl_scan_hex
+#define scan_ident             Perl_scan_ident
 #define scan_inputsymbol       Perl_scan_inputsymbol
-#define scan_num       Perl_scan_num
-#define scan_oct       Perl_scan_oct
-#define scan_pat       Perl_scan_pat
-#define scan_prefix    Perl_scan_prefix
-#define scan_str       Perl_scan_str
-#define scan_subst     Perl_scan_subst
-#define scan_trans     Perl_scan_trans
-#define scan_word      Perl_scan_word
-#define scope          Perl_scope
-#define screaminstr    Perl_screaminstr
-#define setdefout      Perl_setdefout
-#define setenv_getix   Perl_setenv_getix
-#define share_hek      Perl_share_hek
-#define sharepvn       Perl_sharepvn
-#define sighandler     Perl_sighandler
-#define skipspace      Perl_skipspace
-#define stack_grow     Perl_stack_grow
-#define start_subparse Perl_start_subparse
-#define sublex_done    Perl_sublex_done
-#define sublex_start   Perl_sublex_start
-#define sv_2bool       Perl_sv_2bool
-#define sv_2cv         Perl_sv_2cv
-#define sv_2io         Perl_sv_2io
-#define sv_2iv         Perl_sv_2iv
-#define sv_2mortal     Perl_sv_2mortal
-#define sv_2nv         Perl_sv_2nv
-#define sv_2pv         Perl_sv_2pv
-#define sv_2uv         Perl_sv_2uv
-#define sv_add_arena   Perl_sv_add_arena
-#define sv_backoff     Perl_sv_backoff
-#define sv_bless       Perl_sv_bless
-#define sv_catpv       Perl_sv_catpv
-#define sv_catpvn      Perl_sv_catpvn
-#define sv_catsv       Perl_sv_catsv
-#define sv_chop                Perl_sv_chop
-#define sv_clean_all   Perl_sv_clean_all
-#define sv_clean_objs  Perl_sv_clean_objs
-#define sv_clear       Perl_sv_clear
-#define sv_cmp         Perl_sv_cmp
-#define sv_cmp_locale  Perl_sv_cmp_locale
-#define sv_collxfrm    Perl_sv_collxfrm
-#define sv_dec         Perl_sv_dec
-#define sv_derived_from        Perl_sv_derived_from
-#define sv_dump                Perl_sv_dump
-#define sv_eq          Perl_sv_eq
-#define sv_free                Perl_sv_free
-#define sv_free_arenas Perl_sv_free_arenas
-#define sv_gets                Perl_sv_gets
-#define sv_grow                Perl_sv_grow
-#define sv_inc         Perl_sv_inc
-#define sv_insert      Perl_sv_insert
-#define sv_isa         Perl_sv_isa
-#define sv_isobject    Perl_sv_isobject
-#define sv_len         Perl_sv_len
-#define sv_magic       Perl_sv_magic
-#define sv_mortalcopy  Perl_sv_mortalcopy
-#define sv_newmortal   Perl_sv_newmortal
-#define sv_newref      Perl_sv_newref
-#define sv_peek                Perl_sv_peek
-#define sv_pvn         Perl_sv_pvn
-#define sv_pvn_force   Perl_sv_pvn_force
-#define sv_ref         Perl_sv_ref
-#define sv_reftype     Perl_sv_reftype
-#define sv_replace     Perl_sv_replace
-#define sv_report_used Perl_sv_report_used
-#define sv_reset       Perl_sv_reset
-#define sv_setiv       Perl_sv_setiv
-#define sv_setnv       Perl_sv_setnv
-#define sv_setptrobj   Perl_sv_setptrobj
-#define sv_setpv       Perl_sv_setpv
-#define sv_setpvn      Perl_sv_setpvn
-#define sv_setref_iv   Perl_sv_setref_iv
-#define sv_setref_nv   Perl_sv_setref_nv
-#define sv_setref_pv   Perl_sv_setref_pv
-#define sv_setref_pvn  Perl_sv_setref_pvn
-#define sv_setsv       Perl_sv_setsv
-#define sv_setuv       Perl_sv_setuv
-#define sv_taint       Perl_sv_taint
-#define sv_tainted     Perl_sv_tainted
-#define sv_unmagic     Perl_sv_unmagic
-#define sv_unref       Perl_sv_unref
-#define sv_untaint     Perl_sv_untaint
-#define sv_upgrade     Perl_sv_upgrade
-#define sv_usepvn      Perl_sv_usepvn
-#define taint_env      Perl_taint_env
-#define taint_proper   Perl_taint_proper
+#define scan_num               Perl_scan_num
+#define scan_oct               Perl_scan_oct
+#define scan_pat               Perl_scan_pat
+#define scan_prefix            Perl_scan_prefix
+#define scan_str               Perl_scan_str
+#define scan_subst             Perl_scan_subst
+#define scan_trans             Perl_scan_trans
+#define scan_word              Perl_scan_word
+#define scmp_amg               Perl_scmp_amg
+#define scope                  Perl_scope
+#define scopestack             Perl_scopestack
+#define scopestack_ix          Perl_scopestack_ix
+#define scopestack_max         Perl_scopestack_max
+#define screaminstr            Perl_screaminstr
+#define scrgv                  Perl_scrgv
+#define seq_amg                        Perl_seq_amg
+#define setdefout              Perl_setdefout
+#define setenv_getix           Perl_setenv_getix
+#define sge_amg                        Perl_sge_amg
+#define sgt_amg                        Perl_sgt_amg
+#define sh_path                        Perl_sh_path
+#define share_hek              Perl_share_hek
+#define sharepvn               Perl_sharepvn
+#define sig_name               Perl_sig_name
+#define sig_num                        Perl_sig_num
+#define sighandler             Perl_sighandler
+#define simple                 Perl_simple
+#define sin_amg                        Perl_sin_amg
+#define skipspace              Perl_skipspace
+#define sle_amg                        Perl_sle_amg
+#define slt_amg                        Perl_slt_amg
+#define sne_amg                        Perl_sne_amg
+#define stack_base             Perl_stack_base
+#define stack_grow             Perl_stack_grow
+#define stack_max              Perl_stack_max
+#define stack_sp               Perl_stack_sp
+#define start_subparse         Perl_start_subparse
+#define statbuf                        Perl_statbuf
+#define string_amg             Perl_string_amg
+#define sub_generation         Perl_sub_generation
+#define sublex_done            Perl_sublex_done
+#define sublex_start           Perl_sublex_start
+#define subline                        Perl_subline
+#define subname                        Perl_subname
+#define subtr_amg              Perl_subtr_amg
+#define subtr_ass_amg          Perl_subtr_ass_amg
+#define sv_2bool               Perl_sv_2bool
+#define sv_2cv                 Perl_sv_2cv
+#define sv_2io                 Perl_sv_2io
+#define sv_2iv                 Perl_sv_2iv
+#define sv_2mortal             Perl_sv_2mortal
+#define sv_2nv                 Perl_sv_2nv
+#define sv_2pv                 Perl_sv_2pv
+#define sv_2uv                 Perl_sv_2uv
+#define sv_add_arena           Perl_sv_add_arena
+#define sv_backoff             Perl_sv_backoff
+#define sv_bless               Perl_sv_bless
+#define sv_catpv               Perl_sv_catpv
+#define sv_catpvn              Perl_sv_catpvn
+#define sv_catsv               Perl_sv_catsv
+#define sv_chop                        Perl_sv_chop
+#define sv_clean_all           Perl_sv_clean_all
+#define sv_clean_objs          Perl_sv_clean_objs
+#define sv_clear               Perl_sv_clear
+#define sv_cmp                 Perl_sv_cmp
+#define sv_cmp_locale          Perl_sv_cmp_locale
+#define sv_collxfrm            Perl_sv_collxfrm
+#define sv_dec                 Perl_sv_dec
+#define sv_derived_from                Perl_sv_derived_from
+#define sv_dump                        Perl_sv_dump
+#define sv_eq                  Perl_sv_eq
+#define sv_free                        Perl_sv_free
+#define sv_free_arenas         Perl_sv_free_arenas
+#define sv_gets                        Perl_sv_gets
+#define sv_grow                        Perl_sv_grow
+#define sv_inc                 Perl_sv_inc
+#define sv_insert              Perl_sv_insert
+#define sv_isa                 Perl_sv_isa
+#define sv_isobject            Perl_sv_isobject
+#define sv_len                 Perl_sv_len
+#define sv_magic               Perl_sv_magic
+#define sv_mortalcopy          Perl_sv_mortalcopy
+#define sv_newmortal           Perl_sv_newmortal
+#define sv_newref              Perl_sv_newref
+#define sv_no                  Perl_sv_no
+#define sv_peek                        Perl_sv_peek
+#define sv_pvn_force           Perl_sv_pvn_force
+#define sv_ref                 Perl_sv_ref
+#define sv_reftype             Perl_sv_reftype
+#define sv_replace             Perl_sv_replace
+#define sv_report_used         Perl_sv_report_used
+#define sv_reset               Perl_sv_reset
+#define sv_setiv               Perl_sv_setiv
+#define sv_setnv               Perl_sv_setnv
+#define sv_setptrobj           Perl_sv_setptrobj
+#define sv_setpv               Perl_sv_setpv
+#define sv_setpvn              Perl_sv_setpvn
+#define sv_setref_iv           Perl_sv_setref_iv
+#define sv_setref_nv           Perl_sv_setref_nv
+#define sv_setref_pv           Perl_sv_setref_pv
+#define sv_setref_pvn          Perl_sv_setref_pvn
+#define sv_setsv               Perl_sv_setsv
+#define sv_setuv               Perl_sv_setuv
+#define sv_taint               Perl_sv_taint
+#define sv_tainted             Perl_sv_tainted
+#define sv_undef               Perl_sv_undef
+#define sv_unmagic             Perl_sv_unmagic
+#define sv_unref               Perl_sv_unref
+#define sv_untaint             Perl_sv_untaint
+#define sv_upgrade             Perl_sv_upgrade
+#define sv_usepvn              Perl_sv_usepvn
+#define sv_yes                 Perl_sv_yes
+#define taint_env              Perl_taint_env
+#define taint_proper           Perl_taint_proper
+#define thisexpr               Perl_thisexpr
+#define timesbuf               Perl_timesbuf
+#define tokenbuf               Perl_tokenbuf
 #define too_few_arguments      Perl_too_few_arguments
 #define too_many_arguments     Perl_too_many_arguments
-#define unlnk          Perl_unlnk
-#define unshare_hek    Perl_unshare_hek
-#define unsharepvn     Perl_unsharepvn
-#define utilize                Perl_utilize
-#define wait4pid       Perl_wait4pid
-#define warn           Perl_warn
-#define watch          Perl_watch
-#define whichsig       Perl_whichsig
-#define xiv_arenaroot  Perl_xiv_arenaroot
-#define xiv_root       Perl_xiv_root
-#define xnv_root       Perl_xnv_root
-#define xpv_root       Perl_xpv_root
-#define xrv_root       Perl_xrv_root
-#define yyerror                Perl_yyerror
-#define yydestruct     Perl_yydestruct
-#define yylex          Perl_yylex
-#define yyparse                Perl_yyparse
-#define yywarn         Perl_yywarn
+#define uid                    Perl_uid
+#define unlnk                  Perl_unlnk
+#define unshare_hek            Perl_unshare_hek
+#define unsharepvn             Perl_unsharepvn
+#define utilize                        Perl_utilize
+#define varies                 Perl_varies
+#define vert                   Perl_vert
+#define vtbl_amagic            Perl_vtbl_amagic
+#define vtbl_amagicelem                Perl_vtbl_amagicelem
+#define vtbl_arylen            Perl_vtbl_arylen
+#define vtbl_bm                        Perl_vtbl_bm
+#define vtbl_collxfrm          Perl_vtbl_collxfrm
+#define vtbl_dbline            Perl_vtbl_dbline
+#define vtbl_env               Perl_vtbl_env
+#define vtbl_envelem           Perl_vtbl_envelem
+#define vtbl_fm                        Perl_vtbl_fm
+#define vtbl_glob              Perl_vtbl_glob
+#define vtbl_isa               Perl_vtbl_isa
+#define vtbl_isaelem           Perl_vtbl_isaelem
+#define vtbl_mglob             Perl_vtbl_mglob
+#define vtbl_nkeys             Perl_vtbl_nkeys
+#define vtbl_pack              Perl_vtbl_pack
+#define vtbl_packelem          Perl_vtbl_packelem
+#define vtbl_pos               Perl_vtbl_pos
+#define vtbl_sig               Perl_vtbl_sig
+#define vtbl_sigelem           Perl_vtbl_sigelem
+#define vtbl_substr            Perl_vtbl_substr
+#define vtbl_sv                        Perl_vtbl_sv
+#define vtbl_taint             Perl_vtbl_taint
+#define vtbl_uvar              Perl_vtbl_uvar
+#define vtbl_vec               Perl_vtbl_vec
+#define wait4pid               Perl_wait4pid
+#define warn                   Perl_warn
+#define warn_nl                        Perl_warn_nl
+#define warn_nosemi            Perl_warn_nosemi
+#define warn_reserved          Perl_warn_reserved
+#define watch                  Perl_watch
+#define watchaddr              Perl_watchaddr
+#define watchok                        Perl_watchok
+#define whichsig               Perl_whichsig
+#define xiv_arenaroot          Perl_xiv_arenaroot
+#define xiv_root               Perl_xiv_root
+#define xnv_root               Perl_xnv_root
+#define xpv_root               Perl_xpv_root
+#define xrv_root               Perl_xrv_root
+#define yychar                 Perl_yychar
+#define yycheck                        Perl_yycheck
+#define yydebug                        Perl_yydebug
+#define yydefred               Perl_yydefred
+#define yydgoto                        Perl_yydgoto
+#define yyerrflag              Perl_yyerrflag
+#define yyerror                        Perl_yyerror
+#define yygindex               Perl_yygindex
+#define yylen                  Perl_yylen
+#define yylex                  Perl_yylex
+#define yylhs                  Perl_yylhs
+#define yylval                 Perl_yylval
+#define yyname                 Perl_yyname
+#define yynerrs                        Perl_yynerrs
+#define yyparse                        Perl_yyparse
+#define yyrindex               Perl_yyrindex
+#define yyrule                 Perl_yyrule
+#define yysindex               Perl_yysindex
+#define yytable                        Perl_yytable
+#define yyval                  Perl_yyval
+#define yywarn                 Perl_yywarn
+
+/* Hide global symbols that 5.003 revealed? */
+
+#ifndef BINCOMPAT3
+
+#define Error                  Perl_Error
+#define SvIV                   Perl_SvIV
+#define SvNV                   Perl_SvNV
+#define SvTRUE                 Perl_SvTRUE
+#define SvUV                   Perl_SvUV
+#define block_type             Perl_block_type
+#define boot_core_UNIVERSAL    Perl_boot_core_UNIVERSAL
+#define comppad_name_floor     Perl_comppad_name_floor
+#define debug                  Perl_debug
+#define do_undump              Perl_do_undump
+#define nice_chunk             Perl_nice_chunk
+#define nice_chunk_size                Perl_nice_chunk_size
+#define no_myglob              Perl_no_myglob
+#define no_symref              Perl_no_symref
+#define no_wrongref            Perl_no_wrongref
+#define pad_reset_pending      Perl_pad_reset_pending
+#define padix_floor            Perl_padix_floor
+#define regflags               Perl_regflags
+#define safecalloc             Perl_safecalloc
+#define safefree               Perl_safefree
+#define safemalloc             Perl_safemalloc
+#define saferealloc            Perl_saferealloc
+#define safexcalloc            Perl_safexcalloc
+#define safexfree              Perl_safexfree
+#define safexmalloc            Perl_safexmalloc
+#define safexrealloc           Perl_safexrealloc
+#define save_iv                        Perl_save_iv
+#define sv_pvn                 Perl_sv_pvn
+#define warn_uninit            Perl_warn_uninit
+#define yydestruct             Perl_yydestruct
+
+#endif /* !BINCOMPAT3 */
 
 #endif /* EMBED */
 
-/* Put interpreter specific symbols into a struct? */
+/* Put interpreter-specific symbols into a struct? */
 
 #ifdef MULTIPLICITY
 
-#define Argv           (curinterp->IArgv)
-#define Cmd            (curinterp->ICmd)
-#define DBgv           (curinterp->IDBgv)
-#define DBline         (curinterp->IDBline)
-#define DBsignal       (curinterp->IDBsignal)
-#define DBsingle       (curinterp->IDBsingle)
-#define DBsub          (curinterp->IDBsub)
-#define DBtrace                (curinterp->IDBtrace)
-#define allgvs         (curinterp->Iallgvs)
-#define ampergv                (curinterp->Iampergv)
-#define argvgv         (curinterp->Iargvgv)
-#define argvoutgv      (curinterp->Iargvoutgv)
-#define basetime       (curinterp->Ibasetime)
-#define beginav                (curinterp->Ibeginav)
-#define bodytarget     (curinterp->Ibodytarget)
-#define cddir          (curinterp->Icddir)
-#define chopset                (curinterp->Ichopset)
-#define copline                (curinterp->Icopline)
-#define curblock       (curinterp->Icurblock)
-#define curcop         (curinterp->Icurcop)
-#define curcopdb       (curinterp->Icurcopdb)
-#define curcsv         (curinterp->Icurcsv)
-#define curpm          (curinterp->Icurpm)
-#define curstack       (curinterp->Icurstack)
-#define curstash       (curinterp->Icurstash)
-#define curstname      (curinterp->Icurstname)
-#define cxstack                (curinterp->Icxstack)
-#define cxstack_ix     (curinterp->Icxstack_ix)
-#define cxstack_max    (curinterp->Icxstack_max)
-#define dbargs         (curinterp->Idbargs)
-#define debdelim       (curinterp->Idebdelim)
-#define debname                (curinterp->Idebname)
-#define debstash       (curinterp->Idebstash)
-#define defgv          (curinterp->Idefgv)
-#define defoutgv       (curinterp->Idefoutgv)
-#define defstash       (curinterp->Idefstash)
-#define delaymagic     (curinterp->Idelaymagic)
-#define diehook                (curinterp->Idiehook)
-#define dirty          (curinterp->Idirty)
-#define dlevel         (curinterp->Idlevel)
-#define dlmax          (curinterp->Idlmax)
-#define doextract      (curinterp->Idoextract)
-#define doswitches     (curinterp->Idoswitches)
-#define dowarn         (curinterp->Idowarn)
-#define dumplvl                (curinterp->Idumplvl)
-#define e_fp           (curinterp->Ie_fp)
-#define e_tmpname      (curinterp->Ie_tmpname)
-#define endav          (curinterp->Iendav)
-#define envgv          (curinterp->Ienvgv)
-#define errgv          (curinterp->Ierrgv)
-#define eval_root      (curinterp->Ieval_root)
-#define eval_start     (curinterp->Ieval_start)
-#define fdpid          (curinterp->Ifdpid)
-#define filemode       (curinterp->Ifilemode)
-#define firstgv                (curinterp->Ifirstgv)
-#define forkprocess    (curinterp->Iforkprocess)
-#define formfeed       (curinterp->Iformfeed)
-#define formtarget     (curinterp->Iformtarget)
-#define gensym         (curinterp->Igensym)
-#define in_eval                (curinterp->Iin_eval)
-#define incgv          (curinterp->Iincgv)
-#define inplace                (curinterp->Iinplace)
-#define last_in_gv     (curinterp->Ilast_in_gv)
-#define lastfd         (curinterp->Ilastfd)
-#define lastretstr     (curinterp->Ilastretstr)
-#define lastscream     (curinterp->Ilastscream)
-#define lastsize       (curinterp->Ilastsize)
-#define lastspbase     (curinterp->Ilastspbase)
-#define laststatval    (curinterp->Ilaststatval)
-#define laststype      (curinterp->Ilaststype)
-#define leftgv         (curinterp->Ileftgv)
-#define lineary                (curinterp->Ilineary)
-#define localizing     (curinterp->Ilocalizing)
-#define localpatches   (curinterp->Ilocalpatches)
-#define main_cv                (curinterp->Imain_cv)
-#define main_root      (curinterp->Imain_root)
-#define main_start     (curinterp->Imain_start)
-#define mainstack      (curinterp->Imainstack)
-#define maxscream      (curinterp->Imaxscream)
-#define maxsysfd       (curinterp->Imaxsysfd)
-#define minus_F                (curinterp->Iminus_F)
-#define minus_a                (curinterp->Iminus_a)
-#define minus_c                (curinterp->Iminus_c)
-#define minus_l                (curinterp->Iminus_l)
-#define minus_n                (curinterp->Iminus_n)
-#define minus_p                (curinterp->Iminus_p)
-#define multiline      (curinterp->Imultiline)
-#define mystack_base   (curinterp->Imystack_base)
-#define mystack_mark   (curinterp->Imystack_mark)
-#define mystack_max    (curinterp->Imystack_max)
-#define mystack_sp     (curinterp->Imystack_sp)
-#define mystrk         (curinterp->Imystrk)
-#define nrs            (curinterp->Inrs)
-#define ofmt           (curinterp->Iofmt)
-#define ofs            (curinterp->Iofs)
-#define ofslen         (curinterp->Iofslen)
-#define oldlastpm      (curinterp->Ioldlastpm)
-#define oldname                (curinterp->Ioldname)
-#define op_mask                (curinterp->Iop_mask)
-#define origargc       (curinterp->Iorigargc)
-#define origargv       (curinterp->Iorigargv)
-#define origfilename   (curinterp->Iorigfilename)
-#define ors            (curinterp->Iors)
-#define orslen         (curinterp->Iorslen)
-#define parsehook      (curinterp->Iparsehook)
-#define patchlevel     (curinterp->Ipatchlevel)
-#define perldb         (curinterp->Iperldb)
+#define Argv                   (curinterp->IArgv)
+#define Cmd                    (curinterp->ICmd)
+#define DBgv                   (curinterp->IDBgv)
+#define DBline                 (curinterp->IDBline)
+#define DBsignal               (curinterp->IDBsignal)
+#define DBsingle               (curinterp->IDBsingle)
+#define DBsub                  (curinterp->IDBsub)
+#define DBtrace                        (curinterp->IDBtrace)
+#define allgvs                 (curinterp->Iallgvs)
+#define ampergv                        (curinterp->Iampergv)
+#define argvgv                 (curinterp->Iargvgv)
+#define argvoutgv              (curinterp->Iargvoutgv)
+#define basetime               (curinterp->Ibasetime)
+#define beginav                        (curinterp->Ibeginav)
+#define bodytarget             (curinterp->Ibodytarget)
+#define cddir                  (curinterp->Icddir)
+#define chopset                        (curinterp->Ichopset)
+#define copline                        (curinterp->Icopline)
+#define curblock               (curinterp->Icurblock)
+#define curcop                 (curinterp->Icurcop)
+#define curcopdb               (curinterp->Icurcopdb)
+#define curcsv                 (curinterp->Icurcsv)
+#define curpm                  (curinterp->Icurpm)
+#define curstack               (curinterp->Icurstack)
+#define curstash               (curinterp->Icurstash)
+#define curstname              (curinterp->Icurstname)
+#define cxstack                        (curinterp->Icxstack)
+#define cxstack_ix             (curinterp->Icxstack_ix)
+#define cxstack_max            (curinterp->Icxstack_max)
+#define dbargs                 (curinterp->Idbargs)
+#define debdelim               (curinterp->Idebdelim)
+#define debname                        (curinterp->Idebname)
+#define debstash               (curinterp->Idebstash)
+#define defgv                  (curinterp->Idefgv)
+#define defoutgv               (curinterp->Idefoutgv)
+#define defstash               (curinterp->Idefstash)
+#define delaymagic             (curinterp->Idelaymagic)
+#define diehook                        (curinterp->Idiehook)
+#define dirty                  (curinterp->Idirty)
+#define dlevel                 (curinterp->Idlevel)
+#define dlmax                  (curinterp->Idlmax)
+#define doextract              (curinterp->Idoextract)
+#define doswitches             (curinterp->Idoswitches)
+#define dowarn                 (curinterp->Idowarn)
+#define dumplvl                        (curinterp->Idumplvl)
+#define e_fp                   (curinterp->Ie_fp)
+#define e_tmpname              (curinterp->Ie_tmpname)
+#define endav                  (curinterp->Iendav)
+#define envgv                  (curinterp->Ienvgv)
+#define errgv                  (curinterp->Ierrgv)
+#define eval_root              (curinterp->Ieval_root)
+#define eval_start             (curinterp->Ieval_start)
+#define fdpid                  (curinterp->Ifdpid)
+#define filemode               (curinterp->Ifilemode)
+#define firstgv                        (curinterp->Ifirstgv)
+#define forkprocess            (curinterp->Iforkprocess)
+#define formfeed               (curinterp->Iformfeed)
+#define formtarget             (curinterp->Iformtarget)
+#define gensym                 (curinterp->Igensym)
+#define in_eval                        (curinterp->Iin_eval)
+#define incgv                  (curinterp->Iincgv)
+#define inplace                        (curinterp->Iinplace)
+#define last_in_gv             (curinterp->Ilast_in_gv)
+#define lastfd                 (curinterp->Ilastfd)
+#define lastretstr             (curinterp->Ilastretstr)
+#define lastscream             (curinterp->Ilastscream)
+#define lastsize               (curinterp->Ilastsize)
+#define lastspbase             (curinterp->Ilastspbase)
+#define laststatval            (curinterp->Ilaststatval)
+#define laststype              (curinterp->Ilaststype)
+#define leftgv                 (curinterp->Ileftgv)
+#define lineary                        (curinterp->Ilineary)
+#define localizing             (curinterp->Ilocalizing)
+#define localpatches           (curinterp->Ilocalpatches)
+#define main_cv                        (curinterp->Imain_cv)
+#define main_root              (curinterp->Imain_root)
+#define main_start             (curinterp->Imain_start)
+#define mainstack              (curinterp->Imainstack)
+#define maxscream              (curinterp->Imaxscream)
+#define maxsysfd               (curinterp->Imaxsysfd)
+#define minus_F                        (curinterp->Iminus_F)
+#define minus_a                        (curinterp->Iminus_a)
+#define minus_c                        (curinterp->Iminus_c)
+#define minus_l                        (curinterp->Iminus_l)
+#define minus_n                        (curinterp->Iminus_n)
+#define minus_p                        (curinterp->Iminus_p)
+#define multiline              (curinterp->Imultiline)
+#define mystack_base           (curinterp->Imystack_base)
+#define mystack_mark           (curinterp->Imystack_mark)
+#define mystack_max            (curinterp->Imystack_max)
+#define mystack_sp             (curinterp->Imystack_sp)
+#define mystrk                 (curinterp->Imystrk)
+#define nrs                    (curinterp->Inrs)
+#define ofmt                   (curinterp->Iofmt)
+#define ofs                    (curinterp->Iofs)
+#define ofslen                 (curinterp->Iofslen)
+#define oldlastpm              (curinterp->Ioldlastpm)
+#define oldname                        (curinterp->Ioldname)
+#define op_mask                        (curinterp->Iop_mask)
+#define origargc               (curinterp->Iorigargc)
+#define origargv               (curinterp->Iorigargv)
+#define origfilename           (curinterp->Iorigfilename)
+#define ors                    (curinterp->Iors)
+#define orslen                 (curinterp->Iorslen)
+#define parsehook              (curinterp->Iparsehook)
+#define patchlevel             (curinterp->Ipatchlevel)
 #define perl_destruct_level    (curinterp->Iperl_destruct_level)
-#define pidstatus      (curinterp->Ipidstatus)
-#define preambled      (curinterp->Ipreambled)
-#define preambleav     (curinterp->Ipreambleav)
-#define preprocess     (curinterp->Ipreprocess)
-#define restartop      (curinterp->Irestartop)
-#define rightgv                (curinterp->Irightgv)
-#define rs             (curinterp->Irs)
-#define runlevel       (curinterp->Irunlevel)
-#define sawampersand   (curinterp->Isawampersand)
-#define sawstudy       (curinterp->Isawstudy)
-#define sawvec         (curinterp->Isawvec)
-#define screamfirst    (curinterp->Iscreamfirst)
-#define screamnext     (curinterp->Iscreamnext)
-#define secondgv       (curinterp->Isecondgv)
-#define siggv          (curinterp->Isiggv)
-#define signalstack    (curinterp->Isignalstack)
-#define sortcop                (curinterp->Isortcop)
-#define sortstack      (curinterp->Isortstack)
-#define sortstash      (curinterp->Isortstash)
-#define splitstr       (curinterp->Isplitstr)
-#define statcache      (curinterp->Istatcache)
-#define statgv         (curinterp->Istatgv)
-#define statname       (curinterp->Istatname)
-#define statusvalue    (curinterp->Istatusvalue)
-#define stdingv                (curinterp->Istdingv)
-#define strchop                (curinterp->Istrchop)
-#define strtab         (curinterp->Istrtab)
-#define sv_count       (curinterp->Isv_count)
-#define sv_objcount    (curinterp->Isv_objcount)
-#define sv_root                (curinterp->Isv_root)
-#define sv_arenaroot   (curinterp->Isv_arenaroot)
-#define tainted                (curinterp->Itainted)
-#define tainting       (curinterp->Itainting)
-#define tmps_floor     (curinterp->Itmps_floor)
-#define tmps_ix                (curinterp->Itmps_ix)
-#define tmps_max       (curinterp->Itmps_max)
-#define tmps_stack     (curinterp->Itmps_stack)
-#define top_env                (curinterp->Itop_env)
-#define toptarget      (curinterp->Itoptarget)
-#define unsafe         (curinterp->Iunsafe)
-#define warnhook       (curinterp->Iwarnhook)
+#define perldb                 (curinterp->Iperldb)
+#define pidstatus              (curinterp->Ipidstatus)
+#define preambleav             (curinterp->Ipreambleav)
+#define preambled              (curinterp->Ipreambled)
+#define preprocess             (curinterp->Ipreprocess)
+#define restartop              (curinterp->Irestartop)
+#define rightgv                        (curinterp->Irightgv)
+#define rs                     (curinterp->Irs)
+#define runlevel               (curinterp->Irunlevel)
+#define sawampersand           (curinterp->Isawampersand)
+#define sawstudy               (curinterp->Isawstudy)
+#define sawvec                 (curinterp->Isawvec)
+#define screamfirst            (curinterp->Iscreamfirst)
+#define screamnext             (curinterp->Iscreamnext)
+#define secondgv               (curinterp->Isecondgv)
+#define siggv                  (curinterp->Isiggv)
+#define signalstack            (curinterp->Isignalstack)
+#define sortcop                        (curinterp->Isortcop)
+#define sortstack              (curinterp->Isortstack)
+#define sortstash              (curinterp->Isortstash)
+#define splitstr               (curinterp->Isplitstr)
+#define statcache              (curinterp->Istatcache)
+#define statgv                 (curinterp->Istatgv)
+#define statname               (curinterp->Istatname)
+#define statusvalue            (curinterp->Istatusvalue)
+#define stdingv                        (curinterp->Istdingv)
+#define strchop                        (curinterp->Istrchop)
+#define strtab                 (curinterp->Istrtab)
+#define sv_arenaroot           (curinterp->Isv_arenaroot)
+#define sv_count               (curinterp->Isv_count)
+#define sv_objcount            (curinterp->Isv_objcount)
+#define sv_root                        (curinterp->Isv_root)
+#define tainted                        (curinterp->Itainted)
+#define tainting               (curinterp->Itainting)
+#define tmps_floor             (curinterp->Itmps_floor)
+#define tmps_ix                        (curinterp->Itmps_ix)
+#define tmps_max               (curinterp->Itmps_max)
+#define tmps_stack             (curinterp->Itmps_stack)
+#define top_env                        (curinterp->Itop_env)
+#define toptarget              (curinterp->Itoptarget)
+#define unsafe                 (curinterp->Iunsafe)
+#define warnhook               (curinterp->Iwarnhook)
 
-#else  /* not multiple, so translate interpreter symbols the other way... */
+#else  /* !MULTIPLICITY */
 
-#define IArgv          Argv
-#define ICmd           Cmd
-#define IDBgv          DBgv
-#define IDBline                DBline
-#define IDBsignal      DBsignal
-#define IDBsingle      DBsingle
-#define IDBsub         DBsub
-#define IDBtrace       DBtrace
-#define Iallgvs                allgvs
-#define Iampergv       ampergv
-#define Iargvgv                argvgv
-#define Iargvoutgv     argvoutgv
-#define Ibasetime      basetime
-#define Ibeginav       beginav
-#define Ibodytarget    bodytarget
-#define Icddir         cddir
-#define Ichopset       chopset
-#define Icopline       copline
-#define Icurblock      curblock
-#define Icurcop                curcop
-#define Icurcopdb      curcopdb
-#define Icurcsv                curcsv
-#define Icurpm         curpm
-#define Icurstack      curstack
-#define Icurstash      curstash
-#define Icurstname     curstname
-#define Icxstack       cxstack
-#define Icxstack_ix    cxstack_ix
-#define Icxstack_max   cxstack_max
-#define Idbargs                dbargs
-#define Idebdelim      debdelim
-#define Idebname       debname
-#define Idebstash      debstash
-#define Idefgv         defgv
-#define Idefoutgv      defoutgv
-#define Idefstash      defstash
-#define Idelaymagic    delaymagic
-#define Idiehook       diehook
-#define Idirty         dirty
-#define Idlevel                dlevel
-#define Idlmax         dlmax
-#define Idoextract     doextract
-#define Idoswitches    doswitches
-#define Idowarn                dowarn
-#define Idumplvl       dumplvl
-#define Ie_fp          e_fp
-#define Ie_tmpname     e_tmpname
-#define Iendav         endav
-#define Ienvgv         envgv
-#define Ierrgv         errgv
-#define Ieval_root     eval_root
-#define Ieval_start    eval_start
-#define Ifdpid         fdpid
-#define Ifilemode      filemode
-#define Ifirstgv       firstgv
-#define Iforkprocess   forkprocess
-#define Iformfeed      formfeed
-#define Iformtarget    formtarget
-#define Igensym                gensym
-#define Iin_eval       in_eval
-#define Iincgv         incgv
-#define Iinplace       inplace
-#define Ilast_in_gv    last_in_gv
-#define Ilastfd                lastfd
-#define Ilastretstr    lastretstr
-#define Ilastscream    lastscream
-#define Ilastsize      lastsize
-#define Ilastspbase    lastspbase
-#define Ilaststatval   laststatval
-#define Ilaststype     laststype
-#define Ileftgv                leftgv
-#define Ilineary       lineary
-#define Ilocalizing    localizing
-#define Ilocalpatches  localpatches
-#define Imain_cv       main_cv
-#define Imain_root     main_root
-#define Imain_start    main_start
-#define Imainstack     mainstack
-#define Imaxscream     maxscream
-#define Imaxsysfd      maxsysfd
-#define Iminus_F       minus_F
-#define Iminus_a       minus_a
-#define Iminus_c       minus_c
-#define Iminus_l       minus_l
-#define Iminus_n       minus_n
-#define Iminus_p       minus_p
-#define Imultiline     multiline
-#define Imystack_base  mystack_base
-#define Imystack_mark  mystack_mark
-#define Imystack_max   mystack_max
-#define Imystack_sp    mystack_sp
-#define Imystrk                mystrk
-#define Inrs           nrs
-#define Iofmt          ofmt
-#define Iofs           ofs
-#define Iofslen                ofslen
-#define Ioldlastpm     oldlastpm
-#define Ioldname       oldname
-#define Iop_mask       op_mask
-#define Iorigargc      origargc
-#define Iorigargv      origargv
-#define Iorigfilename  origfilename
-#define Iors           ors
-#define Iorslen                orslen
-#define Iparsehook     parsehook
-#define Ipatchlevel    patchlevel
-#define Iperldb                perldb
+#define IArgv                  Argv
+#define ICmd                   Cmd
+#define IDBgv                  DBgv
+#define IDBline                        DBline
+#define IDBsignal              DBsignal
+#define IDBsingle              DBsingle
+#define IDBsub                 DBsub
+#define IDBtrace               DBtrace
+#define Iallgvs                        allgvs
+#define Iampergv               ampergv
+#define Iargvgv                        argvgv
+#define Iargvoutgv             argvoutgv
+#define Ibasetime              basetime
+#define Ibeginav               beginav
+#define Ibodytarget            bodytarget
+#define Icddir                 cddir
+#define Ichopset               chopset
+#define Icopline               copline
+#define Icurblock              curblock
+#define Icurcop                        curcop
+#define Icurcopdb              curcopdb
+#define Icurcsv                        curcsv
+#define Icurpm                 curpm
+#define Icurstack              curstack
+#define Icurstash              curstash
+#define Icurstname             curstname
+#define Icxstack               cxstack
+#define Icxstack_ix            cxstack_ix
+#define Icxstack_max           cxstack_max
+#define Idbargs                        dbargs
+#define Idebdelim              debdelim
+#define Idebname               debname
+#define Idebstash              debstash
+#define Idefgv                 defgv
+#define Idefoutgv              defoutgv
+#define Idefstash              defstash
+#define Idelaymagic            delaymagic
+#define Idiehook               diehook
+#define Idirty                 dirty
+#define Idlevel                        dlevel
+#define Idlmax                 dlmax
+#define Idoextract             doextract
+#define Idoswitches            doswitches
+#define Idowarn                        dowarn
+#define Idumplvl               dumplvl
+#define Ie_fp                  e_fp
+#define Ie_tmpname             e_tmpname
+#define Iendav                 endav
+#define Ienvgv                 envgv
+#define Ierrgv                 errgv
+#define Ieval_root             eval_root
+#define Ieval_start            eval_start
+#define Ifdpid                 fdpid
+#define Ifilemode              filemode
+#define Ifirstgv               firstgv
+#define Iforkprocess           forkprocess
+#define Iformfeed              formfeed
+#define Iformtarget            formtarget
+#define Igensym                        gensym
+#define Iin_eval               in_eval
+#define Iincgv                 incgv
+#define Iinplace               inplace
+#define Ilast_in_gv            last_in_gv
+#define Ilastfd                        lastfd
+#define Ilastretstr            lastretstr
+#define Ilastscream            lastscream
+#define Ilastsize              lastsize
+#define Ilastspbase            lastspbase
+#define Ilaststatval           laststatval
+#define Ilaststype             laststype
+#define Ileftgv                        leftgv
+#define Ilineary               lineary
+#define Ilocalizing            localizing
+#define Ilocalpatches          localpatches
+#define Imain_cv               main_cv
+#define Imain_root             main_root
+#define Imain_start            main_start
+#define Imainstack             mainstack
+#define Imaxscream             maxscream
+#define Imaxsysfd              maxsysfd
+#define Iminus_F               minus_F
+#define Iminus_a               minus_a
+#define Iminus_c               minus_c
+#define Iminus_l               minus_l
+#define Iminus_n               minus_n
+#define Iminus_p               minus_p
+#define Imultiline             multiline
+#define Imystack_base          mystack_base
+#define Imystack_mark          mystack_mark
+#define Imystack_max           mystack_max
+#define Imystack_sp            mystack_sp
+#define Imystrk                        mystrk
+#define Inrs                   nrs
+#define Iofmt                  ofmt
+#define Iofs                   ofs
+#define Iofslen                        ofslen
+#define Ioldlastpm             oldlastpm
+#define Ioldname               oldname
+#define Iop_mask               op_mask
+#define Iorigargc              origargc
+#define Iorigargv              origargv
+#define Iorigfilename          origfilename
+#define Iors                   ors
+#define Iorslen                        orslen
+#define Iparsehook             parsehook
+#define Ipatchlevel            patchlevel
 #define Iperl_destruct_level   perl_destruct_level
-#define Ipidstatus     pidstatus
-#define Ipreambled     preambled
-#define Ipreambleav    preambleav
-#define Ipreprocess    preprocess
-#define Irestartop     restartop
-#define Irightgv       rightgv
-#define Irs            rs
-#define Irunlevel      runlevel
-#define Isawampersand  sawampersand
-#define Isawstudy      sawstudy
-#define Isawvec                sawvec
-#define Iscreamfirst   screamfirst
-#define Iscreamnext    screamnext
-#define Isecondgv      secondgv
-#define Isiggv         siggv
-#define Isignalstack   signalstack
-#define Isortcop       sortcop
-#define Isortstack     sortstack
-#define Isortstash     sortstash
-#define Isplitstr      splitstr
-#define Istatcache     statcache
-#define Istatgv                statgv
-#define Istatname      statname
-#define Istatusvalue   statusvalue
-#define Istdingv       stdingv
-#define Istrchop       strchop
-#define Istrtab                strtab
-#define Isv_count      sv_count
-#define Isv_objcount   sv_objcount
-#define Isv_root       sv_root
-#define Isv_arenaroot  sv_arenaroot
-#define Itainted       tainted
-#define Itainting      tainting
-#define Itmps_floor    tmps_floor
-#define Itmps_ix       tmps_ix
-#define Itmps_max      tmps_max
-#define Itmps_stack    tmps_stack
-#define Itop_env       top_env
-#define Itoptarget     toptarget
-#define Iunsafe                unsafe
-#define Iwarnhook      warnhook
+#define Iperldb                        perldb
+#define Ipidstatus             pidstatus
+#define Ipreambleav            preambleav
+#define Ipreambled             preambled
+#define Ipreprocess            preprocess
+#define Irestartop             restartop
+#define Irightgv               rightgv
+#define Irs                    rs
+#define Irunlevel              runlevel
+#define Isawampersand          sawampersand
+#define Isawstudy              sawstudy
+#define Isawvec                        sawvec
+#define Iscreamfirst           screamfirst
+#define Iscreamnext            screamnext
+#define Isecondgv              secondgv
+#define Isiggv                 siggv
+#define Isignalstack           signalstack
+#define Isortcop               sortcop
+#define Isortstack             sortstack
+#define Isortstash             sortstash
+#define Isplitstr              splitstr
+#define Istatcache             statcache
+#define Istatgv                        statgv
+#define Istatname              statname
+#define Istatusvalue           statusvalue
+#define Istdingv               stdingv
+#define Istrchop               strchop
+#define Istrtab                        strtab
+#define Isv_arenaroot          sv_arenaroot
+#define Isv_count              sv_count
+#define Isv_objcount           sv_objcount
+#define Isv_root               sv_root
+#define Itainted               tainted
+#define Itainting              tainting
+#define Itmps_floor            tmps_floor
+#define Itmps_ix               tmps_ix
+#define Itmps_max              tmps_max
+#define Itmps_stack            tmps_stack
+#define Itop_env               top_env
+#define Itoptarget             toptarget
+#define Iunsafe                        unsafe
+#define Iwarnhook              warnhook
+
+/* Hide interpreter-specific symbols? */
 
 #ifdef EMBED
 
-#define Argv           Perl_Argv
-#define Cmd            Perl_Cmd
-#define DBgv           Perl_DBgv
-#define DBline         Perl_DBline
-#define DBsignal       Perl_DBsignal
-#define DBsingle       Perl_DBsingle
-#define DBsub          Perl_DBsub
-#define DBtrace                Perl_DBtrace
-#define allgvs         Perl_allgvs
-#define ampergv                Perl_ampergv
-#define argvgv         Perl_argvgv
-#define argvoutgv      Perl_argvoutgv
-#define basetime       Perl_basetime
-#define beginav                Perl_beginav
-#define bodytarget     Perl_bodytarget
-#define cddir          Perl_cddir
-#define chopset                Perl_chopset
-#define copline                Perl_copline
-#define curblock       Perl_curblock
-#define curcop         Perl_curcop
-#define curcopdb       Perl_curcopdb
-#define curcsv         Perl_curcsv
-#define curpm          Perl_curpm
-#define curstack       Perl_curstack
-#define curstash       Perl_curstash
-#define curstname      Perl_curstname
-#define cxstack                Perl_cxstack
-#define cxstack_ix     Perl_cxstack_ix
-#define cxstack_max    Perl_cxstack_max
-#define dbargs         Perl_dbargs
-#define debdelim       Perl_debdelim
-#define debname                Perl_debname
-#define debstash       Perl_debstash
-#define defgv          Perl_defgv
-#define defoutgv       Perl_defoutgv
-#define defstash       Perl_defstash
-#define delaymagic     Perl_delaymagic
-#define diehook                Perl_diehook
-#define dirty          Perl_dirty
-#define dlevel         Perl_dlevel
-#define dlmax          Perl_dlmax
-#define doextract      Perl_doextract
-#define doswitches     Perl_doswitches
-#define dowarn         Perl_dowarn
-#define dumplvl                Perl_dumplvl
-#define e_fp           Perl_e_fp
-#define e_tmpname      Perl_e_tmpname
-#define endav          Perl_endav
-#define envgv          Perl_envgv
-#define errgv          Perl_errgv
-#define eval_root      Perl_eval_root
-#define eval_start     Perl_eval_start
-#define fdpid          Perl_fdpid
-#define filemode       Perl_filemode
-#define firstgv                Perl_firstgv
-#define forkprocess    Perl_forkprocess
-#define formfeed       Perl_formfeed
-#define formtarget     Perl_formtarget
-#define gensym         Perl_gensym
-#define in_eval                Perl_in_eval
-#define incgv          Perl_incgv
-#define inplace                Perl_inplace
-#define last_in_gv     Perl_last_in_gv
-#define lastfd         Perl_lastfd
-#define lastretstr     Perl_lastretstr
-#define lastscream     Perl_lastscream
-#define lastsize       Perl_lastsize
-#define lastspbase     Perl_lastspbase
-#define laststatval    Perl_laststatval
-#define laststype      Perl_laststype
-#define leftgv         Perl_leftgv
-#define lineary                Perl_lineary
-#define localizing     Perl_localizing
-#define localpatches   Perl_localpatches
-#define main_cv                Perl_main_cv
-#define main_root      Perl_main_root
-#define main_start     Perl_main_start
-#define mainstack      Perl_mainstack
-#define maxscream      Perl_maxscream
-#define maxsysfd       Perl_maxsysfd
-#define minus_F                Perl_minus_F
-#define minus_a                Perl_minus_a
-#define minus_c                Perl_minus_c
-#define minus_l                Perl_minus_l
-#define minus_n                Perl_minus_n
-#define minus_p                Perl_minus_p
-#define multiline      Perl_multiline
-#define mystack_base   Perl_mystack_base
-#define mystack_mark   Perl_mystack_mark
-#define mystack_max    Perl_mystack_max
-#define mystack_sp     Perl_mystack_sp
-#define mystrk         Perl_mystrk
-#define nrs            Perl_nrs
-#define ofmt           Perl_ofmt
-#define ofs            Perl_ofs
-#define ofslen         Perl_ofslen
-#define oldlastpm      Perl_oldlastpm
-#define oldname                Perl_oldname
-#define op_mask                Perl_op_mask
-#define origargc       Perl_origargc
-#define origargv       Perl_origargv
-#define origfilename   Perl_origfilename
-#define ors            Perl_ors
-#define orslen         Perl_orslen
-#define parsehook      Perl_parsehook
-#define patchlevel     Perl_patchlevel
-#define perldb         Perl_perldb
+#define curcop                 Perl_curcop
+#define curcopdb               Perl_curcopdb
+#define envgv                  Perl_envgv
+#define siggv                  Perl_siggv
+#define tainting               Perl_tainting
+
+/* Hide interpreter symbols that 5.003 revealed? */
+
+#ifndef BINCOMPAT3
+
+#define Argv                   Perl_Argv
+#define Cmd                    Perl_Cmd
+#define DBgv                   Perl_DBgv
+#define DBline                 Perl_DBline
+#define DBsignal               Perl_DBsignal
+#define DBsingle               Perl_DBsingle
+#define DBsub                  Perl_DBsub
+#define DBtrace                        Perl_DBtrace
+#define allgvs                 Perl_allgvs
+#define ampergv                        Perl_ampergv
+#define argvgv                 Perl_argvgv
+#define argvoutgv              Perl_argvoutgv
+#define basetime               Perl_basetime
+#define beginav                        Perl_beginav
+#define bodytarget             Perl_bodytarget
+#define cddir                  Perl_cddir
+#define chopset                        Perl_chopset
+#define copline                        Perl_copline
+#define curblock               Perl_curblock
+#define curcsv                 Perl_curcsv
+#define curpm                  Perl_curpm
+#define curstack               Perl_curstack
+#define curstash               Perl_curstash
+#define curstname              Perl_curstname
+#define cxstack                        Perl_cxstack
+#define cxstack_ix             Perl_cxstack_ix
+#define cxstack_max            Perl_cxstack_max
+#define dbargs                 Perl_dbargs
+#define debdelim               Perl_debdelim
+#define debname                        Perl_debname
+#define debstash               Perl_debstash
+#define defgv                  Perl_defgv
+#define defoutgv               Perl_defoutgv
+#define defstash               Perl_defstash
+#define delaymagic             Perl_delaymagic
+#define diehook                        Perl_diehook
+#define dirty                  Perl_dirty
+#define dlevel                 Perl_dlevel
+#define dlmax                  Perl_dlmax
+#define doextract              Perl_doextract
+#define doswitches             Perl_doswitches
+#define dowarn                 Perl_dowarn
+#define dumplvl                        Perl_dumplvl
+#define e_fp                   Perl_e_fp
+#define e_tmpname              Perl_e_tmpname
+#define endav                  Perl_endav
+#define errgv                  Perl_errgv
+#define eval_root              Perl_eval_root
+#define eval_start             Perl_eval_start
+#define fdpid                  Perl_fdpid
+#define filemode               Perl_filemode
+#define firstgv                        Perl_firstgv
+#define forkprocess            Perl_forkprocess
+#define formfeed               Perl_formfeed
+#define formtarget             Perl_formtarget
+#define gensym                 Perl_gensym
+#define in_eval                        Perl_in_eval
+#define incgv                  Perl_incgv
+#define inplace                        Perl_inplace
+#define last_in_gv             Perl_last_in_gv
+#define lastfd                 Perl_lastfd
+#define lastretstr             Perl_lastretstr
+#define lastscream             Perl_lastscream
+#define lastsize               Perl_lastsize
+#define lastspbase             Perl_lastspbase
+#define laststatval            Perl_laststatval
+#define laststype              Perl_laststype
+#define leftgv                 Perl_leftgv
+#define lineary                        Perl_lineary
+#define localizing             Perl_localizing
+#define localpatches           Perl_localpatches
+#define main_cv                        Perl_main_cv
+#define main_root              Perl_main_root
+#define main_start             Perl_main_start
+#define mainstack              Perl_mainstack
+#define maxscream              Perl_maxscream
+#define maxsysfd               Perl_maxsysfd
+#define minus_F                        Perl_minus_F
+#define minus_a                        Perl_minus_a
+#define minus_c                        Perl_minus_c
+#define minus_l                        Perl_minus_l
+#define minus_n                        Perl_minus_n
+#define minus_p                        Perl_minus_p
+#define multiline              Perl_multiline
+#define mystack_base           Perl_mystack_base
+#define mystack_mark           Perl_mystack_mark
+#define mystack_max            Perl_mystack_max
+#define mystack_sp             Perl_mystack_sp
+#define mystrk                 Perl_mystrk
+#define nrs                    Perl_nrs
+#define ofmt                   Perl_ofmt
+#define ofs                    Perl_ofs
+#define ofslen                 Perl_ofslen
+#define oldlastpm              Perl_oldlastpm
+#define oldname                        Perl_oldname
+#define op_mask                        Perl_op_mask
+#define origargc               Perl_origargc
+#define origargv               Perl_origargv
+#define origfilename           Perl_origfilename
+#define ors                    Perl_ors
+#define orslen                 Perl_orslen
+#define parsehook              Perl_parsehook
+#define patchlevel             Perl_patchlevel
 #define perl_destruct_level    Perl_perl_destruct_level
-#define pidstatus      Perl_pidstatus
-#define preambled      Perl_preambled
-#define preambleav     Perl_preambleav
-#define preprocess     Perl_preprocess
-#define restartop      Perl_restartop
-#define rightgv                Perl_rightgv
-#define rs             Perl_rs
-#define runlevel       Perl_runlevel
-#define sawampersand   Perl_sawampersand
-#define sawstudy       Perl_sawstudy
-#define sawvec         Perl_sawvec
-#define screamfirst    Perl_screamfirst
-#define screamnext     Perl_screamnext
-#define secondgv       Perl_secondgv
-#define siggv          Perl_siggv
-#define signalstack    Perl_signalstack
-#define sortcop                Perl_sortcop
-#define sortstack      Perl_sortstack
-#define sortstash      Perl_sortstash
-#define splitstr       Perl_splitstr
-#define statcache      Perl_statcache
-#define statgv         Perl_statgv
-#define statname       Perl_statname
-#define statusvalue    Perl_statusvalue
-#define stdingv                Perl_stdingv
-#define strchop                Perl_strchop
-#define strtab         Perl_strtab
-#define sv_count       Perl_sv_count
-#define sv_objcount    Perl_sv_objcount
-#define sv_root                Perl_sv_root
-#define sv_arenaroot   Perl_sv_arenaroot
-#define tainted                Perl_tainted
-#define tainting       Perl_tainting
-#define tmps_floor     Perl_tmps_floor
-#define tmps_ix                Perl_tmps_ix
-#define tmps_max       Perl_tmps_max
-#define tmps_stack     Perl_tmps_stack
-#define top_env                Perl_top_env
-#define toptarget      Perl_toptarget
-#define unsafe         Perl_unsafe
-#define warnhook       Perl_warnhook
+#define perldb                 Perl_perldb
+#define pidstatus              Perl_pidstatus
+#define preambleav             Perl_preambleav
+#define preambled              Perl_preambled
+#define preprocess             Perl_preprocess
+#define restartop              Perl_restartop
+#define rightgv                        Perl_rightgv
+#define rs                     Perl_rs
+#define runlevel               Perl_runlevel
+#define sawampersand           Perl_sawampersand
+#define sawstudy               Perl_sawstudy
+#define sawvec                 Perl_sawvec
+#define screamfirst            Perl_screamfirst
+#define screamnext             Perl_screamnext
+#define secondgv               Perl_secondgv
+#define signalstack            Perl_signalstack
+#define sortcop                        Perl_sortcop
+#define sortstack              Perl_sortstack
+#define sortstash              Perl_sortstash
+#define splitstr               Perl_splitstr
+#define statcache              Perl_statcache
+#define statgv                 Perl_statgv
+#define statname               Perl_statname
+#define statusvalue            Perl_statusvalue
+#define stdingv                        Perl_stdingv
+#define strchop                        Perl_strchop
+#define strtab                 Perl_strtab
+#define sv_arenaroot           Perl_sv_arenaroot
+#define sv_count               Perl_sv_count
+#define sv_objcount            Perl_sv_objcount
+#define sv_root                        Perl_sv_root
+#define tainted                        Perl_tainted
+#define tmps_floor             Perl_tmps_floor
+#define tmps_ix                        Perl_tmps_ix
+#define tmps_max               Perl_tmps_max
+#define tmps_stack             Perl_tmps_stack
+#define top_env                        Perl_top_env
+#define toptarget              Perl_toptarget
+#define unsafe                 Perl_unsafe
+#define warnhook               Perl_warnhook
+
+#endif /* !BINCOMPAT3 */
 
 #endif /* EMBED */
 
index a1e77db..266a33e 100755 (executable)
--- a/embed.pl
+++ b/embed.pl
@@ -1,12 +1,52 @@
-#!/usr/bin/perl
+#!/usr/bin/perl -w
 
-unlink "embed.h";
-open(EM, ">embed.h") || die "Can't create embed.h: $!\n";
+require 5.003;
+
+sub readsyms (\%$) {
+    my ($syms, $file) = @_;
+    %$syms = ();
+    local (*FILE, $_);
+    open(FILE, "< $file")
+       or die "embed.pl: Can't open $file: $!\n";
+    while (<FILE>) {
+       s/[ \t]*#.*//;          # Delete comments.
+       if (/^\s*(\S+)\s*$/) {
+           $$syms{$1} = 1;
+       }
+    }
+    close(FILE);
+}
+
+readsyms %global, 'global.sym';
+readsyms %interp, 'interp.sym';
+readsyms %compat3, 'compat3.sym';
+
+sub hide ($$) {
+    my ($from, $to) = @_;
+    my $t = int(length($from) / 8);
+    "#define $from" . "\t" x ($t < 3 ? 3 - $t : 1) . "$to\n";
+}
+sub embed ($) {
+    my ($sym) = @_;
+    hide($sym, "Perl_$sym");
+}
+sub multon ($) {
+    my ($sym) = @_;
+    hide($sym, "(curinterp->I$sym)");
+}
+sub multoff ($) {
+    my ($sym) = @_;
+    hide("I$sym", $sym);
+}
+
+unlink 'embed.h';
+open(EM, '> embed.h')
+    or die "Can't create embed.h: $!\n";
 
 print EM <<'END';
 /* !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!! 
-   This file is built by embed.pl from global.sym and interp.sym.
-   Any changes made here will be lost 
+   This file is built by embed.pl from global.sym, interp.sym,
+   and compat3.sym.  Any changes made here will be lost!
 */
 
 /* (Doing namespace management portably in C is really gross.) */
@@ -21,78 +61,82 @@ print EM <<'END';
 #  define EMBED 1 
 #endif
 
+/* Hide global symbols? */
+
 #ifdef EMBED
 
-/* globals we need to hide from the world */
 END
 
-open(GL, "<global.sym") || die "Can't open global.sym: $!\n";
-
-while(<GL>) {
-       s/[ \t]*#.*//;          # Delete comments.
-       next unless /\S/;
-       s/^\s*(\S+).*$/#define $1\t\tPerl_$1/;
-       $global{$1} = 1; 
-       s/(................\t)\t/$1/;
-       print EM $_;
+for $sym (sort keys %global) {
+    print EM embed($sym) unless $compat3{$sym};
 }
 
-close(GL) || warn "Can't close global.sym: $!\n";
+print EM <<'END';
+
+/* Hide global symbols that 5.003 revealed? */
+
+#ifndef BINCOMPAT3
+
+END
+
+for $sym (sort keys %global) {
+    print EM embed($sym) if $compat3{$sym};
+}
 
 print EM <<'END';
 
+#endif /* !BINCOMPAT3 */
+
 #endif /* EMBED */
 
-/* Put interpreter specific symbols into a struct? */
+/* Put interpreter-specific symbols into a struct? */
 
 #ifdef MULTIPLICITY
 
 END
 
-open(INT, "<interp.sym") || die "Can't open interp.sym: $!\n";
-while (<INT>) {
-       s/[ \t]*#.*//;          # Delete comments.
-       next unless /\S/;
-       s/^\s*(\S+).*$/#define $1\t\t(curinterp->I$1)/;
-       s/(................\t)\t/$1/;
-       print EM $_;
+for $sym (sort keys %interp) {
+    print EM multon($sym);
 }
-close(INT) || warn "Can't close interp.sym: $!\n";
 
 print EM <<'END';
 
-#else  /* not multiple, so translate interpreter symbols the other way... */
+#else  /* !MULTIPLICITY */
 
 END
 
-open(INT, "<interp.sym") || die "Can't open interp.sym: $!\n";
-while (<INT>) {
-       s/[ \t]*#.*//;          # Delete comments.
-       next unless /\S/;
-       s/^\s*(\S+).*$/#define I$1\t\t$1/;
-       s/(................\t)\t/$1/;
-       print EM $_;
+for $sym (sort keys %interp) {
+    print EM multoff($sym);
 }
-close(INT) || warn "Can't close interp.sym: $!\n";
 
 print EM <<'END';
 
+/* Hide interpreter-specific symbols? */
+
 #ifdef EMBED
 
 END
 
-open(INT, "<interp.sym") || die "Can't open interp.sym: $!\n";
-while (<INT>) {
-       s/[ \t]*#.*//;          # Delete comments.
-       next unless /\S/;
-       s/^\s*(\S+).*$/#define $1\t\tPerl_$1/;
-       s/(................\t)\t/$1/;
-       print EM $_;
+for $sym (sort keys %interp) {
+    print EM embed($sym) if $compat3{$sym};
 }
-close(INT) || warn "Can't close interp.sym: $!\n";
 
 print EM <<'END';
 
+/* Hide interpreter symbols that 5.003 revealed? */
+
+#ifndef BINCOMPAT3
+
+END
+
+for $sym (sort keys %interp) {
+    print EM embed($sym) unless $compat3{$sym};
+}
+
+print EM <<'END';
+
+#endif /* !BINCOMPAT3 */
+
 #endif /* EMBED */
 
 #endif /* MULTIPLICITY */
index 2e20cfd..925b208 100644 (file)
@@ -408,7 +408,7 @@ sub write {
 
 sub syswrite {
     @_ == 3 || @_ == 4 or croak '$fh->syswrite(BUF, LEN [, OFFSET])';
-    sysread($_[0], $_[1], $_[2], $_[3] || 0);
+    syswrite($_[0], $_[1], $_[2], $_[3] || 0);
 }
 
 sub stat {
index 6007b97..2277279 100644 (file)
@@ -1,14 +1,13 @@
 package Safe;
 
-require 5.002;
-
+use 5.003_11;
 use strict;
-use Carp;
-
 use vars qw($VERSION);
 
 $VERSION = "2.06";
 
+use Carp;
+
 use Opcode 1.01, qw(
     opset opset_to_ops opmask_add
     empty_opset full_opset invert_opset verify_opset
index e5f9b2f..70527cd 100644 (file)
@@ -2665,6 +2665,7 @@ localeconv()
 #ifdef HAS_LOCALECONV
        struct lconv *lcbuf;
        RETVAL = newHV();
+       SET_NUMERIC_LOCAL();
        if (lcbuf = localeconv()) {
            /* the strings */
            if (lcbuf->decimal_point && *lcbuf->decimal_point)
index 729aa18..3e9f9de 100644 (file)
@@ -4,7 +4,6 @@
 
 AMG_names
 Error
-He
 No
 Sv
 Xpv
@@ -64,9 +63,6 @@ exp_amg
 expect
 expectterm
 fallback_amg
-filter_add
-filter_del
-filter_read
 fold
 fold_locale
 freq
@@ -124,8 +120,6 @@ ne_amg
 neg_amg
 nexttoke
 nexttype
-nexttype
-nextval
 nextval
 nice_chunk
 nice_chunk_size
@@ -207,8 +201,6 @@ rsfp
 rsfp_filters
 rshift_amg
 rshift_ass_amg
-save_iv
-save_pptr
 savestack
 savestack_ix
 savestack_max
@@ -224,7 +216,6 @@ sgt_amg
 sh_path
 sig_name
 sig_num
-sighandler
 simple
 sin_amg
 sle_amg
@@ -496,6 +487,7 @@ magic_clearenv
 magic_clearpack
 magic_clearsig
 magic_existspack
+magic_freevivary
 magic_get
 magic_getarylen
 magic_getglob
@@ -525,6 +517,7 @@ magic_setsubstr
 magic_settaint
 magic_setuvar
 magic_setvec
+magic_setvivary
 magic_wipepack
 magicname
 markstack_grow
@@ -1008,10 +1001,12 @@ save_destructor
 save_freeop
 save_freepv
 save_freesv
+save_gp
 save_hash
 save_hptr
 save_int
 save_item
+save_iv
 save_list
 save_long
 save_nogv
index e8bee39..f1ab871 100644 (file)
@@ -63,6 +63,16 @@ case "$osvers" in
        d_setreuid='define'
        d_setegid='undef'
        d_seteuid='undef'
+       cat <<EOF
+
+Unless you've upgraded your DB library manually you will see failures in
+db-recno tests 51, 53 and 55.  The behavior these tests are checking is
+broken in the DB library which is included with the OS.  You can ignore
+the errors if you're never going to use the broken functionality (recno
+databases with a modified bval), otherwise you'll have to upgrade your
+DB library or OS.
+
+EOF
        ;;
 #
 # 2.2 and above have phkmalloc(3).
diff --git a/hints/lynxos.sh b/hints/lynxos.sh
new file mode 100644 (file)
index 0000000..5f8991b
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# LynxOS hints
+#
+# These hints were submitted by:
+#   Greg Seibert
+#   seibert@Lynx.COM
+#
+
+cc='gcc'
+ccflags='-D_filbuf=_fillbuf'
+so='none'
+usemymalloc='n'
index f4e6895..ddbe595 100755 (executable)
@@ -1,6 +1,7 @@
 #!./perl
 BEGIN { @INC=('./lib', '../lib') }
 use File::Find;
+use File::Compare;
 use File::Path ();
 use Config;
 use subs qw(unlink rename link chmod);
@@ -23,7 +24,7 @@ while (@ARGV) {
 umask 022;
 
 @scripts = qw( utils/c2ph utils/h2ph utils/h2xs
-               utils/perlbug utils/perldoc utils/pl2pm
+               utils/perlbug utils/perldoc utils/pl2pm utils/splain
                x2p/s2p x2p/find2perl
                pod/pod2man pod/pod2html pod/pod2latex pod/pod2text);
 
@@ -343,8 +344,11 @@ sub installlib {
 
     $name = "$dir/$name" if $dir ne '';
 
+    # ignore Chip-style patch backups.
+    return if grep(/^P\d+$/, split(m{/+}, $name));
+
     my $installlib = $installprivlib;
-    if ((substr($dir, 0, 4) eq 'auto') || ($name eq 'Config.pm')) {
+    if ($dir =~ /^auto/ || $name =~ /^(Config|FileHandle|Safe)\.pm$/) {
         $installlib = $installarchlib;
        return unless $do_installarchlib;
     } else {
@@ -360,8 +364,7 @@ sub installlib {
            #This might not work because $archname might have changed.
            &unlink("$installarchlib/$name");
        }
-       system "cmp", "-s", $_, "$installlib/$name";
-       if ($? || $nonono) {
+       if (compare($_, "$installlib/$name") || $nonono) {
            &unlink("$installlib/$name");
            mkpath("$installlib/$dir", 1, 0777);
            cp_if_diff($_, "$installlib/$name");
@@ -390,8 +393,7 @@ sub installlib {
 sub cp_if_diff {
     my($from,$to)=@_;
     -f $from || die "$0: $from not found";
-    system "cmp", "-s", $from, $to;
-    if ($? || $nonono) {
+    if (compare($from, $to) || $nonono) {
        my ($atime, $mtime);
        unlink($to);   # In case we don't have write permissions.
         if ($nonono) {
diff --git a/lib/CPAN.pm b/lib/CPAN.pm
new file mode 100644 (file)
index 0000000..c755aa1
--- /dev/null
@@ -0,0 +1,2350 @@
+package CPAN;
+use vars qw{$META $Signal $Cwd $End $Suppress_readline};
+
+$VERSION = '1.02';
+
+# $Id: CPAN.pm,v 1.77 1996/12/11 01:26:43 k Exp $
+
+# my $version = substr q$Revision: 1.77 $, 10; # only used during development
+
+BEGIN {require 5.003;}
+require UNIVERSAL if $] == 5.003;
+
+use Carp ();
+use Config ();
+use Cwd ();
+use DirHandle;
+use Exporter ();
+use ExtUtils::MakeMaker ();
+use File::Basename ();
+use File::Find;
+use File::Path ();
+use IO::File ();
+use Safe ();
+
+$Cwd = Cwd::cwd();
+
+END { $End++; &cleanup; }
+
+%CPAN::DEBUG = qw(
+                 CPAN              1
+                 Index             2
+                 InfoObj           4
+                 Author            8
+                 Distribution     16
+                 Bundle           32
+                 Module           64
+                 CacheMgr        128
+                 Complete        256
+                 FTP             512
+                 Shell          1024
+                 Eval           2048
+                 Config         4096
+                );
+
+$CPAN::DEBUG ||= 0;
+
+package CPAN;
+use vars qw($VERSION @ISA @EXPORT $AUTOLOAD $DEBUG $META);
+use strict qw(vars);
+
+@ISA = qw(CPAN::Debug Exporter MY); # the MY class from MakeMaker, gives us catfile and catdir
+
+$META ||= new CPAN;                 # In case we reeval ourselves we need a ||
+
+CPAN::Config->load;
+
+@EXPORT = qw(autobundle bundle expand force install make recompile shell test clean);
+
+sub autobundle;
+sub bundle;
+sub bundles;
+sub expand;
+sub force;
+sub install;
+sub make;
+sub shell;
+sub clean;
+sub test;
+
+sub AUTOLOAD {
+    my($l) = $AUTOLOAD;
+    $l =~ s/.*:://;
+    my(%EXPORT);
+    @EXPORT{@EXPORT} = '';
+    if (exists $EXPORT{$l}){
+       CPAN::Shell->$l(@_);
+    } else {
+       warn "CPAN doesn't know how to autoload $AUTOLOAD :-(
+Nothing Done.
+";
+       CPAN::Shell->h;
+    }
+}
+
+sub all {
+    my($mgr,$class) = @_;
+    CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG;
+    CPAN::Index->reload;
+    values %{ $META->{$class} };
+}
+
+# Called by shell, not in batch mode. Not clean XXX
+sub checklock {
+    my($self) = @_;
+    my $lockfile = CPAN->catfile($CPAN::Config->{cpan_home},".lock");
+    if (-f $lockfile && -M _ > 0) {
+       my $fh = IO::File->new($lockfile);
+       my $other = <$fh>;
+       $fh->close;
+       if (defined $other && $other) {
+           chomp $other;
+           return if $$==$other; # should never happen
+           print qq{There seems to be running another CPAN process ($other). Trying to contact...\n};
+           if (kill 0, $other) {
+               Carp::croak qq{Other job is running.\n}.
+                   qq{You may want to kill it and delete the lockfile, maybe. On UNIX try:\n}.
+                       qq{    kill $other\n}.
+                           qq{    rm $lockfile\n};
+           } elsif (-w $lockfile) {
+               my($ans)=
+                   ExtUtils::MakeMaker::prompt
+                       (qq{Other job not responding. Shall I overwrite the lockfile? (Y/N)},"y");
+               print("Ok, bye\n"), exit unless $ans =~ /^y/i;
+           } else {
+               Carp::croak(
+                           qq{Lockfile $lockfile not writeable by you. Cannot proceed.\n}.
+                           qq{    On UNIX try:\n}.
+                           qq{    rm $lockfile\n}.
+                           qq{  and then rerun us.\n}
+                          );
+           }
+       }
+    }
+    File::Path::mkpath($CPAN::Config->{cpan_home});
+    my $fh;
+    unless ($fh = IO::File->new(">$lockfile")) {
+       if ($! =~ /Permission/) {
+           my $incc = $INC{'CPAN/Config.pm'};
+           my $myincc = MY->catfile($ENV{HOME},'.cpan','CPAN','MyConfig.pm');
+           print qq{
+
+Your configuration suggests that CPAN.pm should use a working
+directory of
+    $CPAN::Config->{cpan_home}
+Unfortunately we could not create the lock file
+    $lockfile
+due to permission problems.
+
+Please make sure that the configuration variable
+    \$CPAN::Config->{cpan_home}
+points to a directory where you can write a .lock file. You can set
+this variable in either
+    $incc
+or
+    $myincc
+
+};
+       }
+       Carp::croak "Could not open >$lockfile: $!";
+    }
+    print $fh $$, "\n";
+    $self->{LOCK} = $lockfile;
+    $fh->close;
+    $SIG{'TERM'} = sub { &cleanup; die "Got SIGTERM, leaving"; };
+    $SIG{'INT'} = sub { &cleanup, die "Got a second SIGINT" if $Signal; $Signal = 1; };
+    $SIG{'__DIE__'} = \&cleanup;
+    print STDERR "Signal handler set.\n" unless $CPAN::Config->{'inhibit_startup_message'};
+}
+
+sub DESTROY {
+    &cleanup; # need an eval?
+}
+
+sub exists {
+    my($mgr,$class,$id) = @_;
+    CPAN::Index->reload;
+    Carp::croak "exists called without class argument" unless $class;
+    $id ||= "";
+    exists $META->{$class}{$id};
+}
+
+sub hasFTP {
+    my($self,$arg) = @_;
+    if (defined $arg) {
+       return $self->{'hasFTP'} = $arg;
+    } elsif (not defined $self->{'hasFTP'}) {
+       eval {require Net::FTP;};
+       $self->{'hasFTP'} = $@ ? 0 : 1;
+    }
+    return $self->{'hasFTP'};
+}
+
+sub hasLWP {
+    my($self,$arg) = @_;
+    if (defined $arg) {
+       return $self->{'hasLWP'} = $arg;
+    } elsif (not defined $self->{'hasLWP'}) {
+       eval {require LWP;};
+       $LWP::VERSION ||= 0;
+        $self->{'hasLWP'} = $LWP::VERSION >= 4.98;
+    }
+    return $self->{'hasLWP'};
+}
+
+sub hasMD5 {
+    my($self,$arg) = @_;
+    if (defined $arg) {
+       $self->{'hasMD5'} = $arg;
+    } elsif (not defined $self->{'hasMD5'}) {
+       eval {require MD5;};
+       if ($@) {
+           print "MD5 security checks disabled because MD5 not installed. Please consider installing MD5\n";
+           $self->{'hasMD5'} = 0;
+       } else {
+           $self->{'hasMD5'}++;
+       }
+    }
+    return $self->{'hasMD5'};
+}
+
+sub instance {
+    my($mgr,$class,$id) = @_;
+    CPAN::Index->reload;
+    Carp::croak "instance called without class argument" unless $class;
+    $id ||= "";
+    $META->{$class}{$id} ||= $class->new(ID => $id );
+}
+
+sub new {
+    bless {}, shift;
+}
+
+sub cleanup {
+    local $SIG{__DIE__} = '';
+    my $i = 0; my $ineval = 0; my $sub;
+    while ((undef,undef,undef,$sub) = caller(++$i)) {
+      $ineval = 1, last if $sub eq '(eval)';
+    }
+    return if $ineval && !$End;
+    return unless defined $META->{'LOCK'};
+    return unless -f $META->{'LOCK'};
+    unlink $META->{'LOCK'};
+    print STDERR "Lockfile removed.\n";
+#    my $mess = Carp::longmess(@_);
+#    die @_;
+}
+
+sub shell {
+    $Suppress_readline ||= ! -t STDIN;
+
+    my $prompt = "cpan> ";
+    local($^W) = 1;
+    my $term;
+    unless ($Suppress_readline) {
+       require Term::ReadLine;
+       import Term::ReadLine;
+       $term = new Term::ReadLine 'CPAN Monitor';
+       $readline::rl_completion_function =
+           $readline::rl_completion_function = 'CPAN::Complete::complete';
+    }
+
+    no strict;
+    $META->checklock();
+    my $cwd = Cwd::cwd();
+    # How should we determine if we have more than stub ReadLine enabled?
+    my $rl_avail = $Suppress_readline ? "suppressed" :
+       defined &Term::ReadLine::Perl::readline ? "enabled" :
+           "available (get Term::ReadKey and Term::ReadLine::Perl)";
+
+    print qq{
+cpan shell -- CPAN exploration and modules installation (v$CPAN::VERSION)
+Readline support $rl_avail
+
+} unless $CPAN::Config->{'inhibit_startup_message'} ;
+    while () {
+       if ($Suppress_readline) {
+           print $prompt;
+           last unless defined (chomp($_ = <>));
+       } else {
+           last unless defined ($_ = $term->readline($prompt));
+       }
+       s/^\s//;
+       next if /^$/;
+       $_ = 'h' if $_ eq '?';
+       if (/^\!/) {
+           s/^\!//;
+           my($eval) = $_;
+           package CPAN::Eval;
+           use vars qw($import_done);
+           CPAN->import(':DEFAULT') unless $import_done++;
+           CPAN->debug("eval[$eval]") if $CPAN::DEBUG;
+           eval($eval);
+           warn $@ if $@;
+       } elsif (/^q(?:uit)?$/i) {
+           last;
+       } elsif (/./) {
+           my @line = split;
+           my $command = shift @line;
+           eval { CPAN::Shell->$command(@line) };
+           warn $@ if $@;
+       }
+    } continue {
+       &cleanup, die if $Signal;
+       chdir $cwd;
+       print "\n";
+    }
+}
+
+package CPAN::Shell;
+use vars qw(@ISA $AUTOLOAD);
+@ISA = qw(CPAN::Debug);
+
+# private function ro re-eval this module (handy during development)
+sub AUTOLOAD {
+    warn "CPAN::Shell doesn't know how to autoload $AUTOLOAD :-(
+Nothing Done.
+";
+       CPAN::Shell->h;
+}
+
+sub h {
+    my($class,$about) = @_;
+    if (defined $about) {
+       print "Detailed help not yet implemented\n";
+    } else {
+       print q{
+command   arguments       description
+a         string                  authors
+b         or              display bundles
+d         /regex/         info    distributions
+m         or              about   modules
+i         none                    anything of above
+
+r          as             reinstall recommendations
+u          above          uninstalled distributions
+See manpage for autobundle() and recompile()
+
+make      modules,        make
+test      dists, bundles, make test (implies make)
+install   "r" or "u"      make install (implies test)
+clean                     make clean
+
+reload    index|cpan    load most recent indices/CPAN.pm
+h or ?                  display this menu
+o         various       set and query options
+!         perl-code     eval a perl command
+q                       quit the shell subroutine
+};
+    }
+}
+
+sub a { print shift->format_result('Author',@_);}
+sub b {
+    my($self,@which) = @_;
+    my($bdir) = $CPAN::META->catdir($CPAN::Config->{'cpan_home'},"Bundle");
+    my($dh) = DirHandle->new($bdir); # may fail!
+    my($entry);
+    for $entry ($dh->read) {
+       next if -d $CPAN::META->catdir($bdir,$entry);
+       next unless $entry =~ s/\.pm$//;
+       $CPAN::META->instance('CPAN::Bundle',"Bundle::$entry");
+    }
+    print $self->format_result('Bundle',@which);
+}
+sub d { print shift->format_result('Distribution',@_);}
+sub m { print shift->format_result('Module',@_);}
+
+sub i {
+    my($self) = shift;
+    my(@args) = @_;
+    my(@type,$type,@m);
+    @type = qw/Author Bundle Distribution Module/;
+    @args = '/./' unless @args;
+    my(@result);
+    for $type (@type) {
+       push @result, $self->expand($type,@args);
+    }
+    my $result =  @result==1 ? $result[0]->as_string : join "", map {$_->as_glimpse} @result;
+    $result ||= "No objects found of any type for argument @args\n";
+    print $result;
+}
+
+sub o {
+    my($self,$o_type,@o_what) = @_;
+    $o_type ||= "";
+    CPAN->debug("o_type[$o_type] o_what[@o_what]\n");
+    if ($o_type eq 'conf') {
+       shift @o_what if @o_what && $o_what[0] eq 'help';
+       if (!@o_what) {
+           my($k,$v);
+           print "CPAN::Config options:\n";
+           for $k (sort keys %CPAN::Config::can) {
+               $v = $CPAN::Config::can{$k};
+               printf "    %-18s %s\n", $k, $v;
+           }
+           print "\n";
+           for $k (sort keys %$CPAN::Config) {
+               $v = $CPAN::Config->{$k};
+               if (ref $v) {
+                   printf "    %-18s\n", $k;
+                   print map {"\t$_\n"} @{$v};
+               } else {
+                   printf "    %-18s %s\n", $k, $v;
+               }
+           }
+           print "\n";
+       } elsif (!CPAN::Config->edit(@o_what)) {
+           print qq[Type 'o conf' to view configuration edit options\n\n];
+       }
+    } elsif ($o_type eq 'debug') {
+       my(%valid);
+       @o_what = () if defined $o_what[0] && $o_what[0] =~ /help/i;
+       if (@o_what) {
+           while (@o_what) {
+               my($what) = shift @o_what;
+               if ( exists $CPAN::DEBUG{$what} ) {
+                   $CPAN::DEBUG |= $CPAN::DEBUG{$what};
+               } elsif ($what =~ /^\d/) {
+                   $CPAN::DEBUG = $what;
+               } elsif (lc $what eq 'all') {
+                   my($max) = 0;
+                   for (values %CPAN::DEBUG) {
+                       $max += $_;
+                   }
+                   $CPAN::DEBUG = $max;
+               } else {
+                   for (keys %CPAN::DEBUG) {
+                       next unless lc($_) eq lc($what);
+                       $CPAN::DEBUG |= $CPAN::DEBUG{$_};
+                   }
+                   print "unknown argument $what\n";
+               }
+           }
+       } else {
+           print "Valid options for debug are ".join(", ",sort(keys %CPAN::DEBUG), 'all').
+               " or a number. Completion works on the options. Case is ignored.\n\n";
+       }
+       if ($CPAN::DEBUG) {
+           print "Options set for debugging:\n";
+           my($k,$v);
+           for $k (sort {$CPAN::DEBUG{$a} <=> $CPAN::DEBUG{$b}} keys %CPAN::DEBUG) {
+               $v = $CPAN::DEBUG{$k};
+               printf "    %-14s(%s)\n", $k, $v if $v & $CPAN::DEBUG;
+           }
+       } else {
+           print "Debugging turned off completely.\n";
+       }
+    } else {
+       print qq{
+Known options:
+  conf    set or get configuration variables
+  debug   set or get debugging options
+};
+    }
+}
+
+sub reload {
+    if ($_[1] =~ /cpan/i) {
+       CPAN->debug("reloading the whole CPAN.pm") if $CPAN::DEBUG;
+       my $fh = IO::File->new($INC{'CPAN.pm'});
+       local $/;
+       undef $/;
+       eval <$fh>;
+       warn $@ if $@;
+    } elsif ($_[1] =~ /index/) {
+       CPAN::Index->force_reload;
+    }
+}
+
+sub _binary_extensions {
+    my($self) = shift @_;
+    my(@result,$module,%seen,%need,$headerdone);
+    for $module ($self->expand('Module','/./')) {
+       my $file  = $module->cpan_file;
+       next if $file eq "N/A";
+       next if $file =~ /^Contact Author/;
+       next if $file =~ /perl5[._-]\d{3}(?:[\d_]+)?\.tar[._-]gz$/;
+       next unless $module->xs_file;
+       push @result, $module;
+    }
+#    print join " | ", @result;
+#    print "\n";
+    return @result;
+}
+
+sub recompile {
+    my($self) = shift @_;
+    my($module,@module,$cpan_file,%dist);
+    @module = $self->_binary_extensions();
+    for $module (@module){  # we force now and compile later, so we don't do it twice
+       $cpan_file = $module->cpan_file;
+       my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
+       $pack->force;
+       $dist{$cpan_file}++;
+    }
+    for $cpan_file (sort keys %dist) {
+       print "  CPAN: Recompiling $cpan_file\n\n";
+       my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
+       $pack->install;
+       $CPAN::Signal = 0; # it's tempting to reset Signal, so we can
+                           # stop a package from recompiling,
+                           # e.g. IO-1.12 when we have perl5.003_10
+    }
+}
+
+sub _u_r_common {
+    my($self) = shift @_;
+    my($what) = shift @_;
+    CPAN->debug("self[$self] what[$what] args[@_]") if $CPAN::DEBUG;
+    Carp::croak "Usage: \$obj->_u_r_common($what)" unless defined $what;
+    Carp::croak "Usage: \$obj->_u_r_common(a|r|u)" unless $what =~ /^[aru]$/;
+    my(@args) = @_;
+    @args = '/./' unless @args;
+    my(@result,$module,%seen,%need,$headerdone,$version_zeroes);
+    $version_zeroes = 0;
+    my $sprintf = "%-25s %9s %9s  %s\n";
+    for $module ($self->expand('Module',@args)) {
+       my $file  = $module->cpan_file;
+       next unless defined $file; # ??
+       my($latest) = $module->cpan_version || 0;
+       my($inst_file) = $module->inst_file;
+       my($have);
+       if ($inst_file){
+           if ($what eq "a") {
+               $have = $module->inst_version;
+           } elsif ($what eq "r") {
+               $have = $module->inst_version;
+               local($^W) = 0;
+               $version_zeroes++ unless $have;
+               next if $have >= $latest;
+           } elsif ($what eq "u") {
+               next;
+           }
+       } else {
+           if ($what eq "a") {
+               next;
+           } elsif ($what eq "r") {
+               next;
+           } elsif ($what eq "u") {
+               $have = "-";
+           }
+       }
+       $seen{$file} ||= 0;
+       if ($what eq "a") {
+           push @result, sprintf "%s %s\n", $module->id, $have;
+       } elsif ($what eq "r") {
+           push @result, $module->id;
+           next if $seen{$file}++;
+       } elsif ($what eq "u") {
+           push @result, $module->id;
+           next if $seen{$file}++;
+           next if $file =~ /^Contact/;
+       }
+       unless ($headerdone++){
+           print "\n";
+           printf $sprintf, "Package namespace", "installed", "latest", "in CPAN file";
+       }
+       $latest = substr($latest,0,8) if length($latest) > 8;
+       $have = substr($have,0,8) if length($have) > 8;
+       printf $sprintf, $module->id, $have, $latest, $file;
+       $need{$module->id}++;
+       return if $CPAN::Signal; # this is sometimes lengthy
+    }
+    unless (%need) {
+       if ($what eq "u") {
+           print "No modules found for @args\n";
+       } elsif ($what eq "r") {
+           print "All modules are up to date for @args\n";
+       }
+    }
+    if ($what eq "r" && $version_zeroes) {
+       my $s = $version_zeroes>1 ? "s have" : " has";
+       print qq{$version_zeroes installed module$s no version number to compare\n};
+    }
+    @result;
+}
+
+sub r {
+    shift->_u_r_common("r",@_);
+}
+
+sub u {
+    shift->_u_r_common("u",@_);
+}
+
+sub autobundle {
+    my($self) = shift;
+    my(@bundle) = $self->_u_r_common("a",@_);
+    my($todir) = $CPAN::META->catdir($CPAN::Config->{'cpan_home'},"Bundle");
+    File::Path::mkpath($todir);
+    unless (-d $todir) {
+       print "Couldn't mkdir $todir for some reason\n";
+       return;
+    }
+    my($y,$m,$d) =  (localtime)[5,4,3];
+    $y+=1900;
+    $m++;
+    my($c) = 0;
+    my($me) = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, $c;
+    my($to) = $CPAN::META->catfile($todir,"$me.pm");
+    while (-f $to) {
+       $me = sprintf "Snapshot_%04d_%02d_%02d_%02d", $y, $m, $d, ++$c;
+       $to = $CPAN::META->catfile($todir,"$me.pm");
+    }
+    my($fh) = IO::File->new(">$to") or Carp::croak "Can't open >$to: $!";
+    $fh->print(
+              "package Bundle::$me;\n\n",
+              "\$VERSION = '0.01';\n\n",
+              "1;\n\n",
+              "__END__\n\n",
+              "=head1 NAME\n\n",
+              "Bundle::$me - Snapshot of installation on ",
+              $Config::Config{'myhostname'},
+              " on ",
+              scalar(localtime),
+              "\n\n=head1 SYNOPSIS\n\n",
+              "perl -MCPAN -e 'install Bundle::$me'\n\n",
+              "=head1 CONTENTS\n\n",
+              join("\n", @bundle),
+              "\n\n=head1 CONFIGURATION\n\n",
+              Config->myconfig,
+              "\n\n=head1 AUTHOR\n\n",
+              "This Bundle has been generated automatically by the autobundle routine in CPAN.pm.\n",
+             );
+    $fh->close;
+    print "\nWrote bundle file
+    $to\n\n";
+}
+
+sub bundle {
+    shift;
+    my(@bundles) = @_;
+    my $bundle;
+    my @pack = ();
+    foreach $bundle (@bundles) {
+       my $pack = $bundle;
+       $pack =~ s/^(Bundle::)?(.*)/Bundle::$2/;
+       push @pack, $CPAN::META->instance('CPAN::Bundle',$pack)->contains;
+    }
+    @pack;
+}
+
+sub bundles {
+    my($self) = @_;
+    CPAN->debug("self[$self]") if $CPAN::DEBUG;
+    sort grep $_->id() =~ /^Bundle::/, $CPAN::META->all('CPAN::Bundle');
+}
+
+sub expand {
+    shift;
+    my($type,@args) = @_;
+    my($arg,@m);
+    for $arg (@args) {
+       my $regex;
+       if ($arg =~ m|^/(.*)/$|) {
+           $regex = $1;
+       }
+       my $class = "CPAN::$type";
+       my $obj;
+       if (defined $regex) {
+           for $obj ( sort {$a->id cmp $b->id} $CPAN::META->all($class)) {
+               push @m, $obj if $obj->id =~ /$regex/i or $obj->can('name') && $obj->name  =~ /$regex/i;
+           }
+       } else {
+           my($xarg) = $arg;
+           if ( $type eq 'Bundle' ) {
+               $xarg =~ s/^(Bundle::)?(.*)/Bundle::$2/;
+           }
+           if ($CPAN::META->exists($class,$xarg)) {
+               $obj = $CPAN::META->instance($class,$xarg);
+           } elsif ($obj = $CPAN::META->exists($class,$arg)) {
+               $obj = $CPAN::META->instance($class,$arg);
+           } else {
+               next;
+           }
+           push @m, $obj;
+       }
+    }
+    return @m;
+}
+
+sub format_result {
+    my($self) = shift;
+    my($type,@args) = @_;
+    @args = '/./' unless @args;
+    my(@result) = $self->expand($type,@args);
+    my $result =  @result==1 ? $result[0]->as_string : join "", map {$_->as_glimpse} @result;
+    $result ||= "No objects of type $type found for argument @args\n";
+    $result;
+}
+
+sub rematein {
+    shift;
+    my($meth,@some) = @_;
+    my $pragma = "";
+    if ($meth eq 'force') {
+       $pragma = $meth;
+       $meth = shift @some;
+    }
+    CPAN->debug("pragma[$pragma]meth[$meth] some[@some]") if $CPAN::DEBUG;
+    my($s,@s);
+    foreach $s (@some) {
+       my $obj;
+       if (ref $s) {
+           $obj = $s;
+       } elsif ($s =~ m|/|) { # looks like a file
+           $obj = $CPAN::META->instance('CPAN::Distribution',$s);
+       } elsif ($s =~ m|^Bundle::|) {
+           $obj = $CPAN::META->instance('CPAN::Bundle',$s);
+       } else {
+           $obj = $CPAN::META->instance('CPAN::Module',$s) if $CPAN::META->exists('CPAN::Module',$s);
+       }
+       if (ref $obj) {
+           CPAN->debug(qq{pragma[$pragma] meth[$meth] obj[$obj] as_string\[}.$obj->as_string.qq{\]}) if $CPAN::DEBUG;
+           $obj->$pragma() if $pragma && $obj->can($pragma);
+           $obj->$meth();
+       } else {
+           print "Warning: Cannot $meth $s, don't know what it is\n";
+       }
+    }
+}
+
+sub force   { shift->rematein('force',@_); }
+sub readme  { shift->rematein('readme',@_); }
+sub make    { shift->rematein('make',@_); }
+sub clean   { shift->rematein('clean',@_); }
+sub test    { shift->rematein('test',@_); }
+sub install { shift->rematein('install',@_); }
+
+package CPAN::FTP;
+use vars qw($Ua @ISA);
+@ISA = qw(CPAN::Debug);
+
+sub ftp_get {
+    my($class,$host,$dir,$file,$target) = @_;
+    $class->debug(
+                      qq[Going to fetch file [$file] from dir [$dir]
+       on host [$host] as local [$target]\n]
+                     ) if $CPAN::DEBUG;
+    my $ftp = Net::FTP->new($host);
+    $ftp->debug(1) if $CPAN::DEBUG{'FTP'} & $CPAN::DEBUG;
+    $class->debug(qq[Going to ->login("anonymous","$Config::Config{'cf_email'}")\n]);
+    unless ( $ftp->login("anonymous",$Config::Config{'cf_email'}) ){
+       warn "Couldn't login on $host";
+       return;
+    }
+    # print qq[Going to ->cwd("$dir")\n];
+    unless ( $ftp->cwd($dir) ){
+       warn "Couldn't cwd $dir";
+       return;
+    }
+    $ftp->binary;
+    print qq[Going to ->get("$file","$target")\n] if $CPAN::DEBUG;
+    unless ( $ftp->get($file,$target) ){
+       warn "Couldn't fetch $file from $host";
+       return;
+    }
+    $ftp->quit;
+}
+
+sub localize {
+    my($self,$file,$aslocal,$force) = @_;
+    $force ||= 0;
+    Carp::croak "Usage: ->localize(cpan_file,as_local_file[,$force])" unless defined $aslocal;
+    $self->debug("file [$file] aslocal [$aslocal]") if $CPAN::DEBUG;
+
+    return $aslocal if -f $aslocal && -r _ && ! $force;
+
+    my($aslocal_dir) = File::Basename::dirname($aslocal);
+    File::Path::mkpath($aslocal_dir);
+    print STDERR qq{Warning: You are not allowed to write into directory "$aslocal_dir".
+    I\'ll continue, but if you face any problems, they may be due
+    to insufficient permissions.\n} unless -w $aslocal_dir;
+
+    # Inheritance is not easier to manage than a few if/else branches
+    if ($CPAN::META->hasLWP) {
+       require LWP::UserAgent;
+       unless ($Ua) {
+           $Ua = new LWP::UserAgent;
+           $Ua->proxy('ftp',  $ENV{'ftp_proxy'})  if defined $ENV{'ftp_proxy'};
+           $Ua->proxy('http', $ENV{'http_proxy'}) if defined $ENV{'http_proxy'};
+           $Ua->no_proxy($ENV{'no_proxy'})        if defined $ENV{'no_proxy'};
+       }
+    }
+
+    # Try the list of urls for each single object. We keep a record
+    # where we did get a file from
+    for (0..$#{$CPAN::Config->{urllist}}) {
+       my $url = $CPAN::Config->{urllist}[$_];
+       $url .= "/" unless substr($url,-1) eq "/";
+       $url .= $file;
+       $self->debug("localizing[$url]") if $CPAN::DEBUG;
+       if ($url =~ /^file:/) {
+           my $l;
+           if ($CPAN::META->hasLWP) {
+               require URI::URL;
+               my $u = new URI::URL $url;
+               $l = $u->path;
+           } else { # works only on Unix
+               ($l = $url) =~ s/^file://;
+           }
+           return $l if -f $l && -r _;
+       }
+
+       if ($CPAN::META->hasLWP) {
+           print "Fetching $url\n";
+           my $res = $Ua->mirror($url, $aslocal);
+           if ($res->is_success) {
+               return $aslocal;
+           }
+       } elsif ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
+           unless ($CPAN::META->hasFTP) {
+               warn "Can't access URL $url without module Net::FTP";
+               next;
+           }
+           my($host,$dir,$getfile) = ($1,$2,$3);
+           $dir =~ s|/+|/|g;
+           print "Going to fetch file [$getfile] from dir [$dir] on host [$host] as local [$aslocal]\n";
+
+           #### This was the bug where I contacted Graham and got so strange error messages
+           #### ftp_get($host,$dir,$getfile,$aslocal) && return $aslocal;
+           CPAN::FTP->ftp_get($host,$dir,$getfile,$aslocal) && return $aslocal;
+       }
+    }
+    Carp::croak("Cannot fetch $file from anywhere");
+}
+
+package CPAN::Complete;
+use vars qw(@ISA);
+@ISA = qw(CPAN::Debug);
+
+sub complete {
+    my($word,$line,$pos) = @_;
+    $word ||= "";
+    $line ||= "";
+    $pos ||= 0;
+    CPAN->debug("word [$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
+    $line =~ s/^\s*//;
+    my @return;
+    if ($pos == 0) {
+       @return = grep(/^$word/, sort qw(! a b d h i m o q r u autobundle clean make test install reload));
+    } elsif ( $line !~ /^[\!abdhimorut]/ ) {
+       @return = ();
+    } elsif ($line =~ /^a\s/) {
+       @return = completex('CPAN::Author',$word);
+    } elsif ($line =~ /^b\s/) {
+       @return = completex('CPAN::Bundle',$word);
+    } elsif ($line =~ /^d\s/) {
+       @return = completex('CPAN::Distribution',$word);
+    } elsif ($line =~ /^([mru]\s|(make|clean|test|install)\s)/ ) {
+       @return = (completex('CPAN::Module',$word),completex('CPAN::Bundle',$word));
+    } elsif ($line =~ /^i\s/) {
+       @return = complete_any($word);
+    } elsif ($line =~ /^reload\s/) {
+       @return = complete_reload($word,$line,$pos);
+    } elsif ($line =~ /^o\s/) {
+       @return = complete_option($word,$line,$pos);
+    } else {
+       @return = ();
+    }
+    return @return;
+}
+
+sub completex {
+    my($class, $word) = @_;
+    grep /^\Q$word\E/, map { $_->id } $CPAN::META->all($class);
+}
+
+sub complete_any {
+    my($word) = shift;
+    return (
+           completex('CPAN::Author',$word),
+           completex('CPAN::Bundle',$word),
+           completex('CPAN::Distribution',$word),
+           completex('CPAN::Module',$word),
+          );
+}
+
+sub complete_reload {
+    my($word,$line,$pos) = @_;
+    $word ||= "";
+    my(@words) = split " ", $line;
+    CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
+    my(@ok) = qw(cpan index);
+    return @ok if @words==1;
+    return grep /^\Q$word\E/, @ok if @words==2 && $word;
+}
+
+sub complete_option {
+    my($word,$line,$pos) = @_;
+    $word ||= "";
+    my(@words) = split " ", $line;
+    CPAN->debug("word[$word] line[$line] pos[$pos]") if $CPAN::DEBUG;
+    my(@ok) = qw(conf debug);
+    return @ok if @words==1;
+    return grep /^\Q$word\E/, @ok if @words==2 && $word;
+    if (0) {
+    } elsif ($words[1] eq 'index') {
+       return ();
+    } elsif ($words[1] eq 'conf') {
+       return CPAN::Config::complete(@_);
+    } elsif ($words[1] eq 'debug') {
+       return sort grep /^\Q$word\E/, sort keys %CPAN::DEBUG, 'all';
+    }
+}
+
+package CPAN::Index;
+use vars qw($last_time @ISA);
+@ISA = qw(CPAN::Debug);
+$last_time ||= 0;
+
+sub force_reload {
+    my($class) = @_;
+    $CPAN::Index::last_time = 0;
+    $class->reload(1);
+}
+
+sub reload {
+    my($cl,$force) = @_;
+    my $time = time;
+
+    # XXX check if a newer one is available. (We currently read it from time to time)
+    return if $last_time + $CPAN::Config->{index_expire}*86400 > $time;
+    $last_time = $time;
+
+    $cl->read_authindex($cl->reload_x("authors/01mailrc.txt.gz","01mailrc.gz",$force));
+    return if $CPAN::Signal; # this is sometimes lengthy
+    $cl->read_modpacks($cl->reload_x("modules/02packages.details.txt.gz","02packag.gz",$force));
+    return if $CPAN::Signal; # this is sometimes lengthy
+    $cl->read_modlist($cl->reload_x("modules/03modlist.data.gz","03mlist.gz",$force));
+}
+
+sub reload_x {
+    my($cl,$wanted,$localname,$force) = @_;
+    $force ||= 0;
+    my $abs_wanted = CPAN->catfile($CPAN::Config->{'keep_source_where'},$localname);
+    if (-f $abs_wanted && -M $abs_wanted < $CPAN::Config->{'index_expire'} && !$force) {
+       my($s) = $CPAN::Config->{'index_expire'} != 1;
+       $cl->debug(qq{$abs_wanted younger than $CPAN::Config->{'index_expire'} day$s. I\'ll use that.\n});
+       return $abs_wanted;
+    } else {
+       $force ||= 1;
+    }
+    return CPAN::FTP->localize($wanted,$abs_wanted,$force);
+}
+
+sub read_authindex {
+    my($cl,$index_target) = @_;
+    my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $index_target";
+    warn "Going to read $index_target\n";
+    my $fh = IO::File->new("$pipe|");
+    while (<$fh>) {
+       chomp;
+       my($userid,$fullname,$email) = /alias\s+(\S+)\s+\"([^\"\<]+)\s+<([^\>]+)\>\"/;
+       next unless $userid && $fullname && $email;
+
+       # instantiate an author object
+       my $userobj = $CPAN::META->instance('CPAN::Author',$userid);
+       $userobj->set('FULLNAME' => $fullname, 'EMAIL' => $email);
+       return if $CPAN::Signal;
+    }
+    $fh->close;
+    $? and Carp::croak "FAILED $pipe: exit status [$?]";
+}
+
+sub read_modpacks {
+    my($cl,$index_target) = @_;
+    my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $index_target";
+    warn "Going to read $index_target\n";
+    my $fh = IO::File->new("$pipe|");
+    while (<$fh>) {
+       next if 1../^\s*$/;
+       chomp;
+       my($mod,$version,$dist) = split;
+       $version =~ s/^\+//;
+
+       # if it as a bundle, instatiate a bundle object
+       my($bundle) = $mod =~ /^Bundle::(.*)/;
+       $version = "n/a" if $mod =~ s/(.+::.+::).+/$1*/; # replace the third level with a star
+
+       if ($mod eq 'CPAN') {
+           local($^W)=0;
+           if ($version > $CPAN::VERSION){
+               print qq{
+  Hey, you know what? There\'s a new CPAN.pm version (v$version)
+  available! I\'d suggest--provided you have time--you try
+    install CPAN
+    reload cpan
+  without quitting the current session. It should be a seemless upgrade
+  while we are running...
+};
+               sleep 2;
+               print qq{\n};
+           }
+       }
+
+       my($id);
+       if ($bundle){
+           $id =  $CPAN::META->instance('CPAN::Bundle',$mod);
+           $id->set('CPAN_VERSION' => $version, 'CPAN_FILE' => $dist);
+# This "next" makes us faster but if the job is running long, we ignore
+# rereads which is bad. So we have to be a bit slower again.
+#      } elsif ($CPAN::META->exists('CPAN::Module',$mod)) {
+#          next;
+       } else {
+           # instantiate a module object
+           $id = $CPAN::META->instance('CPAN::Module',$mod);
+           $id->set('CPAN_VERSION' => $version, 'CPAN_FILE' => $dist);
+       }
+
+       # determine the author
+       my($userid) = $dist =~ /([^\/]+)/;
+       $id->set('CPAN_USERID' => $userid) if $userid =~ /\w/;
+
+       # instantiate a distribution object
+       unless ($CPAN::META->exists('CPAN::Distribution',$dist)) {
+           $CPAN::META->instance(
+                                 'CPAN::Distribution' => $dist
+                                )->set(
+                                       'CPAN_USERID' => $userid
+                                      )
+                                    if $userid =~ /\w/;
+       }
+
+       return if $CPAN::Signal;
+    }
+    $fh->close;
+    $? and Carp::croak "FAILED $pipe: exit status [$?]";
+}
+
+sub read_modlist {
+    my($cl,$index_target) = @_;
+    my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $index_target";
+    warn "Going to read $index_target\n";
+    my $fh = IO::File->new("$pipe|");
+    my $eval = "";
+    while (<$fh>) {
+       next if 1../^\s*$/;
+       next if /use vars/; # will go away in 03...
+       $eval .= $_;
+       return if $CPAN::Signal;
+    }
+    $eval .= q{CPAN::Modulelist->data;};
+    local($^W) = 0;
+    my($comp) = Safe->new("CPAN::Safe1");
+    my $ret = $comp->reval($eval);
+    Carp::confess($@) if $@;
+    return if $CPAN::Signal;
+    for (keys %$ret) {
+       my $obj = $CPAN::META->instance(CPAN::Module,$_);
+       $obj->set(%{$ret->{$_}});
+       return if $CPAN::Signal;
+    }
+}
+
+package CPAN::InfoObj;
+use vars qw(@ISA);
+@ISA = qw(CPAN::Debug);
+
+sub new { my $this = bless {}, shift; %$this = @_; $this }
+
+sub set {
+    my($self,%att) = @_;
+    my(%oldatt) = %$self;
+    %$self = (%oldatt, %att);
+}
+
+sub id { shift->{'ID'} }
+
+sub as_glimpse {
+    my($self) = @_;
+    my(@m);
+    my $class = ref($self);
+    $class =~ s/^CPAN:://;
+    push @m, sprintf "%-15s %s\n", $class, $self->{ID};
+    join "", @m;
+}
+
+sub as_string {
+    my($self) = @_;
+    my(@m);
+    my $class = ref($self);
+    $class =~ s/^CPAN:://;
+    push @m, $class, " id = $self->{ID}\n";
+    for (sort keys %$self) {
+       next if $_ eq 'ID';
+       my $extra = "";
+       $_ eq "CPAN_USERID" and $extra = " (".$self->author.")";
+       if (ref $self->{$_}) { # Should we setup a language interface? XXX
+           push @m, sprintf "    %-12s %s%s\n", $_, "@{$self->{$_}}", $extra;
+       } else {
+           push @m, sprintf "    %-12s %s%s\n", $_, $self->{$_}, $extra;
+       }
+    }
+    join "", @m, "\n";
+}
+
+sub author {
+    my($self) = @_;
+    $CPAN::META->instance(CPAN::Author,$self->{CPAN_USERID})->fullname;
+}
+
+package CPAN::Author;
+use vars qw(@ISA);
+@ISA = qw(CPAN::Debug CPAN::InfoObj);
+
+sub as_glimpse {
+    my($self) = @_;
+    my(@m);
+    my $class = ref($self);
+    $class =~ s/^CPAN:://;
+    push @m, sprintf "%-15s %s (%s)\n", $class, $self->{ID}, $self->fullname;
+    join "", @m;
+}
+
+sub fullname { shift->{'FULLNAME'} }
+*name = \&fullname;
+sub email    { shift->{'EMAIL'} }
+
+package CPAN::Distribution;
+use vars qw(@ISA);
+@ISA = qw(CPAN::Debug CPAN::InfoObj);
+
+sub called_for {
+    my($self,$id) = @_;
+    $self->{'CALLED_FOR'} = $id if defined $id;
+    return $self->{'CALLED_FOR'};
+}
+
+sub get {
+    my($self) = @_;
+  EXCUSE: {
+       my @e;
+       exists $self->{'build_dir'} and push @e, "Unwrapped into directory $self->{'build_dir'}";
+       print join "", map {"  $_\n"} @e and return if @e;
+    }
+    my($local_file);
+    my($local_wanted) =
+        CPAN->catfile(
+                       $CPAN::Config->{keep_source_where},
+                       "authors",
+                       "id",
+                       split("/",$self->{ID})
+                      );
+
+    $self->debug("Doing localize") if $CPAN::DEBUG;
+    $local_file = CPAN::FTP->localize("authors/id/$self->{ID}", $local_wanted);
+    $self->{localfile} = $local_file;
+    my $builddir = $CPAN::META->{cachemgr}->dir;
+    $self->debug("doing chdir $builddir") if $CPAN::DEBUG;
+    chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
+    my $packagedir;
+
+    $self->debug("local_file[$local_file]") if $CPAN::DEBUG;
+    if ($local_file =~ /(\.tar\.(gz|Z)|\.tgz|\.zip)$/i){
+       $self->debug("Removing tmp") if $CPAN::DEBUG;
+       File::Path::rmtree("tmp");
+       mkdir "tmp", 0777 or Carp::croak "Couldn't mkdir tmp: $!";
+       chdir "tmp";
+       $self->debug("Changed directory to tmp") if $CPAN::DEBUG;
+       if ($local_file =~ /z$/i){
+           $self->{archived} = "tar";
+           if (system("$CPAN::Config->{gzip} --decompress --stdout $local_file | $CPAN::Config->{tar} xvf -")==0) {
+               $self->{unwrapped} = "YES";
+           } else {
+               $self->{unwrapped} = "NO";
+           }
+       } elsif ($local_file =~ /zip$/i) {
+           $self->{archived} = "zip";
+           if (system("$CPAN::Config->{unzip} $local_file")==0) {
+               $self->{unwrapped} = "YES";
+           } else {
+               $self->{unwrapped} = "NO";
+           }
+       }
+       # Let's check if the package has its own directory.
+       opendir DIR, "." or Carp::croak("Weird: couldn't opendir .: $!");
+       my @readdir = grep $_ !~ /^\.\.?$/, readdir DIR; ### MAC??
+       closedir DIR;
+       my ($distdir,$packagedir);
+       if (@readdir == 1 && -d $readdir[0]) {
+           $distdir = $readdir[0];
+           $packagedir = $CPAN::META->catdir($builddir,$distdir);
+           -d $packagedir and print "Removing previously used $packagedir\n";
+           File::Path::rmtree($packagedir);
+           rename($distdir,$packagedir) or Carp::confess("Couldn't rename $distdir to $packagedir");
+       } else {
+           my $pragmatic_dir = $self->{'CPAN_USERID'} . '000';
+           $pragmatic_dir =~ s/\W_//g;
+           $pragmatic_dir++ while -d "../$pragmatic_dir";
+           $packagedir = $CPAN::META->catdir($builddir,$pragmatic_dir);
+           File::Path::mkpath($packagedir);
+           my($f);
+           for $f (@readdir) { # is already without "." and ".."
+               my $to = $CPAN::META->catdir($packagedir,$f);
+               rename($f,$to) or Carp::confess("Couldn't rename $f to $to");
+           }
+       }
+       $self->{'build_dir'} = $packagedir;
+
+       chdir "..";
+       $self->debug("Changed directory to .. (self is $self [".$self->as_string."])") if $CPAN::DEBUG;
+       File::Path::rmtree("tmp");
+       if ($CPAN::Config->{keep_source_where} =~ /^no/i ){
+           print "Going to unlink $local_file\n";
+           unlink $local_file or Carp::carp "Couldn't unlink $local_file";
+       }
+       my($makefilepl) = $CPAN::META->catfile($packagedir,"Makefile.PL");
+       unless (-f $makefilepl) {
+           my($configure) = $CPAN::META->catfile($packagedir,"Configure");
+           if (-f $configure) {
+               # do we have anything to do?
+               $self->{'configure'} = $configure;
+           } else {
+               my $fh = IO::File->new(">$makefilepl") or Carp::croak("Could not open >$makefilepl");
+               my $cf = $self->called_for || "unknown";
+               $fh->print(qq{
+# This Makefile.PL has been autogenerated by the module CPAN.pm
+# Autogenerated on: }.scalar localtime().qq{
+                   use ExtUtils::MakeMaker;
+                   WriteMakefile(NAME => q[$cf]);
+});
+               print qq{Package comes without Makefile.PL.\n}.
+                   qq{  Writing one on our own (calling it $cf)\n};
+           }
+       }
+    } else {
+       $self->{archived} = "NO";
+    }
+    return $self;
+}
+
+sub new {
+    my($class,%att) = @_;
+
+    $CPAN::META->{cachemgr} ||= CPAN::CacheMgr->new();
+
+    my $this = { %att };
+    return bless $this, $class;
+}
+
+sub readme {
+    my($self) = @_;
+    print "Readme not yet implemented (says ".$self->id.")\n";
+}
+
+sub verifyMD5 {
+    my($self) = @_;
+  EXCUSE: {
+       my @e;
+       $self->{MD5_STATUS} and push @e, "MD5 Checksum was ok";
+       print join "", map {"  $_\n"} @e and return if @e;
+    }
+    my($local_file);
+    my(@local) = split("/",$self->{ID});
+    my($basename) = pop @local;
+    push @local, "CHECKSUMS";
+    my($local_wanted) =
+       CPAN->catfile(
+                     $CPAN::Config->{keep_source_where},
+                     "authors",
+                     "id",
+                     @local
+                    );
+    local($") = "/";
+    if (
+       -f $local_wanted
+       &&
+       $self->MD5_check_file($local_wanted,$basename)
+       ) {
+       return $self->{MD5_STATUS}="OK";
+    }
+    $local_file = CPAN::FTP->localize("authors/id/@local", $local_wanted, 'force>:-{');
+    my($checksum_pipe);
+    if ($local_file) {
+       # fine
+    } else {
+       $local[-1] .= ".gz";
+       $local_file = CPAN::FTP->localize(
+                                         "authors/id/@local",
+                                         "$local_wanted.gz",
+                                         'force>:-{'
+                                        );
+       my $system = "$CPAN::Config->{gzip} --decompress $local_file";
+       system($system)==0 or die "Could not uncompress $local_file";
+       $local_file =~ s/\.gz$//;
+    }
+    $self->MD5_check_file($local_file,$basename);
+}
+
+sub MD5_check_file {
+    my($self,$lfile,$basename) = @_;
+    my($cksum);
+    my $fh = new IO::File;
+    local($/)=undef;
+    if (open $fh, $lfile){
+       my $eval = <$fh>;
+       close $fh;
+       my($comp) = Safe->new();
+       $cksum = $comp->reval($eval);
+       Carp::confess($@) if $@;
+       if ($cksum->{$basename}->{md5}) {
+           $self->debug("Found checksum for $basename: $cksum->{$basename}->{md5}\n") if $CPAN::DEBUG;
+           my $file = $self->{localfile};
+           my $pipe = "$CPAN::Config->{gzip} --decompress --stdout $self->{localfile}|";
+           if (
+               open($fh, $file) && $self->eq_MD5($fh,$cksum->{$basename}->{md5})
+               or
+               open($fh, $pipe) && $self->eq_MD5($fh,$cksum->{$basename}->{'md5-ungz'})
+              ){
+               print "Checksum for $file ok\n";
+               return $self->{MD5_STATUS}="OK";
+           } else {
+               die join(
+                        "",
+                        "\nChecksum mismatch for distribution file. Please investigate.\n\n",
+                        $self->as_string,
+                        $CPAN::META->instance('CPAN::Author',$self->{CPAN_USERID})->as_string,
+                        "Please contact the author or your CPAN site admin"
+                       );
+           }
+           close $fh if fileno($fh);
+       } else {
+           print "No md5 checksum for $basename in local $lfile\n";
+           return;
+       }
+    } else {
+       Carp::carp "Could not open $lfile for reading";
+    }
+}
+
+sub eq_MD5 {
+    my($self,$fh,$expectMD5) = @_;
+    my $md5 = new MD5;
+    $md5->addfile($fh);
+    my $hexdigest = $md5->hexdigest;
+    $hexdigest eq $expectMD5;
+}
+
+sub force {
+    my($self) = @_;
+    $self->{'force_update'}++;
+    delete $self->{'MD5_STATUS'};
+    delete $self->{'archived'};
+    delete $self->{'build_dir'};
+    delete $self->{'localfile'};
+    delete $self->{'make'};
+    delete $self->{'install'};
+    delete $self->{'unwrapped'};
+    delete $self->{'writemakefile'};
+}
+
+sub make {
+    my($self) = @_;
+    $self->debug($self->id) if $CPAN::DEBUG;
+    print "Running make\n";
+    $self->get;
+    if ($CPAN::META->hasMD5) {
+       $self->verifyMD5;
+    }
+    EXCUSE: {
+         my @e;
+         $self->{archived} eq "NO" and push @e, "Is neither a tar nor a zip archive.";
+         $self->{unwrapped} eq "NO"   and push @e, "had problems unarchiving. Please build manually";
+         exists $self->{writemakefile} && $self->{writemakefile} eq "NO" and push @e, "Had some problem writing Makefile";
+         defined $self->{'make'} and push @e, "Has already been processed within this session";
+         print join "", map {"  $_\n"} @e and return if @e;
+     }
+    print "\n  CPAN: Going to build ".$self->id."\n\n";
+    my $builddir = $self->dir;
+    chdir $builddir or Carp::croak("Couldn't chdir $builddir: $!");
+    $self->debug("Changed directory to $builddir") if $CPAN::DEBUG;
+
+    my $system;
+    if ($self->{'configure'}) {
+       $system = $self->{'configure'};
+    } else {
+       my($perl) = $^X =~ /^\.\// ? "$CPAN::Cwd/$^X" : $^X; # XXX subclassing folks, forgive me!
+       $system = "$perl Makefile.PL $CPAN::Config->{makepl_arg}";
+    }
+    if (system($system)!=0) {
+        $self->{writemakefile} = "NO";
+        return;
+    }
+    $self->{writemakefile} = "YES";
+    return if $CPAN::Signal;
+    $system = join " ", $CPAN::Config->{'make'}, $CPAN::Config->{make_arg};
+    if (system($system)==0) {
+        print "  $system -- OK\n";
+        $self->{'make'} = "YES";
+    } else {
+        $self->{writemakefile} = "YES";
+        $self->{'make'} = "NO";
+        print "  $system -- NOT OK\n";
+    }
+}
+
+sub test {
+    my($self) = @_;
+    $self->make;
+    return if $CPAN::Signal;
+    print "Running make test\n";
+    EXCUSE: {
+         my @e;
+         exists $self->{'make'} or push @e, "Make had some problems, maybe interrupted? Won't test";
+         exists $self->{'make'} and $self->{'make'} eq 'NO' and push @e, "Oops, make had returned bad status";
+         exists $self->{'build_dir'} or push @e, "Has no own directory";
+         print join "", map {"  $_\n"} @e and return if @e;
+     }
+    chdir $self->{'build_dir'} or Carp::croak("Couldn't chdir to $self->{'build_dir'}");
+    $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
+    my $system = join " ", $CPAN::Config->{'make'}, "test";
+    if (system($system)==0) {
+        print "  $system -- OK\n";
+        $self->{'make_test'} = "YES";
+    } else {
+        $self->{'make_test'} = "NO";
+        print "  $system -- NOT OK\n";
+    }
+}
+
+sub clean {
+    my($self) = @_;
+    print "Running make clean\n";
+    EXCUSE: {
+         my @e;
+         exists $self->{'build_dir'} or push @e, "Has no own directory";
+         print join "", map {"  $_\n"} @e and return if @e;
+     }
+    chdir $self->{'build_dir'} or Carp::croak("Couldn't chdir to $self->{'build_dir'}");
+    $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
+    my $system = join " ", $CPAN::Config->{'make'}, "clean";
+    if (system($system)==0) {
+       print "  $system -- OK\n";
+       $self->force;
+    } else {
+       # Hmmm, what to do if make clean failed?
+    }
+}
+
+sub install {
+    my($self) = @_;
+    $self->test;
+    return if $CPAN::Signal;
+    print "Running make install\n";
+    EXCUSE: {
+         my @e;
+         exists $self->{'build_dir'} or push @e, "Has no own directory";
+         exists $self->{'make'} or push @e, "Make had some problems, maybe interrupted? Won't install";
+         exists $self->{'make'} and $self->{'make'} eq 'NO' and push @e, "Oops, make had returned bad status";
+         exists $self->{'install'} and push @e, $self->{'install'} eq "YES" ? "Already done" : "Already tried without success";
+         print join "", map {"  $_\n"} @e and return if @e;
+     }
+    chdir $self->{'build_dir'} or Carp::croak("Couldn't chdir to $self->{'build_dir'}");
+    $self->debug("Changed directory to $self->{'build_dir'}") if $CPAN::DEBUG;
+    my $system = join " ", $CPAN::Config->{'make'}, "install", $CPAN::Config->{make_install_arg};
+    my($pipe) = IO::File->new("$system 2>&1 |");
+    my($makeout) = "";
+    while (<$pipe>){
+       print;
+       $makeout .= $_;
+    }
+    $pipe->close;
+    if ($?==0) {
+        print "  $system -- OK\n";
+        $self->{'install'} = "YES";
+    } else {
+        $self->{'install'} = "NO";
+        print "  $system -- NOT OK\n";
+        if ($makeout =~ /permission/s && $> > 0) {
+            print "    You may have to su to root to install the package\n";
+        }
+    }
+}
+
+sub dir {
+    shift->{'build_dir'};
+}
+
+package CPAN::Bundle;
+use vars qw(@ISA);
+@ISA = qw(CPAN::Debug CPAN::InfoObj CPAN::Module);
+
+sub as_string {
+    my($self) = @_;
+    $self->contains;
+    return $self->SUPER::as_string;
+}
+
+sub contains {
+    my($self) = @_;
+    my($parsefile) = $self->inst_file;
+    unless ($parsefile) {
+       # Try to get at it in the cpan directory
+       $self->debug("no parsefile") if $CPAN::DEBUG;
+       my $dist = $CPAN::META->instance('CPAN::Distribution',$self->{'CPAN_FILE'});
+       $self->debug($dist->as_string) if $CPAN::DEBUG;
+       $dist->get;
+       $self->debug($dist->as_string) if $CPAN::DEBUG;
+       my($todir) = $CPAN::META->catdir($CPAN::Config->{'cpan_home'},"Bundle");
+       File::Path::mkpath($todir);
+       my($me,$from,$to);
+       ($me = $self->id) =~ s/.*://;
+       $from = $CPAN::META->catfile($dist->{'build_dir'},"$me.pm");
+       $to = $CPAN::META->catfile($todir,"$me.pm");
+       rename($from, $to) or Carp::croak("Couldn't rename $from to $to: $!");
+       $parsefile = $to;
+    }
+    my @result;
+    my $fh = new IO::File;
+    local $/ = "\n";
+    open($fh,$parsefile) or die "Could not open '$parsefile': $!";
+    my $inpod = 0;
+    while (<$fh>) {
+       $inpod = /^=(?!head1\s+CONTENTS)/ ? 0 : /^=head1\s+CONTENTS/ ? 1 : $inpod;
+       next unless $inpod;
+       next if /^=/;
+       next if /^\s+$/;
+       chomp;
+       push @result, (split " ", $_, 2)[0];
+    }
+    close $fh;
+    delete $self->{STATUS};
+    $self->{CONTAINS} = [@result];
+    @result;
+}
+
+sub inst_file {
+    my($self) = @_;
+    my($me,$inst_file);
+    ($me = $self->id) =~ s/.*://;
+    $inst_file = $CPAN::META->catfile($CPAN::Config->{'cpan_home'},"Bundle", "$me.pm");
+    return $self->{'INST_FILE'} = $inst_file if -f $inst_file;
+    $inst_file = $self->SUPER::inst_file;
+    return $self->{'INST_FILE'} = $inst_file if -f $inst_file;
+    return $self->{'INST_FILE'}; # even if undefined?
+}
+
+sub rematein {
+    my($self,$meth) = @_;
+    $self->debug("self[$self] meth[$meth]") if $CPAN::DEBUG;
+    my($s);
+    for $s ($self->contains) {
+       $CPAN::META->instance('CPAN::Module',$s)->$meth();
+    }
+}
+
+sub install { shift->rematein('install',@_); }
+sub clean   { shift->rematein('clean',@_); }
+sub test    { shift->rematein('test',@_); }
+sub make    { shift->rematein('make',@_); }
+
+# XXX not yet implemented!
+sub readme  {
+    my($self) = @_;
+    my($file) = $self->cpan_file or print("No File found for bundle ", $self->id, "\n"), return;
+    $self->debug("self[$self] file[$file]") if $CPAN::DEBUG;
+    $CPAN::META->instance('CPAN::Distribution',$file)->readme;
+#    CPAN::FTP->localize("authors/id/$file",$index_wanted); # XXX
+}
+
+package CPAN::Module;
+use vars qw(@ISA);
+@ISA = qw(CPAN::Debug CPAN::InfoObj);
+
+sub as_glimpse {
+    my($self) = @_;
+    my(@m);
+    my $class = ref($self);
+    $class =~ s/^CPAN:://;
+    push @m, sprintf "%-15s %-15s (%s)\n", $class, $self->{ID}, $self->cpan_file;
+    join "", @m;
+}
+
+sub as_string {
+    my($self) = @_;
+    my(@m);
+    CPAN->debug($self) if $CPAN::DEBUG;
+    my $class = ref($self);
+    $class =~ s/^CPAN:://;
+    local($^W) = 0;
+    push @m, $class, " id = $self->{ID}\n";
+    my $sprintf = "    %-12s %s\n";
+    push @m, sprintf $sprintf, 'DESCRIPTION', $self->{description} if $self->{description};
+    my $sprintf2 = "    %-12s %s (%s)\n";
+    my($userid);
+    if ($userid = $self->{'CPAN_USERID'} || $self->{'userid'}){
+       push @m, sprintf(
+                        $sprintf2,
+                        'CPAN_USERID',
+                        $userid,
+                        $CPAN::META->instance(CPAN::Author,$userid)->fullname
+                       )
+    }
+    push @m, sprintf $sprintf, 'CPAN_VERSION', $self->{CPAN_VERSION} if $self->{CPAN_VERSION};
+    push @m, sprintf $sprintf, 'CPAN_FILE', $self->{CPAN_FILE} if $self->{CPAN_FILE};
+    my $sprintf3 = "    %-12s %1s%1s%1s%1s (%s,%s,%s,%s)\n";
+    my(%statd,%stats,%statl,%stati);
+    @statd{qw,? i c a b R M S,} = qw,unknown idea pre-alpha alpha beta released mature standard,;
+    @stats{qw,? m d u n,}       = qw,unknown mailing-list developer comp.lang.perl.* none,;
+    @statl{qw,? p c + o,}       = qw,unknown perl C C++ other,;
+    @stati{qw,? f r O,}         = qw,unknown functions references+ties object-oriented,;
+    $statd{' '} = 'unknown';
+    $stats{' '} = 'unknown';
+    $statl{' '} = 'unknown';
+    $stati{' '} = 'unknown';
+    push @m, sprintf(
+                    $sprintf3,
+                    'DSLI_STATUS',
+                    $self->{statd},
+                    $self->{stats},
+                    $self->{statl},
+                    $self->{stati},
+                    $statd{$self->{statd}},
+                    $stats{$self->{stats}},
+                    $statl{$self->{statl}},
+                    $stati{$self->{stati}}
+                   ) if $self->{statd};
+    my $local_file = $self->inst_file;
+    if ($local_file && ! exists $self->{MANPAGE}) {
+       my $fh = IO::File->new($local_file) or Carp::croak("Couldn't open $local_file: $!");
+       my $inpod = 0;
+       my(@result);
+       local $/ = "\n";
+       while (<$fh>) {
+           $inpod = /^=(?!head1\s+NAME)/ ? 0 : /^=head1\s+NAME/ ? 1 : $inpod;
+           next unless $inpod;
+           next if /^=/;
+           next if /^\s+$/;
+           chomp;
+           push @result, $_;
+       }
+       close $fh;
+       $self->{MANPAGE} = join " ", @result;
+    }
+    push @m, sprintf $sprintf, 'MANPAGE', $self->{MANPAGE} if $self->{MANPAGE};
+    push @m, sprintf $sprintf, 'INST_FILE', $local_file || "(not installed)";
+    push @m, sprintf $sprintf, 'INST_VERSION', $self->inst_version if $local_file;
+    join "", @m, "\n";
+}
+
+sub cpan_file    {
+    my $self = shift;
+    CPAN->debug($self->id) if $CPAN::DEBUG;
+    unless (defined $self->{'CPAN_FILE'}) {
+       CPAN::Index->reload;
+    }
+    if (defined $self->{'CPAN_FILE'}){
+       return $self->{'CPAN_FILE'};
+    } elsif (defined $self->{'userid'}) {
+       return "Contact Author ".$self->{'userid'}."=".$CPAN::META->instance(CPAN::Author,$self->{'userid'})->fullname
+    } else {
+       return "N/A";
+    }
+}
+
+*name = \&cpan_file;
+
+sub cpan_version { shift->{'CPAN_VERSION'} }
+
+sub force {
+    my($self) = @_;
+    $self->{'force_update'}++;
+}
+
+sub rematein {
+    my($self,$meth) = @_;
+    $self->debug($self->id) if $CPAN::DEBUG;
+    my $cpan_file = $self->cpan_file;
+    return if $cpan_file eq "N/A";
+    return if $cpan_file =~ /^Contact Author/;
+    my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
+    $pack->called_for($self->id);
+    $pack->force if exists $self->{'force_update'};
+    $pack->$meth();
+    delete $self->{'force_update'};
+}
+
+sub readme { shift->rematein('readme') }
+sub make   { shift->rematein('make') }
+sub clean  { shift->rematein('clean') }
+sub test   { shift->rematein('test') }
+sub install {
+    my($self) = @_;
+    my($doit) = 0;
+    my($latest) = $self->cpan_version;
+    $latest ||= 0;
+    my($inst_file) = $self->inst_file;
+    my($have) = 0;
+    if (defined $inst_file) {
+       $have = $self->inst_version;
+    }
+    if ($inst_file && $have >= $latest && not exists $self->{'force_update'}) {
+       print $self->id, " is up to date.\n";
+    } else {
+       $doit = 1;
+    }
+    $self->rematein('install') if $doit;
+}
+
+sub inst_file {
+    my($self) = @_;
+    my($dir,@packpath);
+    @packpath = split /::/, $self->{ID};
+    $packpath[-1] .= ".pm";
+    foreach $dir (@INC) {
+       my $pmfile = CPAN->catfile($dir,@packpath);
+       if (-f $pmfile){
+           return $pmfile;
+       }
+    }
+}
+
+sub xs_file {
+    my($self) = @_;
+    my($dir,@packpath);
+    @packpath = split /::/, $self->{ID};
+    push @packpath, $packpath[-1];
+    $packpath[-1] .= "." . $Config::Config{'dlext'};
+    foreach $dir (@INC) {
+       my $xsfile = CPAN->catfile($dir,'auto',@packpath);
+       if (-f $xsfile){
+           return $xsfile;
+       }
+    }
+}
+
+sub inst_version {
+    my($self) = @_;
+    my $parsefile = $self->inst_file or return 0;
+    my $have = MY->parse_version($parsefile);
+    $have ||= 0;
+    $have =~ s/\s+//g;
+    $have ||= 0;
+    $have;
+}
+
+package CPAN::CacheMgr;
+use vars qw($Du @ISA);
+@ISA=qw(CPAN::Debug CPAN::InfoObj);
+use File::Find;
+
+sub as_string {
+    eval { require Data::Dumper };
+    if ($@) {
+       return shift->SUPER::as_string;
+    } else {
+       return Data::Dumper::Dumper(shift);
+    }
+}
+
+sub cachesize {
+    shift->{DU};
+}
+
+# sub check {
+#     my($self,@dirs) = @_;
+#     return unless -d $self->{ID};
+#     my $dir;
+#     @dirs = $self->dirs unless @dirs;
+#     for $dir (@dirs) {
+#        $self->disk_usage($dir);
+#     }
+# }
+
+sub clean_cache {
+    my $self = shift;
+    my $dir;
+    while ($self->{DU} > $self->{'MAX'} and $dir = shift @{$self->{FIFO}}) {
+       $self->force_clean_cache($dir);
+    }
+    $self->debug("leaving clean_cache with $self->{DU}") if $CPAN::DEBUG;
+}
+
+sub dir {
+    shift->{ID};
+}
+
+sub entries {
+    my($self,$dir) = @_;
+    $dir ||= $self->{ID};
+    my($cwd) = Cwd::cwd();
+    chdir $dir or Carp::croak("Can't chdir to $dir: $!");
+    my $dh = DirHandle->new(".") or Carp::croak("Couldn't opendir $dir: $!");
+    my(@entries);
+    for ($dh->read) {
+       next if $_ eq "." || $_ eq "..";
+       if (-f $_) {
+           push @entries, $CPAN::META->catfile($dir,$_);
+       } elsif (-d _) {
+           push @entries, $CPAN::META->catdir($dir,$_);
+       } else {
+           print STDERR "Warning: weird direntry in $dir: $_\n";
+       }
+    }
+    chdir $cwd or Carp::croak("Can't chdir to $cwd: $!");
+    sort {-M $b <=> -M $a} @entries;
+}
+
+sub disk_usage {
+    my($self,$dir) = @_;
+    if (! defined $dir or $dir eq "") {
+       $self->debug("Cannot determine disk usage for some reason") if $CPAN::DEBUG;
+       return;
+    }
+    return if defined $self->{SIZE}{$dir};
+    local($Du) = 0;
+    find(
+        sub {
+            return if -l $_;
+            $Du += -s;
+        },
+        $dir
+       );
+    $self->{SIZE}{$dir} = $Du/1024/1024;
+    push @{$self->{FIFO}}, $dir;
+    $self->debug("measured $dir is $Du") if $CPAN::DEBUG;
+    $self->{DU} += $Du/1024/1024;
+    if ($self->{DU} > $self->{'MAX'} ) {
+       printf "...Hold on a sec... CPAN's cleaning the cache: %.2f MB > %.2f MB\n",
+               $self->{DU}, $self->{'MAX'};
+       $self->clean_cache;
+    } else {
+       $self->debug("NOT have to clean the cache: $self->{DU} <= $self->{'MAX'}") if $CPAN::DEBUG;
+       $self->debug($self->as_string) if $CPAN::DEBUG;
+    }
+    $self->{DU};
+}
+
+sub force_clean_cache {
+    my($self,$dir) = @_;
+    $self->debug("have to rmtree $dir, will free $self->{SIZE}{$dir}") if $CPAN::DEBUG;
+    File::Path::rmtree($dir);
+    $self->{DU} -= $self->{SIZE}{$dir};
+    delete $self->{SIZE}{$dir};
+}
+
+sub new {
+    my $class = shift;
+    my $self = { ID => $CPAN::Config->{'build_dir'}, MAX => $CPAN::Config->{'build_cache'}, DU => 0 };
+    File::Path::mkpath($self->{ID});
+    my $dh = DirHandle->new($self->{ID});
+    bless $self, $class;
+    $self->debug("dir [$self->{ID}]") if $CPAN::DEBUG;
+    my $e;
+    for $e ($self->entries) {
+       next if $e eq ".." || $e eq ".";
+       $self->debug("Have to check size $e") if $CPAN::DEBUG;
+       $self->disk_usage($e);
+    }
+    $self;
+}
+
+package CPAN::Debug;
+
+sub debug {
+    my($self,$arg) = @_;
+    my($caller,$func,$line,@rest) = caller(1); # caller(0) eg Complete, caller(1) eg readline
+    ($caller) = caller(0);
+    $caller =~ s/.*:://;
+#    print "caller[$caller]func[$func]line[$line]rest[@rest]\n";
+#    print "CPAN::DEBUG{caller}[$CPAN::DEBUG{$caller}]CPAN::DEBUG[$CPAN::DEBUG]\n";
+    if ($CPAN::DEBUG{$caller} & $CPAN::DEBUG){
+       if (ref $arg) {
+           eval { require Data::Dumper };
+           if ($@) {
+               print $arg->as_string;
+           } else {
+               print Data::Dumper::Dumper($arg);
+           }
+       } else {
+           print "Debug($caller:$func,$line,@rest): $arg\n"
+       }
+    }
+}
+
+package CPAN::Config;
+import ExtUtils::MakeMaker 'neatvalue';
+use vars qw(%can);
+
+%can = (
+  'commit' => "Commit changes to disk",
+  'defaults' => "Reload defaults from disk",
+);
+
+sub edit {
+    my($class,@args) = @_;
+    return unless @args;
+    CPAN->debug("class[$class]args[@args]");
+    my($o,$str,$func,$args,$key_exists);
+    $o = shift @args;
+    if($can{$o}) {
+       $class->$o(@args);
+       return 1;
+    }
+    return unless exists $CPAN::Config->{$o};
+
+    if (ref($CPAN::Config->{$o}) eq ARRAY) {
+       if (@args) {
+           $func = shift @args;
+           # Let's avoid eval, it's easier to comprehend without.
+           if ($func eq "push") {
+               push @{$CPAN::Config->{$o}}, @args;
+           } elsif ($func eq "pop") {
+               pop @{$CPAN::Config->{$o}};
+           } elsif ($func eq "shift") {
+               shift @{$CPAN::Config->{$o}};
+           } elsif ($func eq "unshift") {
+               unshift @{$CPAN::Config->{$o}}, @args;
+           } elsif ($func eq "splice") {
+               splice @{$CPAN::Config->{$o}}, @args;
+           } else {
+               $CPAN::Config->{$o} = [@args];
+           }
+       } else {
+           print qq{    $o    }, neatvalue($CPAN::Config->{$o}), qq{
+Usage:
+    o conf $o [shift|pop]
+or
+    o conf $o [unshift|push|splice] <list>
+};
+       }
+    } else {
+       if (@args) {
+           $CPAN::Config->{$o} = $args[0];
+       }
+       print "    $o    ";
+       print defined $CPAN::Config->{$o} ? $CPAN::Config->{$o} : "UNDEFINED";
+    }
+}
+
+sub commit {
+    my($self, $configpm) = @_;
+    my $mode;
+    # mkpath!?
+
+    my($fh) = IO::File->new;
+    $configpm ||= cfile();
+    if (-f $configpm) {
+       $mode = (stat $configpm)[2];
+       if ($mode && ! -w _) {
+           print "$configpm is not writable\n" and return;
+       }
+       #chmod 0644, $configpm; #?
+    }
+
+    my $msg = <<EOF unless $configpm =~ /MyConfig/;
+
+# This is CPAN.pm's systemwide configuration file.  This file provides
+# defaults for users, and the values can be changed in a per-user configuration
+# file. The user-config file is being looked for as ~/.cpan/CPAN/MyConfig.pm.
+
+EOF
+    $msg ||= "\n";
+    open $fh, ">$configpm" or warn "Couldn't open >$configpm: $!";
+    print $fh qq[$msg\$CPAN::Config = \{\n];
+    foreach (sort keys %$CPAN::Config) {
+       print $fh "  '$_' => ", ExtUtils::MakeMaker::neatvalue($CPAN::Config->{$_}), ",\n";
+    }
+
+    print $fh "};\n1;\n__END__\n";
+    close $fh;
+
+    #$mode = 0444 | ( $mode & 0111 ? 0111 : 0 );
+    #chmod $mode, $configpm;
+    $self->defaults;
+    print "commit: wrote $configpm\n";
+    1;
+}
+
+*default = \&defaults;
+sub defaults {
+    my($self) = @_;
+    $self->unload;
+    $self->load;
+    1;
+}
+
+my $dot_cpan;
+sub load {
+    my($self) = @_;
+    eval {require CPAN::Config;};       # We eval, because of some MakeMaker problems
+    unshift @INC, $CPAN::META->catdir($ENV{HOME},".cpan") unless $dot_cpan++;
+    eval {require CPAN::MyConfig;};     # where you can override system wide settings
+    unless ( $self->load_succeeded ) {
+         require CPAN::FirstTime;
+         my($configpm,$fh);
+         if (defined $INC{"CPAN/Config.pm"} && -w $INC{"CPAN/Config.pm"}) {
+             $configpm = $INC{"CPAN/Config.pm"};
+         } elsif (defined $INC{"CPAN/MyConfig.pm"} && -w $INC{"CPAN/MyConfig.pm"}) {
+             $configpm = $INC{"CPAN/MyConfig.pm"};
+         } else {
+             my($path_to_cpan) = File::Basename::dirname($INC{"CPAN.pm"});
+             my($configpmdir) = MY->catdir($path_to_cpan,"CPAN");
+             my($configpmtest) = MY->catfile($configpmdir,"Config.pm");
+             if (-d $configpmdir || File::Path::mkpath($configpmdir)) {
+#_#_# following code dumped core on me with 5.003_11, a.k.
+#_#_#                 $fh = IO::File->new;
+#_#_#                 if ($fh->open(">$configpmtest")) {
+#_#_#                    $fh->print("1;\n");
+#_#_#                     $configpm = $configpmtest;
+#_#_#                 }
+                 if (-w $configpmtest or -w $configpmdir) {
+                     $configpm = $configpmtest;
+                 }
+             }
+             unless ($configpm) {
+                 $configpmdir = MY->catdir($ENV{HOME},".cpan","CPAN");
+                 File::Path::mkpath($configpmdir);
+                 $configpmtest = MY->catfile($configpmdir,"MyConfig.pm");
+                 if (-w $configpmtest or -w $configpmdir) {
+                     $configpm = $configpmtest;
+                 } else {
+                     warn "WARNING: CPAN.pm is unable to create a configuration file.\n";
+                 }
+             }
+         }
+         warn "Calling CPAN::FirstTime::init($configpm)";
+         CPAN::FirstTime::init($configpm);
+    }
+}
+
+sub load_succeeded {
+    my($miss) = 0;
+    for (qw(
+           cpan_home keep_source_where build_dir build_cache index_expire
+           gzip tar unzip make pager makepl_arg make_arg make_install_arg
+           urllist inhibit_startup_message
+          )) {
+       $miss++ unless defined $CPAN::Config->{$_}; # we want them all
+    }
+    return !$miss;
+}
+
+sub unload {
+    delete $INC{'CPAN/MyConfig.pm'};
+    delete $INC{'CPAN/Config.pm'};
+}
+
+sub cfile {
+    $INC{'CPAN/MyConfig.pm'} || $INC{'CPAN/Config.pm'};
+}
+
+*h = \&help;
+sub help {
+    print <<EOF;
+Known options:
+  defaults  reload default config values from disk
+  commit    commit session changes to disk
+
+You may edit key values in the follow fashion:
+
+  o conf build_cache 15
+
+  o conf build_dir "/foo/bar"
+
+  o conf urllist shift
+
+  o conf urllist unshift ftp://ftp.foo.bar/
+
+EOF
+    undef; #don't reprint CPAN::Config
+}
+
+sub complete {
+    my($word,$line,$pos) = @_;
+    $word ||= "";
+    my(@words) = split " ", $line;
+    my(@o_conf) = (sort keys %CPAN::Config::can, sort keys %$CPAN::Config);
+    return (@o_conf) unless @words>2;
+    if($words[2] =~ /->(.*)/) {
+       my $meth = $1;
+       my(@methods) = qw(shift unshift push pop splice);
+       return @methods unless $meth;
+       return sort grep /^\Q$meth\E/, @methods;
+    }
+    return sort grep /^\Q$word\E/, @o_conf;
+}
+
+1;
+
+=head1 NAME
+
+CPAN - query, download and build perl modules from CPAN sites
+
+=head1 SYNOPSIS
+
+Interactive mode:
+
+  perl -MCPAN -e shell;
+
+Batch mode:
+
+  use CPAN;
+
+  autobundle, bundle, clean, expand, install, make, recompile, test
+
+=head1 DESCRIPTION
+
+The CPAN module is designed to automate the building and installing of
+perl modules and extensions including the searching and fetching from
+the net.
+
+Modules are fetched from one or more of the mirrored CPAN
+(Comprehensive Perl Archive Network) sites and unpacked in a dedicated
+directory.
+
+The CPAN module also supports the concept of named and versioned
+'bundles' of modules. Bundles simplify the handling of sets of
+related modules. See BUNDLES below.
+
+The package contains a session manager and a cache manager. There is
+no status retained between sessions. The session manager keeps track
+of what has been fetched, built and installed in the current
+session. The cache manager keeps track of the disk space occupied by
+the make processes and deletes excess space in a simple FIFO style.
+
+=head2 Interactive Mode
+
+The interactive mode is entered by running
+
+    perl -MCPAN -e shell
+
+which puts you into a readline interface. You will have most fun if
+you install Term::ReadKey and Term::ReadLine to enjoy both history and
+completion.
+
+Once you are on the command line, type 'h' and the rest should be
+self-explanatory.
+
+=head2 CPAN::Shell
+
+The commands that are available in the shell interface are methods in
+the package CPAN::Shell. If you enter the shell command, all your
+input is split on whitespace, the first word is being interpreted as
+the method to be called and the rest of the words are treated as
+arguments to this method.
+
+If you do not enter the shell, most of the available shell commands
+are both available as methods (C<CPAN::Shell-E<gt>install(...)>) and as
+functions in the calling package (C<install(...)>).
+
+=head2 Cache Manager
+
+Currently the cache manager only keeps track of the build directory
+($CPAN::Config->{build_dir}). It is a simple FIFO mechanism that
+deletes complete directories below build_dir as soon as the size of
+all directories there gets bigger than $CPAN::Config->{build_cache}
+(in MB). The contents of this cache may be used for later
+re-installations that you intend to do manually, but will never be
+trusted by CPAN itself.
+
+There is another directory ($CPAN::Config->{keep_source_where}) where
+the original distribution files are kept. This directory is not
+covered by the cache manager and must be controlled by the user. If
+you choose to have the same directory as build_dir and as
+keep_source_where directory, then your sources will be deleted with
+the same fifo mechanism.
+
+=head2 Bundles
+
+A bundle is just a perl module in the namespace Bundle:: that does not
+define any functions or methods. It usually only contains documentation.
+
+It starts like a perl module with a package declaration and a $VERSION
+variable. After that the pod section looks like any other pod with the
+only difference, that one pod section exists starting with (verbatim):
+
+       =head1 CONTENTS
+
+In this pod section each line obeys the format
+
+        Module_Name [Version_String] [- optional text]
+
+The only required part is the first field, the name of a module
+(eg. Foo::Bar, ie. I<not> the name of the distribution file). The rest
+of the line is optional. The comment part is delimited by a dash just
+as in the man page header.
+
+The distribution of a bundle should follow the same convention as
+other distributions. The bundle() function in the CPAN module simply
+parses the module that defines the bundle and returns the module names
+that are listed in the described CONTENTS section.
+
+Bundles are treated specially in the CPAN package. If you say 'install
+Bundle::Tkkit' (assuming such a bundle exists), CPAN will install all
+the modules in the CONTENTS section of the pod.  You can install your
+own Bundles locally by placing a conformant Bundle file somewhere into
+your @INC path. The autobundle() command which is available in the
+shell interface does that for you by including all currently installed
+modules in a snapshot bundle file.
+
+=head2 autobundle
+
+autobundle() writes a bundle file into the directory
+$CPAN::Config->{cpan_home}/Bundle directory. The file contains a list
+of all modules that are both available from CPAN and currently
+installed within @INC. The name of the bundle file is based on the
+current date and a counter.
+
+=head2 Pragma: force
+
+Normally CPAN keeps track of what it has done within the current
+session and doesn't try to build a package a second time regardless if
+it succeeded or not. The force command takes as first argument the
+method to invoke (currently: make, test, or install) and executes the
+command from scratch.
+
+Example:
+
+    cpan> install OpenGL
+    OpenGL is up to date.
+    cpan> force install OpenGL
+    Running make
+    OpenGL-0.4/
+    OpenGL-0.4/COPYRIGHT
+    [...]
+
+=head2 recompile
+
+recompile() is a very special command in that it takes no argument and
+runs the make/test/install cycle with brute force over all installed
+dynamically loadable extensions (aka XS modules) with 'force' in
+effect. Primary purpose of this command is to act as a rescue in case
+your perl breaks binary compatibility. If one of the modules that CPAN
+uses is in turn depending on binary compatibility (so you cannot run
+CPAN commands), then you should try the CPAN::Nox module for recovery.
+
+=head1 CONFIGURATION
+
+When the CPAN module is installed a site wide configuration file is
+created as CPAN/Config.pm. The default values defined there can be
+overridden in another configuration file: CPAN/MyConfig.pm. You can
+store this file in $HOME/.cpan/CPAN/MyConfig.pm if you want, because
+$HOME/.cpan is added to the search path of the CPAN module before the
+use() or require() statements.
+
+Currently the following keys in the hash reference $CPAN::Config are
+defined:
+
+  build_cache       size of cache for directories to build modules
+  build_dir         locally accessible directory to build modules
+  index_expire      after how many days refetch index files
+  cpan_home         local directory reserved for this package
+  gzip             location of external program gzip
+  inhibit_startup_message
+                    if true, does not print the startup message
+  keep_source       keep the source in a local directory?
+  keep_source_where where keep the source (if we do)
+  make              location of external program make
+  make_arg         arguments that should always be passed to 'make'
+  make_install_arg  same as make_arg for 'make install'
+  makepl_arg       arguments passed to 'perl Makefile.PL'
+  pager             location of external program more (or any pager)
+  tar               location of external program tar
+  unzip             location of external program unzip
+  urllist          arrayref to nearby CPAN sites (or equivalent locations)
+
+You can set and query each of these options interactively in the cpan
+shell with the command set defined within the C<o conf> command:
+
+=over 2
+
+=item o conf E<lt>scalar optionE<gt>
+
+prints the current value of the I<scalar option>
+
+=item o conf E<lt>scalar optionE<gt> E<lt>valueE<gt>
+
+Sets the value of the I<scalar option> to I<value>
+
+=item o conf E<lt>list optionE<gt>
+
+prints the current value of the I<list option> in MakeMaker's
+neatvalue format.
+
+=item o conf E<lt>list optionE<gt> [shift|pop]
+
+shifts or pops the array in the I<list option> variable
+
+=item o conf E<lt>list optionE<gt> [unshift|push|splice] E<lt>listE<gt>
+
+works like the corresponding perl commands. Whitespace is used to
+determine the arguments.
+
+=back
+
+=head1 SECURITY
+
+There's no strong security layer in CPAN.pm. CPAN.pm helps you to
+install foreign, unmasked, unsigned code on your machine. We compare
+to a checksum that comes from the net just as the distribution file
+itself. If somebody has managed to tamper with the distribution file,
+they may have as well tampered with the CHECKSUMS file. Future
+development will go towards stong authentification.
+
+=head1 EXPORT
+
+Most functions in package CPAN are exported per default. The reason
+for this is that the primary use is intended for the cpan shell or for
+oneliners.
+
+=head1 Debugging
+
+The debugging of this module is pretty difficult, because we have
+interferences of the software producing the indices on CPAN, of the
+mirroring process on CPAN, of packaging, of configuration, of
+synchronicity, and of bugs within CPAN.pm.
+
+In interactive mode you can try "o debug" which will list options for
+debugging the various parts of the package. The output may not be very
+useful for you as it's just a byproduct of my own testing, but if you
+have an idea which part of the package may have a bug, it's sometimes
+worth to give it a try and send me more specific output. You should
+know that "o debug" has built-in completion support.
+
+=head2 Prerequisites
+
+If you have a local mirror of CPAN and can access all files with
+"file:" URLs, then you only need perl5.003 to run this
+module. Otherwise you need Net::FTP intalled. LWP may be required for
+non-UNIX systems or if your nearest CPAN site is associated with an
+URL that is not C<ftp:>.
+
+This module presumes that all packages on CPAN
+
+=over 2
+
+=item *
+
+declare their $VERSION variable in an easy to parse manner. This
+prerequisite can hardly be relaxed because it consumes by far too much
+memory to load all packages into the running program just to determine
+the $VERSION variable . Currently all programs that are dealing with
+VERSION use something like this
+
+    perl -MExtUtils::MakeMaker -le \
+        'print MM->parse_version($ARGV[0])' filename
+
+If you are author of a package and wonder if your VERSION can be
+parsed, please try the above method.
+
+=item *
+
+come as compressed or gzipped tarfiles or as zip files and contain a
+Makefile.PL (well we try to handle a bit more, but without much
+enthusiasm).
+
+=back
+
+=head1 AUTHOR
+
+Andreas König E<lt>a.koenig@mind.deE<gt>
+
+=head1 SEE ALSO
+
+perl(1), CPAN::Nox(3)
+
+=cut
+
diff --git a/lib/CPAN/FirstTime.pm b/lib/CPAN/FirstTime.pm
new file mode 100644 (file)
index 0000000..9cac32d
--- /dev/null
@@ -0,0 +1,284 @@
+package CPAN::Mirrored::By;
+
+sub new { 
+    my($self,@arg) = @_;
+    bless [@arg], $self;
+}
+sub con { shift->[0] }
+sub cou { shift->[1] }
+sub url { shift->[2] }
+
+package CPAN::FirstTime;
+
+use strict;
+use ExtUtils::MakeMaker qw(prompt);
+require File::Path;
+use vars qw($VERSION);
+$VERSION = "1.00";
+
+=head1 NAME
+
+CPAN::FirstTime - Utility for CPAN::Config file Initialization
+
+=head1 SYNOPSIS
+
+CPAN::FirstTime::init()
+
+=head1 DESCRIPTION
+
+The init routine asks a few questions and writes a CPAN::Config
+file. Nothing special.
+
+=cut
+
+
+sub init {
+    my($configpm) = @_;
+    use Config;
+    require CPAN::Nox;
+    eval {require CPAN::Config;};
+    $CPAN::Config ||= {};
+    
+    my($ans,$default,$local,$cont,$url,$expected_size);
+    
+    print qq{
+
+The CPAN module needs a directory of its own to cache important
+index files and maybe keep a temporary mirror of CPAN files. This may
+be a site-wide directory or a personal directory.
+};
+
+    my $cpan_home = $CPAN::Config->{cpan_home} || MM->catdir($ENV{HOME}, ".cpan");
+    if (-d $cpan_home) {
+       print qq{
+
+I see you already have a  directory
+    $cpan_home
+Shall we use it as the general CPAN build and cache directory?
+
+};
+    } else {
+       print qq{
+
+First of all, I\'d like to create this directory. Where?
+
+};
+    }
+
+    $default = $cpan_home;
+    $ans = prompt("CPAN build and cache directory?",$default);
+    File::Path::mkpath($ans); # dies if it can't
+    $CPAN::Config->{cpan_home} = $ans;
+    
+    print qq{
+
+If you want, I can keep the source files after a build in the cpan
+home directory. If you choose so then future builds will take the
+files from there. If you don\'t want to keep them, answer 0 to the
+next question.
+
+};
+
+    $CPAN::Config->{keep_source_where} = MM->catdir($CPAN::Config->{cpan_home},"sources");
+    $CPAN::Config->{build_dir} = MM->catdir($CPAN::Config->{cpan_home},"build");
+
+    print qq{
+
+How big should the disk cache be for keeping the build directories
+with all the intermediate files?
+
+};
+
+    $default = $CPAN::Config->{build_cache} || 10;
+    $ans = prompt("Cache size for build directory (in MB)?", $default);
+    $CPAN::Config->{build_cache} = $ans;
+
+    # XXX This the time when we refetch the index files (in days)
+    $CPAN::Config->{'index_expire'} = 1;
+
+    print qq{
+
+The CPAN module will need a few external programs to work
+properly. Please correct me, if I guess the wrong path for a program.
+
+};
+
+    my(@path) = split($Config{path_sep},$ENV{PATH});
+    my $prog;
+    for $prog (qw/gzip tar unzip make/){
+       my $path = $CPAN::Config->{$prog} || find_exe($prog,[@path]) || $prog;
+       $ans = prompt("Where is your $prog program?",$path) || $path;
+       $CPAN::Config->{$prog} = $ans;
+    }
+    my $path = $CPAN::Config->{'pager'} || 
+       $ENV{PAGER} || find_exe("less",[@path]) || 
+           find_exe("more",[@path]) || "more";
+    $ans = prompt("What is your favorite pager program?",$path) || $path;
+    $CPAN::Config->{'pager'} = $ans;
+    print qq{
+
+Every Makefile.PL is run by perl in a seperate process. Likewise we
+run \'make\' and \'make install\' in processes. If you have any parameters
+\(e.g. PREFIX, INSTALLPRIVLIB, UNINST or the like\) you want to pass to
+the calls, please specify them here.
+
+};
+
+    $default = $CPAN::Config->{makepl_arg} || "";
+    $CPAN::Config->{makepl_arg} =
+       prompt("Parameters for the 'perl Makefile.PL' command?",$default);
+    $default = $CPAN::Config->{make_arg} || "";
+    $CPAN::Config->{make_arg} = prompt("Parameters for the 'make' command?",$default);
+
+    $default = $CPAN::Config->{make_install_arg} || $CPAN::Config->{make_arg} || "";
+    $CPAN::Config->{make_install_arg} =
+       prompt("Parameters for the 'make install' command?",$default);
+
+    $local = 'MIRRORED.BY';
+    if (@{$CPAN::Config->{urllist}||[]}) {
+       print qq{
+I found a list of URLs in CPAN::Config and will use this.
+You can change it later with the 'o conf' command.
+
+}
+    } elsif (-f $local) { # if they really have a MIRRORED.BY in the
+                     # current directory, we can't help
+       read_mirrored_by($local);
+    } else {
+       $CPAN::Config->{urllist} ||= [];
+       while (! @{$CPAN::Config->{urllist}}) {
+           print qq{
+We need to know the URL of your favorite CPAN site.
+Please enter it here: };
+           chop($_ = <>);
+           s/\s//g;
+           push @{$CPAN::Config->{urllist}}, $_ if $_;
+       }
+    }
+
+    # We don't ask that now, it will be noticed in time....
+    $CPAN::Config->{'inhibit_startup_message'} = 0;
+
+    print "\n\n";
+    CPAN::Config->commit($configpm);
+}
+
+sub find_exe {
+    my($exe,$path) = @_;
+    my($dir,$MY);
+    $MY = {};
+    bless $MY, 'MY';
+    for $dir (@$path) {
+       my $abs = $MY->catfile($dir,$exe);
+       if ($MY->maybe_command($abs)) {
+           return $abs;
+       }
+    }
+}
+
+sub read_mirrored_by {
+    my($local) = @_;
+    my(%all,$url,$expected_size,$default,$ans,$host,$dst,$country,$continent,@location);
+    open FH, $local or die "Couldn't open $local: $!";
+    while (<FH>) {
+       ($host) = /^([\w\.\-]+)/ unless defined $host;
+       next unless defined $host;
+       next unless /\s+dst_(dst|location)/;
+       /location\s+=\s+\"([^\"]+)/ and @location = (split /\s*,\s*/, $1) and
+           ($continent, $country) = @location[-1,-2];
+       $continent =~ s/\s\(.*//;
+       /dst_dst\s+=\s+\"([^\"]+)/  and $dst = $1;
+       next unless $host && $dst && $continent && $country;
+       $all{$continent}{$country}{$dst} = CPAN::Mirrored::By->new($continent,$country,$dst);
+       undef $host;
+       $dst=$continent=$country="";
+    }
+    $CPAN::Config->{urllist} ||= [];
+    if ($expected_size = @{$CPAN::Config->{urllist}}) {
+       for $url (@{$CPAN::Config->{urllist}}) {
+           # sanity check, scheme+colon, not "q" there:
+           next unless $url =~ /^\w+:\/./;
+           $all{"[From previous setup]"}{"found URL"}{$url}=CPAN::Mirrored::By->new('[From previous setup]','found URL',$url);
+       }
+       $CPAN::Config->{urllist} = [];
+    } else {
+       $expected_size = 6;
+    }
+    
+    print qq{
+
+Now we need to know, where your favorite CPAN sites are located. Push
+a few sites onto the array (just in case the first on the array won\'t
+work). If you are mirroring CPAN to your local workstation, specify a
+file: URL.
+
+You can enter the number in front of the URL on the next screen, a
+file:, ftp: or http: URL, or "q" to finish selecting.
+
+};
+
+    $ans = prompt("Press RETURN to continue");
+    my $other;
+    $ans = $other = "";
+    my(%seen);
+    
+    while () {
+       my $pipe = -t *STDIN ? "| $CPAN::Config->{'pager'}" : ">/dev/null";
+       my(@valid,$previous_best);
+       open FH, $pipe;
+       {
+           my($cont,$country,$url,$item);
+           my(@cont) = sort keys %all;
+           for $cont (@cont) {
+               print FH "    $cont\n";
+               for $country (sort {lc $a cmp lc $b} keys %{$all{$cont}}) {
+                   for $url (sort {lc $a cmp lc $b} keys %{$all{$cont}{$country}}) {
+                       my $t = sprintf(
+                                       "      %-18s (%2d) %s\n",
+                                       $country,
+                                       ++$item,
+                                       $url
+                                      );
+                       if ($cont =~ /^\[/) {
+                           $previous_best ||= $item;
+                       }
+                       push @valid, $all{$cont}{$country}{$url};
+                       print FH $t;
+                   }
+               }
+           }
+       }
+       close FH;
+       $previous_best ||= 1;
+       $default =
+           @{$CPAN::Config->{urllist}} >= $expected_size ? "q" : $previous_best;
+       $ans = prompt(
+                     "\nSelect an$other ftp or file URL or a number (q to finish)",
+                     $default
+                    );
+       my $sel;
+       if ($ans =~ /^\d/) {
+           my $this = $valid[$ans-1];
+           my($con,$cou,$url) = ($this->con,$this->cou,$this->url);
+           push @{$CPAN::Config->{urllist}}, $url unless $seen{$url}++;
+           delete $all{$con}{$cou}{$url};
+           #       print "Was a number [$ans] con[$con] cou[$cou] url[$url]\n";
+       } elsif (@{$CPAN::Config->{urllist}} && $ans =~ /^q/i) {
+           last;
+       } else {
+           $ans =~ s|/?$|/|; # has to end with one slash
+           $ans = "file:$ans" unless $ans =~ /:/; # without a scheme is a file:
+           if ($ans =~ /^\w+:\/./) {
+               push @{$CPAN::Config->{urllist}}, $ans unless $seen{$ans}++;
+           } else {
+               print qq{"$ans" doesn\'t look like an URL at first sight.
+I\'ll ignore it for now. You can add it to lib/CPAN/Config.pm
+later and report a bug in my Makefile.PL to me (andreas koenig).
+Thanks.\n};
+           }
+       }
+       $other ||= "other";
+    }
+}
+
+1;
diff --git a/lib/CPAN/Nox.pm b/lib/CPAN/Nox.pm
new file mode 100644 (file)
index 0000000..b0b70fe
--- /dev/null
@@ -0,0 +1,33 @@
+BEGIN{$CPAN::Suppress_readline++;}
+
+use CPAN;
+
+$CPAN::META->hasMD5(0);
+$CPAN::META->hasLWP(0);
+@EXPORT = @CPAN::EXPORT;
+
+*AUTOLOAD = \&CPAN::AUTOLOAD;
+
+=head1 NAME
+
+CPAN::Nox - Wrapper around CPAN.pm without using any XS module
+
+=head1 SYNOPSIS
+
+Interactive mode:
+
+  perl -MCPAN::Nox -e shell;
+
+=head1 DESCRIPTION
+
+This package has the same functionality as CPAN.pm, but tries to
+prevent the usage of compiled extensions during it's own
+execution. It's primary purpose is a rescue in case you upgraded perl
+and broke binary compatibility somehow.
+
+=head1  SEE ALSO
+
+CPAN(3)
+
+=cut
+
index 0d9c51b..281474c 100644 (file)
@@ -43,7 +43,7 @@ sub _make_fatal {
     $code .= "\(\@_\) || croak \"Can't $name\(\@_\): \$!\";\n}\n";
     print $code if $Debug;
     eval($code);
-    die($@) if $@;
+    die if $@;
     local($^W) = 0;   # to avoid: Subroutine foo redefined ...
     no strict 'refs'; # to avoid: Can't use string (...) as a symbol ref ...
     *{$sub} = \&{"Fatal::$name"};
diff --git a/lib/File/Compare.pm b/lib/File/Compare.pm
new file mode 100644 (file)
index 0000000..e76c10f
--- /dev/null
@@ -0,0 +1,136 @@
+package File::Compare;
+
+use strict;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $Too_Big *FROM *TO);
+
+require Exporter;
+use Carp;
+use UNIVERSAL qw(isa);
+
+$VERSION = '1.1';
+@ISA = qw(Exporter);
+@EXPORT = qw(compare);
+@EXPORT_OK = qw(cmp);
+
+$Too_Big = 1024 * 1024 * 2;
+
+sub VERSION {
+    # Version of File::Compare
+    return $File::Compare::VERSION;
+}
+
+sub compare {
+    croak("Usage: compare( file1, file2 [, buffersize]) ")
+      unless(@_ == 2 || @_ == 3);
+
+    my $from = shift;
+    my $to = shift;
+    my $closefrom=0;
+    my $closeto=0;
+    my ($size, $status, $fr, $tr, $fbuf, $tbuf);
+    local(*FROM, *TO);
+    local($\) = '';
+
+    croak("from undefined") unless (defined $from);
+    croak("to undefined") unless (defined $to);
+
+    if (ref($from) && (isa($from,'GLOB') || isa($from,'IO::Handle'))) {
+       *FROM = *$from;
+    } elsif (ref(\$from) eq 'GLOB') {
+       *FROM = $from;
+    } else {
+       open(FROM,"<$from") or goto fail_open1;
+       binmode FROM;
+       $closefrom = 1;
+    }
+
+    if (ref($to) && (isa($to,'GLOB') || isa($to,'IO::Handle'))) {
+       *TO = *$to;
+    } elsif (ref(\$to) eq 'GLOB') {
+       *TO = $to;
+    } else {
+       open(TO,"<$to") or goto fail_open2;
+       binmode TO;
+       $closeto = 1;
+    }
+
+    if (@_) {
+       $size = shift(@_) + 0;
+       croak("Bad buffer size for compare: $size\n") unless ($size > 0);
+    } else {
+       $size = -s FROM;
+       $size = 1024 if ($size < 512);
+       $size = $Too_Big if ($size > $Too_Big);
+    }
+
+    $fbuf = '';
+    $tbuf = '';
+    while(defined($fr = read(FROM,$fbuf,$size)) && $fr > 0) {
+       unless (defined($tr = read(TO,$tbuf,$fr)) and $tbuf eq $fbuf) {
+            goto fail_inner;
+       }
+    }
+    goto fail_inner if (defined($tr = read(TO,$tbuf,$size)) && $tr > 0);
+
+    close(TO) || goto fail_open2 if $closeto;
+    close(FROM) || goto fail_open1 if $closefrom;
+
+    return 0;
+    
+  # All of these contortions try to preserve error messages...
+  fail_inner:
+    close(TO) || goto fail_open2 if $closeto;
+    close(FROM) || goto fail_open1 if $closefrom;
+
+    return 1;
+
+  fail_open2:
+    if ($closefrom) {
+       $status = $!;
+       $! = 0;
+       close FROM;
+       $! = $status unless $!;
+    }
+  fail_open1:
+    return -1;
+}
+
+*cmp = \&compare;
+
+1;
+
+__END__
+
+=head1 NAME
+
+File::Compare - Compare files or filehandles
+
+=head1 SYNOPSIS
+
+       use File::Compare;
+
+       if (compare("file1","file2") == 0) {
+           print "They're equal\n";
+       }
+
+=head1 DESCRIPTION
+
+The File::Compare::compare function compares the contents of two
+sources, each of which can be a file or a file handle.  It is exported
+from File::Compare by default.
+
+File::Compare::cmp is a synonym for File::Compare::compare.  It is
+exported from File::Compare only by request.
+
+=head1 RETURN
+
+File::Compare::compare return 0 if the files are equal, 1 if the
+files are unequal, or -1 if an error was encountered.
+
+=head1 AUTHOR
+
+File::Compare was written by Nick Ing-Simmons.
+Its original documentation was written by Chip Salzenberg.
+
+=cut
+
index b215147..e2ce83d 100644 (file)
@@ -1,6 +1,6 @@
 package FileHandle;
 
-require 5.003;
+use 5.003_11;
 use strict;
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
 
@@ -39,6 +39,24 @@ require IO::File;
 import IO::Handle grep { !defined(&$_) } @EXPORT, @EXPORT_OK;
 
 #
+# Some people call "FileHandle::function", so all the functions
+# that were in the old FileHandle class must be imported, too.
+#
+{
+    no strict 'refs';
+    for my $f (qw(DESTROY new_from_fd fdopen close fileno getc ungetc gets eof
+                 setbuf setvbuf _open_mode_string)) {
+       *{$f} = \&{"IO::Handle::$f"} or die "$f missing";
+    }
+    for my $f (qw(seek tell fgetpos fsetpos fflush ferror clearerr)) {
+       *{$f} = \&{"IO::Seekable::$f"} or die "$f missing";
+    }
+    for my $f (qw(new new_tmpfile open)) {
+       *{$f} = \&{"IO::File::$f"} or die "$f missing";
+    }
+}
+
+#
 # Specialized importer for Fcntl magic.
 #
 sub import {
index d684577..4047bf1 100644 (file)
@@ -1,11 +1,11 @@
 # GetOpt::Long.pm -- POSIX compatible options parsing
 
-# RCS Status      : $Id: GetoptLong.pm,v 2.4 1996-10-02 11:16:26+02 jv Exp $
+# RCS Status      : $Id: GetoptLong.pm,v 2.5 1996-10-19 16:47:51+02 jv Exp $
 # Author          : Johan Vromans
 # Created On      : Tue Sep 11 15:00:12 1990
 # Last Modified By: Johan Vromans
-# Last Modified On: Wed Oct  2 11:13:12 1996
-# Update Count    : 500
+# Last Modified On: Sat Oct 19 16:46:23 1996
+# Update Count    : 504
 # Status          : Released
 
 package Getopt::Long;
@@ -14,7 +14,7 @@ require Exporter;
 
 @ISA = qw(Exporter);
 @EXPORT = qw(&GetOptions $REQUIRE_ORDER $PERMUTE $RETURN_IN_ORDER);
-$VERSION = sprintf("%d.%02d", '$Revision: 2.4 $ ' =~ /(\d+)\.(\d+)/);
+$VERSION = sprintf("%d.%02d", '$Revision: 2.5 $ ' =~ /(\d+)\.(\d+)/);
 use vars qw($autoabbrev $getopt_compat $ignorecase $bundling $order
            $passthrough $error $debug 
            $REQUIRE_ORDER $PERMUTE $RETURN_IN_ORDER
@@ -86,7 +86,7 @@ followed by an argument specifier. Values for argument specifiers are:
 
 =over 8
 
-=item <none>
+=item E<lt>noneE<gt>
 
 Option does not take an argument. 
 The option variable will be set to 1.
@@ -225,7 +225,7 @@ The option name is always the true name, not an abbreviation or alias.
 
 The option name may actually be a list of option names, separated by
 "|"s, e.g. "foo|bar|blech=s". In this example, "foo" is the true name
-op this option. If no linkage is specified, options "foo", "bar" and
+of this option. If no linkage is specified, options "foo", "bar" and
 "blech" all will set $opt_foo.
 
 Option names may be abbreviated to uniqueness, depending on
@@ -233,7 +233,7 @@ configuration variable $Getopt::Long::autoabbrev.
 
 =head2 Non-option call-back routine
 
-A special option specifier, <>, can be used to designate a subroutine
+A special option specifier, E<lt>E<gt>, can be used to designate a subroutine
 to handle non-option arguments. GetOptions will immediately call this
 subroutine for every non-option it encounters in the options list.
 This subroutine gets the name of the non-option passed.
@@ -316,11 +316,11 @@ Example of using variable references:
 With command line options "-foo blech -bar 24 -ar xx -ar yy" 
 this will result in:
 
-   $bar = 'blech'
+   $foo = 'blech'
    $opt_bar = 24
    @ar = ('xx','yy')
 
-Example of using the <> option specifier:
+Example of using the E<lt>E<gt> option specifier:
 
    @ARGV = qw(-foo 1 bar -foo 2 blech);
    &GetOptions("foo=i", \$myfoo, "<>", \&mysub);
@@ -530,7 +530,7 @@ sub GetOptions {
                                # than once in differing environments
     $error = 0;
 
-    print STDERR ('GetOptions $Revision: 2.4 $ ',
+    print STDERR ('GetOptions $Revision: 2.5 $ ',
                  "[GetOpt::Long $Getopt::Long::VERSION] -- ",
                  "called from package \"$pkg\".\n",
                  "  (@ARGV)\n",
diff --git a/lib/Net/FTP.pm b/lib/Net/FTP.pm
new file mode 100644 (file)
index 0000000..64b21fe
--- /dev/null
@@ -0,0 +1,943 @@
+;# Net::FTP.pm
+;#
+;# Copyright (c) 1995 Graham Barr <Graham.Barr@tiuk.ti.com>. All rights
+;# reserved. This program is free software; you can redistribute it and/or
+;# modify it under the same terms as Perl itself.
+
+;#Notes
+;# should I have a dataconn::close sub which calls response ??
+;# FTP should hold state reguarding cmds sent
+;# A::read needs some more thought
+;# A::write What is previous pkt ended in \r or not ??
+;# need to do some heavy tidy-ing up !!!!
+;# need some documentation
+
+package Net::FTP;
+
+=head1 NAME
+
+Net::FTP - FTP Client class
+
+=head1 SYNOPSIS
+
+ require Net::FTP;
+
+ $ftp = Net::FTP->new("some.host.name");
+ $ftp->login("anonymous","me@here.there");
+ $ftp->cwd("/pub");
+ $ftp->get("that.file");
+ $ftp->quit;
+
+=head1 DESCRIPTION
+
+C<Net::FTP> is a class implementing a simple FTP client in Perl as described
+in RFC959
+
+=head2 TO BE CONTINUED ...
+
+=cut
+
+require 5.001;
+use Socket 1.3;
+use Carp;
+use Net::Socket;
+
+@ISA = qw(Net::Socket);
+
+$VERSION = sprintf("%d.%02d", q$Revision: 1.18 $ =~ /(\d+)\.(\d+)/);
+sub Version { $VERSION }
+
+use strict;
+
+=head1 METHODS
+
+All methods return 0 or undef upon failure
+
+=head2 * new($host [, option => value [,...]] )
+
+Constructor for the FTP client. It will create the connection to the
+remote host. Possible options are:
+
+ Port   => port to use for FTP connection
+ Timeout => set timeout value (defaults to 120)
+ Debug  => debug level
+
+=cut
+
+sub FTP_READY    { 0 } # Ready 
+sub FTP_RESPONSE { 1 } # Waiting for a response
+sub FTP_XFER     { 2 } # Doing data xfer
+
+sub new {
+ my $pkg  = shift;
+ my $host = shift;
+ my %arg  = @_; 
+ my $me = bless Net::Socket->new(Peer  => $host, 
+                               Service => 'ftp', 
+                               Port    => $arg{Port} || 'ftp'
+                               ), $pkg;
+
+ ${*$me} = "";                                 # partial response text
+ @{*$me} = ();                                 # Last response text
+
+ %{*$me} = (%{*$me},                           # Copy current values
+           Code    => 0,                       # Last response code
+           Type    => 'A',                     # Ascii/Binary/etc mode
+           Timeout => $arg{Timeout} || 120,    # Timeout value
+           Debug   => $arg{Debug}   || 0,      # Output debug information
+           FtpHost => $host,                   # Remote hostname
+           State   => FTP_RESPONSE,            # Current state
+
+           ##############################################################
+           # Other elements used during the lifetime of the object are
+           #
+           # LISTEN  Listen socket
+           # DATA    Data socket
+          );
+
+ $me->autoflush(1);
+
+ $me->debug($arg{Debug})
+   if(exists $arg{Debug});
+
+ unless(2 == $me->response())
+  {
+   $me->close();
+   undef $me;
+  }
+
+ $me;
+}
+
+##
+## User interface methods
+##
+
+=head2 * debug( $value )
+
+Set the level of debug information for this object. If no argument is given
+then the current state is returned. Otherwise the state is changed to 
+C<$value>and the previous state returned.
+
+=cut
+
+sub debug {
+ my $me = shift;
+ my $debug = ${*$me}{Debug};
+ if(@_)
+  {
+   ${*$me}{Debug} = 0 + shift;
+
+   printf STDERR "\n$me VERSION %s\n", $Net::FTP::VERSION
+     if(${*$me}{Debug});
+  }
+
+ $debug;
+}
+
+=head2 quit
+
+Send the QUIT command to the remote FTP server and close the socket connection.
+
+=cut
+
+sub quit {
+ my $me = shift;
+
+ return undef
+       unless $me->QUIT;
+
+ close($me);
+
+ return 1;
+}
+
+=head2 ascii/ebcdic/binary/byte
+
+Put the remote FTP server ant the FTP package into the given mode
+of data transfer.
+
+=cut
+
+sub ascii  { shift->type('A',@_); }
+sub ebcdic { shift->type('E',@_); }
+sub binary { shift->type('I',@_); }
+sub byte   { shift->type('L',@_); }
+
+# Allow the user to send a command directly, BE CAREFUL !!
+
+sub quot  { 
+ my $me = shift;
+ my $cmd = shift;
+
+ $me->send_cmd( uc $cmd, @_);
+
+ $me->response();
+}
+
+=head2 login([$login [, $password [, $account]]])
+
+Log into the remote FTP server with the given login information. If
+no arguments are given then the users $HOME/.netrc file is searched
+for the remote server's hostname. If no information is found then
+a login of I<anonymous> is used. If no password is given and the login
+is anonymous then the users Email address will be used for a password
+
+=cut
+
+sub login {
+ my $me = shift;
+ my $user = shift;
+ my $pass = shift if(defined $user);
+ my $acct = shift if(defined $pass);
+ my $ok;
+
+ unless(defined $user)
+  {
+   require Net::Netrc;
+   my $rc = Net::Netrc->lookup(${*$me}{FtpHost});
+
+   ($user,$pass,$acct) = $rc->lpa()
+       if $rc;
+  }
+
+ $user = "anonymous"
+       unless defined $user;
+
+ $pass = "-" . (getpwuid($>))[0] . "@" 
+       if !defined $pass && $user eq "anonymous";
+
+ $ok = $me->USER($user);
+
+ $ok = $me->PASS($pass)
+       if $ok == 3;
+
+ $ok = $me->ACCT($acct || "")
+       if $ok == 3;
+
+ $ok == 2;
+}
+
+=head2 authorise($auth, $resp)
+
+This is a protocol used by some firewall ftp proxies. It is used
+to authorise the user to send data out.
+
+=cut
+
+sub authorise {
+ my($me,$auth,$resp) = @_;
+ my $ok;
+
+ carp "Net::FTP::authorise <auth> <resp>\n"
+       unless defined $auth && defined $resp;
+
+ $ok = $me->AUTH($auth);
+
+ $ok = $me->RESP($resp)
+       if $ok == 3;
+
+ $ok == 2;
+}
+
+=head2 rename( $oldname, $newname)
+
+Rename a file on the remote FTP server from C<$oldname> to C<$newname>
+
+=cut
+
+sub rename {
+ my($me,$from,$to) = @_;
+
+ croak "Net::FTP:rename <from> <to>\n"
+       unless defined $from && defined $to;
+
+ $me->RNFR($from) and $me->RNTO($to);
+}
+
+sub type {
+ my $me          = shift;
+ my $type = shift;
+ my $ok          = 0;
+
+ return ${*$me}{Type}
+       unless defined $type;
+
+ return undef
+       unless($me->TYPE($type,@_));
+
+ ${*$me}{Type} = join(" ",$type,@_);
+}
+
+sub abort {
+ my $me = shift;
+
+ ${*$me}{DATA}->abort()
+       if defined ${*$me}{DATA};
+}
+
+sub get {
+ my $me = shift;
+ my $remote = shift;
+ my $local  = shift;
+ my $where  = shift || 0;
+ my($loc,$len,$buf,$resp,$localfd,$data);
+ local *FD;
+
+ $localfd = ref($local) ? fileno($local)
+                       : 0;
+
+ ($local = $remote) =~ s#^.*/## unless(defined $local);
+
+ if($localfd)
+  {
+   $loc = $local;
+  }
+ else
+  {
+   $loc = \*FD;
+
+   unless(($where) ? open($loc,">>$local") : open($loc,">$local"))
+    {
+     carp "Cannot open Local file $local: $!\n";
+     return undef;
+    }
+  }
+
+ if ($where) {   
+   $data = $me->rest_cmd($where,$remote) or
+       return undef; 
+ }
+ else {
+   $data = $me->retr($remote) or
+     return undef;
+ }
+
+ $buf = '';
+
+ do
+  {
+   $len = $data->read($buf,1024);
+  }
+ while($len > 0 && syswrite($loc,$buf,$len) == $len);
+
+ close($loc)
+       unless $localfd;
+ $data->close() == 2; # implied $me->response
+}
+
+sub cwd {
+ my $me = shift;
+ my $dir = shift || "/";
+
+ return $dir eq ".." ? $me->CDUP()
+                    : $me->CWD($dir);
+}
+
+sub pwd {
+ my $me = shift;
+
+ $me->PWD() ? ($me->message =~ /\"([^\"]+)/)[0]
+            : undef;
+}
+
+sub put               { shift->send("stor",@_) }
+sub put_unique { shift->send("stou",@_) }
+sub append     { shift->send("appe",@_) }
+
+sub nlst { shift->data_cmd("NLST",@_) }
+sub list { shift->data_cmd("LIST",@_) }
+sub retr { shift->data_cmd("RETR",@_) }
+sub stor { shift->data_cmd("STOR",@_) }
+sub stou { shift->data_cmd("STOU",@_) }
+sub appe { shift->data_cmd("APPE",@_) }
+
+sub send {
+ my $me            = shift;
+ my $cmd    = shift;
+ my $local  = shift;
+ my $remote = shift;
+ my($loc,$sock,$len,$buf,$localfd);
+ local *FD;
+
+ $localfd = ref($local) ? fileno($local)
+                       : 0;
+
+ unless(defined $remote)
+  {
+   croak "Must specify remote filename with stream input\n"
+       if $localfd;
+
+   ($remote = $local) =~ s%.*/%%;
+  }
+
+ if($localfd)
+  {
+   $loc = $local;
+  }
+ else
+  {
+   $loc = \*FD;
+
+   unless(open($loc,"<$local"))
+    {
+     carp "Cannot open Local file $local: $!\n";
+     return undef;
+    }
+  }
+
+ $cmd = lc $cmd;
+
+ $sock = $me->$cmd($remote) or
+       return undef;
+
+ do
+  {
+   $len = sysread($loc,$buf,1024);
+  }
+ while($len && $sock->write($buf,$len) == $len);
+
+ close($loc)
+       unless $localfd;
+
+ $sock->close();
+
+ ($remote) = $me->message =~ /unique file name:\s*(\S*)\s*\)/
+       if $cmd eq 'stou' ;
+
+ return $remote;
+}
+
+sub port {
+ my $me = shift;
+ my $port = shift;
+ my $ok;
+
+ unless(defined $port)
+  {
+   my $listen;
+
+   if(defined ${*$me}{LISTEN})
+    {
+     ${*$me}{LISTEN}->close();
+     delete ${*$me}{LISTEN};
+    }
+
+   # create a Listen socket at same address as the command socket
+
+   $listen = Net::Socket->new(Listen  => 5,
+                            Service => 'ftp',
+                            Addr    => $me->sockhost, 
+                           );
+  
+   ${*$me}{LISTEN} = $listen;
+
+   my($myport, @myaddr) = ($listen->sockport, split(/\./,$listen->sockhost));
+
+   $port = join(',', @myaddr, $myport >> 8, $myport & 0xff);
+  }
+
+ $ok = $me->PORT($port);
+
+ ${*$me}{Port} = $port;
+
+ $ok;
+}
+
+sub ls { shift->list_cmd("NLST",@_); }
+sub lsl { shift->list_cmd("LIST",@_); }
+
+sub pasv {
+ my $me = shift;
+ my $hostport;
+
+ return undef
+       unless $me->PASV();
+
+ ($hostport) = $me->message =~ /(\d+(,\d+)+)/;
+
+ ${*$me}{Pasv} = $hostport;
+}
+
+##
+## Communication methods
+##
+
+sub timeout {
+ my $me = shift;
+ my $timeout = ${*$me}{Timeout};
+
+ ${*$me}{Timeout} = 0 + shift if(@_);
+
+ $timeout;
+}
+
+sub accept {
+ my $me = shift;
+
+ return undef unless defined ${*$me}{LISTEN};
+
+ my $data = ${*$me}{LISTEN}->accept;
+
+ ${*$me}{LISTEN}->close();
+ delete ${*$me}{LISTEN};
+
+ ${*$data}{Timeout} = ${*$me}{Timeout};
+ ${*$data}{Cmd} = $me;
+ ${*$data} = "";
+
+ ${*$me}{State} = FTP_XFER;
+ ${*$me}{DATA}  = bless $data, "Net::FTP::" . ${*$me}{Type};
+}
+
+sub message {
+ my $me = shift;
+ join("\n", @{*$me});
+}
+
+sub ok {
+ my $me = shift;
+ my $code = ${*$me}{Code} || 0;
+
+ 0 < $code && $code < 400;
+}
+
+sub code {
+ my $me = shift;
+
+ ${*$me}{Code};
+}
+
+sub list_cmd {
+ my $me = shift;
+ my $cmd = lc shift;
+ my $data = $me->$cmd(@_);
+
+ return undef
+       unless(defined $data);
+
+ bless $data, "Net::FTP::A"; # Force ASCII mode
+
+ my $databuf = '';
+ my $buf = '';
+
+ while($data->read($databuf,1024)) {
+   $buf .= $databuf;
+ }
+
+ my $list = [ split(/\n/,$buf) ];
+
+ $data->close();
+
+ wantarray ? @{$list} : $list;
+}
+
+sub data_cmd {
+ my $me = shift;
+ my $cmd = uc shift;
+ my $ok = 1;
+ my $pasv = defined ${*$me}{Pasv} ? 1 : 0;
+
+ $ok = $me->port
+       unless $pasv || defined ${*$me}{Port};
+
+ $ok = $me->$cmd(@_)
+       if $ok;
+
+ return $pasv ? $ok
+             : $ok ? $me->accept()
+                   : undef;
+}
+
+sub rest_cmd {
+ my $me = shift;
+ my $ok = 1;
+ my $pasv = defined ${*$me}{Pasv} ? 1 : 0;
+ my $where = shift;
+ my $file = shift;
+
+ $ok = $me->port
+       unless $pasv || defined ${*$me}{Port};
+
+ $ok = $me->REST($where)
+       if $ok;
+
+ $ok = $me->RETR($file)
+       if $ok;
+
+ return $pasv ? $ok
+             : $ok ? $me->accept()
+                   : undef;
+}
+
+sub cmd {
+ my $me = shift;
+
+ $me->send_cmd(@_);
+ $me->response();
+}
+
+sub send_cmd {
+ my $me = shift;
+
+ if(scalar(@_)) {     
+  my $cmd = join(" ", @_) . "\r\n";
+
+  delete ${*$me}{Pasv};
+  delete ${*$me}{Port};
+
+  syswrite($me,$cmd,length $cmd);
+
+  ${*$me}{State} = FTP_RESPONSE;
+
+  printf STDERR "\n$me>> %s", $cmd=~/^(pass|resp)/i ? "$1 ....\n" : $cmd
+       if $me->debug;
+ }
+
+ $me;
+}
+
+sub pasv_wait {
+ my $me = shift;
+ my $non_pasv = shift;
+ my $file;
+
+ my($rin,$rout);
+ vec($rin,fileno($me),1) = 1;
+ select($rout=$rin, undef, undef, undef);
+
+ $me->response();
+ $non_pasv->response();
+
+ return undef
+       unless $me->ok() && $non_pasv->ok();
+
+ return $1
+       if $me->message =~ /unique file name:\s*(\S*)\s*\)/;
+
+ return $1
+       if $non_pasv->message =~ /unique file name:\s*(\S*)\s*\)/;
+
+ return 1;
+}
+
+sub response {
+ my $me = shift;
+ my $timeout = ${*$me}{Timeout};
+ my($code,$more,$rin,$rout,$partial,$buf) = (undef,0,'','','','');
+
+ @{*$me} = (); # the responce
+ $buf = ${*$me};
+ my @buf = ();
+
+ vec($rin,fileno($me),1) = 1;
+
+ do
+  {
+   if(length($buf) || ($timeout==0) || select($rout=$rin, undef, undef, $timeout))
+    {
+     unless(length($buf) || sysread($me, $buf, 1024))
+      {
+       carp "Unexpected EOF on command channel";
+       return undef;
+      } 
+
+     substr($buf,0,0) = $partial;    ## prepend from last sysread
+
+     @buf = split(/\r?\n/, $buf);  ## break into lines
+
+     $partial = (substr($buf, -1, 1) eq "\n") ? ''
+                                             : pop(@buf); 
+
+     $buf = "";
+
+     while (@buf)
+      {
+       my $cmd = shift @buf;
+       print STDERR "$me<< $cmd\n"
+        if $me->debug;
+       ($code,$more) = ($1,$2)
+       if $cmd =~ /^(\d\d\d)(.)/;
+
+       push(@{*$me},$');
+
+       last unless(defined $more && $more eq "-");
+      } 
+    }
+   else
+    {
+     carp "$me: Timeout" if($me->debug);
+     return undef;
+    }
+  }
+ while((scalar(@{*$me}) == 0) || (defined $more && $more eq "-"));
+
+ ${*$me} = @buf ? join("\n",@buf,"") : "";
+ ${*$me} .= $partial;
+
+ ${*$me}{Code} = $code;
+ ${*$me}{State} = FTP_READY;
+
+ substr($code,0,1);
+}
+
+;########################################
+;#
+;# RFC959 commands
+;#
+
+sub no_imp { croak "Not implemented\n"; }
+
+sub ABOR { shift->send_cmd("ABOR")->response() == 2}
+sub CDUP { shift->send_cmd("CDUP")->response() == 2}
+sub NOOP { shift->send_cmd("NOOP")->response() == 2}
+sub PASV { shift->send_cmd("PASV")->response() == 2}
+sub QUIT { shift->send_cmd("QUIT")->response() == 2}
+sub DELE { shift->send_cmd("DELE",@_)->response() == 2}
+sub CWD  { shift->send_cmd("CWD", @_)->response() == 2}
+sub PORT { shift->send_cmd("PORT",@_)->response() == 2}
+sub RMD  { shift->send_cmd("RMD", @_)->response() == 2}
+sub MKD  { shift->send_cmd("MKD", @_)->response() == 2}
+sub PWD  { shift->send_cmd("PWD", @_)->response() == 2}
+sub TYPE { shift->send_cmd("TYPE",@_)->response() == 2}
+sub APPE { shift->send_cmd("APPE",@_)->response() == 1}
+sub LIST { shift->send_cmd("LIST",@_)->response() == 1}
+sub NLST { shift->send_cmd("NLST",@_)->response() == 1}
+sub RETR { shift->send_cmd("RETR",@_)->response() == 1}
+sub STOR { shift->send_cmd("STOR",@_)->response() == 1}
+sub STOU { shift->send_cmd("STOU",@_)->response() == 1}
+sub RNFR { shift->send_cmd("RNFR",@_)->response() == 3}
+sub RNTO { shift->send_cmd("RNTO",@_)->response() == 2}
+sub ACCT { shift->send_cmd("ACCT",@_)->response() == 2}
+sub RESP { shift->send_cmd("RESP",@_)->response() == 2}
+sub REST { shift->send_cmd("REST",@_)->response() == 3}
+sub USER { my $ok = shift->send_cmd("USER",@_)->response();($ok == 2 || $ok == 3) ? $ok : 0;}
+sub PASS { my $ok = shift->send_cmd("PASS",@_)->response();($ok == 2 || $ok == 3) ? $ok : 0;}
+sub AUTH { my $ok = shift->send_cmd("AUTH",@_)->response();($ok == 2 || $ok == 3) ? $ok : 0;}
+
+sub ALLO { no_imp; }
+sub SMNT { no_imp; }
+sub HELP { no_imp; }
+sub MODE { no_imp; }
+sub SITE { no_imp; }
+sub SYST { no_imp; }
+sub STAT { no_imp; }
+sub STRU { no_imp; }
+sub REIN { no_imp; }
+
+package Net::FTP::dataconn;
+use Carp;
+no strict 'vars';
+
+sub abort {
+ my $fd = shift;
+ my $ftp = ${*$fd}{Cmd};
+
+ $ftp->send_cmd("ABOR");
+ $fd->close();
+}
+
+sub close {
+ my $fd = shift;
+ my $ftp = ${*$fd}{Cmd};
+
+ $fd->Net::Socket::close();
+ delete ${*$ftp}{DATA};
+
+ $ftp->response();
+}
+
+sub timeout {
+ my $me = shift;
+ my $timeout = ${*$me}{Timeout};
+
+ ${*$me}{Timeout} = 0 + shift if(@_);
+
+ $timeout;
+}
+
+sub _select {
+ my $fd = shift;
+ local *timeout = \$_[0]; shift;
+ my $rw = shift;
+ my($rin,$win);
+
+ return 1 unless $timeout;
+
+ $rin = '';
+ vec($rin,fileno($fd),1) = 1;
+
+ $win = $rw ? undef : $rin;
+ $rin = undef unless $rw;
+
+ my $nfound = select($rin, $win, undef, $timeout);
+
+ croak "select: $!"
+       if $nfound < 0;
+
+ return $nfound;
+}
+
+sub can_read {
+ my $fd = shift;
+ local *timeout = \$_[0];
+
+ $fd->_select($timeout,1);
+}
+
+sub can_write {
+ my $fd = shift;
+ local *timeout = \$_[0];
+
+ $fd->_select($timeout,0);
+}
+
+sub cmd {
+ my $me = shift;
+
+ ${*$me}{Cmd};
+}
+
+
+@Net::FTP::L::ISA = qw(Net::FTP::I);
+@Net::FTP::E::ISA = qw(Net::FTP::I);
+
+package Net::FTP::A;
+@Net::FTP::A::ISA = qw(Net::FTP::dataconn);
+use Carp;
+
+no strict 'vars';
+
+sub read {
+ my $fd = shift;
+ local *buf = \$_[0]; shift;
+ my $size = shift || croak 'read($buf,$size,[$offset])';
+ my $offset = shift || 0;
+ my $timeout = ${*$fd}{Timeout};
+ my $l;
+
+ croak "Bad offset"
+       if($offset < 0);
+
+ $offset = length $buf
+       if($offset > length $buf);
+
+ $l = 0;
+ READ:
+  {
+   $fd->can_read($timeout) or
+       croak "Timeout";
+
+   my $n = sysread($fd, ${*$fd}, $size, length ${*$fd});
+
+   return $n
+       unless($n >= 0);
+
+#   my $lf = substr(${*$fd},-1,1) eq "\r" ? chop(${*$fd})
+#                                       : "";
+
+   my $lf = (length ${*$fd} > 0 && substr(${*$fd},-1,1) eq "\r") ? chop(${*$fd})
+                     : "";
+
+   ${*$fd} =~ s/\r\n/\n/go;
+
+   substr($buf,$offset) = ${*$fd};
+
+   $l += length(${*$fd});
+   $offset += length(${*$fd});
+
+   ${*$fd} = $lf;
+   
+   redo READ
+     if($l == 0 && $n > 0);
+
+   if($n == 0 && $l == 0)
+    {
+     substr($buf,$offset) = ${*$fd};
+     ${*$fd} = "";
+    }
+  }
+
+ return $l;
+}
+
+sub write {
+ my $fd = shift;
+ local *buf = \$_[0]; shift;
+ my $size = shift || croak 'write($buf,$size,[$timeout])';
+ my $timeout = @_ ? shift : ${*$fd}{Timeout};
+
+ $fd->can_write($timeout) or
+       croak "Timeout";
+
+ # What is previous pkt ended in \r or not ??
+
+ my $tmp;
+ ($tmp = $buf) =~ s/(?!\r)\n/\r\n/g;
+
+ my $len = $size + length($tmp) - length($buf);
+ my $wrote = syswrite($fd, $tmp, $len);
+
+ if($wrote >= 0)
+  {
+   $wrote = $wrote == $len ? $size
+                          : $len - $wrote
+  }
+
+ return $wrote;
+}
+
+package Net::FTP::I;
+@Net::FTP::I::ISA = qw(Net::FTP::dataconn);
+use Carp;
+
+no strict 'vars';
+
+sub read {
+ my $fd = shift;
+ local *buf = \$_[0]; shift;
+ my $size = shift || croak 'read($buf,$size,[$timeout])';
+ my $timeout = @_ ? shift : ${*$fd}{Timeout};
+
+ $fd->can_read($timeout) or
+       croak "Timeout";
+
+ my $n = sysread($fd, $buf, $size);
+
+ $n;
+}
+
+sub write {
+ my $fd = shift;
+ local *buf = \$_[0]; shift;
+ my $size = shift || croak 'write($buf,$size,[$timeout])';
+ my $timeout = @_ ? shift : ${*$fd}{Timeout};
+
+ $fd->can_write($timeout) or
+       croak "Timeout";
+
+ syswrite($fd, $buf, $size);
+}
+
+=head2 AUTHOR
+
+Graham Barr <Graham.Barr@tiuk.ti.com>
+
+=head2 REVISION
+
+$Revision: 1.17 $
+
+=head2 COPYRIGHT
+
+Copyright (c) 1995 Graham Barr. All rights reserved. This program is free
+software; you can redistribute it and/or modify it under the same terms
+as Perl itself.
+
+=cut
+
+
+1;
+
diff --git a/lib/Net/Netrc.pm b/lib/Net/Netrc.pm
new file mode 100644 (file)
index 0000000..58f0663
--- /dev/null
@@ -0,0 +1,123 @@
+package Net::Netrc;
+
+use Carp;
+use strict;
+
+my %netrc = ();
+
+sub _readrc {
+ my $host = shift;
+ my $file = (getpwuid($>))[7] . "/.netrc";
+ my($login,$pass,$acct) = (undef,undef,undef);
+ local *NETRC;
+ local $_;
+
+ $netrc{default} = undef;
+
+ my @stat = stat($file);
+
+ if(@stat)
+  {
+   if($stat[2] & 077)
+    {
+     carp "Bad permissions: $file";
+     return ();
+    }
+   if($stat[4] != $<)
+    {
+     carp "Not owner: $file";
+     return ();
+    }
+  }
+
+ if(open(NETRC,$file))
+  {
+   my($mach,$macdef,$tok,@tok) = (0,0);
+
+   while(<NETRC>) 
+    {
+     undef $macdef if /\A\n\Z/;
+
+     if($macdef)
+      {
+       push(@$macdef,$_);
+       next;
+      }
+
+     push(@tok, split(/[\s\n]+/, $_));
+
+TOKEN:
+     while(@tok)
+      {
+       if($tok[0] eq "default")
+       {
+        shift(@tok);
+         $mach = $netrc{default} = {};
+
+        next TOKEN;
+       }
+
+       last TOKEN unless @tok > 1;
+       $tok = shift(@tok);
+
+       if($tok eq "machine")
+       {
+         my $host = shift @tok;
+         $mach = $netrc{$host} = {};
+       }
+       elsif($tok =~ /^(login|password|account)$/)
+       {
+         next TOKEN unless $mach;
+         my $value = shift @tok;
+         $mach->{$1} = $value;
+       }
+       elsif($tok eq "macdef")
+       {
+         next TOKEN unless $mach;
+         my $value = shift @tok;
+         $mach->{macdef} = {} unless exists $mach->{macdef};
+         $macdef = $mach->{machdef}{$value} = [];
+       }
+      }
+    }
+   close(NETRC);
+  }
+}
+
+sub lookup {
+ my $pkg = shift;
+ my $mach = shift;
+
+ _readrc() unless exists $netrc{default};
+
+ return bless \$mach if exists $netrc{$mach};
+
+ return bless \("default") if defined $netrc{default};
+
+ return undef;
+}
+
+sub login {
+ my $me = shift;
+ $me = $netrc{$$me};
+ exists $me->{login} ? $me->{login} : undef;
+}
+
+sub account {
+ my $me = shift;
+ $me = $netrc{$$me};
+ exists $me->{account} ? $me->{account} : undef;
+}
+
+sub password {
+ my $me = shift;
+ $me = $netrc{$$me};
+ exists $me->{password} ? $me->{password} : undef;
+}
+
+sub lpa {
+ my $me = shift;
+ ($me->login, $me->password, $me->account);
+}
+
+1;
diff --git a/lib/Net/Socket.pm b/lib/Net/Socket.pm
new file mode 100644 (file)
index 0000000..d24e625
--- /dev/null
@@ -0,0 +1,332 @@
+package Net::Socket;
+
+=head1 NAME
+
+Net::Socket - TEMPORARY Socket filedescriptor class, so Net::FTP still
+works while IO::Socket is having a re-fit <GBARR>
+
+=head1 DESCRIPTION
+
+NO TEXT --- THIS MODULE IS TEMPORARY
+
+=cut
+
+require 5.001;
+use Socket 1.3;
+use Carp;
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT_OK = @Socket::EXPORT;
+
+$VERSION = sprintf("%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/);
+sub Version { $VERSION }
+
+##
+## Really WANT FileHandle::new to return this !!!
+##
+my $seq = 0;
+sub _gensym {
+    my $pkg = @_ ? ref($_[0]) || $_[0] : "";
+    local *{$pkg . "::GLOB" . ++$seq};
+    \delete ${$pkg . "::"}{'GLOB' . $seq};
+}
+
+my %socket_type = (
+ tcp => SOCK_STREAM,
+ udp => SOCK_DGRAM,
+ rpc => SOCK_DGRAM,
+);
+
+# Peer     => remote host name for a 'connect' socket
+# Proto    => specifiy protocol by it self (but override by Service)
+# Service  => require service eg 'ftp' or 'ftp/tcp', overrides Proto
+# Port     => port num for connect eg 'ftp' or 21, defaults to Service
+# Bind     => port to bind to, defaults to INADDR_ANY
+# Listen   => queue size for listen
+#
+# if Listen is defined then a listen socket is created, else if the socket
+# type, which is derived from the protocol, is SOCK_STREAM then a connect
+# is called
+
+=head2 new( %args )
+
+The new constructor takes its arguments in the form of a hash. Accepted 
+arguments are
+
+ Peer     => remote host name for a 'connect' socket
+ Proto    => specifiy protocol by it self (but override by Service)
+ Service  => require service eg 'ftp' or 'ftp/tcp', overrides Proto
+ Port     => port num for connect eg 'ftp' or 21, defaults to Service
+ Bind     => port to bind to, defaults to INADDR_ANY
+ Listen   => queue size for listen
+
+=cut
+
+sub new {
+ my $pkg = shift;
+ my %arg = @_;
+
+ my $proto    = $arg{Proto} || "";
+ my $bindport = $arg{Bind}  || 0;
+ my $servport = $arg{Port}  || 0;
+
+ my $service  = $arg{Service} || $servport || $bindport;
+
+ ($service,$proto) = split(m,/,, $service)
+       if $service =~ m,/,;
+
+ my @serv  = $service =~ /\D/ ? getservbyname($service,$proto)
+                              : getservbyport($service,$proto);
+
+ $proto = $proto || $serv[3];
+
+ croak "cannot determine protocol"
+       unless $proto;
+
+ my @proto = $proto =~ /\D/ ? getprotobyname($proto)
+                            : getprotobynumber($proto);
+
+ croak "unknown protocol"
+       unless @proto;
+
+ my $type = $arg{Type} || $socket_type{$proto[0]} or
+       croak "Unknown socket type";
+
+ my $bindaddr = exists $arg{Addr} ? inet_aton($arg{Addr}) 
+                                 : INADDR_ANY;
+
+ croak "bad bind address $arg{Addr}"
+       unless $bindaddr;
+
+ my $sock = bless _gensym(), ref($pkg) || $pkg;
+
+ socket($sock, AF_INET, $type, $proto[2]) or
+       croak "socket: $!";
+ $bindport = (getservbyname($bindport,$proto))[2]
+       if $bindport =~ /\D/;
+
+ bind($sock, sockaddr_in($bindport, $bindaddr)) or
+       croak "bind: $!";
+
+ if(defined $arg{Listen})
+  {
+   my $queue = $arg{Listen} || 1;
+   listen($sock, $queue) or
+       croak "listen: $!";
+  }
+ else
+  {
+   $servport = $serv[2] || 0
+       unless $servport =~ /^\d+$/ && $servport > 0;
+
+   croak "cannot determine port"
+       unless($servport);
+
+   my $destaddr = defined $arg{Peer} ? inet_aton($arg{Peer})
+                                    : undef;
+
+   my $peername = defined $destaddr ? sockaddr_in($servport,$destaddr)
+                                   : undef;
+   
+   
+   if($type == SOCK_STREAM || $destaddr)
+    {
+     croak "bad peer address"
+       unless defined $destaddr;
+     
+     connect($sock, $peername) or
+       croak "connect: $!";
+
+     ${*$sock}{Peername} = getpeername($sock);
+    }
+   else
+    {
+     ${*$sock}{Peername} = $peername;
+    }
+  }
+ ${*$sock}{Sockname} = getsockname($sock);
+
+ $sock;
+}
+
+=head2 autoflush( [$val] )
+
+Set the file descriptor to autoflush, depending on C<$val>
+
+=cut
+
+sub autoflush {
+ my $sock = shift;
+ my $val = @_ ? shift : 0;
+
+ select((select($sock), $| = $val)[$[]);
+}
+
+=head2 accept
+
+perform the system call C<accept> on the socket and return a new Net::Socket
+object. This object can be used to communicate with the client that was trying
+to connect.
+
+=cut
+
+sub accept {
+ my $sock = shift;
+
+ my $new = bless _gensym();
+
+ accept($new,$sock) or
+       croak "accept: $!";
+
+ ${*$new}{Peername} = getpeername($new) or
+       croak "getpeername: $!";
+
+ ${*$new}{Sockname} = getsockname($new) or
+       croak "getsockname: $!";
+
+ $new;
+}
+
+=head2 close
+
+Close the file descriptor
+
+=cut
+
+sub close {
+ my $sock = shift;
+
+ delete ${*$sock}{Sockname};
+ delete ${*$sock}{Peername};
+
+ close($sock);
+}
+
+=head2 dup
+
+Create a duplicate of the socket object
+
+=cut
+
+sub dup {
+ my $sock = shift;
+ my $dup = bless _gensym(), ref($sock);
+
+ if(open($dup,">&" . fileno($sock))) { 
+  # Copy all the internals
+  ${*$dup} = ${*$sock};
+  @{*$dup} = @{*$sock};
+  %{*$dup} = %{*$sock};
+ }
+ else {
+  undef $dup;
+ }
+
+ $dup;
+}
+
+# Some info about the local socket
+
+=head2 sockname
+
+Return a packed sockaddr structure for the socket
+
+=head2 sockaddr
+
+Return the address part of the sockaddr structure for the socket
+
+=head2 sockport
+
+Return the port number that the socket is using on the local host
+
+=head2 sockhost
+
+Return the address part of the sockaddr structure for the socket in a
+text form xx.xx.xx.xx
+
+=cut
+
+sub sockname { my $sock = shift;  ${*$sock}{Sockname} }
+sub sockaddr { (sockaddr_in(shift->sockname))[1]}
+sub sockport { (sockaddr_in(shift->sockname))[0]}
+sub sockhost { inet_ntoa( shift->sockaddr);}
+
+# Some info about the remote socket, for connect-d sockets
+
+=head2 peername, peeraddr, peerport, peerhost
+
+Same as for the sock* functions, but returns the data about the peer
+host instead of the local host.
+
+=cut
+
+sub peername { my $sock = shift;  ${*$sock}{Peername} or croak "no peer" }
+sub peeraddr { (sockaddr_in(shift->peername))[1]}
+sub peerport { (sockaddr_in(shift->peername))[0]}
+sub peerhost { inet_ntoa( shift->peeraddr);}
+
+=head2 send( $buf [, $flags [, $to]] )
+
+For a udp socket, send the contents of C<$buf> to the remote host C<$to> using
+flags C<$flags>. 
+
+If C<$to> is not specified then the data is sent to the host which the socket
+last communicated with, ie sent to or recieved from.
+
+If C<$flags> is ommited then 0 is used
+
+=cut
+
+sub send {
+ my $sock = shift;
+ local *buf = \$_[0]; shift;
+ my $flags = shift || 0;
+ my $to = shift || $sock->peername;
+
+ # remember who we send to
+ ${*$sock}{Peername} = $to;
+
+ send($sock, $buf, $flags, $to);
+}
+
+=head2 recv( $buf, $len [, $flags] )
+
+Receive C<$len> bytes of data from the socket and place into C<$buf>
+
+If C<$flags> is ommited then 0 is used
+
+=cut
+
+sub recv {
+ my $sock = shift;
+ local *buf = \$_[0]; shift;
+ my $len = shift;
+ my $flags = shift || 0;
+
+ # remember who we recv'd from
+ ${*$sock}{Peername} = recv($sock, $buf='', $len, $flags);
+}
+
+=head1 AUTHOR
+
+Graham Barr <Graham.Barr@tiuk.ti.com>
+
+=head1 REVISION
+
+$Revision: 1.2 $
+
+=head1 COPYRIGHT
+
+Copyright (c) 1995 Graham Barr. All rights reserved. This program is free
+software; you can redistribute it and/or modify it under the same terms
+as Perl itself.
+
+=cut
+
+1; # Keep require happy
+
+
index 5d7d8bf..cca05b7 100644 (file)
@@ -1,6 +1,7 @@
 package Test::Harness;
 
-use 5.002;
+require 5.002;
+
 use Exporter;
 use Benchmark;
 use Config;
diff --git a/lib/Tie/RefHash.pm b/lib/Tie/RefHash.pm
new file mode 100644 (file)
index 0000000..66de257
--- /dev/null
@@ -0,0 +1,123 @@
+package Tie::RefHash;
+
+=head1 NAME
+
+Tie::RefHash - use references as hash keys
+
+=head1 SYNOPSIS
+
+    require 5.004;
+    use Tie::RefHash;
+    tie HASHVARIABLE, 'Tie::RefHash', LIST;
+
+    untie HASHVARIABLE;
+
+=head1 DESCRIPTION
+
+This module provides the ability to use references as hash keys if
+you first C<tie> the hash variable to this module.
+
+It is implemented using the standard perl TIEHASH interface.  Please
+see the C<tie> entry in perlfunc(1) and perltie(1) for more information.
+
+=head1 EXAMPLE
+
+    use Tie::RefHash;
+    tie %h, 'Tie::RefHash';
+    $a = [];
+    $b = {};
+    $c = \*main;
+    $d = \"gunk";
+    $e = sub { 'foo' };
+    %h = ($a => 1, $b => 2, $c => 3, $d => 4, $e => 5);
+    $a->[0] = 'foo';
+    $b->{foo} = 'bar';
+    for (keys %h) {
+       print ref($_), "\n";
+    }
+
+
+=head1 AUTHOR
+
+Gurusamy Sarathy        gsar@umich.edu
+
+=head1 VERSION
+
+Version 1.2    15 Dec 1996
+
+=head1 SEE ALSO
+
+perl(1), perlfunc(1), perltie(1)
+
+=cut
+
+require 5.003_11;
+use Tie::Hash;
+@ISA = qw(Tie::Hash);
+use strict;
+
+sub TIEHASH {
+  my $c = shift;
+  my $s = [];
+  bless $s, $c;
+  while (@_) {
+    $s->STORE(shift, shift);
+  }
+  return $s;
+}
+
+sub FETCH {
+  my($s, $k) = @_;
+  (ref $k) ? $s->[0]{"$k"}[1] : $s->[1]{$k};
+}
+
+sub STORE {
+  my($s, $k, $v) = @_;
+  if (ref $k) {
+    $s->[0]{"$k"} = [$k, $v];
+  }
+  else {
+    $s->[1]{$k} = $v;
+  }
+  $v;
+}
+
+sub DELETE {
+  my($s, $k) = @_;
+  (ref $k) ? delete($s->[0]{"$k"}) : delete($s->[1]{$k});
+}
+
+sub EXISTS {
+  my($s, $k) = @_;
+  (ref $k) ? exists($s->[0]{"$k"}) : exists($s->[1]{$k});
+}
+
+sub FIRSTKEY {
+  my $s = shift;
+  my $a = scalar(keys %{$s->[0]}) + scalar(keys %{$s->[1]});
+  $s->[2] = 0;
+  $s->NEXTKEY;
+}
+
+sub NEXTKEY {
+  my $s = shift;
+  my ($k, $v);
+  if (!$s->[2]) {
+    if (($k, $v) = each %{$s->[0]}) {
+      return $s->[0]{"$k"}[0];
+    }
+    else {
+      $s->[2] = 1;
+    }
+  }
+  return each %{$s->[1]};
+}
+
+sub CLEAR {
+  my $s = shift;
+  $s->[2] = 0;
+  %{$s->[0]} = ();
+  %{$s->[1]} = ();
+}
+
+1;
index 4d8f609..8af1727 100644 (file)
@@ -38,7 +38,6 @@ Nick Ing-Simmons nik@tiuk.ti.com
 
 use Cwd;
 
-warn __FILE__;
 
 sub import
 {
@@ -60,7 +59,7 @@ sub import
    if (-d $blib && -d "$blib/arch" && -d "$blib/lib")
     {
      unshift(@INC,"$blib/arch","$blib/lib");
-     warn "Using $blib";
+     warn "Using $blib\n";
      return;
     }
    $dir .= "/..";
index c3e5b93..31e7670 100755 (executable)
@@ -1,18 +1,4 @@
-#!/usr/local/bin/perl
-eval 'exec perl -S $0  ${1+"$@"}'
-    if 0;
-
-use Config;
-if ($^O eq 'VMS') {
-   $diagnostics::PODFILE = VMS::Filespec::unixify($Config{'privlibexp'}) .
-                           '/pod/perldiag.pod';
-}
-else { $diagnostics::PODFILE= $Config{privlibexp} . "/pod/perldiag.pod"; }
-
 package diagnostics;
-require 5.001;
-use English;
-use Carp;
 
 =head1 NAME
 
@@ -176,6 +162,18 @@ Tom Christiansen F<E<lt>tchrist@mox.perl.comE<gt>>, 25 June 1995.
 
 =cut
 
+require 5.001;
+use English;
+use Carp;
+
+use Config;
+if ($^O eq 'VMS') {
+    $PODFILE = VMS::Filespec::unixify($Config{privlibexp}).'/pod/perldiag.pod';
+}
+else {
+    $PODFILE = $Config{privlibexp} . "/pod/perldiag.pod";
+}
+
 $DEBUG ||= 0;
 my $WHOAMI = ref bless [];  # nobody's business, prolly not even mine
 
index d621e67..16b7435 100755 (executable)
@@ -20,8 +20,8 @@ echo "Extracting makeaperl (with variable substitutions)"
 rm -f makeaperl
 $spitshell >makeaperl <<!GROK!THIS!
 $startperl
-    eval 'exec perl -S \$0 "\$@"'
-       if 0;
+    eval 'exec $perlpath -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
 !GROK!THIS!
 
 $spitshell >>makeaperl <<'!NO!SUBS!'
index 6f22da6..f702c57 100644 (file)
--- a/malloc.c
+++ b/malloc.c
@@ -130,11 +130,6 @@ static u_short blk_shift[11 - 3] = {256, 128, 64, 32,
 #  define MAX_NONSHIFT 2       /* Shift 64 greater than chunk 32. */
 };
 
-#  ifdef DEBUGGING_MSTATS
-static u_int sbrk_slack;
-static u_int start_slack;
-#  endif
-
 #else  /* !PACK_MALLOC */
 
 #  define OV_MAGIC(block,bucket) (block)->ov_magic
@@ -151,8 +146,12 @@ static u_int start_slack;
 
 #ifdef TWO_POT_OPTIMIZE
 
-#  define PERL_PAGESIZE 4096
-#  define FIRST_BIG_TWO_POT 14         /* 16K */
+#  ifndef PERL_PAGESIZE
+#    define PERL_PAGESIZE 4096
+#  endif 
+#  ifndef FIRST_BIG_TWO_POT
+#    define FIRST_BIG_TWO_POT 14       /* 16K */
+#  endif
 #  define FIRST_BIG_BLOCK (1<<FIRST_BIG_TWO_POT) /* 16K */
 /* If this value or more, check against bigger blocks. */
 #  define FIRST_BIG_BOUND (FIRST_BIG_BLOCK - M_OVERHEAD)
@@ -239,6 +238,9 @@ extern      char *sbrk();
  * for a given block size.
  */
 static u_int nmalloc[NBUCKETS];
+static u_int goodsbrk;
+static  u_int sbrk_slack;
+static  u_int start_slack;
 #endif
 
 #ifdef DEBUGGING
@@ -337,9 +339,6 @@ malloc(nbytes)
 #ifndef PACK_MALLOC
        OV_INDEX(p) = bucket;
 #endif
-#ifdef DEBUGGING_MSTATS
-       nmalloc[bucket]++;
-#endif
 #ifdef RCHECK
        /*
         * Record allocated size of block and
@@ -386,7 +385,7 @@ morecore(bucket)
        if ((u_int)op & 0x3ff)
                (void)sbrk(slack = 1024 - ((u_int)op & 0x3ff));
 #    endif
-#    if defined(DEBUGGING_MSTATS) && defined(PACK_MALLOC)
+#    if defined(DEBUGGING_MSTATS)
        sbrk_slack += slack;
 #    endif
 #  else
@@ -414,6 +413,9 @@ morecore(bucket)
            if (op == (union overhead *)-1)
                return;
        }
+#ifdef DEBUGGING_MSTATS
+       goodsbrk += needed;
+#endif 
        /*
         * Round up to minimum allocation size boundary
         * and deduct from block count to reflect.
@@ -450,6 +452,9 @@ morecore(bucket)
        } else op++;            /* One chunk per block. */
 #endif /* !PACK_MALLOC */
        nextf[bucket] = op;
+#ifdef DEBUGGING_MSTATS
+       nmalloc[bucket] += nblks;
+#endif 
        while (--nblks > 0) {
                op->ov_next = (union overhead *)((caddr_t)op + siz);
                op = (union overhead *)((caddr_t)op + siz);
@@ -518,9 +523,6 @@ free(mp)
        size = OV_INDEX(op);
        op->ov_next = nextf[size];
        nextf[size] = op;
-#ifdef DEBUGGING_MSTATS
-       nmalloc[size]--;
-#endif
 }
 
 /*
@@ -705,7 +707,7 @@ dump_mstats(s)
 {
        register int i, j;
        register union overhead *p;
-       int topbucket=0, totfree=0, totused=0;
+       int topbucket=0, totfree=0, total=0;
        u_int nfree[NBUCKETS];
 
        for (i=0; i < NBUCKETS; i++) {
@@ -713,28 +715,23 @@ dump_mstats(s)
                        ;
                nfree[i] = j;
                totfree += nfree[i]   * (1 << (i + 3));
-               totused += nmalloc[i] * (1 << (i + 3));
-               if (nfree[i] || nmalloc[i])
+               total += nmalloc[i] * (1 << (i + 3));
+               if (nmalloc[i])
                        topbucket = i;
        }
        if (s)
                PerlIO_printf(PerlIO_stderr(), "Memory allocation statistics %s (buckets 8..%d)\n",
                        s, (1 << (topbucket + 3)) );
-       PerlIO_printf(PerlIO_stderr(), " %7d free: ", totfree);
+       PerlIO_printf(PerlIO_stderr(), "%8d free:", totfree);
        for (i=0; i <= topbucket; i++) {
-               PerlIO_printf(PerlIO_stderr(), (i<5)?" %5d":" %3d", nfree[i]);
+               PerlIO_printf(PerlIO_stderr(), (i<5 || i==7)?" %5d": (i<9)?" %3d":" %d", nfree[i]);
        }
-       PerlIO_printf(PerlIO_stderr(), "\n %7d used: ", totused);
+       PerlIO_printf(PerlIO_stderr(), "\n%8d used:", total - totfree);
        for (i=0; i <= topbucket; i++) {
-               PerlIO_printf(PerlIO_stderr(), (i<5)?" %5d":" %3d", nmalloc[i]);
+               PerlIO_printf(PerlIO_stderr(), (i<5 || i==7)?" %5d": (i<9)?" %3d":" %d", nmalloc[i] - nfree[i]);
        }
-       PerlIO_printf(PerlIO_stderr(), "\n");
-#ifdef PACK_MALLOC
-       if (sbrk_slack || start_slack) {
-           PerlIO_printf(PerlIO_stderr(), "Odd ends: %7d bytes from sbrk(), %7d from malloc.\n",
-                   sbrk_slack, start_slack);
-       }
-#endif
+       PerlIO_printf(PerlIO_stderr(), "\nTotal sbrk(): %8d. Odd ends: sbrk(): %7d, malloc(): %7d bytes.\n",
+                     goodsbrk + sbrk_slack, sbrk_slack, start_slack);
 }
 #else
 void
diff --git a/mg.c b/mg.c
index 816b4b8..d4c781e 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -1101,6 +1101,37 @@ MAGIC* mg;
 }
 
 int
+magic_setvivary(sv,mg)
+SV* sv;
+MAGIC* mg;
+{
+    if (LvTARGLEN(sv)) {
+       AV* av = (AV*)LvTARG(sv);
+       if (LvTARGOFF(sv) <= AvFILL(av)) {
+           SV** svp = AvARRAY(av) + LvTARGOFF(sv);
+           LvTARG(sv) = newSVsv(*svp);
+           SvREFCNT_dec(*svp);
+           *svp = SvREFCNT_inc(LvTARG(sv));
+       }
+       else
+           LvTARG(sv) = Nullsv;
+       LvTARGLEN(sv) = 0;
+       SvREFCNT_dec(av);
+    }
+    if (LvTARG(sv))
+       sv_setsv(LvTARG(sv), sv);
+    return 0;
+}
+
+int
+magic_freevivary(sv,mg)
+SV* sv;
+MAGIC* mg;
+{
+    SvREFCNT_dec(LvTARG(sv));
+}
+
+int
 magic_setmglob(sv,mg)
 SV* sv;
 MAGIC* mg;
index 2d66964..680b042 100644 (file)
@@ -40,6 +40,7 @@ char **env;
        if (!my_perl)
            exit(1);
        perl_construct( my_perl );
+       perl_destruct_level = 0;
     }
 
     exitstatus = perl_parse( my_perl, xs_init, argc, argv, (char **) NULL );
diff --git a/op.c b/op.c
index 639454d..a7460b1 100644 (file)
--- a/op.c
+++ b/op.c
@@ -189,9 +189,18 @@ pad_findlex(char *name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix)
                seq > (I32)SvNVX(sv) &&
                strEQ(SvPVX(sv), name))
            {
-               I32 depth = CvDEPTH(cv) ? CvDEPTH(cv) : 1;
-               AV *oldpad = (AV*)*av_fetch(curlist, depth, FALSE);
-               SV *oldsv = *av_fetch(oldpad, off, TRUE);
+               I32 depth;
+               AV *oldpad;
+               SV *oldsv;
+
+               depth = CvDEPTH(cv);
+               if (!depth) {
+                   if (newoff)
+                       return 0; /* don't clone inactive stack frame */
+                   depth = 1;
+               }
+               oldpad = (AV*)*av_fetch(curlist, depth, FALSE);
+               oldsv = *av_fetch(oldpad, off, TRUE);
                if (!newoff) {          /* Not a mere clone operation. */
                    SV *sv = NEWSV(1103,0);
                    newoff = pad_alloc(OP_PADSV, SVs_PADMY);
@@ -201,9 +210,17 @@ pad_findlex(char *name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix)
                    SvNVX(sv) = (double)curcop->cop_seq;
                    SvIVX(sv) = 999999999;      /* A ref, intro immediately */
                    SvFLAGS(sv) |= SVf_FAKE;
+                   /* "It's closures all the way down." */
+                   CvCLONE_on(compcv);
+                   if (cv != startcv) {
+                       CV *bcv;
+                       for (bcv = startcv;
+                            bcv && bcv != cv && !CvCLONE(bcv);
+                            bcv = CvOUTSIDE(bcv))
+                           CvCLONE_on(bcv);
+                   }
                }
                av_store(comppad, newoff, SvREFCNT_inc(oldsv));
-               CvCLONE_on(compcv);
                return newoff;
            }
        }
@@ -441,9 +458,9 @@ OP *op;
        break;
     case OP_NEXTSTATE:
     case OP_DBSTATE:
+       Safefree(cCOP->cop_label);
        SvREFCNT_dec(cCOP->cop_filegv);
        break;
-    /* case OP_ANONCODE: XXX breaks eval of anon subs in closures (cf. Opcode) */
     case OP_CONST:
        SvREFCNT_dec(cSVOP->op_sv);
        break;
@@ -900,7 +917,6 @@ I32 type;
 {
     OP *kid;
     SV *sv;
-    char mtype;
 
     if (!op || error_count)
        return op;
@@ -922,6 +938,10 @@ I32 type;
        else
            croak("That use of $[ is unsupported");
        break;
+    case OP_STUB:
+       if (op->op_flags & OPf_PARENS)
+           break;
+       goto nomod;
     case OP_ENTERSUB:
        if ((type == OP_UNDEF || type == OP_REFGEN) &&
            !(op->op_flags & OPf_STACKED)) {
@@ -1024,23 +1044,13 @@ I32 type;
     case OP_KEYS:
        if (type != OP_SASSIGN)
            goto nomod;
-       mtype = 'k';
-       goto makelv;
+       /* FALL THROUGH */
     case OP_POS:
-       mtype = '.';
-       goto makelv;
     case OP_VEC:
-       mtype = 'v';
-       goto makelv;
     case OP_SUBSTR:
-       mtype = 'x';
-      makelv:
        pad_free(op->op_targ);
        op->op_targ = pad_alloc(op->op_type, SVs_PADMY);
-       sv = PAD_SV(op->op_targ);
-       sv_upgrade(sv, SVt_PVLV);
-       sv_magic(sv, Nullsv, mtype, Nullch, 0);
-       curpad[op->op_targ] = sv;
+       assert(SvTYPE(PAD_SV(op->op_targ)) == SVt_NULL);
        if (op->op_flags & OPf_KIDS)
            mod(cBINOP->op_first->op_sibling, type);
        break;
@@ -1127,8 +1137,10 @@ I32 type;
        ref(cUNOP->op_first, op->op_type);
        /* FALL THROUGH */
     case OP_PADSV:
-       if (type == OP_RV2AV || type == OP_RV2HV) {
-           op->op_private |= (type == OP_RV2AV ? OPpDEREF_AV : OPpDEREF_HV);
+       if (type == OP_RV2SV || type == OP_RV2AV || type == OP_RV2HV) {
+           op->op_private |= (type == OP_RV2AV ? OPpDEREF_AV
+                              : type == OP_RV2HV ? OPpDEREF_HV
+                              : OPpDEREF_SV);
            op->op_flags |= OPf_MOD;
        }
        break;
@@ -1155,8 +1167,10 @@ I32 type;
     case OP_AELEM:
     case OP_HELEM:
        ref(cBINOP->op_first, op->op_type);
-       if (type == OP_RV2AV || type == OP_RV2HV) {
-           op->op_private |= (type == OP_RV2AV ? OPpDEREF_AV : OPpDEREF_HV);
+       if (type == OP_RV2SV || type == OP_RV2AV || type == OP_RV2HV) {
+           op->op_private |= (type == OP_RV2AV ? OPpDEREF_AV
+                              : type == OP_RV2HV ? OPpDEREF_HV
+                              : OPpDEREF_SV);
            op->op_flags |= OPf_MOD;
        }
        break;
@@ -2698,7 +2712,7 @@ newFOROP(I32 flags,char *label,line_t forline,OP *sv,OP *expr,OP *block,OP *cont
     else {
        sv = newGVOP(OP_GV, 0, defgv);
     }
-    if (expr->op_type == OP_RV2AV) {
+    if (expr->op_type == OP_RV2AV || expr->op_type == OP_PADAV) {
        expr = scalar(ref(expr, OP_ITER));
        iterflags |= OPf_STACKED;
     }
@@ -2767,16 +2781,43 @@ CV *cv;
     }
 }
 
-CV *
-cv_clone(proto)
+#ifdef DEBUG_CLOSURES
+static void
+cv_dump(cv)
+CV* cv;
+{
+    CV *outside = CvOUTSIDE(cv);
+    AV* padlist = CvPADLIST(cv);
+    AV* pad_name = (AV*)*av_fetch(padlist, 0, FALSE);
+    AV* pad = (AV*)*av_fetch(padlist, 1, FALSE);
+    SV** pname = AvARRAY(pad_name);
+    SV** ppad = AvARRAY(pad);
+    I32 ix;
+
+    PerlIO_printf(Perl_debug_log, "\tCV=0x%p (%s), OUTSIDE=0x%p (%s)\n",
+                 cv, CvANON(cv) ? "ANON" : GvNAME(CvGV(cv)),
+                 outside, CvANON(outside) ? "ANON" : GvNAME(CvGV(outside)));
+
+    for (ix = 1; ix <= AvFILL(pad); ix++) {
+       if (SvPOK(pname[ix]))
+           PerlIO_printf(Perl_debug_log, "\t%4d. 0x%p (\"%s\")\n",
+                         ix, ppad[ix], SvPVX(pname[ix]))
+    }
+}
+#endif /* DEBUG_CLOSURES */
+
+static CV *
+cv_clone2(proto, outside)
 CV* proto;
+CV* outside;
 {
     AV* av;
     I32 ix;
     AV* protopadlist = CvPADLIST(proto);
     AV* protopad_name = (AV*)*av_fetch(protopadlist, 0, FALSE);
     AV* protopad = (AV*)*av_fetch(protopadlist, 1, FALSE);
-    SV** svp = AvARRAY(protopad);
+    SV** pname = AvARRAY(protopad_name);
+    SV** ppad = AvARRAY(protopad);
     AV* comppadlist;
     CV* cv;
 
@@ -2788,14 +2829,16 @@ CV* proto;
     cv = compcv = (CV*)NEWSV(1104,0);
     sv_upgrade((SV *)cv, SVt_PVCV);
     CvCLONED_on(cv);
+    if (CvANON(proto))
+       CvANON_on(cv);
 
     CvFILEGV(cv)       = CvFILEGV(proto);
     CvGV(cv)           = GvREFCNT_inc(CvGV(proto));
     CvSTASH(cv)                = CvSTASH(proto);
     CvROOT(cv)         = CvROOT(proto);
     CvSTART(cv)                = CvSTART(proto);
-    if (CvOUTSIDE(proto))
-       CvOUTSIDE(cv)   = (CV*)SvREFCNT_inc((SV*)CvOUTSIDE(proto));
+    if (outside)
+       CvOUTSIDE(cv)   = (CV*)SvREFCNT_inc(outside);
 
     comppad = newAV();
 
@@ -2804,7 +2847,7 @@ CV* proto;
     av_store(comppadlist, 0, SvREFCNT_inc((SV*)protopad_name));
     av_store(comppadlist, 1, (SV*)comppad);
     CvPADLIST(cv) = comppadlist;
-    av_extend(comppad, AvFILL(protopad));
+    av_fill(comppad, AvFILL(protopad));
     curpad = AvARRAY(comppad);
 
     av = newAV();           /* will be @_ */
@@ -2812,37 +2855,75 @@ CV* proto;
     av_store(comppad, 0, (SV*)av);
     AvFLAGS(av) = AVf_REIFY;
 
-    svp = AvARRAY(protopad_name);
-    for ( ix = AvFILL(protopad); ix > 0; ix--) {
-       SV *sv;
-       if (svp[ix] != &sv_undef) {
-           char *name = SvPVX(svp[ix]);    /* XXX */
-           if (SvFLAGS(svp[ix]) & SVf_FAKE) {  /* lexical from outside? */
-               I32 off = pad_findlex(name,ix,curcop->cop_seq, CvOUTSIDE(proto),
-                                       cxstack_ix);
-               if (off != ix)
+    for (ix = AvFILL(protopad); ix > 0; ix--) {
+       SV* sv;
+       if (pname[ix] != &sv_undef) {
+           char *name = SvPVX(pname[ix]);    /* XXX */
+           if (SvFLAGS(pname[ix]) & SVf_FAKE) {   /* lexical from outside? */
+               I32 off = pad_findlex(name, ix, SvIVX(pname[ix]),
+                                     CvOUTSIDE(cv), cxstack_ix);
+               if (!off)
+                   curpad[ix] = SvREFCNT_inc(ppad[ix]);
+               else if (off != ix)
                    croak("panic: cv_clone: %s", name);
            }
            else {                              /* our own lexical */
-               if (*name == '@')
-                   av_store(comppad, ix, sv = (SV*)newAV());
+               if (*name == '&') {
+                   /* anon code -- we'll come back for it */
+                   sv = SvREFCNT_inc(ppad[ix]);
+               }
+               else if (*name == '@')
+                   sv = (SV*)newAV();
                else if (*name == '%')
-                   av_store(comppad, ix, sv = (SV*)newHV());
+                   sv = (SV*)newHV();
                else
-                   av_store(comppad, ix, sv = NEWSV(0,0));
-               SvPADMY_on(sv);
+                   sv = NEWSV(0,0);
+               if (!SvPADBUSY(sv))
+                   SvPADMY_on(sv);
+               curpad[ix] = sv;
            }
        }
        else {
-           av_store(comppad, ix, sv = NEWSV(0,0));
+           sv = NEWSV(0,0);
            SvPADTMP_on(sv);
+           curpad[ix] = sv;
        }
     }
 
+    /* Now that vars are all in place, clone nested closures. */
+
+    for (ix = AvFILL(protopad); ix > 0; ix--) {
+       if (pname[ix] != &sv_undef
+           && !(SvFLAGS(pname[ix]) & SVf_FAKE)
+           && *SvPVX(pname[ix]) == '&'
+           && CvCLONE(ppad[ix]))
+       {
+           CV *kid = cv_clone2((CV*)ppad[ix], cv);
+           SvREFCNT_dec(ppad[ix]);
+           CvCLONE_on(kid);
+           SvPADMY_on(kid);
+           curpad[ix] = (SV*)kid;
+       }
+    }
+
+#ifdef DEBUG_CLOSURES
+    PerlIO_printf(Perl_debug_log, "Cloned from:\n");
+    cv_dump(proto);
+    PerlIO_printf(Perl_debug_log, "  to:\n");
+    cv_dump(cv);
+#endif
+
     LEAVE;
     return cv;
 }
 
+CV *
+cv_clone(proto)
+CV* proto;
+{
+    return cv_clone2(proto, CvOUTSIDE(proto));
+}
+
 SV *
 cv_const_sv(cv)
 CV *cv;
@@ -3300,6 +3381,19 @@ OP *o;
 /* Check routines. */
 
 OP *
+ck_anoncode(op)
+OP *op;
+{
+    PADOFFSET ix = pad_alloc(op->op_type, SVs_PADMY);
+    av_store(comppad_name, ix, newSVpv("&", 1));
+    av_store(comppad, ix, cSVOP->op_sv);
+    SvPADMY_on(cSVOP->op_sv);
+    cSVOP->op_sv = Nullsv;
+    cSVOP->op_targ = ix;
+    return op;
+}
+
+OP *
 ck_bitop(op)
 OP *op;
 {
@@ -3346,10 +3440,14 @@ ck_delete(op)
 OP *op;
 {
     op = ck_fun(op);
+    op->op_private = 0;
     if (op->op_flags & OPf_KIDS) {
        OP *kid = cUNOP->op_first;
-       if (kid->op_type != OP_HELEM)
-           croak("%s argument is not a HASH element", op_desc[op->op_type]);
+       if (kid->op_type == OP_HSLICE)
+           op->op_private |= OPpSLICE;
+       else if (kid->op_type != OP_HELEM)
+           croak("%s argument is not a HASH element or slice",
+                 op_desc[op->op_type]);
        null(kid);
     }
     return op;
@@ -3431,6 +3529,20 @@ OP *op;
 }
 
 OP *
+ck_exists(op)
+OP *op;
+{
+    op = ck_fun(op);
+    if (op->op_flags & OPf_KIDS) {
+       OP *kid = cUNOP->op_first;
+       if (kid->op_type != OP_HELEM)
+           croak("%s argument is not a HASH element", op_desc[op->op_type]);
+       null(kid);
+    }
+    return op;
+}
+
+OP *
 ck_gvconst(o)
 register OP *o;
 {
@@ -4232,7 +4344,7 @@ register OP* o;
 
        case OP_GV:
            if (o->op_next->op_type == OP_RV2SV) {
-               if (!(o->op_next->op_private & (OPpDEREF_HV|OPpDEREF_AV))) {
+               if (!(o->op_next->op_private & OPpDEREF)) {
                    null(o->op_next);
                    o->op_private |= o->op_next->op_private & OPpLVAL_INTRO;
                    o->op_next = o->op_next->op_next;
@@ -4246,8 +4358,7 @@ register OP* o;
                if (pop->op_type == OP_CONST &&
                    (op = pop->op_next) &&
                    pop->op_next->op_type == OP_AELEM &&
-                   !(pop->op_next->op_private &
-                       (OPpDEREF_HV|OPpDEREF_AV|OPpLVAL_INTRO)) &&
+                   !(pop->op_next->op_private & (OPpDEREF|OPpLVAL_INTRO)) &&
                    (i = SvIV(((SVOP*)pop)->op_sv) - compiling.cop_arybase)
                                <= 255 &&
                    i >= 0)
diff --git a/op.h b/op.h
index eb26f9c..4b57b33 100644 (file)
--- a/op.h
+++ b/op.h
@@ -86,8 +86,10 @@ typedef U32 PADOFFSET;
   /* (lower bits carry hints) */
 #define OPpENTERSUB_AMPER      8       /* Used & form to call. */
 #define OPpENTERSUB_DB         16      /* Debug subroutine. */
-#define OPpDEREF_AV            32      /* Want ref to AV. */
-#define OPpDEREF_HV            64      /* Want ref to HV. */
+#define OPpDEREF               (32|64) /* Want ref to something: */
+#define OPpDEREF_AV            32      /*   Want ref to AV. */
+#define OPpDEREF_HV            64      /*   Want ref to HV. */
+#define OPpDEREF_SV            (32|64) /*   Want ref to SV. */
 
 /* Private for OP_CONST */
 #define OPpCONST_ENTERED       16      /* Has been entered as symbol. */
@@ -100,9 +102,12 @@ typedef U32 PADOFFSET;
 /* Private for OP_LIST */
 #define OPpLIST_GUESSED                64      /* Guessed that pushmark was needed. */
 
-/* Private for OP_LEAVE and friends */
+/* Private for OP_LEAVE, OP_DELETE, and friends(?) */
 #define OPpLEAVE_VOID          64      /* No need to copy out values. */
 
+/* Private for OP_DELETE */
+#define OPpSLICE               32      /* Operating on a list of keys */
+
 /* Private for OP_SORT, OP_PRTF, OP_SPRINTF, string cmp'n, and case changers */
 #define OPpLOCALE              64      /* Use locale */
 
index f0b18d0..518c1e4 100644 (file)
--- a/opcode.h
+++ b/opcode.h
@@ -1052,12 +1052,14 @@ EXT char *op_desc[] = {
 };
 #endif
 
+OP *   ck_anoncode     _((OP* op));
 OP *   ck_bitop        _((OP* op));
 OP *   ck_concat       _((OP* op));
 OP *   ck_delete       _((OP* op));
 OP *   ck_eof          _((OP* op));
 OP *   ck_eval         _((OP* op));
 OP *   ck_exec         _((OP* op));
+OP *   ck_exists       _((OP* op));
 OP *   ck_ftst         _((OP* op));
 OP *   ck_fun          _((OP* op));
 OP *   ck_fun_locale   _((OP* op));
@@ -1799,7 +1801,7 @@ EXT OP * (*check[]) _((OP *op)) = {
        ck_rvconst,     /* rv2sv */
        ck_null,        /* av2arylen */
        ck_rvconst,     /* rv2cv */
-       ck_null,        /* anoncode */
+       ck_anoncode,    /* anoncode */
        ck_null,        /* prototype */
        ck_spair,       /* refgen */
        ck_null,        /* srefgen */
@@ -1912,7 +1914,7 @@ EXT OP * (*check[]) _((OP *op)) = {
        ck_fun,         /* values */
        ck_fun,         /* keys */
        ck_delete,      /* delete */
-       ck_delete,      /* exists */
+       ck_exists,      /* exists */
        ck_rvconst,     /* rv2hv */
        ck_null,        /* helem */
        ck_null,        /* hslice */
@@ -2261,7 +2263,7 @@ EXT U32 opargs[] = {
        0x00000408,     /* each */
        0x00000408,     /* values */
        0x00000408,     /* keys */
-       0x00000104,     /* delete */
+       0x00000100,     /* delete */
        0x00000114,     /* exists */
        0x00000048,     /* rv2hv */
        0x00001404,     /* helem */
index 3b3672d..b231933 100755 (executable)
--- a/opcode.pl
+++ b/opcode.pl
@@ -214,7 +214,7 @@ rv2gv               ref-to-glob cast        ck_rvconst      ds
 rv2sv          scalar deref            ck_rvconst      ds      
 av2arylen      array length            ck_null         is      
 rv2cv          subroutine deref        ck_rvconst      d
-anoncode       anonymous subroutine    ck_null         0       
+anoncode       anonymous subroutine    ck_anoncode     0       
 prototype      subroutine prototype    ck_null         s       S
 refgen         reference constructor   ck_spair        m       L
 srefgen                scalar ref constructor  ck_null         fs      S
@@ -362,8 +362,8 @@ aslice              array slice             ck_null         m       A L
 each           each                    ck_fun          t       H
 values         values                  ck_fun          t       H
 keys           keys                    ck_fun          t       H
-delete         delete                  ck_delete       s       S
-exists         exists operator         ck_delete       is      S
+delete         delete                  ck_delete       0       S
+exists         exists operator         ck_exists       is      S
 rv2hv          associative array deref ck_rvconst      dt      
 helem          associative array elem  ck_null         s       H S
 hslice         associative array slice ck_null         m       H L
index a047efb..73210e2 100644 (file)
@@ -1,5 +1,5 @@
 #define PATCHLEVEL 3
-#define SUBVERSION 11
+#define SUBVERSION 12
 
 /*
        local_patches -- list of locally applied less-than-subversion patches.
diff --git a/perl.c b/perl.c
index 2544fd3..3e03044 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -117,6 +117,7 @@ register PerlInterpreter *sv_interp;
     rsfp       = Nullfp;
     statname   = Nullsv;
     tmps_floor = -1;
+    perl_destruct_level = 1;
 #endif
 
     init_ids();
@@ -159,11 +160,22 @@ register PerlInterpreter *sv_interp;
 #ifdef DEBUGGING
     {
        char *s;
-       if (s = getenv("PERL_DESTRUCT_LEVEL"))
-           destruct_level = atoi(s);
+       if (s = getenv("PERL_DESTRUCT_LEVEL")) {
+           int i = atoi(s);
+           if (destruct_level < i)
+               destruct_level = i;
+       }
     }
 #endif
 
+    /* unhook hooks which will soon be, or use, destroyed data */
+    SvREFCNT_dec(warnhook);
+    warnhook = Nullsv;
+    SvREFCNT_dec(diehook);
+    diehook = Nullsv;
+    SvREFCNT_dec(parsehook);
+    parsehook = Nullsv;
+
     LEAVE;
     FREETMPS;
 
@@ -192,15 +204,23 @@ register PerlInterpreter *sv_interp;
        return;
     }
 
-    /* unhook hooks which may now point to, or use, broken code        */
-    if (warnhook && SvREFCNT(warnhook))
-       SvREFCNT_dec(warnhook);
-    if (diehook && SvREFCNT(diehook))
-       SvREFCNT_dec(diehook);
-    if (parsehook && SvREFCNT(parsehook))
-       SvREFCNT_dec(parsehook);
-    
+    /* loosen bonds of global variables */
+
+    setdefout(Nullgv);
+
+    sv_free(nrs);
+    nrs = Nullsv;
+
+    sv_free(lastscream);
+    lastscream = Nullsv;
+
+    sv_free(statname);
+    statname = Nullsv;
+    statgv = Nullgv;
+    laststatval = -1;
+
     /* Prepare to destruct main symbol table.  */
+
     hv = defstash;
     defstash = 0;
     SvREFCNT_dec(hv);
@@ -1943,15 +1963,32 @@ static void
 init_stacks()
 {
     curstack = newAV();
-    mainstack = curstack;                      /* remember in case we switch stacks */
-    AvREAL_off(curstack);                      /* not a real array */
+    mainstack = curstack;              /* remember in case we switch stacks */
+    AvREAL_off(curstack);              /* not a real array */
     av_extend(curstack,127);
 
     stack_base = AvARRAY(curstack);
     stack_sp = stack_base;
     stack_max = stack_base + 127;
 
-    /* Shouldn't these stacks be per-interpreter? */
+    cxstack_max = 8192 / sizeof(CONTEXT) - 2;  /* Use most of 8K. */
+    New(50,cxstack,cxstack_max + 1,CONTEXT);
+    cxstack_ix = -1;
+
+    New(50,tmps_stack,128,SV*);
+    tmps_ix = -1;
+    tmps_max = 128;
+
+    DEBUG( {
+       New(51,debname,128,char);
+       New(52,debdelim,128,char);
+    } )
+
+    /*
+     * The following stacks almost certainly should be per-interpreter,
+     * but for now they're not.  XXX
+     */
+
     if (markstack) {
        markstack_ptr = markstack;
     } else {
@@ -1982,20 +2019,7 @@ init_stacks()
        New(54,retstack,16,OP*);
        retstack_ix = 0;
        retstack_max = 16;
-   }
-
-    cxstack_max = 8192 / sizeof(CONTEXT) - 2;  /* Use most of 8K. */
-    New(50,cxstack,cxstack_max + 1,CONTEXT);
-    cxstack_ix = -1;
-
-    New(50,tmps_stack,128,SV*);
-    tmps_ix = -1;
-    tmps_max = 128;
-
-    DEBUG( {
-       New(51,debname,128,char);
-       New(52,debdelim,128,char);
-    } )
+    }
 }
 
 static void
@@ -2003,6 +2027,10 @@ nuke_stacks()
 {
     Safefree(cxstack);
     Safefree(tmps_stack);
+    DEBUG( {
+       Safefree(debname);
+       Safefree(debdelim);
+    } )
 }
 
 static PerlIO *tmpfp;  /* moved outside init_lexer() because of UNICOS bug */
diff --git a/perl.h b/perl.h
index 17402a4..85c7c86 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -1285,7 +1285,6 @@ EXT SV ** curpad;
 
 /* temp space */
 EXT SV *       Sv;
-EXT HE         He;
 EXT XPV *      Xpv;
 EXT char       buf[2048];      /* should be longer than PATH_MAX */
 EXT char       tokenbuf[256];
@@ -1664,7 +1663,7 @@ IEXT char *       Ie_tmpname;
 IEXT PerlIO *  Ie_fp;
 IEXT U32       Iperldb;
        /* This value may be raised by extensions for testing purposes */
-IEXT int       Iperl_destruct_level;   /* 0=none, 1=full, 2=full with checks */
+IEXT int       Iperl_destruct_level IINIT(1);  /* 0=none, 1=full, 2=full with checks */
 
 /* magical thingies */
 IEXT Time_t    Ibasetime;              /* $^T */
@@ -1886,6 +1885,8 @@ EXT MGVTBL vtbl_substr =  {0,     magic_setsubstr,
                                        0,      0,      0};
 EXT MGVTBL vtbl_vec =  {0,     magic_setvec,
                                        0,      0,      0};
+EXT MGVTBL vtbl_vivary = {0,   magic_setvivary,
+                                       0,      0,      magic_freevivary};
 EXT MGVTBL vtbl_pos =  {magic_getpos,
                                magic_setpos,
                                        0,      0,      0};
@@ -1929,6 +1930,7 @@ EXT MGVTBL vtbl_nkeys;
 EXT MGVTBL vtbl_taint;
 EXT MGVTBL vtbl_substr;
 EXT MGVTBL vtbl_vec;
+EXT MGVTBL vtbl_vivary;
 EXT MGVTBL vtbl_pos;
 EXT MGVTBL vtbl_bm;
 EXT MGVTBL vtbl_fm;
index cef4d64..49e8119 100755 (executable)
@@ -20,13 +20,25 @@ echo "Extracting perl.exp"
 rm -f perl.exp
 echo "#!" > perl.exp
 
-sed -n '/^[A-Za-z]/ s/^/Perl_/p' global.sym >> perl.exp
-
-#
-# also add symbols from interp.sym
-# They are only needed if -DMULTIPLICITY is not set but it
-# doesn't hurt to include them anyway.
-sed -n '/^[A-Za-z]/ s/^/Perl_/p' interp.sym >> perl.exp
+case "$bincompat3" in
+y*)
+       global=/tmp/exp$$g
+       interp=/tmp/exp$$i
+       compat3=/tmp/exp$$c
+       trap 'rm -f $global $interp $compat3' 0
+       trap 'exit 1' 1 2 3 13 15
+       grep '^[A-Za-z]' global.sym | sort >$global
+       grep '^[A-Za-z]' interp.sym | sort >$interp
+       grep '^[A-Za-z]' compat3.sym | sort >$compat3
+       comm -23 $global $compat3 | sed 's/^/Perl_/p' >> perl.exp
+       comm -12 $global $compat3 >> perl.exp
+       comm -12 $interp $compat3 | sed 's/^/Perl_/p' >> perl.exp
+       comm -23 $interp $compat3 >> perl.exp
+       ;;
+*)
+       sed -n '/^[A-Za-z]/ s/^/Perl_/p' global.sym interp.sym >> perl.exp
+       ;;
+esac
 
 # extra globals not included above.
 cat <<END >> perl.exp
diff --git a/perly.c b/perly.c
index 3bcc237..8f1de62 100644 (file)
--- a/perly.c
+++ b/perly.c
@@ -1273,7 +1273,7 @@ int yyerrflag;
 int yychar;
 YYSTYPE yyval;
 YYSTYPE yylval;
-#line 620 "perly.y"
+#line 624 "perly.y"
  /* PROGRAM */
 #line 1349 "perly.c"
 #define YYABORT goto yyabort
@@ -1658,34 +1658,38 @@ break;
 case 31:
 #line 206 "perly.y"
 { copline = yyvsp[-3].ival;
-                           yyval.opval = newWHILEOP(0, 1, (LOOP*)Nullop,
-                                           scope(yyvsp[-2].opval), yyvsp[-1].opval, yyvsp[0].opval); }
+                           deprecate("while BLOCK BLOCK");
+                           yyval.opval = newSTATEOP(0, yyvsp[-4].pval,
+                                  newWHILEOP(0, 1, (LOOP*)Nullop,
+                                             scope(yyvsp[-2].opval), yyvsp[-1].opval, yyvsp[0].opval)); }
 break;
 case 32:
-#line 210 "perly.y"
+#line 212 "perly.y"
 { copline = yyvsp[-3].ival;
-                           yyval.opval = newWHILEOP(0, 1, (LOOP*)Nullop,
-                                           invert(scalar(scope(yyvsp[-2].opval))),
-                                           yyvsp[-1].opval, yyvsp[0].opval); }
+                           deprecate("until BLOCK BLOCK");
+                           yyval.opval = newSTATEOP(0, yyvsp[-4].pval,
+                                  newWHILEOP(0, 1, (LOOP*)Nullop,
+                                             invert(scalar(scope(yyvsp[-2].opval))),
+                                             yyvsp[-1].opval, yyvsp[0].opval)); }
 break;
 case 33:
-#line 215 "perly.y"
+#line 219 "perly.y"
 { yyval.opval = block_end(yyvsp[-6].ival,
                                 newFOROP(0, yyvsp[-9].pval, yyvsp[-8].ival, yyvsp[-5].opval, yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval)); }
 break;
 case 34:
-#line 218 "perly.y"
+#line 222 "perly.y"
 { yyval.opval = block_end(yyvsp[-4].ival,
                                 newFOROP(0, yyvsp[-8].pval, yyvsp[-7].ival, mod(yyvsp[-6].opval, OP_ENTERLOOP),
                                          yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval)); }
 break;
 case 35:
-#line 222 "perly.y"
+#line 226 "perly.y"
 { yyval.opval = block_end(yyvsp[-4].ival,
                                 newFOROP(0, yyvsp[-7].pval, yyvsp[-6].ival, Nullop, yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval)); }
 break;
 case 36:
-#line 226 "perly.y"
+#line 230 "perly.y"
 { copline = yyvsp[-9].ival;
                            yyval.opval = block_end(yyvsp[-7].ival,
                                   append_elem(OP_LINESEQ, scalar(yyvsp[-6].opval),
@@ -1695,356 +1699,356 @@ case 36:
                                                  yyvsp[0].opval, scalar(yyvsp[-2].opval))))); }
 break;
 case 37:
-#line 234 "perly.y"
+#line 238 "perly.y"
 { yyval.opval = newSTATEOP(0,
                                yyvsp[-2].pval, newWHILEOP(0, 1, (LOOP*)Nullop,
                                        Nullop, yyvsp[-1].opval, yyvsp[0].opval)); }
 break;
 case 38:
-#line 240 "perly.y"
+#line 244 "perly.y"
 { yyval.opval = Nullop; }
 break;
 case 40:
-#line 245 "perly.y"
+#line 249 "perly.y"
 { (void)scan_num("1"); yyval.opval = yylval.opval; }
 break;
 case 42:
-#line 250 "perly.y"
+#line 254 "perly.y"
 { yyval.opval = invert(scalar(yyvsp[0].opval)); }
 break;
 case 43:
-#line 254 "perly.y"
+#line 258 "perly.y"
 { yyval.opval = yyvsp[0].opval; intro_my(); }
 break;
 case 44:
-#line 258 "perly.y"
+#line 262 "perly.y"
 { yyval.opval = yyvsp[0].opval; intro_my(); }
 break;
 case 45:
-#line 262 "perly.y"
+#line 266 "perly.y"
 { yyval.opval = yyvsp[0].opval; intro_my(); }
 break;
 case 46:
-#line 266 "perly.y"
+#line 270 "perly.y"
 { yyval.opval = yyvsp[0].opval; intro_my(); }
 break;
 case 47:
-#line 270 "perly.y"
+#line 274 "perly.y"
 { yyval.pval = Nullch; }
 break;
 case 49:
-#line 275 "perly.y"
+#line 279 "perly.y"
 { yyval.ival = 0; }
 break;
 case 50:
-#line 277 "perly.y"
+#line 281 "perly.y"
 { yyval.ival = 0; }
 break;
 case 51:
-#line 279 "perly.y"
+#line 283 "perly.y"
 { yyval.ival = 0; }
 break;
 case 52:
-#line 281 "perly.y"
+#line 285 "perly.y"
 { yyval.ival = 0; }
 break;
 case 53:
-#line 285 "perly.y"
+#line 289 "perly.y"
 { newFORM(yyvsp[-2].ival, yyvsp[-1].opval, yyvsp[0].opval); }
 break;
 case 54:
-#line 287 "perly.y"
+#line 291 "perly.y"
 { newFORM(yyvsp[-1].ival, Nullop, yyvsp[0].opval); }
 break;
 case 55:
-#line 291 "perly.y"
+#line 295 "perly.y"
 { newSUB(yyvsp[-3].ival, yyvsp[-2].opval, yyvsp[-1].opval, yyvsp[0].opval); }
 break;
 case 56:
-#line 293 "perly.y"
+#line 297 "perly.y"
 { newSUB(yyvsp[-3].ival, yyvsp[-2].opval, yyvsp[-1].opval, Nullop); expect = XSTATE; }
 break;
 case 57:
-#line 297 "perly.y"
+#line 301 "perly.y"
 { yyval.opval = Nullop; }
 break;
 case 59:
-#line 302 "perly.y"
+#line 306 "perly.y"
 { yyval.ival = start_subparse(); }
 break;
 case 60:
-#line 306 "perly.y"
+#line 310 "perly.y"
 { package(yyvsp[-1].opval); }
 break;
 case 61:
-#line 308 "perly.y"
+#line 312 "perly.y"
 { package(Nullop); }
 break;
 case 62:
-#line 312 "perly.y"
+#line 316 "perly.y"
 { utilize(yyvsp[-5].ival, yyvsp[-4].ival, yyvsp[-3].opval, yyvsp[-2].opval, yyvsp[-1].opval); }
 break;
 case 63:
-#line 316 "perly.y"
+#line 320 "perly.y"
 { yyval.opval = newLOGOP(OP_AND, 0, yyvsp[-2].opval, yyvsp[0].opval); }
 break;
 case 64:
-#line 318 "perly.y"
+#line 322 "perly.y"
 { yyval.opval = newLOGOP(yyvsp[-1].ival, 0, yyvsp[-2].opval, yyvsp[0].opval); }
 break;
 case 66:
-#line 323 "perly.y"
+#line 327 "perly.y"
 { yyval.opval = yyvsp[-1].opval; }
 break;
 case 67:
-#line 325 "perly.y"
+#line 329 "perly.y"
 { yyval.opval = append_elem(OP_LIST, yyvsp[-2].opval, yyvsp[0].opval); }
 break;
 case 69:
-#line 330 "perly.y"
+#line 334 "perly.y"
 { yyval.opval = convert(yyvsp[-2].ival, OPf_STACKED,
                                prepend_elem(OP_LIST, newGVREF(yyvsp[-2].ival,yyvsp[-1].opval), yyvsp[0].opval) ); }
 break;
 case 70:
-#line 333 "perly.y"
+#line 337 "perly.y"
 { yyval.opval = convert(yyvsp[-4].ival, OPf_STACKED,
                                prepend_elem(OP_LIST, newGVREF(yyvsp[-4].ival,yyvsp[-2].opval), yyvsp[-1].opval) ); }
 break;
 case 71:
-#line 336 "perly.y"
+#line 340 "perly.y"
 { yyval.opval = convert(OP_ENTERSUB, OPf_STACKED,
                                append_elem(OP_LIST,
                                    prepend_elem(OP_LIST, scalar(yyvsp[-5].opval), yyvsp[-1].opval),
                                    newUNOP(OP_METHOD, 0, yyvsp[-3].opval))); }
 break;
 case 72:
-#line 341 "perly.y"
+#line 345 "perly.y"
 { yyval.opval = convert(OP_ENTERSUB, OPf_STACKED,
                                append_elem(OP_LIST,
                                    prepend_elem(OP_LIST, yyvsp[-1].opval, yyvsp[0].opval),
                                    newUNOP(OP_METHOD, 0, yyvsp[-2].opval))); }
 break;
 case 73:
-#line 346 "perly.y"
+#line 350 "perly.y"
 { yyval.opval = convert(OP_ENTERSUB, OPf_STACKED,
                                append_elem(OP_LIST,
                                    prepend_elem(OP_LIST, yyvsp[-3].opval, yyvsp[-1].opval),
                                    newUNOP(OP_METHOD, 0, yyvsp[-4].opval))); }
 break;
 case 74:
-#line 351 "perly.y"
+#line 355 "perly.y"
 { yyval.opval = convert(yyvsp[-1].ival, 0, yyvsp[0].opval); }
 break;
 case 75:
-#line 353 "perly.y"
+#line 357 "perly.y"
 { yyval.opval = convert(yyvsp[-3].ival, 0, yyvsp[-1].opval); }
 break;
 case 76:
-#line 355 "perly.y"
+#line 359 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED,
                            append_elem(OP_LIST,
                              prepend_elem(OP_LIST, newANONSUB(yyvsp[-2].ival, 0, yyvsp[-1].opval), yyvsp[0].opval),
                              yyvsp[-3].opval)); }
 break;
 case 79:
-#line 366 "perly.y"
+#line 370 "perly.y"
 { yyval.opval = newASSIGNOP(OPf_STACKED, yyvsp[-2].opval, yyvsp[-1].ival, yyvsp[0].opval); }
 break;
 case 80:
-#line 368 "perly.y"
+#line 372 "perly.y"
 { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); }
 break;
 case 81:
-#line 370 "perly.y"
+#line 374 "perly.y"
 {   if (yyvsp[-1].ival != OP_REPEAT)
                                scalar(yyvsp[-2].opval);
                            yyval.opval = newBINOP(yyvsp[-1].ival, 0, yyvsp[-2].opval, scalar(yyvsp[0].opval)); }
 break;
 case 82:
-#line 374 "perly.y"
+#line 378 "perly.y"
 { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); }
 break;
 case 83:
-#line 376 "perly.y"
+#line 380 "perly.y"
 { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); }
 break;
 case 84:
-#line 378 "perly.y"
+#line 382 "perly.y"
 { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); }
 break;
 case 85:
-#line 380 "perly.y"
+#line 384 "perly.y"
 { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); }
 break;
 case 86:
-#line 382 "perly.y"
+#line 386 "perly.y"
 { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); }
 break;
 case 87:
-#line 384 "perly.y"
+#line 388 "perly.y"
 { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); }
 break;
 case 88:
-#line 386 "perly.y"
+#line 390 "perly.y"
 { yyval.opval = newRANGE(yyvsp[-1].ival, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval));}
 break;
 case 89:
-#line 388 "perly.y"
+#line 392 "perly.y"
 { yyval.opval = newLOGOP(OP_AND, 0, yyvsp[-2].opval, yyvsp[0].opval); }
 break;
 case 90:
-#line 390 "perly.y"
+#line 394 "perly.y"
 { yyval.opval = newLOGOP(OP_OR, 0, yyvsp[-2].opval, yyvsp[0].opval); }
 break;
 case 91:
-#line 392 "perly.y"
+#line 396 "perly.y"
 { yyval.opval = newCONDOP(0, yyvsp[-4].opval, yyvsp[-2].opval, yyvsp[0].opval); }
 break;
 case 92:
-#line 394 "perly.y"
+#line 398 "perly.y"
 { yyval.opval = bind_match(yyvsp[-1].ival, yyvsp[-2].opval, yyvsp[0].opval); }
 break;
 case 93:
-#line 397 "perly.y"
+#line 401 "perly.y"
 { yyval.opval = newUNOP(OP_NEGATE, 0, scalar(yyvsp[0].opval)); }
 break;
 case 94:
-#line 399 "perly.y"
+#line 403 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
 case 95:
-#line 401 "perly.y"
+#line 405 "perly.y"
 { yyval.opval = newUNOP(OP_NOT, 0, scalar(yyvsp[0].opval)); }
 break;
 case 96:
-#line 403 "perly.y"
+#line 407 "perly.y"
 { yyval.opval = newUNOP(OP_COMPLEMENT, 0, scalar(yyvsp[0].opval));}
 break;
 case 97:
-#line 405 "perly.y"
+#line 409 "perly.y"
 { yyval.opval = newUNOP(OP_REFGEN, 0, mod(yyvsp[0].opval,OP_REFGEN)); }
 break;
 case 98:
-#line 407 "perly.y"
+#line 411 "perly.y"
 { yyval.opval = newUNOP(OP_POSTINC, 0,
                                        mod(scalar(yyvsp[-1].opval), OP_POSTINC)); }
 break;
 case 99:
-#line 410 "perly.y"
+#line 414 "perly.y"
 { yyval.opval = newUNOP(OP_POSTDEC, 0,
                                        mod(scalar(yyvsp[-1].opval), OP_POSTDEC)); }
 break;
 case 100:
-#line 413 "perly.y"
+#line 417 "perly.y"
 { yyval.opval = newUNOP(OP_PREINC, 0,
                                        mod(scalar(yyvsp[0].opval), OP_PREINC)); }
 break;
 case 101:
-#line 416 "perly.y"
+#line 420 "perly.y"
 { yyval.opval = newUNOP(OP_PREDEC, 0,
                                        mod(scalar(yyvsp[0].opval), OP_PREDEC)); }
 break;
 case 102:
-#line 419 "perly.y"
+#line 423 "perly.y"
 { yyval.opval = localize(yyvsp[0].opval,yyvsp[-1].ival); }
 break;
 case 103:
-#line 421 "perly.y"
+#line 425 "perly.y"
 { yyval.opval = sawparens(yyvsp[-1].opval); }
 break;
 case 104:
-#line 423 "perly.y"
+#line 427 "perly.y"
 { yyval.opval = sawparens(newNULLLIST()); }
 break;
 case 105:
-#line 425 "perly.y"
+#line 429 "perly.y"
 { yyval.opval = newANONLIST(yyvsp[-1].opval); }
 break;
 case 106:
-#line 427 "perly.y"
+#line 431 "perly.y"
 { yyval.opval = newANONLIST(Nullop); }
 break;
 case 107:
-#line 429 "perly.y"
+#line 433 "perly.y"
 { yyval.opval = newANONHASH(yyvsp[-2].opval); }
 break;
 case 108:
-#line 431 "perly.y"
+#line 435 "perly.y"
 { yyval.opval = newANONHASH(Nullop); }
 break;
 case 109:
-#line 433 "perly.y"
+#line 437 "perly.y"
 { yyval.opval = newANONSUB(yyvsp[-2].ival, yyvsp[-1].opval, yyvsp[0].opval); }
 break;
 case 110:
-#line 435 "perly.y"
+#line 439 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
 case 111:
-#line 437 "perly.y"
+#line 441 "perly.y"
 { yyval.opval = newBINOP(OP_GELEM, 0, newGVREF(0,yyvsp[-4].opval), yyvsp[-2].opval); }
 break;
 case 112:
-#line 439 "perly.y"
+#line 443 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
 case 113:
-#line 441 "perly.y"
+#line 445 "perly.y"
 { yyval.opval = newBINOP(OP_AELEM, 0, oopsAV(yyvsp[-3].opval), scalar(yyvsp[-1].opval)); }
 break;
 case 114:
-#line 443 "perly.y"
+#line 447 "perly.y"
 { yyval.opval = newBINOP(OP_AELEM, 0,
                                        ref(newAVREF(yyvsp[-4].opval),OP_RV2AV),
                                        scalar(yyvsp[-1].opval));}
 break;
 case 115:
-#line 447 "perly.y"
+#line 451 "perly.y"
 { assertref(yyvsp[-3].opval); yyval.opval = newBINOP(OP_AELEM, 0,
                                        ref(newAVREF(yyvsp[-3].opval),OP_RV2AV),
                                        scalar(yyvsp[-1].opval));}
 break;
 case 116:
-#line 451 "perly.y"
+#line 455 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
 case 117:
-#line 453 "perly.y"
+#line 457 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
 case 118:
-#line 455 "perly.y"
+#line 459 "perly.y"
 { yyval.opval = newUNOP(OP_AV2ARYLEN, 0, ref(yyvsp[0].opval, OP_AV2ARYLEN));}
 break;
 case 119:
-#line 457 "perly.y"
+#line 461 "perly.y"
 { yyval.opval = newBINOP(OP_HELEM, 0, oopsHV(yyvsp[-4].opval), jmaybe(yyvsp[-2].opval));
                            expect = XOPERATOR; }
 break;
 case 120:
-#line 460 "perly.y"
+#line 464 "perly.y"
 { yyval.opval = newBINOP(OP_HELEM, 0,
                                        ref(newHVREF(yyvsp[-5].opval),OP_RV2HV),
                                        jmaybe(yyvsp[-2].opval));
                            expect = XOPERATOR; }
 break;
 case 121:
-#line 465 "perly.y"
+#line 469 "perly.y"
 { assertref(yyvsp[-4].opval); yyval.opval = newBINOP(OP_HELEM, 0,
                                        ref(newHVREF(yyvsp[-4].opval),OP_RV2HV),
                                        jmaybe(yyvsp[-2].opval));
                            expect = XOPERATOR; }
 break;
 case 122:
-#line 470 "perly.y"
+#line 474 "perly.y"
 { yyval.opval = newSLICEOP(0, yyvsp[-1].opval, yyvsp[-4].opval); }
 break;
 case 123:
-#line 472 "perly.y"
+#line 476 "perly.y"
 { yyval.opval = newSLICEOP(0, yyvsp[-1].opval, Nullop); }
 break;
 case 124:
-#line 474 "perly.y"
+#line 478 "perly.y"
 { yyval.opval = prepend_elem(OP_ASLICE,
                                newOP(OP_PUSHMARK, 0),
                                    newLISTOP(OP_ASLICE, 0,
@@ -2052,7 +2056,7 @@ case 124:
                                        ref(yyvsp[-3].opval, OP_ASLICE))); }
 break;
 case 125:
-#line 480 "perly.y"
+#line 484 "perly.y"
 { yyval.opval = prepend_elem(OP_HSLICE,
                                newOP(OP_PUSHMARK, 0),
                                    newLISTOP(OP_HSLICE, 0,
@@ -2061,37 +2065,37 @@ case 125:
                            expect = XOPERATOR; }
 break;
 case 126:
-#line 487 "perly.y"
+#line 491 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
 case 127:
-#line 489 "perly.y"
+#line 493 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, 0, scalar(yyvsp[0].opval)); }
 break;
 case 128:
-#line 491 "perly.y"
+#line 495 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar(yyvsp[-2].opval)); }
 break;
 case 129:
-#line 493 "perly.y"
+#line 497 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED,
                            append_elem(OP_LIST, yyvsp[-1].opval, scalar(yyvsp[-3].opval))); }
 break;
 case 130:
-#line 496 "perly.y"
+#line 500 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED,
                            append_elem(OP_LIST, yyvsp[0].opval, scalar(yyvsp[-1].opval))); }
 break;
 case 131:
-#line 499 "perly.y"
+#line 503 "perly.y"
 { yyval.opval = newUNOP(OP_DOFILE, 0, scalar(yyvsp[0].opval)); }
 break;
 case 132:
-#line 501 "perly.y"
+#line 505 "perly.y"
 { yyval.opval = newUNOP(OP_NULL, OPf_SPECIAL, scope(yyvsp[0].opval)); }
 break;
 case 133:
-#line 503 "perly.y"
+#line 507 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB,
                            OPf_SPECIAL|OPf_STACKED,
                            prepend_elem(OP_LIST,
@@ -2101,7 +2105,7 @@ case 133:
                                )),Nullop)); dep();}
 break;
 case 134:
-#line 511 "perly.y"
+#line 515 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB,
                            OPf_SPECIAL|OPf_STACKED,
                            append_elem(OP_LIST,
@@ -2112,150 +2116,150 @@ case 134:
                                )))); dep();}
 break;
 case 135:
-#line 520 "perly.y"
+#line 524 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
                            prepend_elem(OP_LIST,
                                scalar(newCVREF(0,scalar(yyvsp[-2].opval))), Nullop)); dep();}
 break;
 case 136:
-#line 524 "perly.y"
+#line 528 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
                            prepend_elem(OP_LIST,
                                yyvsp[-1].opval,
                                scalar(newCVREF(0,scalar(yyvsp[-3].opval))))); dep();}
 break;
 case 137:
-#line 529 "perly.y"
+#line 533 "perly.y"
 { yyval.opval = newOP(yyvsp[0].ival, OPf_SPECIAL);
                            hints |= HINT_BLOCK_SCOPE; }
 break;
 case 138:
-#line 532 "perly.y"
+#line 536 "perly.y"
 { yyval.opval = newLOOPEX(yyvsp[-1].ival,yyvsp[0].opval); }
 break;
 case 139:
-#line 534 "perly.y"
+#line 538 "perly.y"
 { yyval.opval = newUNOP(OP_NOT, 0, scalar(yyvsp[0].opval)); }
 break;
 case 140:
-#line 536 "perly.y"
+#line 540 "perly.y"
 { yyval.opval = newOP(yyvsp[0].ival, 0); }
 break;
 case 141:
-#line 538 "perly.y"
+#line 542 "perly.y"
 { yyval.opval = newUNOP(yyvsp[-1].ival, 0, yyvsp[0].opval); }
 break;
 case 142:
-#line 540 "perly.y"
+#line 544 "perly.y"
 { yyval.opval = newUNOP(yyvsp[-1].ival, 0, yyvsp[0].opval); }
 break;
 case 143:
-#line 542 "perly.y"
+#line 546 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED,
                            append_elem(OP_LIST, yyvsp[0].opval, scalar(yyvsp[-1].opval))); }
 break;
 case 144:
-#line 545 "perly.y"
+#line 549 "perly.y"
 { yyval.opval = newOP(yyvsp[0].ival, 0); }
 break;
 case 145:
-#line 547 "perly.y"
+#line 551 "perly.y"
 { yyval.opval = newOP(yyvsp[-2].ival, 0); }
 break;
 case 146:
-#line 549 "perly.y"
+#line 553 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, 0,
                                scalar(yyvsp[0].opval)); }
 break;
 case 147:
-#line 552 "perly.y"
+#line 556 "perly.y"
 { yyval.opval = newOP(yyvsp[-2].ival, OPf_SPECIAL); }
 break;
 case 148:
-#line 554 "perly.y"
+#line 558 "perly.y"
 { yyval.opval = newUNOP(yyvsp[-3].ival, 0, yyvsp[-1].opval); }
 break;
 case 149:
-#line 556 "perly.y"
+#line 560 "perly.y"
 { yyval.opval = pmruntime(yyvsp[-3].opval, yyvsp[-1].opval, Nullop); }
 break;
 case 150:
-#line 558 "perly.y"
+#line 562 "perly.y"
 { yyval.opval = pmruntime(yyvsp[-5].opval, yyvsp[-3].opval, yyvsp[-1].opval); }
 break;
 case 153:
-#line 564 "perly.y"
+#line 568 "perly.y"
 { yyval.opval = Nullop; }
 break;
 case 154:
-#line 566 "perly.y"
+#line 570 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
 case 155:
-#line 570 "perly.y"
+#line 574 "perly.y"
 { yyval.opval = Nullop; }
 break;
 case 156:
-#line 572 "perly.y"
+#line 576 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
 case 157:
-#line 574 "perly.y"
+#line 578 "perly.y"
 { yyval.opval = yyvsp[-1].opval; }
 break;
 case 158:
-#line 577 "perly.y"
+#line 581 "perly.y"
 { yyval.ival = 0; }
 break;
 case 159:
-#line 578 "perly.y"
+#line 582 "perly.y"
 { yyval.ival = 1; }
 break;
 case 160:
-#line 582 "perly.y"
+#line 586 "perly.y"
 { in_my = 0; yyval.opval = my(yyvsp[0].opval); }
 break;
 case 161:
-#line 586 "perly.y"
+#line 590 "perly.y"
 { yyval.opval = newCVREF(yyvsp[-1].ival,yyvsp[0].opval); }
 break;
 case 162:
-#line 590 "perly.y"
+#line 594 "perly.y"
 { yyval.opval = newSVREF(yyvsp[0].opval); }
 break;
 case 163:
-#line 594 "perly.y"
+#line 598 "perly.y"
 { yyval.opval = newAVREF(yyvsp[0].opval); }
 break;
 case 164:
-#line 598 "perly.y"
+#line 602 "perly.y"
 { yyval.opval = newHVREF(yyvsp[0].opval); }
 break;
 case 165:
-#line 602 "perly.y"
+#line 606 "perly.y"
 { yyval.opval = newAVREF(yyvsp[0].opval); }
 break;
 case 166:
-#line 606 "perly.y"
+#line 610 "perly.y"
 { yyval.opval = newGVREF(0,yyvsp[0].opval); }
 break;
 case 167:
-#line 610 "perly.y"
+#line 614 "perly.y"
 { yyval.opval = scalar(yyvsp[0].opval); }
 break;
 case 168:
-#line 612 "perly.y"
+#line 616 "perly.y"
 { yyval.opval = scalar(yyvsp[0].opval);  }
 break;
 case 169:
-#line 614 "perly.y"
+#line 618 "perly.y"
 { yyval.opval = scope(yyvsp[0].opval); }
 break;
 case 170:
-#line 617 "perly.y"
+#line 621 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
-#line 2245 "perly.c"
+#line 2249 "perly.c"
     }
     yyssp -= yym;
     yystate = *yyssp;
index 172fae5..a347250 100644 (file)
@@ -1,5 +1,4 @@
-*** y.tab.c.ORIG       Thu Dec  5 13:55:38 1996
---- y.tab.c    Thu Dec  5 13:56:27 1996
+Index: perly.c
 ***************
 *** 13,82 ****
   }
@@ -89,7 +88,7 @@
 - short yyss[YYSTACKSIZE];
 - YYSTYPE yyvs[YYSTACKSIZE];
 - #define yystacksize YYSTACKSIZE
-  #line 620 "perly.y"
+  #line 624 "perly.y"
    /* PROGRAM */
 --- 1272,1277 ----
 ***************
                   yystate, yyn, yyrule[yyn]);
   #endif
 ***************
-*** 2252,2257 ****
+*** 2256,2261 ****
   #if YYDEBUG
           if (yydebug)
 !             printf("yydebug: after reduction, shifting from state 0 to\
 !  state %d\n", YYFINAL);
   #endif
           yystate = YYFINAL;
---- 2266,2272 ----
+--- 2270,2276 ----
   #if YYDEBUG
           if (yydebug)
 !             fprintf(stderr,
   #endif
           yystate = YYFINAL;
 ***************
-*** 2267,2271 ****
+*** 2271,2275 ****
                   if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
                   if (!yys) yys = "illegal-symbol";
 !                 printf("yydebug: state %d, reading %d (%s)\n",
                           YYFINAL, yychar, yys);
               }
---- 2282,2286 ----
+--- 2286,2290 ----
                   if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
                   if (!yys) yys = "illegal-symbol";
 !                 fprintf(stderr, "yydebug: state %d, reading %d (%s)\n",
                           YYFINAL, yychar, yys);
               }
 ***************
-*** 2282,2291 ****
+*** 2286,2295 ****
   #if YYDEBUG
       if (yydebug)
 !         printf("yydebug: after reduction, shifting from state %d \
 !         goto yyoverflow;
       }
       *++yyssp = yystate;
---- 2297,2321 ----
+--- 2301,2325 ----
   #if YYDEBUG
       if (yydebug)
 !         fprintf(stderr,
       }
       *++yyssp = yystate;
 ***************
-*** 2293,2300 ****
+*** 2297,2304 ****
       goto yyloop;
   yyoverflow:
 !     yyerror("yacc stack overflow");
   yyaccept:
 !     return (0);
   }
---- 2323,2330 ----
+--- 2327,2334 ----
       goto yyloop;
   yyoverflow:
 !     yyerror("Out of memory for yacc stack");
diff --git a/perly.y b/perly.y
index b4d8c4f..5ee78f8 100644 (file)
--- a/perly.y
+++ b/perly.y
@@ -204,13 +204,17 @@ loop      :       label WHILE '(' remember mtexpr ')' mblock cont
                                                $5, $7, $8))); }
        |       label WHILE block block cont
                        { copline = $2;
-                           $$ = newWHILEOP(0, 1, (LOOP*)Nullop,
-                                           scope($3), $4, $5); }
+                           deprecate("while BLOCK BLOCK");
+                           $$ = newSTATEOP(0, $1,
+                                  newWHILEOP(0, 1, (LOOP*)Nullop,
+                                             scope($3), $4, $5)); }
        |       label UNTIL block block cont
                        { copline = $2;
-                           $$ = newWHILEOP(0, 1, (LOOP*)Nullop,
-                                           invert(scalar(scope($3))),
-                                           $4, $5); }
+                           deprecate("until BLOCK BLOCK");
+                           $$ = newSTATEOP(0, $1,
+                                  newWHILEOP(0, 1, (LOOP*)Nullop,
+                                             invert(scalar(scope($3))),
+                                             $4, $5)); }
        |       label FOR MY remember my_scalar '(' mexpr ')' mblock cont
                        { $$ = block_end($4,
                                 newFOROP(0, $1, $2, $5, $7, $9, $10)); }
index 25d1f18..5265a19 100644 (file)
@@ -26,9 +26,9 @@ print "Extracting $file (with variable substitutions)\n";
 # You can use $Config{...} to use Configure variables.
 
 print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
-    eval 'exec perl -S \$0 "\$@"'
-       if 0;
+$Config{startperl}
+    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
 !GROK!THIS!
 
 # In the following, perl variables are not expanded during extraction.
index 2487a5e..e43424f 100644 (file)
@@ -19,7 +19,7 @@ For ease of access, the Perl manual has been split up into a number
 of sections:
 
     perl       Perl overview (this section)
-    perltoc    Perl documentation table of contents
+    perlnews   Perl news about changes from previous version
 
     perldata   Perl data structures
     perlsyn    Perl syntax
@@ -31,11 +31,12 @@ of sections:
     perlsub    Perl subroutines
     perlmod    Perl modules
     perlform   Perl formats
-    perli18n   Perl internalization
+    perllocale Perl locale support
 
     perlref    Perl references 
     perldsc    Perl data structures intro
     perllol    Perl data structures: lists of lists
+    perltoot   Perl OO tutorial
     perlobj    Perl objects
     perltie    Perl objects hidden behind simple variables
     perlbot    Perl OO tricks and examples
@@ -69,7 +70,7 @@ in the appropriate start-up files.  To find out where these are, type:
     perl -V:man.dir
 
 If the directories were F</usr/local/man/man1> and F</usr/local/man/man3>,
-you would only need to add F</usr/local/man> to your MANPATH.  If 
+you would need to add only F</usr/local/man> to your MANPATH.  If 
 they are different, you'll have to add both stems.
 
 If that doesn't work for some reason, you can still use the
@@ -82,7 +83,7 @@ will often point out exactly where the trouble is.
 
 =head1 DESCRIPTION
 
-Perl is an interpreted language optimized for scanning arbitrary
+Perl is a language optimized for scanning arbitrary
 text files, extracting information from those text files, and printing
 reports based on that information.  It's also a good language for many
 system management tasks.  The language is intended to be practical
@@ -138,7 +139,8 @@ will continue to work unchanged.
 
 Perl variables may now be declared within a lexical scope, like "auto"
 variables in C.  Not only is this more efficient, but it contributes
-to better privacy for "programming in the large".
+to better privacy for "programming in the large".  Anonymous 
+subroutines exhibit deep binding of lexical variables (closures).
 
 =item * Arbitrarily nested data structures
 
@@ -166,7 +168,7 @@ Perl may now be embedded easily in your C or C++ application, and can
 either call or be called by your routines through a documented
 interface.  The XS preprocessor is provided to make it easy to glue
 your C or C++ routines into Perl.  Dynamic loading of modules is
-supported.
+supported, and Perl itself can be made into a dynamic library.
 
 =item * POSIX compliant
 
@@ -191,7 +193,7 @@ to an object class which defines its access methods.
 =item * Subroutine definitions may now be autoloaded
 
 In fact, the AUTOLOAD mechanism also allows you to define any arbitrary
-semantics for undefined subroutine calls.  It's not just for autoloading.
+semantics for undefined subroutine calls.  It's not for just autoloading.
 
 =item * Regular expression enhancements
 
@@ -201,6 +203,18 @@ with embedded whitespace and comments for readability.  A consistent
 extensibility mechanism has been added that is upwardly compatible with
 all old regular expressions.
 
+=item * Innumerable Unbundled Modules
+
+The Comprehensive Perl Archive Network described in L<perlmod>
+contains hundreds of plug-and-play modules full of reusable
+code.  See F<http://www.perl.com/CPAN> for a site near you.
+
+=item * Compilability
+
+While not yet in full production mode, a working perl-to-C compiler
+does exist.  It can generate portable bytecode, simple C, or
+optimized C code.
+
 =back
 
 Ok, that's I<definitely> enough hype.
@@ -239,6 +253,12 @@ The command used to get the debugger code.  If unset, uses
 
        BEGIN { require 'perl5db.pl' }
 
+=item PERL_DESTRUCT_LEVEL
+
+Relevant only if your perl executable was built with B<-DDEBUGGING>,
+this controls the behavior of global destruction of objects and other
+references.
+
 =item PERLLIB
 
 A colon-separated list of directories in which to look for Perl library
@@ -267,7 +287,7 @@ Larry Wall E<lt>F<larry@wall.org>E<gt>, with the help of oodles of other folks.
 =head1 FILES
 
  "/tmp/perl-e$$"       temporary file for -e commands
- "@INC"                        locations of perl 5 libraries
+ "@INC"                        locations of perl libraries
 
 =head1 SEE ALSO
 
@@ -297,8 +317,8 @@ switch?
 The B<-w> switch is not mandatory.
 
 Perl is at the mercy of your machine's definitions of various
-operations such as type casting, atof() and sprintf().  The latter
-can even trigger a coredump when passed ludicrous input values.
+operations such as type casting, atof(), and sprintf().  The latter
+can even trigger a core dump when passed ludicrous input values.
 
 If your stdio requires a seek or eof between reads and writes on a
 particular stream, so does Perl.  (This doesn't apply to sysread()
@@ -310,7 +330,7 @@ given variable name may not be longer than 255 characters, and no
 component of your PATH may be longer than 255 if you use B<-S>.  A regular
 expression may not compile to more than 32767 bytes internally.
 
-See the perl bugs database at F<http://perl.com/perl/bugs/>.  You may
+See the perl bugs database at F<http://www.perl.com/perl/bugs/>.  You may
 mail your bug reports (be sure to include full configuration information
 as output by the myconfig program in the perl source tree, or by C<perl -V>) to
 F<perlbug@perl.com>.
index d2fd74a..ae67494 100644 (file)
@@ -128,7 +128,7 @@ the meaning of "fileno" may not match UNIX.
 
 =item B<PerlIO_clearerr(f)>
 
-This corresponds to clearerr(), i.e. clears 'eof' and 'error'
+This corresponds to clearerr(), i.e., clears 'eof' and 'error'
 flags for the "stream".
 
 =item B<PerlIO_flush(f)>
@@ -156,7 +156,7 @@ in terms of PerlIO_seek() at some point.
 
 =item B<PerlIO_tmpfile()>
 
-This corresponds to tmpfile(), i.e. returns an anonymous
+This corresponds to tmpfile(), i.e., returns an anonymous
 PerlIO which will automatically be deleted when closed.
 
 =back 
@@ -201,7 +201,7 @@ behaviour.
 =item B<PerlIO_setlinebuf(f)>
 
 This corresponds to setlinebuf(). Use is deprecated pending
-further discussion. (Perl core I<only> uses it when "dumping"
+further discussion. (Perl core uses it I<only> when "dumping"
 is has nothing to do with $| auto-flush.)
 
 =back
@@ -209,7 +209,7 @@ is has nothing to do with $| auto-flush.)
 In addition to user API above there is an "implementation" interface
 which allows perl to get at internals of PerlIO.
 The following calls correspond to the various FILE_xxx macros determined
-by Configure. This section is really only of interest to those
+by Configure. This section is really of interest to only those
 concerned with detailed perl-core behaviour or implementing a
 PerlIO mapping.
 
@@ -236,7 +236,7 @@ bytes in the buffer.
 =item B<PerlIO_fast_gets(f)>
 
 Implementation has all the interfaces required to 
-allow perls fast code to handle <FILE> mechanism.
+allow perl's fast code to handle <FILE> mechanism.
 
   PerlIO_fast_gets(f) = PerlIO_has_cntptr(f) && \ 
                         PerlIO_canset_cnt(f) && \
@@ -245,14 +245,14 @@ allow perls fast code to handle <FILE> mechanism.
 =item B<PerlIO_set_ptrcnt(f,p,c)>
 
 Set pointer into buffer, and a count of bytes still in the 
-buffer. Should only be used to set
+buffer. Should be used only to set
 pointer to within range implied by previous calls
 to C<PerlIO_get_ptr> and C<PerlIO_get_cnt>.
 
 =item B<PerlIO_set_cnt(f,c)>
 
 Obscure - set count of bytes in the buffer. Deprecated.
-Currently only used in doio.c to force count < -1 to -1.
+Currently used in only doio.c to force count < -1 to -1.
 Perhaps should be PerlIO_set_empty or similar.
 This call may actually do nothing if "count" is deduced from pointer
 and a "limit". 
index 0f7078f..30d0055 100644 (file)
@@ -57,7 +57,7 @@ See L<CLASS CONTEXT AND THE OBJECT>.
 
 =item 7
 
-IO syntax is certainly less noisy, but it is also prone to ambiguities which
+IO syntax is certainly less noisy, but it is also prone to ambiguities that
 can cause difficult-to-find bugs.  Allow people to use the sure-thing OO
 syntax, even if you don't like it.
 
@@ -404,7 +404,7 @@ This problem can be solved by using the object to define the context of the
 method.  Let the method look in the object for a reference to the data.  The
 alternative is to force the method to go hunting for the data ("Is it in my
 class, or in a subclass?  Which subclass?"), and this can be inconvenient
-and will lead to hackery.  It is better to just let the object tell the
+and will lead to hackery.  It is better just to let the object tell the
 method where that data is located.
 
        package Bar;
index ac9229f..20c863c 100644 (file)
@@ -5,7 +5,7 @@ perlcall - Perl calling conventions from C
 =head1 DESCRIPTION
 
 The purpose of this document is to show you how to call Perl subroutines
-directly from C, i.e. how to write I<callbacks>.
+directly from C, i.e., how to write I<callbacks>.
 
 Apart from discussing the C interface provided by Perl for writing
 callbacks the document uses a series of examples to show how the
@@ -30,7 +30,7 @@ called instead.
 The classic example of where callbacks are used is when writing an
 event driven program like for an X windows application.  In this case
 you register functions to be called whenever specific events occur,
-e.g. a mouse button is pressed, the cursor moves into a window or a
+e.g., a mouse button is pressed, the cursor moves into a window or a
 menu item is selected.
 
 =back
@@ -61,7 +61,7 @@ subroutines.  They are
 The key function is I<perl_call_sv>.  All the other functions are
 fairly simple wrappers which make it easier to call Perl subroutines in
 special cases. At the end of the day they will all call I<perl_call_sv>
-to actually invoke the Perl subroutine.
+to invoke the Perl subroutine.
 
 All the I<perl_call_*> functions have a C<flags> parameter which is
 used to pass a bit mask of options to Perl.  This bit mask operates
@@ -84,9 +84,9 @@ use of I<perl_call_sv>.
 
 The function, I<perl_call_pv>, is similar to I<perl_call_sv> except it
 expects its first parameter to be a C char* which identifies the Perl
-subroutine you want to call, e.g. C<perl_call_pv("fred", 0)>.  If the
+subroutine you want to call, e.g., C<perl_call_pv("fred", 0)>.  If the
 subroutine you want to call is in another package, just include the
-package name in the string, e.g. C<"pkg::fred">.
+package name in the string, e.g., C<"pkg::fred">.
 
 =item B<perl_call_method>
 
@@ -208,10 +208,10 @@ automatically for you.  Note that it is still possible to indicate a
 context to the Perl subroutine by using either G_SCALAR or G_ARRAY.
 
 If you do not set this flag then it is I<very> important that you make
-sure that any temporaries (i.e. parameters passed to the Perl
+sure that any temporaries (i.e., parameters passed to the Perl
 subroutine and values returned from the subroutine) are disposed of
 yourself.  The section I<Returning a Scalar> gives details of how to
-explicitly dispose of these temporaries and the section I<Using Perl to
+dispose of these temporaries explicitly and the section I<Using Perl to
 dispose of temporaries> discusses the specific circumstances where you
 can ignore the problem and let Perl deal with it for you.
 
@@ -254,7 +254,7 @@ belongs to C<joe>.
 =head2 G_EVAL  
 
 It is possible for the Perl subroutine you are calling to terminate
-abnormally, e.g. by calling I<die> explicitly or by not actually
+abnormally, e.g., by calling I<die> explicitly or by not actually
 existing.  By default, when either of these of events occurs, the
 process will terminate immediately.  If though, you want to trap this
 type of event, specify the G_EVAL flag.  It will put an I<eval { }>
@@ -408,7 +408,7 @@ Enough of the definition talk, let's have a few examples.
 
 Perl provides many macros to assist in accessing the Perl stack.
 Wherever possible, these macros should always be used when interfacing
-to Perl internals.  Hopefully this should make the code less vulnerable
+to Perl internals.  We hope this should make the code less vulnerable
 to any changes made to Perl in the future.
 
 Another point worth noting is that in the first series of examples I
@@ -458,7 +458,7 @@ specified.
 =item 3.
 
 We aren't interested in anything returned from I<PrintUID>, so
-G_DISCARD is specified. Even if I<PrintUID> was changed to actually
+G_DISCARD is specified. Even if I<PrintUID> was changed to
 return some value(s), having specified G_DISCARD will mean that they
 will be wiped by the time control returns from I<perl_call_pv>.
 
@@ -529,15 +529,15 @@ have used this macro.
 
 The exception to this rule is if you are calling a Perl subroutine
 directly from an XSUB function. In this case it is not necessary to
-explicitly use the C<dSP> macro - it will be declared for you
+use the C<dSP> macro explicitly - it will be declared for you
 automatically.
 
 =item 3.
 
 Any parameters to be pushed onto the stack should be bracketed by the
 C<PUSHMARK> and C<PUTBACK> macros.  The purpose of these two macros, in
-this context, is to automatically count the number of parameters you
-are pushing. Then whenever Perl is creating the C<@_> array for the
+this context, is to count the number of parameters you are
+pushing automatically.  Then whenever Perl is creating the C<@_> array for the
 subroutine, it knows how big to make it.
 
 The C<PUSHMARK> macro tells Perl to make a mental note of the current
@@ -555,7 +555,7 @@ local copy, I<not> the global copy.
 
 =item 4.
 
-The only flag specified this time is G_DISCARD. Since we are passing 2
+The only flag specified this time is G_DISCARD. Because we are passing 2
 parameters to the Perl subroutine this time, we have not specified
 G_NOARGS.
 
@@ -580,7 +580,7 @@ function.
 Now for an example of dealing with the items returned from a Perl
 subroutine.
 
-Here is a Perl subroutine, I<Adder>,  which takes 2 integer parameters
+Here is a Perl subroutine, I<Adder>, that takes 2 integer parameters
 and simply returns their sum.
 
     sub Adder
@@ -589,7 +589,7 @@ and simply returns their sum.
         $a + $b ;
     }
 
-Since we are now concerned with the return value from I<Adder>, the C
+Because we are now concerned with the return value from I<Adder>, the C
 function required to call it is now a bit more complex.
 
     static void
@@ -685,7 +685,7 @@ Expecting a single value is not quite the same as knowing that there
 will be one. If someone modified I<Adder> to return a list and we
 didn't check for that possibility and take appropriate action the Perl
 stack would end up in an inconsistent state. That is something you
-I<really> don't want to ever happen.
+I<really> don't want to happen ever.
 
 =item 5.
 
@@ -998,7 +998,7 @@ refers to the C equivalent of C<$@>.
 Note that the stack is popped using C<POPs> in the block where
 C<SvTRUE(GvSV(errgv))> is true.  This is necessary because whenever a
 I<perl_call_*> function invoked with G_EVAL|G_SCALAR returns an error,
-the top of the stack holds the value I<undef>. Since we want the
+the top of the stack holds the value I<undef>. Because we want the
 program to continue after detecting this error, it is essential that
 the stack is tidied up by removing the I<undef>.
 
@@ -1026,7 +1026,7 @@ version of the call_Subtract example above inside a destructor:
 
 This example will fail to recognize that an error occurred inside the
 C<eval {}>.  Here's why: the call_Subtract code got executed while perl
-was cleaning up temporaries when exiting the eval block, and since
+was cleaning up temporaries when exiting the eval block, and because
 call_Subtract is implemented with I<perl_call_pv> using the G_EVAL
 flag, it promptly reset C<$@>.  This results in the failure of the
 outermost test for C<$@>, and thereby the failure of the error trap.
@@ -1064,7 +1064,7 @@ Here is a snippet of XSUB which defines I<CallSubPV>.
        perl_call_pv(name, G_DISCARD|G_NOARGS) ;
 
 That is fine as far as it goes. The thing is, the Perl subroutine 
-can be specified only as a string.  For Perl 4 this was adequate,
+can be specified as only a string.  For Perl 4 this was adequate,
 but Perl 5 allows references to subroutines and anonymous subroutines.
 This is where I<perl_call_sv> is useful.
 
@@ -1079,7 +1079,7 @@ I<perl_call_sv> instead of I<perl_call_pv>.
        PUSHMARK(sp) ;
        perl_call_sv(name, G_DISCARD|G_NOARGS) ;
 
-Since we are using an SV to call I<fred> the following can all be used
+Because we are using an SV to call I<fred> the following can all be used
 
     CallSubSV("fred") ;
     CallSubSV(\&fred) ;
@@ -1092,7 +1092,7 @@ how you can specify the Perl subroutine.
 
 You should note that if it is necessary to store the SV (C<name> in the
 example above) which corresponds to the Perl subroutine so that it can
-be used later in the program, it not enough to just store a copy of the
+be used later in the program, it not enough just to store a copy of the
 pointer to the SV. Say the code above had been like this
 
     static SV * rememberSub ;
@@ -1143,7 +1143,7 @@ the version of Perl you are using)
 
 The variable C<$ref> may have referred to the subroutine C<fred>
 whenever the call to C<SaveSub1> was made but by the time
-C<CallSavedSub1> gets called it now holds the number C<47>. Since we
+C<CallSavedSub1> gets called it now holds the number C<47>. Because we
 saved only a pointer to the original SV in C<SaveSub1>, any changes to
 C<$ref> will be tracked by the pointer C<rememberSub>. This means that
 whenever C<CallSavedSub1> gets called, it will attempt to execute the
@@ -1185,7 +1185,7 @@ SV.  The code below shows C<SaveSub2> modified to do that
        PUSHMARK(sp) ;
        perl_call_sv(keepSub, G_DISCARD|G_NOARGS) ;
 
-In order to avoid creating a new SV every time C<SaveSub2> is called,
+To avoid creating a new SV every time C<SaveSub2> is called,
 the function first checks to see if it has been called before.  If not,
 then space for a new SV is allocated and the reference to the Perl
 subroutine, C<name> is copied to the variable C<keepSub> in one
@@ -1247,9 +1247,9 @@ Consider the following Perl code
         }
     }
 
-It just implements a very simple class to manage an array.  Apart from
+It implements just a very simple class to manage an array.  Apart from
 the constructor, C<new>, it declares methods, one static and one
-virtual. The static method, C<PrintID>, simply prints out the class
+virtual. The static method, C<PrintID>, prints out simply the class
 name and a version number. The virtual method, C<Display>, prints out a
 single element of the array.  Here is an all Perl example of using it.
 
@@ -1346,7 +1346,7 @@ The output from that will be
 =head2 Using Perl to dispose of temporaries
 
 In the examples given to date, any temporaries created in the callback
-(i.e. parameters passed on the stack to the I<perl_call_*> function or
+(i.e., parameters passed on the stack to the I<perl_call_*> function or
 values returned via the stack) have been freed by one of these methods
 
 =over 5
@@ -1441,7 +1441,7 @@ the extreme left.
 
 So what is the big problem? Well, if you are expecting Perl to tidy up
 those temporaries for you, you might be in for a long wait.  For Perl
-to actually dispose of your temporaries, control must drop back to the
+to dispose of your temporaries, control must drop back to the
 enclosing scope at some stage.  In the event driven scenario that may
 never happen.  This means that as time goes on, your program will
 create more and more temporaries, none of which will ever be freed. As
@@ -1450,7 +1450,7 @@ eventually consume all the available memory in your system - kapow!
 
 So here is the bottom line - if you are sure that control will revert
 back to the enclosing Perl scope fairly quickly after the end of your
-callback, then it isn't absolutely necessary to explicitly dispose of
+callback, then it isn't absolutely necessary to dispose explicitly of
 any temporaries you may have created. Mind you, if you are at all
 uncertain about what to do, it doesn't do any harm to tidy up anyway.
 
@@ -1524,7 +1524,7 @@ registers, C<pcb1>, might look like this
 The mapping between the C callback and the Perl equivalent is stored in
 the global variable C<callback>.
 
-This will be adequate if you ever need to have only 1 callback
+This will be adequate if you ever need to have only one callback
 registered at any time. An example could be an error handler like the
 code sketched out above. Remember though, repeated calls to
 C<register_fatal> will replace the previously registered callback
@@ -1761,7 +1761,7 @@ series of C functions to act as the interface to Perl, thus
 
         asynch_close(fh) ;
 
-In this case the functions C<fn1>, C<fn2> and C<fn3> are used to
+In this case the functions C<fn1>, C<fn2>, and C<fn3> are used to
 remember the Perl subroutine to be called. Each of the functions holds
 a separate hard-wired index which is used in the function C<Pcb> to
 access the C<Map> array and actually call the Perl subroutine.
index c114471..407a252 100644 (file)
@@ -19,7 +19,7 @@ I<identifier>, that is, a string beginning with a letter or underscore,
 and containing letters, underscores, and digits.  In some cases, it
 may be a chain of identifiers, separated by C<::> (or by C<'>, but
 that's deprecated); all but the last are interpreted as names of
-packages, in order to locate the namespace in which to look
+packages, to locate the namespace in which to look
 up the final identifier (see L<perlmod/Packages> for details).
 It's possible to substitute for a simple identifier an expression
 which produces a reference to the value at runtime; this is
@@ -65,14 +65,14 @@ This means that $foo and @foo are two different variables.  It also
 means that C<$foo[1]> is a part of @foo, not a part of $foo.  This may
 seem a bit weird, but that's okay, because it is weird.
 
-Since variable and array references always start with '$', '@', or '%',
+Because variable and array references always start with '$', '@', or '%',
 the "reserved" words aren't in fact reserved with respect to variable
 names.  (They ARE reserved with respect to labels and filehandles,
 however, which don't have an initial special character.  You can't have
 a filehandle named "log", for instance.  Hint: you could say
 C<open(LOG,'logfile')> rather than C<open(log,'logfile')>.  Using uppercase
 filehandles also improves readability and protects you from conflict
-with future reserved words.)  Case I<IS> significant--"FOO", "Foo" and
+with future reserved words.)  Case I<IS> significant--"FOO", "Foo", and
 "foo" are all different names.  Names that start with a letter or
 underscore may also contain digits and underscores.
 
@@ -80,9 +80,9 @@ It is possible to replace such an alphanumeric name with an expression
 that returns a reference to an object of that type.  For a description
 of this, see L<perlref>.
 
-Names that start with a digit may only contain more digits.  Names
+Names that start with a digit may contain only more digits.  Names
 which do not start with a letter, underscore,  or digit are limited to
-one character, e.g.  C<$%> or C<$$>.  (Most of these one character names
+one character, e.g.,  C<$%> or C<$$>.  (Most of these one character names
 have a predefined significance to Perl.  For instance, C<$$> is the
 current process id.)
 
@@ -135,7 +135,7 @@ Scalar variables may contain various kinds of singular data, such as
 numbers, strings, and references.  In general, conversion from one form to
 another is transparent.  (A scalar may not contain multiple values, but
 may contain a reference to an array or hash containing multiple values.)
-Because of the automatic conversion of scalars, operations and functions
+Because of the automatic conversion of scalars, operations, and functions
 that return scalars don't need to care (and, in fact, can't care) whether
 the context is looking for a string or a number.
 
@@ -183,7 +183,7 @@ for details on regular expressions.
 
 The length of an array is a scalar value.  You may find the length of
 array @days by evaluating C<$#days>, as in B<csh>.  (Actually, it's not
-the length of the array, it's the subscript of the last element, since
+the length of the array, it's the subscript of the last element, because
 there is (ordinarily) a 0th element.)  Assigning to C<$#days> changes the
 length of the array.  Shortening an array by this method destroys
 intervening values.  Lengthening an array that was previously shortened
@@ -207,7 +207,7 @@ last value, like the C comma operator.)  The following is always true:
 Version 5 of Perl changed the semantics of C<$[>: files that don't set
 the value of C<$[> no longer need to worry about whether another
 file changed its value.  (In other words, use of C<$[> is deprecated.)
-So in general you can just assume that
+So in general you can assume that
 
     scalar(@whatever) == $#whatever + 1;
 
@@ -220,7 +220,7 @@ If you evaluate a hash in a scalar context, it returns a value which is
 true if and only if the hash contains any key/value pairs.  (If there
 are any key/value pairs, the value returned is a string consisting of
 the number of used buckets and the number of allocated buckets, separated
-by a slash.  This is pretty much only useful to find out whether Perl's
+by a slash.  This is pretty much useful only to find out whether Perl's
 (compiled in) hashing algorithm is performing poorly on your data set.
 For example, you stick 10,000 things in a hash, but evaluating %HASH in
 scalar context reveals "1/16", which means only one out of sixteen buckets
@@ -247,7 +247,7 @@ The usual Unix backslash rules apply for making characters such as
 newline, tab, etc., as well as some more exotic forms.  See
 L<perlop/Quote and Quotelike Operators> for a list.
 
-You can also embed newlines directly in your strings, i.e. they can end
+You can also embed newlines directly in your strings, i.e., they can end
 on a different line than they begin.  This is nice, but if you forget
 your trailing quote, the error will not be reported until Perl finds
 another line containing the quote character, which may be much further
@@ -276,16 +276,16 @@ in the subscript will be interpreted as an expression.
 
 Note that a
 single-quoted string must be separated from a preceding word by a
-space, since single quote is a valid (though deprecated) character in
+space, because single quote is a valid (though deprecated) character in
 a variable name (see L<perlmod/Packages>).
 
 Two special literals are __LINE__ and __FILE__, which represent the
 current line number and filename at that point in your program.  They
-may only be used as separate tokens; they will not be interpolated into
+may be used only as separate tokens; they will not be interpolated into
 strings.  In addition, the token __END__ may be used to indicate the
 logical end of the script before the actual end of file.  Any following
 text is ignored, but may be read via the DATA filehandle.  (The DATA
-filehandle may read data only from the main script, but not from any
+filehandle may read data from only the main script, but not from any
 required file or evaluated string.)  The two control characters ^D and
 ^Z are synonyms for __END__ (or __DATA__ in a module; see L<SelfLoader> for 
 details on __DATA__).
@@ -432,7 +432,7 @@ put the list in parentheses to avoid ambiguity.  Examples:
     $time = (stat($file))[8];
 
     # SYNTAX ERROR HERE.
-    $time = stat($file)[8];  # OOPS, FORGOT PARENS
+    $time = stat($file)[8];  # OOPS, FORGOT PARENTHESES
 
     # Find a hex digit.
     $hexdigit = ('a','b','c','d','e','f')[$digit-10];
@@ -454,7 +454,7 @@ produced by the expression on the right side of the assignment:
     $x = (($foo,$bar) = f());          # set $x to f()'s return count
 
 This is very handy when you want to do a list assignment in a Boolean
-context, since most list functions return a null list when finished,
+context, because most list functions return a null list when finished,
 which when assigned produces a 0, which is interpreted as FALSE.
 
 The final element may be an array or a hash:
@@ -513,7 +513,7 @@ Note that just because a hash is initialized in that order doesn't
 mean that it comes out in that order.  See L<perlfunc/sort> for examples
 of how to arrange for an output ordering.
 
-=head2 Typeglobs
+=head2 Typeglobs and Filehandles
 
 Perl uses an internal type called a I<typeglob> to hold an entire
 symbol table entry.  The type prefix of a typeglob is a C<*>, because
@@ -522,7 +522,29 @@ pass arrays and hashes by reference into a function, but now that
 we have real references, this is seldom needed.  It also used to be the
 preferred way to pass filehandles into a function, but now
 that we have the *foo{THING} notation it isn't often needed for that,
-either.
+either.  It is still needed to pass new filehandles into functions
+(*HANDLE{IO} only works if HANDLE has already been used).
+
+If you need to use a typeglob to save away a filehandle, do it this way:
+
+    $fh = *STDOUT;
+
+or perhaps as a real reference, like this:
+
+    $fh = \*STDOUT;
+
+This is also a way to create a local filehandle.  For example:
+
+    sub newopen {
+       my $path = shift;
+       local *FH;  # not my!
+       open (FH, $path) || return undef;
+       return \*FH;
+    }
+    $fh = newopen('/etc/passwd');
+
+Another way to create local filehandles is with IO::Handle and its ilk,
+see the bottom of L<perlfunc/open()>.
 
 See L<perlref>, L<perlsub>, and L<perlmod/"Symbol Tables"> for more
 discussion on typeglobs.
index f9dd6f4..5d67ba4 100644 (file)
@@ -11,7 +11,7 @@ First of all, have you tried using the B<-w> switch?
 If you invoke Perl with the B<-d> switch, your script runs under the
 Perl source debugger.  This works like an interactive Perl
 environment, prompting for debugger commands that let you examine
-source code, set breakpoints, get stack backtraces, change the values of
+source code, set breakpoints, get stack back-traces, change the values of
 variables, etc.  This is so convenient that you often fire up
 the debugger all by itself just to test out Perl constructs 
 interactively to see what they do.  For example:
@@ -63,12 +63,12 @@ it's run through your pager, as in
 =item p expr
 
 Same as C<print {$DB::OUT} expr> in the current package.  In particular,
-since this is just Perl's own B<print> function, this means that nested
+because this is just Perl's own B<print> function, this means that nested
 data structures and objects are not dumped, unlike with the C<x> command.
 
 =item x expr
 
-Evals its expression in list context and dumps out the result 
+Evaluates its expression in list context and dumps out the result 
 in a pretty-printed fashion.  Nested data structures are printed out
 recursively, unlike the C<print> function.
 
@@ -97,7 +97,7 @@ Same as C<V currentpackage [vars]>.
 
 =item T
 
-Produce a stack backtrace.  See below for details on its output.
+Produce a stack back-trace.  See below for details on its output.
 
 =item s [expr]
 
@@ -218,7 +218,7 @@ or, with the C<O>ption C<frame=2> set,
 Set a breakpoint.  If line is omitted, sets a breakpoint on the line
 that is about to be executed.  If a condition is specified, it's
 evaluated each time the statement is reached and a breakpoint is taken
-only if the condition is true.  Breakpoints may only be set on lines
+only if the condition is true.  Breakpoints may be set on only lines
 that begin an executable statement.  Conditions don't use B<if>:
 
     b 237 $x > 30
@@ -332,7 +332,7 @@ affects printing of return value after C<r> command.
 
 affects printing messages on entry and exit from subroutines.  If
 C<frame & 2> is false, messages are printed on entry only. (Printing
-on exit may be useful if interdispersed with other messages.)
+on exit may be useful if inter(di)spersed with other messages.)
 
 If C<frame & 4>, arguments to functions are printed as well as the
 context and caller info.
@@ -455,37 +455,37 @@ See L<"Debugger Internals"> below for more details.
 =item E<lt> [ command ]
 
 Set an action (Perl command) to happen before every debugger prompt.
-A multiline command may be entered by backslashing the newlines.  If
+A multi-line command may be entered by backslashing the newlines.  If
 C<command> is missing, resets the list of actions.
 
 =item E<lt>E<lt> command
 
 Add an action (Perl command) to happen before every debugger prompt.
-A multiline command may be entered by backslashing the newlines.
+A multi-line command may be entered by backslashing the newlines.
 
 =item E<gt> command
 
 Set an action (Perl command) to happen after the prompt when you've
-just given a command to return to executing the script.  A multiline
+just given a command to return to executing the script.  A multi-line
 command may be entered by backslashing the newlines.  If C<command> is
 missing, resets the list of actions.
 
 =item E<gt>E<gt> command
 
 Adds an action (Perl command) to happen after the prompt when you've
-just given a command to return to executing the script.  A multiline
+just given a command to return to executing the script.  A multi-line
 command may be entered by backslashing the newlines.
 
 =item { [ command ]
 
 Set an action (debugger command) to happen before every debugger prompt.
-A multiline command may be entered by backslashing the newlines.  If
+A multi-line command may be entered by backslashing the newlines.  If
 C<command> is missing, resets the list of actions.
 
 =item {{ command
 
 Add an action (debugger command) to happen before every debugger prompt.
-A multiline command may be entered by backslashing the newlines.
+A multi-line command may be entered by backslashing the newlines.
 
 =item ! number
 
@@ -525,9 +525,9 @@ Restart the debugger by B<exec>ing a new session.  It tries to maintain
 your history across this, but internal settings and command line options
 may be lost.
 
-Currently the following setting are preserved: history, breakpoints
-and actions, debugger C<O>ptions and the following command-line
-options: B<-w>, B<-I>, B<-e>.
+Currently the following setting are preserved: history, breakpoints,
+actions, debugger C<O>ptions, and the following command-line
+options: B<-w>, B<-I>, and B<-e>.
 
 =item |dbcmd
 
@@ -566,7 +566,7 @@ or even
     DB<<17>>
 
 where that number is the command number, which you'd use to access with
-the built-in B<csh>-like history mechanism, e.g. C<!17> would repeat
+the built-in B<csh>-like history mechanism, e.g., C<!17> would repeat
 command number 17.  The number of angle brackets indicates the depth of
 the debugger.  You could get more than one set of brackets, for example, if
 you'd already at a breakpoint and then printed out the result of a
@@ -588,7 +588,7 @@ normally end the debugger command with a backslash.  Here's an example:
 Note that this business of escaping a newline is specific to interactive
 commands typed into the debugger.
 
-Here's an example of what a stack backtrace might look like:
+Here's an example of what a stack back-trace might look like:
 
     $ = main::infested called from file `Ambulation.pm' line 10
     @ = Ambulation::legs(1, 2, 3, 4) called from file `camel_flea' line 7
@@ -763,16 +763,16 @@ the form C<(eval 31)> for subroutines defined inside C<eval>s.
 
 =item *
 
-When an exection of the application reaches a place that can have a
-breakpoint, a call to C<DB::DB()> is performed if any one of
-variables $DB::trace, $DB::single, $DB::signal is true. (Note that
+When execution of the application reaches a place that can have
+a breakpoint, a call to C<DB::DB()> is performed if any one of
+variables $DB::trace, $DB::single, or $DB::signal is true. (Note that
 these variables are not C<local>izable.) This feature is disabled when
 the control is inside C<DB::DB()> or functions called from it (unless
 C<$^D & 1 E<lt>E<lt> 30>).
 
 =item *
 
-When an exection of the application reaches a subroutine call, a call
+When execution of the application reaches a subroutine call, a call
 to C<&DB::sub>(I<args>) is performed instead, with C<$DB::sub> being
 the name of the called subroutine. (Unless the subroutine is compiled
 in the package C<DB>.)
@@ -792,7 +792,7 @@ F<~/.perldb> under UNIX), which can set important options.  This file may
 define a subroutine C<&afterinit> to be executed after the debugger is
 initialized.
 
-After the  rc file is read, the debugger reads environment variable
+After the rc file is read, the debugger reads environment variable
 PERLDB_OPTS and parses it as a rest of C<O ...> line in debugger prompt.
 
 It also maintains magical internal variables, such as C<@DB::dbline>,
@@ -807,7 +807,7 @@ function C<DB::dump_trace(skip[, count])> skips the specified number
 of frames, and returns an array containing info about the caller
 frames (all if C<count> is missing). Each entry is a hash with keys
 C<context> (C<$> or C<@>), C<sub> (subroutine name, or info about
-eval), C<args> (C<undef> or a reference to an array), C<file> and
+eval), C<args> (C<undef> or a reference to an array), C<file>, and
 C<line>.
 
 The function C<DB::print_trace(FH, skip[, count[, short]])> prints 
@@ -824,7 +824,4 @@ You cannot get the stack frame information or otherwise debug functions
 that were not compiled by Perl, such as C or C++ extensions.
 
 If you alter your @_ arguments in a subroutine (such as with B<shift>
-or B<pop>, the stack backtrace will not show the original values.
-
-Some subroutines are called without creating a call frame. This may
-confuse backtrace C<T> and output of C<fE<gt>=4>.
+or B<pop>, the stack back-trace will not show the original values.
index 20f4fbd..bbd699f 100644 (file)
@@ -53,7 +53,7 @@ no useful value.  See L<perlmod>.
 
 =item % may only be used in unpack
 
-(F) You can't pack a string by supplying a checksum, since the
+(F) You can't pack a string by supplying a checksum, because the
 checksumming process loses information, and you can't go the other
 way.  See L<perlfunc/unpack>.
 
@@ -61,15 +61,27 @@ way.  See L<perlfunc/unpack>.
 
 (W) You've run afoul of the rule that says that any list operator followed
 by parentheses turns into a function, with all the list operators arguments
-found inside the parens.  See L<perlop/Terms and List Operators (Leftward)>.
+found inside the parentheses.  See L<perlop/Terms and List Operators (Leftward)>.
 
 =item %s argument is not a HASH element
 
-(F) The argument to delete() or exists() must be a hash element, such as
+(F) The argument to exists() must be a hash element, such as
 
     $foo{$bar}
     $ref->[12]->{"susie"}
 
+=item %s argument is not a HASH element or slice
+
+(F) The argument to delete() must be either a hash element, such as
+
+    $foo{$bar}
+    $ref->[12]->{"susie"}
+
+or a hash slice, such as
+
+    @foo{$bar, $baz, $xyzzy}
+    @{$ref->[12]}{"susie", "queue"}
+
 =item %s did not return a true value
 
 (F) A required (or used) file must return a true value to indicate that
@@ -176,7 +188,7 @@ the return value of your socket() call?  See L<perlfunc/accept>.
 
 (W)(S) You said something that may not be interpreted the way
 you thought.  Normally it's pretty easy to disambiguate it by supplying
-a missing quote, operator, paren pair or declaration.
+a missing quote, operator, parenthesis pair or declaration.
 
 =item Args must match #! line
 
@@ -252,7 +264,7 @@ dereference it first.  See L<perlfunc/substr>.
 
 (F) You passed a buffer of the wrong size to one of msgctl(), semctl() or
 shmctl().  In C parlance, the correct sizes are, respectively,
-S<sizeof(struct msqid_ds *)>, S<sizeof(struct semid_ds *)> and
+S<sizeof(struct msqid_ds *)>, S<sizeof(struct semid_ds *)>, and
 S<sizeof(struct shmid_ds *)>.
 
 =item Bad associative array
@@ -336,7 +348,7 @@ exited by calling exit.
 except that there's this itty bitty problem called there isn't a
 current block.  Note that an "if" or "else" block doesn't count as a
 "loopish" block.  You can usually double the curlies to get the same
-effect though, since the inner curlies will be considered a block
+effect though, because the inner curlies will be considered a block
 that loops once.  See L<perlfunc/last>.
 
 =item Can't "next" outside a block
@@ -344,7 +356,7 @@ that loops once.  See L<perlfunc/last>.
 (F) A "next" statement was executed to reiterate the current block, but
 there isn't a current block.  Note that an "if" or "else" block doesn't
 count as a "loopish" block.  You can usually double the curlies to get
-the same effect though, since the inner curlies will be considered a block
+the same effect though, because the inner curlies will be considered a block
 that loops once.  See L<perlfunc/last>.
 
 =item Can't "redo" outside a block
@@ -352,7 +364,7 @@ that loops once.  See L<perlfunc/last>.
 (F) A "redo" statement was executed to restart the current block, but
 there isn't a current block.  Note that an "if" or "else" block doesn't
 count as a "loopish" block.  You can usually double the curlies to get
-the same effect though, since the inner curlies will be considered a block
+the same effect though, because the inner curlies will be considered a block
 that loops once.  See L<perlfunc/last>.
 
 =item Can't bless non-reference value
@@ -427,14 +439,14 @@ or other plumbing problems.
 
 =item Can't declare %s in my
 
-(F) Only scalar, array and hash variables may be declared as lexical variables.
+(F) Only scalar, array, and hash variables may be declared as lexical variables.
 They must have ordinary identifiers as names.
 
 =item Can't do inplace edit on %s: %s
 
 (S) The creation of the new file failed for the indicated reason.
 
-=item Can't do inplace edit without backup
+=item Can't do in-place edit without backup
 
 (F) You're on a system such as MSDOS that gets confused if you try reading
 from a deleted (but still opened) file.  You have to say B<-i>C<.bak>, or some
@@ -484,7 +496,7 @@ For example, it'd be kind of silly to put a B<-x> on the #! line.
 
 =item Can't exec "%s": %s
 
-(W) An system(), exec() or piped open call could not execute the named
+(W) An system(), exec(), or piped open call could not execute the named
 program for the indicated reason.  Typical reasons include: the permissions
 were wrong on the file, the file wasn't found in C<$ENV{PATH}>, the
 executable in question was compiled for another architecture, or the
@@ -510,7 +522,7 @@ for us to go to.  See L<perlfunc/goto>.
 =item Can't find string terminator %s anywhere before EOF
 
 (F) Perl strings can stretch over multiple lines.  This message means that
-the closing delimiter was omitted.  Since bracketed quotes count nesting
+the closing delimiter was omitted.  Because bracketed quotes count nesting
 levels, the following is missing its final parenthesis:
 
     print q(The character '(' starts a side comment.)
@@ -537,7 +549,7 @@ assumes that the stat buffer contains all the necessary information, and passes
 it, instead of the filespec, to the access checking routine.  It will try to
 retrieve the filespec using the device name and FID present in the stat buffer,
 but this works only if you haven't made a subsequent call to the CRTL stat()
-routine, since the device name is overwritten with each call.  If this warning
+routine, because the device name is overwritten with each call.  If this warning
 appears, the name lookup failed, and the access checking routine gave up and
 returned FALSE, just to be conservative.  (Note: The access checking routine
 knows about the Perl C<stat> operator and file tests, so you shouldn't ever
@@ -558,7 +570,7 @@ mailbox buffers to be, and didn't get an answer.
 
 (F) The deeply magical "goto subroutine" call can only replace one subroutine
 call for another.  It can't manufacture one out of whole cloth.  In general
-you should only be calling it out of an AUTOLOAD routine anyway.  See
+you should be calling it out of only an AUTOLOAD routine anyway.  See
 L<perlfunc/goto>.
 
 =item Can't localize a reference
@@ -602,16 +614,16 @@ a B<-e> switch.  Maybe your /tmp partition is full, or clobbered.
 =item Can't modify %s in %s
 
 (F) You aren't allowed to assign to the item indicated, or otherwise try to
-change it, such as with an autoincrement.
+change it, such as with an auto-increment.
 
 =item Can't modify non-existent substring
 
 (P) The internal routine that does assignment to a substr() was handed
 a NULL.
 
-=item Can't msgrcv to readonly var
+=item Can't msgrcv to read-only var
 
-(F) The target of a msgrcv must be modifiable in order to be used as a receive
+(F) The target of a msgrcv must be modifiable to be used as a receive
 buffer.
 
 =item Can't open %s: %s
@@ -684,7 +696,7 @@ of suidperl.
 
 =item Can't take log of %g
 
-(F) Logarithms are only defined on positive real numbers.
+(F) Logarithms are defined on only positive real numbers.
 
 =item Can't take sqrt of %g
 
@@ -738,7 +750,7 @@ test the type of the reference, if need be.
 
 (W) In an ordinary expression, backslash is a unary operator that creates
 a reference to its argument.  The use of backslash to indicate a backreference
-to a matched substring is only valid as part of a regular expression pattern.
+to a matched substring is valid only as part of a regular expression pattern.
 Trying to do this in ordinary Perl code produces a value that prints
 out looking like SCALAR(0xdecaf).  Use the $1 form instead.
 
@@ -755,7 +767,7 @@ be a defined value.  This helps to de-lurk some insidious errors.
 =item Can't use global %s in "my"
 
 (F) You tried to declare a magical variable as a lexical variable.  This is
-not allowed, because the magic can only be tied to one location (namely
+not allowed, because the magic can be tied to only one location (namely
 the global variable) and it would be incredibly confusing to have
 variables in your program that looked like magical variables but
 weren't.
@@ -771,7 +783,7 @@ didn't look like an array reference, or anything else subscriptable.
 (F) The write routine failed for some reason while trying to process
 a B<-e> switch.  Maybe your /tmp partition is full, or clobbered.
 
-=item Can't x= to readonly value
+=item Can't x= to read-only value
 
 (F) You tried to repeat a constant value (often the undefined value) with
 an assignment operator, which implies modifying the value itself.
@@ -830,7 +842,12 @@ case it indicates something else.
 (W) You probably said %hash{$key} when you meant $hash{$key} or @hash{@keys}.
 On the other hand, maybe you just meant %hash and got carried away.
 
-=item Do you need to predeclare %s?
+=item Died.
+
+(F) You passed die() an empty string (the equivalent of C<die "">) or
+you called it with no args and both C<$@> and C<$_> were empty.
+
+=item Do you need to pre-declare %s?
 
 (S) This is an educated guess made in conjunction with the message "%s
 found where operator expected".  It often means a subroutine or module
@@ -869,7 +886,7 @@ The interpreter is immediately exited.
 
 =item Error converting file specification %s
 
-(F) An error peculiar to VMS.  Since Perl may have to deal with file
+(F) An error peculiar to VMS.  Because Perl may have to deal with file
 specifications in either VMS or Unix syntax, it converts them to a
 single form when it must operate on them directly.  Either you've
 passed an invalid file specification to Perl, or you've found a
@@ -912,20 +929,20 @@ PDP-11 or something?
 You need to do an open() or a socket() call, or call a constructor from
 the FileHandle package.
 
-=item Filehandle %s opened only for input
+=item Filehandle %s opened for only input
 
 (W) You tried to write on a read-only filehandle.  If you
 intended it to be a read-write filehandle, you needed to open it with
 "+E<lt>" or "+E<gt>" or "+E<gt>E<gt>" instead of with "E<lt>" or nothing.  If
-you only intended to write the file, use "E<gt>" or "E<gt>E<gt>".  See
+you intended only to write the file, use "E<gt>" or "E<gt>E<gt>".  See
 L<perlfunc/open>.
 
-=item Filehandle only opened for input
+=item Filehandle opened for only input
 
 (W) You tried to write on a read-only filehandle.  If you
 intended it to be a read-write filehandle, you needed to open it with
 "+E<lt>" or "+E<gt>" or "+E<gt>E<gt>" instead of with "E<lt>" or nothing.  If
-you only intended to write the file, use "E<gt>" or "E<gt>E<gt>".  See
+you intended only to write the file, use "E<gt>" or "E<gt>E<gt>".  See
 L<perlfunc/open>.
 
 =item Final $ should be \$ or $name
@@ -1022,8 +1039,8 @@ is now heavily deprecated.
 
 (W) A warning peculiar to VMS.  A logical name was encountered when preparing
 to iterate over %ENV which violates the syntactic rules governing logical
-names.  Since it cannot be translated normally, it is skipped, and will not
-appear in %ENV.  This may be a benign occurence, as some software packages
+names.  Because it cannot be translated normally, it is skipped, and will not
+appear in %ENV.  This may be a benign occurrence, as some software packages
 might directly modify logical name tables and introduce non-standard names,
 or it may indicate that a logical name table has been corrupted.
 
@@ -1084,7 +1101,7 @@ architecture. On a 32-bit architecture the largest octal literal is
 =item Internal inconsistency in tracking vforks
 
 (S) A warning peculiar to VMS.  Perl keeps track of the number
-of times you've called C<fork> and C<exec>, in order to determine
+of times you've called C<fork> and C<exec>, to determine
 whether the current call to C<exec> should affect the current
 script or a subprocess (see L<perlvms/exec>).  Somehow, this count
 has become scrambled, so Perl is making a guess and treating
@@ -1192,7 +1209,7 @@ the previous line just because you saw this message.
 =item Modification of a read-only value attempted
 
 (F) You tried, directly or indirectly, to change the value of a
-constant.  You didn't, of course, try "2 = 1", since the compiler
+constant.  You didn't, of course, try "2 = 1", because the compiler
 catches that.  But an easy way to do the same thing is:
 
     sub mod { $_[0] = 1 }
@@ -1238,10 +1255,10 @@ that is less than 0.  This is difficult to imagine.
 
 =item nested *?+ in regexp
 
-(F) You can't quantify a quantifier without intervening parens.  So
+(F) You can't quantify a quantifier without intervening parentheses.  So
 things like ** or +* or ?* are illegal.
 
-Note, however, that the minimal matching quantifiers, *?, +? and ?? appear
+Note, however, that the minimal matching quantifiers, C<*?>, C<+?>, and C<??> appear
 to be nested quantifiers, but aren't.  See L<perlre>.
 
 =item No #! line
@@ -1284,7 +1301,7 @@ right.
 =item No dbm on this machine
 
 (P) This is counted as an internal error, because every machine should
-supply dbm nowadays, since Perl comes with SDBM.  See L<SDBM_File>.
+supply dbm nowadays, because Perl comes with SDBM.  See L<SDBM_File>.
 
 =item No DBsub routine
 
@@ -1414,7 +1431,7 @@ See L<perlform>.
 
 =item Null filename used
 
-(F) You can't require the null filename, especially since on many machines
+(F) You can't require the null filename, especially because on many machines
 that means the current directory!  See L<perlfunc/require>.
 
 =item Null picture in formline
@@ -1433,7 +1450,7 @@ supplied it an uninitialized value.  See L<perlform>.
 
 =item NULL regexp argument
 
-(P) The internal pattern matching routines blew it bigtime.
+(P) The internal pattern matching routines blew it big time.
 
 =item NULL regexp parameter
 
@@ -1442,7 +1459,7 @@ supplied it an uninitialized value.  See L<perlform>.
 =item Odd number of elements in hash list
 
 (S) You specified an odd number of elements to a hash list, which is odd,
-since hash lists come in key/value pairs.
+because hash lists come in key/value pairs.
 
 =item Offset outside string
 
@@ -1554,7 +1571,7 @@ it wasn't a block context.
 
 =item panic: leave_scope clearsv
 
-(P) A writable lexical variable became readonly somehow within the scope.
+(P) A writable lexical variable became read-only somehow within the scope.
 
 =item panic: leave_scope inconsistency
 
@@ -1640,7 +1657,7 @@ was string.
 
 (P) The lexer got into a bad state while processing a case modifier.
 
-=item Parens missing around "%s" list
+=item Pareneses missing around "%s" list
 
 (W) You said something like
 
@@ -1675,7 +1692,7 @@ the BSD version, which takes a pid.
 
 =item Possible attempt to put comments in qw() list
 
-(W) You probably wrote somthing like this:
+(W) You probably wrote something like this:
 
     qw( a # a comment
         b # another comment
@@ -1689,7 +1706,7 @@ when you should have written this:
 
 =item Possible attempt to separate words with commas
 
-(W) You probably wrote somthing like this:
+(W) You probably wrote something like this:
 
     qw( a, b, c );
 
@@ -1716,7 +1733,7 @@ is now misinterpreted as
 
 because of the strict regularization of Perl 5's grammar into unary and
 list operators.  (The old open was a little of both.) You must put
-parens around the filehandle, or use the new "or" operator instead of "||".
+parentheses around the filehandle, or use the new "or" operator instead of "||".
 
 =item print on closed filehandle %s
 
@@ -1738,7 +1755,7 @@ last argument of the previous construct, for example:
 
 =item Prototype mismatch: (%s) vs (%s)
 
-(S) The subroutine being defined had a predeclared (forward) declaration
+(S) The subroutine being defined had a pre-declared (forward) declaration
 with a different function prototype.
 
 =item Read on closed filehandle E<lt>%sE<gt>
@@ -1803,10 +1820,10 @@ an array.  Generally it's better to ask for a scalar value (indicated by $).
 The difference is that C<$foo[&bar]> always behaves like a scalar, both when
 assigning to it and when evaluating its argument, while C<@foo[&bar]> behaves
 like a list when you assign to it, and provides a list context to its
-subscript, which can do weird things if you're only expecting one subscript.
+subscript, which can do weird things if you're expecting only one subscript.
 
 On the other hand, if you were actually hoping to treat the array
-element as a list, you need to look into how references work, since
+element as a list, you need to look into how references work, because
 Perl will not magically convert between scalars and lists for you.  See
 L<perlref>.
 
@@ -1851,7 +1868,7 @@ Check your logic flow.
 =item Sequence (?#... not terminated
 
 (F) A regular expression comment must be terminated by a closing
-parenthesis.  Embedded parens aren't allowed.  See L<perlre>.
+parenthesis.  Embedded parentheses aren't allowed.  See L<perlre>.
 
 =item Sequence (?%s...) not implemented
 
@@ -1963,7 +1980,7 @@ by itself.
 (P) The substitution was looping infinitely.  (Obviously, a
 substitution shouldn't iterate more times than there are characters of
 input, which is what happened.) See the discussion of substitution in
-L<perlop/"Quote and Quotelike Operators">.
+L<perlop/"Quote and Quote-like Operators">.
 
 =item Substitution pattern not terminated
 
@@ -2001,7 +2018,7 @@ Often there will be another error message associated with the syntax
 error giving more information.  (Sometimes it helps to turn on B<-w>.)
 The error message itself often tells you where it was in the line when
 it decided to give up.  Sometimes the actual error is several tokens
-before this, since Perl is good at understanding random input.
+before this, because Perl is good at understanding random input.
 Occasionally the line number may be misleading, and once in a blue moon
 the only way to figure out what's triggering the error is to call
 C<perl -c> repeatedly, chopping away half the program each time to see
@@ -2015,7 +2032,7 @@ into Perl yourself.
 
 =item System V IPC is not implemented on this machine
 
-(F) You tried to do something with a function beginning with "sem", "shm"
+(F) You tried to do something with a function beginning with "sem", "shm",
 or "msg".  See L<perlfunc/semctl>, for example.
 
 =item Syswrite on closed filehandle
@@ -2036,7 +2053,7 @@ open.  Check your logic.  See also L<perlfunc/-X>.
 =item That use of $[ is unsupported
 
 (F) Assignment to C<$[> is now strictly circumscribed, and interpreted as
-a compiler directive.  You may only say one of
+a compiler directive.  You may say only one of
 
     $[ = 0;
     $[ = 1;
@@ -2087,7 +2104,7 @@ into Perl yourself.
 
 =item Too many args to syscall
 
-(F) Perl only supports a maximum of 14 args to syscall().
+(F) Perl supports a maximum of only 14 args to syscall().
 
 =item Too many arguments for %s
 
@@ -2122,7 +2139,7 @@ certain type.  Arrays must be @NAME or C<@{EXPR}>.  Hashes must be
 
 =item umask: argument is missing initial 0
 
-(W) A umask of 222 is incorrect.  It should be 0222, since octal literals
+(W) A umask of 222 is incorrect.  It should be 0222, because octal literals
 always start with 0 in Perl, as in C.
 
 =item Unable to create sub named "%s"
@@ -2186,13 +2203,13 @@ representative, who probably put it there in the first place.
 
 =item Unknown BYTEORDER
 
-(F) There are no byteswapping functions for a machine with this byte order.
+(F) There are no byte-swapping functions for a machine with this byte order.
 
 =item unmatched () in regexp
 
 (F) Unbackslashed parentheses must always be balanced in regular
 expressions.  If you're a vi user, the % key is valuable for finding
-the matching paren.  See L<perlre>.
+the matching parenthesis.  See L<perlre>.
 
 =item Unmatched right bracket
 
@@ -2263,15 +2280,15 @@ Use an explicit printf() or sprintf() instead.
 
 =item Use of $* is deprecated
 
-(D) This variable magically turned on multiline pattern matching, both for
+(D) This variable magically turned on multi-line pattern matching, both for
 you and for any luckless subroutine that you happen to call.  You should
 use the new C<//m> and C<//s> modifiers now to do that without the dangerous
 action-at-a-distance effects of C<$*>.
 
 =item Use of %s in printf format not supported
 
-(F) You attempted to use a feature of printf that is accessible only
-from C.  This usually means there's a better way to do it in Perl.
+(F) You attempted to use a feature of printf that is accessible from
+only C.  This usually means there's a better way to do it in Perl.
 
 =item Use of %s is deprecated
 
@@ -2346,12 +2363,17 @@ on the front of your variable.
 of Perl.  Check the E<lt>#!E<gt> line, or manually feed your script
 into Perl yourself.
 
+=item Warning: something's wrong.
+
+(W) You passed warn() an empty string (the equivalent of C<warn "">) or
+you called it with no args and C<$_> was empty.
+
 =item Warning: unable to close filehandle %s properly.
 
 (S) The implicit close() done by an open() got an error indication on the
-close().  This usually indicates your filesystem ran out of disk space.
+close().  This usually indicates your file system ran out of disk space.
 
-=item Warning: Use of "%s" without parens is ambiguous
+=item Warning: Use of "%s" without parentheses is ambiguous
 
 (S) You wrote a unary operator followed by something that looks like a
 binary operator that could also have been interpreted as a term or
@@ -2368,7 +2390,7 @@ but in actual fact, you got
 
     rand(+5);
 
-So put in parens to say what you really mean.
+So put in parentheses to say what you really mean.
 
 =item Write on closed filehandle
 
@@ -2401,7 +2423,7 @@ Use a filename instead.
 
 =item YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!
 
-(F) And you probably never will, since you probably don't have the
+(F) And you probably never will, because you probably don't have the
 sources to your kernel, and your vendor probably doesn't give a rip
 about what you want.  Your best bet is to use the wrapsuid script in
 the eg directory to put a setuid C wrapper around your script.
@@ -2422,7 +2444,7 @@ See L<perlfunc/getsockopt>.
 =item \1 better written as $1
 
 (W) Outside of patterns, backreferences live on as variables.  The use
-of backslashes is grandfathered on the righthand side of a
+of backslashes is grandfathered on the right-hand side of a
 substitution, but stylistically it's better to use the variable form
 because other Perl programmers will expect it, and it works better
 if there are more than 9 backreferences.
@@ -2451,7 +2473,7 @@ streams, such as
 =item Got an error from DosAllocMem:
 
 (P) An error peculiar to OS/2. Most probably you use an obsolete version
-of perl, and should not happen anyway.
+of perl, and this should not happen anyway.
 
 =item Malformed PERLLIB_PREFIX
 
index 6991e7a..5beaa8b 100644 (file)
@@ -30,7 +30,7 @@ with three dimensions!
 Alas, however simple this may appear, underneath it's a much more
 elaborate construct than meets the eye!
 
-How do you print it out?  Why can't you just say C<print @LoL>?  How do
+How do you print it out?  Why can't you say just C<print @LoL>?  How do
 you sort it?  How can you pass it to a function or get one of these back
 from a function?  Is is an object?  Can you save it to disk to read
 back later?  How do you access whole rows or columns of that matrix?  Do
@@ -41,11 +41,11 @@ of the blame for this can be attributed to the reference-based
 implementation, it's really more due to a lack of existing documentation with
 examples designed for the beginner.
 
-This document is meant to be a detailed but understandable treatment of
-the many different sorts of data structures you might want to develop.  It should
-also serve as a cookbook of examples.  That way, when you need to create one of these
-complex data structures, you can just pinch, pilfer, or purloin
-a drop-in example from here.
+This document is meant to be a detailed but understandable treatment of the
+many different sorts of data structures you might want to develop.  It
+should also serve as a cookbook of examples.  That way, when you need to
+create one of these complex data structures, you can just pinch, pilfer, or
+purloin a drop-in example from here.
 
 Let's look at each of these possible constructs in detail.  There are separate
 documents on each of the following:
@@ -76,15 +76,15 @@ of these types of data structures.
 The most important thing to understand about all data structures in Perl
 -- including multidimensional arrays--is that even though they might
 appear otherwise, Perl C<@ARRAY>s and C<%HASH>es are all internally
-one-dimensional.  They can only hold scalar values (meaning a string,
+one-dimensional.  They can hold only scalar values (meaning a string,
 number, or a reference).  They cannot directly contain other arrays or
 hashes, but instead contain I<references> to other arrays or hashes.
 
-You can't use a reference to a array or hash in quite the same way that
-you would a real array or hash.  For C or C++ programmers unused to distinguishing
-between arrays and pointers to the same, this can be confusing.  If so,
-just think of it as the difference between a structure and a pointer to a
-structure.
+You can't use a reference to a array or hash in quite the same way that you
+would a real array or hash.  For C or C++ programmers unused to
+distinguishing between arrays and pointers to the same, this can be
+confusing.  If so, just think of it as the difference between a structure
+and a pointer to a structure.
 
 You can (and should) read more about references in the perlref(1) man
 page.  Briefly, references are rather like pointers that know what they
@@ -102,7 +102,7 @@ multidimensional arrays work as well.
     $hash{string}[7]                   # hash of arrays
     $hash{string}{'another string'}    # hash of hashes
 
-Now, because the top level only contains references, if you try to print
+Now, because the top level contains only references, if you try to print
 out your array in with a simple print() function, you'll get something
 that doesn't look very nice, like this:
 
@@ -149,7 +149,7 @@ again and again:
        $LoL[$i] = \@list;      # WRONG!
     }
 
-So, just what's the big problem with that?  It looks right, doesn't it?
+So, what's the big problem with that?  It looks right, doesn't it?
 After all, I just told you that you need an array of references, so by
 golly, you've made me one!
 
@@ -218,7 +218,7 @@ something is "interesting", that rather than meaning "intriguing",
 they're disturbingly more apt to mean that it's "annoying",
 "difficult", or both?  :-)
 
-So just remember to always use the array or hash constructors with C<[]>
+So just remember always to use the array or hash constructors with C<[]>
 or C<{}>, and you'll be fine, although it's not always optimally
 efficient.
 
@@ -290,14 +290,14 @@ this:
     my $listref = [
        [ "fred", "barney", "pebbles", "bambam", "dino", ],
        [ "homer", "bart", "marge", "maggie", ],
-       [ "george", "jane", "alroy", "judy", ],
+       [ "george", "jane", "elroy", "judy", ],
     ];
 
     print $listref[2][2];
 
 The compiler would immediately flag that as an error I<at compile time>,
 because you were accidentally accessing C<@listref>, an undeclared
-variable, and it would thereby remind you to instead write:
+variable, and it would thereby remind you to write instead:
 
     print $listref->[2][2]
 
@@ -325,7 +325,7 @@ example, given the assignment to $LoL above, here's the debugger output:
        2  ARRAY(0x13b540)
          0  'george'
          1  'jane'
-         2  'alroy'
+         2  'elroy'
          3  'judy'
 
 There's also a lower-case B<x> command which is nearly the same.
@@ -449,7 +449,7 @@ types of data structures.
  # print the whole thing with indices
  foreach $family ( keys %HoL ) {
      print "family: ";
-     foreach $i ( 0 .. $#{ $HoL{$family} ) {
+     foreach $i ( 0 .. $#{ $HoL{$family} } ) {
          print " $i = $HoL{$family}[$i]";
      }
      print "\n";
@@ -746,7 +746,7 @@ many different sorts:
      # reading from file
      # this is most easily done by having the file itself be
      # in the raw data format as shown above.  perl is happy
-     # to parse complex datastructures if declared as data, so
+     # to parse complex data structures if declared as data, so
      # sometimes it's easiest to do that
 
      # here's a piece by piece build up
@@ -817,7 +817,7 @@ You cannot easily tie a multilevel data structure (such as a hash of
 hashes) to a dbm file.  The first problem is that all but GDBM and
 Berkeley DB have size limitations, but beyond that, you also have problems
 with how references are to be represented on disk.  One experimental
-module that does attempt to partially address this need is the MLDBM
+module that does partially attempt to address this need is the MLDBM
 module.  Check your nearest CPAN site as described in L<perlmod> for
 source code to MLDBM.
 
index 186dc88..ea0e833 100644 (file)
@@ -16,7 +16,7 @@ Read L<perlcall> and L<perlxs>.
 
 =item B<Use a UNIX program from Perl?>
 
-Read about backquotes and about C<system> and C<exec> in L<perlfunc>.
+Read about back-quotes and about C<system> and C<exec> in L<perlfunc>.
 
 =item B<Use Perl from Perl?>
 
@@ -142,7 +142,7 @@ I<miniperlmain.c> containing the essentials of embedding:
 
 Note that we do not use the C<env> pointer here or in any of the
 following examples.
-Normally handed to C<perl_parse> as it's final argument,
+Normally handed to C<perl_parse> as its final argument,
 we hand it a B<NULL> instead, in which case the current environment
 is used.
 
@@ -303,14 +303,14 @@ substitutions: I<match()>, I<substitute()>, and I<matches()>.
 
    char match(char *string, char *pattern);
 
-Given a string and a pattern (e.g. "m/clasp/" or "/\b\w*\b/", which in
+Given a string and a pattern (e.g., "m/clasp/" or "/\b\w*\b/", which in
 your program might be represented as C<"/\\b\\w*\\b/">),
 returns 1 if the string matches the pattern and 0 otherwise.
 
 
    int substitute(char *string[], char *pattern);
 
-Given a pointer to a string and an "=~" operation (e.g. "s/bob/robert/g" or
+Given a pointer to a string and an "=~" operation (e.g., "s/bob/robert/g" or
 "tr[A-Z][a-z]"), modifies the string according to the operation,
 returning the number of substitutions made.
 
@@ -488,9 +488,9 @@ described in L<perlcall>.
 
 Once you've understood those, embedding Perl in C is easy.
 
-Since C has no built-in function for integer exponentiation, let's
+Because C has no built-in function for integer exponentiation, let's
 make Perl's ** operator available to it (this is less useful than it
-sounds, since Perl implements ** with C's I<pow()> function).  First
+sounds, because Perl implements ** with C's I<pow()> function).  First
 I'll create a stub exponentiation function in I<power.pl>:
 
     sub expo {
@@ -612,7 +612,7 @@ counterpart for each of the extension's XSUBs.  Don't worry about this
 part; leave that to the I<xsubpp> and extension authors.  If your
 extension is dynamically loaded, DynaLoader creates I<Module::bootstrap()>
 for you on the fly.  In fact, if you have a working DynaLoader then there
-is rarely any need to statically link in any other extensions.
+is rarely any need to link in any other extensions statically.
 
 
 Once you have this code, slap it into the second argument of I<perl_parse()>:
@@ -644,7 +644,7 @@ Consult L<perlxs> and L<perlguts> for more details.
 =head1 MORAL
 
 You can sometimes I<write faster code> in C, but
-you can always I<write code faster> in Perl.  Since you can use
+you can always I<write code faster> in Perl.  Because you can use
 each from the other, combine them as you wish.
 
 
index a9ce4a7..4fac1a6 100644 (file)
@@ -198,7 +198,7 @@ Much better!
 
 =head1 NOTES
 
-Since the values line may contain arbitrary expressions (for at fields, 
+Because the values line may contain arbitrary expressions (for at fields, 
 not caret fields), you can farm out more sophisticated processing
 to other functions, like sprintf() or one of your own.  For example:
 
index 35f840f..49b77f0 100644 (file)
@@ -14,8 +14,8 @@ a unary operator, but merely separates the arguments of a list
 operator.  A unary operator generally provides a scalar context to its
 argument, while a list operator may provide either scalar and list
 contexts for its arguments.  If it does both, the scalar arguments will
-be first, and the list argument will follow.  (Note that there can only
-ever be one list argument.)  For instance, splice() has three scalar
+be first, and the list argument will follow.  (Note that there can ever
+be only one list argument.)  For instance, splice() has three scalar
 arguments followed by a list.
 
 In the syntax descriptions that follow, list operators that expect a
@@ -28,7 +28,7 @@ Elements of the LIST should be separated by commas.
 
 Any function in the list below may be used either with or without
 parentheses around its arguments.  (The syntax descriptions omit the
-parens.)  If you use the parens, the simple (but occasionally
+parentheses.)  If you use the parentheses, the simple (but occasionally
 surprising) rule is this: It I<LOOKS> like a function, therefore it I<IS> a
 function, and precedence doesn't matter.  Otherwise it's a list
 operator or unary operator, and precedence does matter.  And whitespace
@@ -252,12 +252,12 @@ operator may be any of:
     -C Same for inode change time.
 
 The interpretation of the file permission operators C<-r>, C<-R>, C<-w>,
-C<-W>, C<-x> and C<-X> is based solely on the mode of the file and the
+C<-W>, C<-x>, and C<-X> is based solely on the mode of the file and the
 uids and gids of the user.  There may be other reasons you can't actually
 read, write or execute the file.  Also note that, for the superuser,
-C<-r>, C<-R>, C<-w> and C<-W> always return 1, and C<-x> and C<-X> return
+C<-r>, C<-R>, C<-w>, and C<-W> always return 1, and C<-x> and C<-X> return
 1 if any execute bit is set in the mode.  Scripts run by the superuser may
-thus need to do a stat() in order to determine the actual mode of the
+thus need to do a stat() to determine the actual mode of the
 file, or temporarily set the uid to something else.
 
 Example:
@@ -385,7 +385,7 @@ is taken as the name of the filehandle.
 This function tells the referenced object (passed as REF) that it is now
 an object in the CLASSNAME package--or the current package if no CLASSNAME
 is specified, which is often the case.  It returns the reference for
-convenience, since a bless() is often the last thing in a constructor.
+convenience, because a bless() is often the last thing in a constructor.
 Always use the two-argument version if the function doing the blessing
 might be inherited by a derived class.  See L<perlobj> for more about the
 blessing (and blessings) of objects.
@@ -536,7 +536,7 @@ omitted, does chroot to $_.
 Closes the file or pipe associated with the file handle, returning TRUE
 only if stdio successfully flushes buffers and closes the system file
 descriptor.  You don't have to close FILEHANDLE if you are immediately
-going to do another open() on it, since open() will close it for you.  (See
+going to do another open() on it, because open() will close it for you.  (See
 open().)  However, an explicit close on an input file resets the line
 counter ($.), while the implicit close done by open() does not.  Also,
 closing a pipe will wait for the process executing on the pipe to
@@ -603,7 +603,7 @@ their own password:
        print "ok\n";
     } 
 
-Of course, typing in your own password to whoever asks you 
+Of course, typing in your own password to whomever asks you 
 for it is unwise.
 
 =item dbmclose ASSOC_ARRAY
@@ -622,7 +622,7 @@ normal open, the first argument is I<NOT> a filehandle, even though it
 looks like one).  DBNAME is the name of the database (without the F<.dir>
 or F<.pag> extension if any).  If the database does not exist, it is
 created with protection specified by MODE (as modified by the umask()).
-If your system only supports the older DBM functions, you may perform only
+If your system supports only the older DBM functions, you may perform only
 one dbmopen() in your program.  In older versions of Perl, if your system
 had neither DBM nor ndbm, calling dbmopen() produced a fatal error; it now
 falls back to sdbm(3).
@@ -687,35 +687,41 @@ matched "nothing".  But it didn't really match nothing--rather, it
 matched something that happened to be 0 characters long.  This is all
 very above-board and honest.  When a function returns an undefined value,
 it's an admission that it couldn't give you an honest answer.  So
-you should only use defined() when you're questioning the integrity
+you should use defined() only when you're questioning the integrity
 of what you're trying to do.  At other times, a simple comparison to
 0 or "" is what you want.
 
 =item delete EXPR
 
-Deletes the specified value from its hash array.  Returns the deleted
-value, or the undefined value if nothing was deleted.  Deleting from
-C<$ENV{}> modifies the environment.  Deleting from an array tied to a DBM
-file deletes the entry from the DBM file.  (But deleting from a tie()d
-hash doesn't necessarily return anything.)
+Deletes the specified key(s) and their associated values from a hash
+array.  For each key, returns the deleted value associated with that key,
+or the undefined value if there was no such key.  Deleting from C<$ENV{}>
+modifies the environment.  Deleting from an array tied to a DBM file
+deletes the entry from the DBM file.  (But deleting from a tie()d hash
+doesn't necessarily return anything.)
 
 The following deletes all the values of an associative array:
 
-    foreach $key (keys %ARRAY) {
-       delete $ARRAY{$key};
+    foreach $key (keys %HASH) {
+       delete $HASH{$key};
     }
 
-(But it would be faster to use the undef() command.)  Note that the
-EXPR can be arbitrarily complicated as long as the final operation is
-a hash key lookup:
+And so does this:
+
+    delete @HASH{keys %HASH}
+
+(But both of these are slower than the undef() command.)  Note that the
+EXPR can be arbitrarily complicated as long as the final operation is a
+hash element lookup or hash slice:
 
     delete $ref->[$x][$y]{$key};
+    delete @{$ref->[$x][$y]}{$key1, $key2, @morekeys};
 
 =item die LIST
 
 Outside of an eval(), prints the value of LIST to C<STDERR> and exits with
 the current value of C<$!> (errno).  If C<$!> is 0, exits with the value of
-C<($? E<gt>E<gt> 8)> (backtick `command` status).  If C<($? E<gt>E<gt> 8)> is 0,
+C<($? E<gt>E<gt> 8)> (back-tick `command` status).  If C<($? E<gt>E<gt> 8)> is 0,
 exits with 255.  Inside an eval(), the error message is stuffed into C<$@>,
 and the eval() is terminated with the undefined value; this makes die()
 the way to raise an exception.
@@ -768,7 +774,7 @@ except that it's more efficient, more concise, keeps track of the
 current filename for error messages, and searches all the B<-I>
 libraries if the file isn't in the current directory (see also the @INC
 array in L<perlvar/Predefined Names>).  It's the same, however, in that it does
-reparse the file every time you call it, so you probably don't want to
+re-parse the file every time you call it, so you probably don't want to
 do this inside a loop.
 
 Note that inclusion of library modules is better done with the
@@ -813,7 +819,7 @@ Example:
 When called in a list context, returns a 2-element array consisting
 of the key and value for the next element of an associative array,
 so that you can iterate over it.  When called in a scalar context,
-returns the key only for the next element in the associative array.
+returns the key for only the next element in the associative array.
 Entries are returned in an apparently random order.  When the array is
 entirely read, a null array is returned in list context (which when
 assigned produces a FALSE (0) value), and C<undef> is returned in a
@@ -821,7 +827,7 @@ scalar context.  The next call to each() after that will start
 iterating again.  The iterator can be reset only by reading all the
 elements from the array.  You should not add elements to an array while
 you're iterating over it.  There is a single iterator for each
-associative array, shared by all each(), keys() and values() function
+associative array, shared by all each(), keys(), and values() function
 calls in the program.  The following prints out your environment like
 the printenv(1) program, only in a different order:
 
@@ -847,7 +853,7 @@ as terminals may lose the end-of-file condition if you do.
 
 An C<eof> without an argument uses the last file read as argument.
 Empty parentheses () may be used to indicate
-the pseudofile formed of the files listed on the command line, i.e.
+the pseudo file formed of the files listed on the command line, i.e.,
 C<eof()> is reasonable to use inside a while (E<lt>E<gt>) loop to detect the end
 of only the last file.  Use C<eof(ARGV)> or eof without the parentheses to
 test I<EACH> file in a while (E<lt>E<gt>) loop.  Examples:
@@ -877,7 +883,7 @@ input operators return undef when they run out of data.
 
 EXPR is parsed and executed as if it were a little Perl program.  It
 is executed in the context of the current Perl program, so that any
-variable settings, subroutine or format definitions remain afterwards.
+variable settings or subroutine and format definitions remain afterwards.
 The value returned is the value of the last expression evaluated, or a
 return statement may be used, just as with subroutines.  The last
 expression is evaluated in scalar or array context, depending on the
@@ -889,7 +895,7 @@ error message.  If there was no error, C<$@> is guaranteed to be a null
 string.  If EXPR is omitted, evaluates $_.  The final semicolon, if
 any, may be omitted from the expression.
 
-Note that, since eval() traps otherwise-fatal errors, it is useful for
+Note that, because eval() traps otherwise-fatal errors, it is useful for
 determining whether a particular feature (such as socket() or symlink())
 is implemented.  It is also Perl's exception trapping mechanism, where
 the die operator is used to raise exceptions.
@@ -974,7 +980,7 @@ if the corresponding value is undefined.
     print "Defined\n" if defined $array{$key};
     print "True\n" if $array{$key};
 
-A hash element can only be TRUE if it's defined, and defined if
+A hash element can be TRUE only if it's defined, and defined if
 it exists, but the reverse doesn't necessarily hold true.
 
 Note that the EXPR can be arbitrarily complicated as long as the final
@@ -1028,7 +1034,7 @@ OPERATION.  Returns TRUE for success, FALSE on failure.  Will produce a
 fatal error if used on a machine that doesn't implement either flock(2) or
 fcntl(2). The fcntl(2) system call will be automatically used if flock(2)
 is missing from your system.  This makes flock() the portable file locking
-strategy, although it will only lock entire files, not records.  Note also
+strategy, although it will lock only entire files, not records.  Note also
 that some versions of flock() cannot lock things over the network; you
 would need to use the more system-specific fcntl() for that.
 
@@ -1123,7 +1129,7 @@ that the C<~> and C<~~> tokens will treat the entire PICTURE as a single line.
 You may therefore need to use multiple formlines to implement a single
 record format, just like the format compiler.
 
-Be careful if you put double quotes around the picture, since an "C<@>"
+Be careful if you put double quotes around the picture, because an "C<@>"
 character may be taken to mean the beginning of an array name.
 formline() always returns TRUE.  See L<perlform> for other examples.
 
@@ -1149,7 +1155,7 @@ single-characters, however.  For that, try something more like:
        system "stty -cbreak </dev/tty >/dev/tty 2>&1";
     }
     else {
-       system "stty", 'icanon', 'eol', '^@'; # ascii null
+       system "stty", 'icanon', 'eol', '^@'; # ASCII null
     }
     print "\n";
 
@@ -1317,7 +1323,7 @@ operator, except it's easier to use.
 =item gmtime EXPR
 
 Converts a time as returned by the time function to a 9-element array
-with the time localized for the standard Greenwich timezone.  
+with the time localized for the standard Greenwich time zone.  
 Typically used as follows:
 
 
@@ -1372,7 +1378,7 @@ or equivalently,
 
     @foo = grep {!/^#/} @bar;    # weed out comments
 
-Note that, since $_ is a reference into the list value, it can be used
+Note that, because $_ is a reference into the list value, it can be used
 to modify the elements of the array.  While this is useful and
 supported, it can cause bizarre results if the LIST is not a named
 array.
@@ -1575,8 +1581,8 @@ it succeeded, FALSE otherwise.  See example in L<perlipc/"Sockets: Client/Server
 =item local EXPR
 
 A local modifies the listed variables to be local to the enclosing block,
-subroutine, C<eval{}> or C<do>.  If more than one value is listed, the
-list must be placed in parens.  See L<perlsub/"Temporary Values via
+subroutine, C<eval{}>, or C<do>.  If more than one value is listed, the
+list must be placed in parentheses.  See L<perlsub/"Temporary Values via
 local()"> for details.
 
 But you really probably want to be using my() instead, because local() isn't
@@ -1586,7 +1592,7 @@ via my()"> for details.
 =item localtime EXPR
 
 Converts a time as returned by the time function to a 9-element array
-with the time analyzed for the local timezone.  Typically used as
+with the time analyzed for the local time zone.  Typically used as
 follows:
 
     ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
@@ -1598,7 +1604,7 @@ the range 0..6.  If EXPR is omitted, does localtime(time).
 
 In a scalar context, prints out the ctime(3) value:
 
-    $now_string = localtime;  # e.g. "Thu Oct 13 04:54:34 1994"
+    $now_string = localtime;  # e.g., "Thu Oct 13 04:54:34 1994"
 
 Also see the F<timelocal.pl> library, and the strftime(3) function available
 via the POSIX module.
@@ -1686,7 +1692,7 @@ an error.
 
 A "my" declares the listed variables to be local (lexically) to the
 enclosing block, subroutine, C<eval>, or C<do/require/use>'d file.  If
-more than one value is listed, the list must be placed in parens.  See
+more than one value is listed, the list must be placed in parentheses.  See
 L<perlsub/"Private Variables via my()"> for details.
 
 =item next LABEL
@@ -1727,22 +1733,28 @@ If EXPR is omitted, uses $_.
 =item open FILEHANDLE
 
 Opens the file whose filename is given by EXPR, and associates it with
-FILEHANDLE.  If FILEHANDLE is an expression, its value is used as the name
-of the real filehandle wanted.  If EXPR is omitted, the scalar variable of
-the same name as the FILEHANDLE contains the filename.  If the filename
-begins with "E<lt>" or nothing, the file is opened for input.  If the filename
-begins with "E<gt>", the file is opened for output.  If the filename begins
-with "E<gt>E<gt>", the file is opened for appending.  You can put a '+' in
-front of the 'E<gt>' or 'E<lt>' to indicate that you want both read and write
-access to the file; thus '+E<lt>' is usually preferred for read/write
-updates--the '+E<gt>' mode would clobber the file first.  These correspond to
-the fopen(3) modes of 'r', 'r+', 'w', 'w+', 'a', and 'a+'.
-
-If the filename begins with "|", the filename is interpreted
-as a command to which output is to be piped, and if the filename ends with
-a "|", the filename is interpreted See L<perlipc/"Using open() for IPC">
-for more examples of this.  as command which pipes input to us.  (You may
-not have a raw open() to a command that pipes both in I<and> out, but see L<open2>,
+FILEHANDLE.  If FILEHANDLE is an expression, its value is used as the
+name of the real filehandle wanted.  If EXPR is omitted, the scalar
+variable of the same name as the FILEHANDLE contains the filename.
+(Note that lexical variables--those declared with C<my>--will not work
+for this purpose; so if you're using C<my>, specify EXPR in your call
+to open.)
+
+If the filename begins with '<' or nothing, the file is opened for input.
+If the filename begins with '>', the file is truncated and opened for
+output.  If the filename begins with '>>', the file is opened for
+appending.  You can put a '+' in front of the '>' or '<' to indicate that
+you want both read and write access to the file; thus '+<' is almost
+always preferred for read/write updates--the '+>' mode would clobber the
+file first.  The prefix and the filename may be separated with spaces.
+These various prefixes correspond to the fopen(3) modes of 'r', 'r+', 'w',
+'w+', 'a', and 'a+'.
+
+If the filename begins with "|", the filename is interpreted as a command
+to which output is to be piped, and if the filename ends with a "|", the
+filename is interpreted See L<perlipc/"Using open() for IPC"> for more
+examples of this.  as command which pipes input to us.  (You may not have
+a raw open() to a command that pipes both in I<and> out, but see L<open2>,
 L<open3>, and L<perlipc/"Bidirectional Communication"> for alternatives.)
 
 Opening '-' opens STDIN and opening 'E<gt>-' opens STDOUT.  Open returns
@@ -1799,7 +1811,7 @@ You may also, in the Bourne shell tradition, specify an EXPR beginning
 with "E<gt>&", in which case the rest of the string is interpreted as the
 name of a filehandle (or file descriptor, if numeric) which is to be
 duped and opened.  You may use & after E<gt>, E<gt>E<gt>, E<lt>, +E<gt>,
-+E<gt>E<gt> and +E<lt>.  The
++E<gt>E<gt>, and +E<lt>.  The
 mode you specify should match the mode of the original filehandle.
 (Duping a filehandle does not take into account any existing contents of
 stdio buffers.)
@@ -1835,7 +1847,7 @@ parsimonious of file descriptors.  For example:
 
     open(FILEHANDLE, "<&=$fd")
 
-If you open a pipe on the command "-", i.e. either "|-" or "-|", then
+If you open a pipe on the command "-", i.e., either "|-" or "-|", then
 there is an implicit fork done, and the return value of open is the pid
 of the child within the parent process, and 0 within the child
 process.  (Use C<defined($pid)> to determine whether the open was successful.)
@@ -1862,16 +1874,17 @@ Note: on any operation which may do a fork, unflushed buffers remain
 unflushed in both processes, which means you may need to set C<$|> to
 avoid duplicate output.
 
-Using the FileHandle constructor from the FileHandle package,
+Using the constructor from the IO::Handle package (or one of its
+subclasses, such as IO::File or IO::Socket),
 you can generate anonymous filehandles which have the scope of whatever
 variables hold references to them, and automatically close whenever
 and however you leave that scope:
 
-    use FileHandle;
+    use IO::File;
     ...
     sub read_myfile_munged {
        my $ALL = shift;
-       my $handle = new FileHandle;
+       my $handle = new IO::File;
        open($handle, "myfile") or die "myfile: $!";
        $first = <$handle>
            or return ();     # Automatically closed here.
@@ -1881,7 +1894,7 @@ and however you leave that scope:
     }
 
 The filename that is passed to open will have leading and trailing
-whitespace deleted.  In order to open a file with arbitrary weird
+whitespace deleted.  To open a file with arbitrary weird
 characters in it, it's necessary to protect any leading and trailing
 whitespace thusly:
 
@@ -1905,7 +1918,7 @@ See L</seek()> for some details about mixing reading and writing.
 =item opendir DIRHANDLE,EXPR
 
 Opens a directory named EXPR for processing by readdir(), telldir(),
-seekdir(), rewinddir() and closedir().  Returns TRUE if successful.
+seekdir(), rewinddir(), and closedir().  Returns TRUE if successful.
 DIRHANDLEs have their own namespace separate from FILEHANDLEs.
 
 =item ord EXPR
@@ -1961,7 +1974,7 @@ follows:
     @  Null fill to absolute position.
 
 Each letter may optionally be followed by a number which gives a repeat
-count.  With all types except "a", "A", "b", "B", "h" and "H", and "P" the
+count.  With all types except "a", "A", "b", "B", "h", "H", and "P" the
 pack function will gobble up that many values from the LIST.  A * for the
 repeat count means to use however many items are left.  The "a" and "A"
 types gobble just one value, but pack it as a string of length count,
@@ -1977,7 +1990,7 @@ point data written on one machine may not be readable on another - even if
 both use IEEE floating point arithmetic (as the endian-ness of the memory
 representation is not part of the IEEE spec).  Note that Perl uses doubles
 internally for all numeric calculation, and converting from double into
-float and thence back to double again will lose precision (i.e.
+float and thence back to double again will lose precision (i.e.,
 C<unpack("f", pack("f", $foo)>) will not in general equal $foo).
 
 Examples:
@@ -2018,11 +2031,11 @@ Declares the compilation unit as being in the given namespace.  The scope
 of the package declaration is from the declaration itself through the end of
 the enclosing block (the same scope as the local() operator).  All further
 unqualified dynamic identifiers will be in this namespace.  A package
-statement only affects dynamic variables--including those you've used
+statement affects only dynamic variables--including those you've used
 local() on--but I<not> lexical variables created with my().  Typically it
 would be the first declaration in a file to be included by the C<require>
 or C<use> operator.  You can switch into a package in more than one place;
-it merely influences which symbol table is used by the compiler for the
+it influences merely which symbol table is used by the compiler for the
 rest of that block.  You can refer to variables and filehandles in other
 packages by prefixing the identifier with the package name and a double
 colon:  C<$Package::Variable>.  If the package name is null, the C<main>
@@ -2073,7 +2086,7 @@ if successful.  FILEHANDLE may be a scalar variable name, in which case
 the variable contains the name of or a reference to the filehandle, thus introducing one
 level of indirection.  (NOTE: If FILEHANDLE is a variable and the next
 token is a term, it may be misinterpreted as an operator unless you
-interpose a + or put parens around the arguments.)  If FILEHANDLE is
+interpose a + or put parentheses around the arguments.)  If FILEHANDLE is
 omitted, prints by default to standard output (or to the last selected
 output channel--see L</select>).  If LIST is also omitted, prints $_ to
 STDOUT.  To set the default output channel to something other than
@@ -2083,7 +2096,7 @@ subroutine that you call will have one or more of its expressions
 evaluated in a list context.  Also be careful not to follow the print
 keyword with a left parenthesis unless you want the corresponding right
 parenthesis to terminate the arguments to the print--interpose a + or
-put parens around all the arguments.
+put parentheses around all the arguments.
 
 Note that if you're storing FILEHANDLES in an array or other expression,
 you will have to use a block returning its value instead:
@@ -2091,18 +2104,18 @@ you will have to use a block returning its value instead:
     print { $files[$i] } "stuff\n";
     print { $OK ? STDOUT : STDERR } "stuff\n";
 
-=item printf FILEHANDLE LIST
+=item printf FILEHANDLE FORMAT, LIST
 
-=item printf LIST
+=item printf FORMAT, LIST
 
-Equivalent to a "print FILEHANDLE sprintf(LIST)".  The first argument
+Equivalent to a "print FILEHANDLE sprintf(FORMAT, LIST)".  The first argument
 of the list will be interpreted as the printf format.
 
 =item prototype FUNCTION
 
 Returns the prototype of a function as a string (or C<undef> if the
-function has no prototype).  FUNCTION is a reference to the the
-function whose prototype you want to retrieve.
+function has no prototype).  FUNCTION is a reference to, or the name of,
+the function whose prototype you want to retrieve.
 
 =item push ARRAY,LIST
 
@@ -2172,7 +2185,7 @@ directory.  If there are no more entries, returns an undefined value in
 a scalar context or a null list in a list context.
 
 If you're planning to filetest the return values out of a readdir(), you'd
-better prepend the directory in question.  Otherwise, since we didn't
+better prepend the directory in question.  Otherwise, because we didn't
 chdir() there, it would have been testing the wrong file.
 
     opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!";
@@ -2256,7 +2269,7 @@ See also L<perlref>.
 =item rename OLDNAME,NEWNAME
 
 Changes the name of a file.  Returns 1 for success, 0 otherwise.  Will
-not work across filesystem boundaries.
+not work across file system boundaries.
 
 =item require EXPR
 
@@ -2315,16 +2328,16 @@ variables and reset ?? searches so that they work again.  The
 expression is interpreted as a list of single characters (hyphens
 allowed for ranges).  All variables and arrays beginning with one of
 those letters are reset to their pristine state.  If the expression is
-omitted, one-match searches (?pattern?) are reset to match again.  Only
-resets variables or searches in the current package.  Always returns
+omitted, one-match searches (?pattern?) are reset to match again.  Resets
+only variables or searches in the current package.  Always returns
 1.  Examples:
 
     reset 'X';         # reset all X variables
     reset 'a-z';       # reset lower case variables
     reset;             # just reset ?? searches
 
-Resetting "A-Z" is not recommended since you'll wipe out your
-ARGV and ENV arrays.  Only resets package variables--lexical variables
+Resetting "A-Z" is not recommended because you'll wipe out your
+ARGV and ENV arrays.  Resets only package variables--lexical variables
 are unaffected, but they clean themselves up on scope exit anyway,
 so you'll probably want to use them instead.  See L</my>.
 
@@ -2405,7 +2418,7 @@ EOF on your read, and then sleep for a while, you might have to stick in a
 seek() to reset things.  First the simple trick listed above to clear the
 filepointer.  The seek() doesn't change the current position, but it
 I<does> clear the end-of-file condition on the handle, so that the next
-C<E<lt>FILEE<gt>> makes Perl try again to read something.  Hopefully.
+C<E<lt>FILEE<gt>> makes Perl try again to read something.  We hope.
 
 If that doesn't work (some stdios are particularly cantankerous), then
 you may need something more like this:
@@ -2455,7 +2468,7 @@ methods, preferring to write the last example as:
 
 =item select RBITS,WBITS,EBITS,TIMEOUT
 
-This calls the select(2) system call with the bitmasks specified, which
+This calls the select(2) system call with the bit masks specified, which
 can be constructed using fileno() and vec(), along these lines:
 
     $rin = $win = $ein = '';
@@ -2485,10 +2498,10 @@ or to block until something becomes ready just do this
 
     $nfound = select($rout=$rin, $wout=$win, $eout=$ein, undef);
 
-Most systems do not both to return anything useful in $timeleft, so
+Most systems do not bother to return anything useful in $timeleft, so
 calling select() in a scalar context just returns $nfound.
 
-Any of the bitmasks can also be undef.  The timeout, if specified, is
+Any of the bit masks can also be undef.  The timeout, if specified, is
 in seconds, which may be fractional.  Note: not all implementations are
 capable of returning the $timeleft.  If not, they always return
 $timeleft equal to the supplied $timeout.
@@ -2543,7 +2556,7 @@ See L<perlipc/"UDP: Message Passing"> for examples.
 
 Sets the current process group for the specified PID, 0 for the current
 process.  Will produce a fatal error if used on a machine that doesn't
-implement setpgrp(2).  If the arguments are ommitted, it defaults to
+implement setpgrp(2).  If the arguments are omitted, it defaults to
 0,0.  Note that the POSIX version of setpgrp() does not accept any
 arguments, so only setpgrp 0,0 is portable.
 
@@ -2613,7 +2626,7 @@ returns sine of $_.
 Causes the script to sleep for EXPR seconds, or forever if no EXPR.
 May be interrupted by sending the process a SIGALRM.  Returns the
 number of seconds actually slept.  You probably cannot mix alarm() and
-sleep() calls, since sleep() is often implemented using alarm().
+sleep() calls, because sleep() is often implemented using alarm().
 
 On some older systems, it may sleep up to a full second less than what
 you requested, depending on how it counts seconds.  Most modern systems
@@ -2623,17 +2636,19 @@ For delays of finer granularity than one second, you may use Perl's
 syscall() interface to access setitimer(2) if your system supports it, 
 or else see L</select()> below.  
 
+See also the POSIX module's sigpause() function.
+
 =item socket SOCKET,DOMAIN,TYPE,PROTOCOL
 
 Opens a socket of the specified kind and attaches it to filehandle
-SOCKET.  DOMAIN, TYPE and PROTOCOL are specified the same as for the
+SOCKET.  DOMAIN, TYPE, and PROTOCOL are specified the same as for the
 system call of the same name.  You should "use Socket;" first to get
 the proper definitions imported.  See the example in L<perlipc/"Sockets: Client/Server Communication">.
 
 =item socketpair SOCKET1,SOCKET2,DOMAIN,TYPE,PROTOCOL
 
 Creates an unnamed pair of sockets in the specified domain, of the
-specified type.  DOMAIN, TYPE and PROTOCOL are specified the same as
+specified type.  DOMAIN, TYPE, and PROTOCOL are specified the same as
 for the system call of the same name.  If unimplemented, yields a fatal
 error.  Returns TRUE if successful.
 
@@ -2688,7 +2703,7 @@ Examples:
     @sortedclass = sort byage @class;
 
     # this sorts the %age associative arrays by value 
-    # instead of key using an inline function
+    # instead of key using an in-line function
     @eldest = sort { $age{$b} <=> $age{$a} } keys %age;
 
     sub backwards { $b cmp $a; }
@@ -2765,7 +2780,7 @@ Removes the elements designated by OFFSET and LENGTH from an array, and
 replaces them with the elements of LIST, if any.  Returns the elements
 removed from the array.  The array grows or shrinks as necessary.  If
 LENGTH is omitted, removes everything from OFFSET onward.  The
-following equivalencies hold (assuming C<$[ == 0>):
+following equivalences hold (assuming C<$[ == 0>):
 
     push(@a,$x,$y)     splice(@a,$#a+1,0,$x,$y)
     pop(@a)            splice(@a,-1)
@@ -2820,7 +2835,7 @@ characters at each point it matches that way.  For example:
 
 produces the output 'h:i:t:h:e:r:e'.
 
-The LIMIT parameter can be used to partially split a line
+The LIMIT parameter can be used to split a line partially
 
     ($login, $passwd, $remainder) = split(/:/, $_, 3);
 
@@ -2869,7 +2884,7 @@ Example:
 (Note that $shell above will still have a newline on it.  See L</chop>, 
 L</chomp>, and L</join>.)
 
-=item sprintf FORMAT,LIST
+=item sprintf FORMAT, LIST
 
 Returns a string formatted by the usual printf conventions of the C
 language.  See L<sprintf(3)> or L<printf(3)> on your system for details.
@@ -2888,9 +2903,9 @@ root of $_.
 =item srand EXPR
 
 Sets the random number seed for the C<rand> operator.  If EXPR is omitted,
-uses a semirandom value based on the current time and process ID, among
+uses a semi-random value based on the current time and process ID, among
 other things.  Of course, you'd need something much more random than that for
-cryptographic purposes, since it's easy to guess the current time.
+cryptographic purposes, because it's easy to guess the current time.
 Checksumming the compressed output of rapidly changing operating system
 status programs is the usual method.  Examples are posted regularly to
 the comp.security.unix newsgroup.
@@ -2919,13 +2934,13 @@ meaning of the fields:
   mode     file mode  (type and permissions)
   nlink            number of (hard) links to the file 
   uid      numeric user ID of file's owner 
-  gid      numer group ID of file's owner 
+  gid      numeric group ID of file's owner 
   rdev     the device identifier (special files only)
   size     total size of file, in bytes 
   atime            last access time since the epoch
   mtime            last modify time since the epoch
   ctime            inode change time (NOT creation type!) since the epoch
-  blksize   preferred blocksize for file system I/O
+  blksize   preferred block size for file system I/O
   blocks    actual number of blocks allocated
 
 (The epoch was at 00:00 January 1, 1970 GMT.)
@@ -2938,7 +2953,7 @@ last stat or filetest are returned.  Example:
        print "$file is executable NFS file\n";
     }
 
-(This only works on machines for which the device number is negative under NFS.)
+(This works on machines only for which the device number is negative under NFS.)
 
 =item study SCALAR
 
@@ -2949,7 +2964,7 @@ doing many pattern matches on the string before it is next modified.
 This may or may not save time, depending on the nature and number of
 patterns you are searching on, and on the distribution of character
 frequencies in the string to be searched--you probably want to compare
-runtimes with and without it to see which runs faster.  Those loops
+run times with and without it to see which runs faster.  Those loops
 which scan for many short constant strings (including the constant
 parts of more complex patterns) will benefit most.  You may have only
 one study active at a time--if you study a different scalar the first
@@ -2994,7 +3009,7 @@ out the names of those files that contain a match:
     @ARGV = @files;
     undef $/;
     eval $search;              # this screams
-    $/ = "\n";         # put back to normal input delim
+    $/ = "\n";         # put back to normal input delimiter
     foreach $file (sort keys(%seen)) {
        print $file, "\n";
     }
@@ -3053,7 +3068,7 @@ like numbers.
     require 'syscall.ph';              # may need to run h2ph
     syscall(&SYS_write, fileno(STDOUT), "hi there\n", 9);
 
-Note that Perl only supports passing of up to 14 arguments to your system call,
+Note that Perl supports passing of up to only 14 arguments to your system call,
 which in practice should usually suffice.
 
 =item sysopen FILEHANDLE,FILENAME,MODE
@@ -3103,7 +3118,7 @@ Note that argument processing varies depending on the number of
 arguments.  The return value is the exit status of the program as
 returned by the wait() call.  To get the actual exit value divide by
 256.  See also L</exec>.  This is I<NOT> what you want to use to capture 
-the output from a command, for that you should merely use backticks, as
+the output from a command, for that you should use merely back-ticks, as
 described in L<perlop/"`STRING`">.
 
 =item syswrite FILEHANDLE,SCALAR,LENGTH,OFFSET
@@ -3249,13 +3264,13 @@ If EXPR is omitted, uses $_.
 =item umask
 
 Sets the umask for the process and returns the old one.  If EXPR is
-omitted, merely returns current umask.
+omitted, returns merely the current umask.
 
 =item undef EXPR
 
 =item undef
 
-Undefines the value of EXPR, which must be an lvalue.  Use only on a
+Undefines the value of EXPR, which must be an lvalue.  Use on only a
 scalar value, an entire array, or a subroutine name (using "&").  (Using undef()
 will probably not do what you expect on most predefined variables or
 DBM list values, so don't do that.)  Always returns the undefined value.  You can omit
@@ -3292,7 +3307,7 @@ If LIST is omitted, uses $_.
 
 Unpack does the reverse of pack: it takes a string representing a
 structure and expands it out into a list value, returning the array
-value.  (In a scalar context, it merely returns the first value
+value.  (In a scalar context, it returns merely the first value
 produced.)  The TEMPLATE has the same format as in the pack function.
 Here's a subroutine that does substring:
 
@@ -3391,12 +3406,12 @@ are also implemented this way.  Currently implemented pragmas are:
     use strict  qw(subs vars refs);
     use subs    qw(afunc blurfl);
 
-These pseudomodules import semantics into the current block scope, unlike
+These pseudo-modules import semantics into the current block scope, unlike
 ordinary modules, which import symbols into the current package (which are
 effective through the end of the file).
 
 There's a corresponding "no" command that unimports meanings imported
-by use, i.e. it calls C<unimport Module LIST> instead of C<import>.
+by use, i.e., it calls C<unimport Module LIST> instead of C<import>.
 
     no integer;
     no strict 'refs';
@@ -3428,16 +3443,16 @@ on the same array.  See also keys(), each(), and sort().
 =item vec EXPR,OFFSET,BITS
 
 Treats the string in EXPR as a vector of unsigned integers, and
-returns the value of the bitfield specified by OFFSET.  BITS specifies
+returns the value of the bit field specified by OFFSET.  BITS specifies
 the number of bits that are reserved for each entry in the bit
 vector. This must be a power of two from 1 to 32. vec() may also be
-assigned to, in which case parens are needed to give the expression
+assigned to, in which case parentheses are needed to give the expression
 the correct precedence as in
 
     vec($image, $max_x * $x + $y, 8) = 3;
 
 Vectors created with vec() can also be manipulated with the logical
-operators |, & and ^, which will assume a bit vector operation is
+operators |, &, and ^, which will assume a bit vector operation is
 desired when both operands are strings.
 
 To transform a bit vector into a string or array of 0's and 1's, use these:
@@ -3459,12 +3474,12 @@ Waits for a particular child process to terminate and returns the pid
 of the deceased process, or -1 if there is no such child process.  The
 status is returned in C<$?>.  If you say
 
-    use POSIX ":wait_h";
+    use POSIX ":sys_wait_h";
     ...
     waitpid(-1,&WNOHANG);
 
 then you can do a non-blocking wait for any process.  Non-blocking wait
-is only available on machines supporting either the waitpid(2) or
+is available on machines supporting either the waitpid(2) or
 wait4(2) system calls.  However, waiting for a particular pid with
 FLAGS of 0 is implemented everywhere.  (Perl emulates the system call
 by remembering the status values of processes that have exited but have
index 251d959..6743032 100644 (file)
@@ -8,7 +8,7 @@ This document attempts to describe some of the internal functions of the
 Perl executable.  It is far from complete and probably contains many errors.
 Please refer any questions or comments to the author below.
 
-=head1 Datatypes
+=head2 Datatypes
 
 Perl has three typedefs that handle Perl's three main data types:
 
@@ -20,13 +20,13 @@ Each typedef has specific routines that manipulate the various data types.
 
 =head2 What is an "IV"?
 
-Perl uses a special typedef IV which is large enough to hold either an
-integer or a pointer.
+Perl uses a special typedef IV which is a simple integer type that is
+guaranteed to be large enough to hold a pointer (as well as an integer).
 
 Perl also uses two special typedefs, I32 and I16, which will always be at
 least 32-bits and 16-bits long, respectively.
 
-=head2 Working with SVs
+=head2 Working with SV's
 
 An SV can be created and loaded with one command.  There are four types of
 values that can be loaded: an integer value (IV), a double (NV), a string,
@@ -54,6 +54,14 @@ argument to C<newSVpv>.  Be warned, though, that Perl will determine the
 string's length by using C<strlen>, which depends on the string terminating
 with a NUL character.
 
+All SV's that will contain strings should, but need not, be terminated
+with a NUL character.  If it is not NUL-terminated there is a risk of
+core dumps and corruptions from code which passes the string to C
+functions or system calls which expect a NUL-terminated string.
+Perl's own functions typically add a trailing NUL for this reason.
+Nevertheless, you should be very careful when you pass a string stored
+in an SV to a C function or system call.
+
 To access the actual value that an SV points to, you can use the macros:
 
     SvIV(SV*)
@@ -67,9 +75,9 @@ In the C<SvPV> macro, the length of the string returned is placed into the
 variable C<len> (this is a macro, so you do I<not> use C<&len>).  If you do not
 care what the length of the data is, use the global variable C<na>.  Remember,
 however, that Perl allows arbitrary strings of data that may both contain
-NULs and not be terminated by a NUL.
+NUL's and might not be terminated by a NUL.
 
-If you simply want to know if the scalar value is TRUE, you can use:
+If you want to know simply if the scalar value is TRUE, you can use:
 
     SvTRUE(SV*)
 
@@ -80,7 +88,9 @@ Perl to allocate more memory for your SV, you can use the macro
 
 which will determine if more memory needs to be allocated.  If so, it will
 call the function C<sv_grow>.  Note that C<SvGROW> can only increase, not
-decrease, the allocated memory of an SV.
+decrease, the allocated memory of an SV and that it does not automatically
+add a byte for the a trailing NUL (perl's own string functions typically do
+SvGROW(sv, len + 1)).
 
 If you have an SV and want to know what kind of data Perl thinks is stored
 in it, you can use the following macros to check the type of SV you have.
@@ -118,7 +128,7 @@ be interpreted as a string.
 If you know the name of a scalar variable, you can get a pointer to its SV
 by using the following:
 
-    SV*  perl_get_sv("varname", FALSE);
+    SV*  perl_get_sv("package::varname", FALSE);
 
 This returns NULL if the variable does not exist.
 
@@ -146,16 +156,16 @@ Take this code:
 This code tries to return a new SV (which contains the value 42) if it should
 return a real value, or undef otherwise.  Instead it has returned a null
 pointer which, somewhere down the line, will cause a segmentation violation,
-bus error, or just plain weird results.  Change the zero to C<&sv_undef> in
-the first line and all will be well.
+bus error, or just weird results.  Change the zero to C<&sv_undef> in the first
+line and all will be well.
 
 To free an SV that you've created, call C<SvREFCNT_dec(SV*)>.  Normally this
-call is not necessary.  See the section on L<Mortality>.
+call is not necessary (see the section on L<Mortality>).
 
 =head2 What's Really Stored in an SV?
 
 Recall that the usual method of determining the type of scalar you have is
-to use C<Sv*OK> macros.  Since a scalar can be both a number and a string,
+to use C<Sv*OK> macros.  Because a scalar can be both a number and a string,
 usually these macros will always return TRUE and calling the C<Sv*V>
 macros will do the appropriate conversion of string to integer/double or
 integer/double to string.
@@ -170,23 +180,23 @@ pointer in an SV, you can use the following three macros instead:
 These will tell you if you truly have an integer, double, or string pointer
 stored in your SV.  The "p" stands for private.
 
-In general, though, it's best to just use the C<Sv*V> macros.
+In general, though, it's best just to use the C<Sv*V> macros.
 
-=head2 Working with AVs
+=head2 Working with AV's
 
-There are two ways to create and load an AV.  The first method just creates
+There are two ways to create and load an AV.  The first method creates just
 an empty AV:
 
     AV*  newAV();
 
-The second method both creates the AV and initially populates it with SVs:
+The second method both creates the AV and initially populates it with SV's:
 
     AV*  av_make(I32 num, SV **ptr);
 
-The second argument points to an array containing C<num> C<SV*>s.  Once the
-AV has been created, the SVs can be destroyed, if so desired.
+The second argument points to an array containing C<num> C<SV*>'s.  Once the
+AV has been created, the SV's can be destroyed, if so desired.
 
-Once the AV has been created, the following operations are possible on AVs:
+Once the AV has been created, the following operations are possible on AV's:
 
     void  av_push(AV*, SV*);
     SV*   av_pop(AV*);
@@ -200,63 +210,77 @@ to these new elements.
 
 Here are some other functions:
 
-    I32   av_len(AV*); /* Returns highest index value in array */
-
+    I32   av_len(AV*);
     SV**  av_fetch(AV*, I32 key, I32 lval);
-            /* Fetches value at key offset, but it stores an undef value
-               at the offset if lval is non-zero */
     SV**  av_store(AV*, I32 key, SV* val);
-            /* Stores val at offset key */
 
-Take note that C<av_fetch> and C<av_store> return C<SV**>s, not C<SV*>s.
+The C<av_len> function returns the highest index value in array (just
+like $#array in Perl).  If the array is empty, -1 is returned.  The
+C<av_fetch> function returns the value at index C<key>, but if C<lval>
+is non-zero, then C<av_fetch> will store an undef value at that index.
+The C<av_store> function stores the value C<val> at index C<key>.
+note that C<av_fetch> and C<av_store> both return C<SV**>'s, not C<SV*>'s
+as their return value.
 
     void  av_clear(AV*);
-            /* Clear out all elements, but leave the array */
     void  av_undef(AV*);
-            /* Undefines the array, removing all elements */
     void  av_extend(AV*, I32 key);
-            /* Extend the array to a total of key elements */
+
+The C<av_clear> function deletes all the elements in the AV* array, but
+does not actually delete the array itself.  The C<av_undef> function will
+delete all the elements in the array plus the array itself.  The
+C<av_extend> function extends the array so that it contains C<key>
+elements.  If C<key> is less than the current length of the array, then
+nothing is done.
 
 If you know the name of an array variable, you can get a pointer to its AV
 by using the following:
 
-    AV*  perl_get_av("varname", FALSE);
+    AV*  perl_get_av("package::varname", FALSE);
 
 This returns NULL if the variable does not exist.
 
-=head2 Working with HVs
+=head2 Working with HV's
 
 To create an HV, you use the following routine:
 
     HV*  newHV();
 
-Once the HV has been created, the following operations are possible on HVs:
+Once the HV has been created, the following operations are possible on HV's:
 
     SV**  hv_store(HV*, char* key, U32 klen, SV* val, U32 hash);
     SV**  hv_fetch(HV*, char* key, U32 klen, I32 lval);
 
-The C<klen> parameter is the length of the key being passed in.  The C<val>
-argument contains the SV pointer to the scalar being stored, and C<hash> is
-the pre-computed hash value (zero if you want C<hv_store> to calculate it
-for you).  The C<lval> parameter indicates whether this fetch is actually a
-part of a store operation.
+The C<klen> parameter is the length of the key being passed in (Note that
+you cannot pass 0 in as a value of C<klen> to tell Perl to measure the
+length of the key).  The C<val> argument contains the SV pointer to the
+scalar being stored, and C<hash> is the pre-computed hash value (zero if
+you want C<hv_store> to calculate it for you).  The C<lval> parameter
+indicates whether this fetch is actually a part of a store operation, in
+which case a new undefined value will be added to the HV with the supplied
+key and C<hv_fetch> will return as if the value had already existed.
 
-Remember that C<hv_store> and C<hv_fetch> return C<SV**>s and not just
-C<SV*>.  In order to access the scalar value, you must first dereference
-the return value.  However, you should check to make sure that the return
-value is not NULL before dereferencing it.
+Remember that C<hv_store> and C<hv_fetch> return C<SV**>'s and not just
+C<SV*>.  To access the scalar value, you must first dereference the return
+value.  However, you should check to make sure that the return value is
+not NULL before dereferencing it.
 
 These two functions check if a hash table entry exists, and deletes it.
 
     bool  hv_exists(HV*, char* key, U32 klen);
     SV*   hv_delete(HV*, char* key, U32 klen, I32 flags);
 
+If C<flags> does not include the C<G_DISCARD> flag then C<hv_delete> will
+create and return a mortal copy of the deleted value.
+
 And more miscellaneous functions:
 
     void   hv_clear(HV*);
-            /* Clears all entries in hash table */
     void   hv_undef(HV*);
-            /* Undefines the hash table */
+
+Like their AV counterparts, C<hv_clear> deletes all the entries in the hash
+table but does not actually delete the hash table.  The C<hv_undef> deletes
+both the entries and the hash table itself.
 
 Perl keeps the actual data in linked list of structures with a typedef of HE.
 These contain the actual key and value pointers (plus extra administrative
@@ -284,11 +308,11 @@ specified below.
 If you know the name of a hash variable, you can get a pointer to its HV
 by using the following:
 
-    HV*  perl_get_hv("varname", FALSE);
+    HV*  perl_get_hv("package::varname", FALSE);
 
 This returns NULL if the variable does not exist.
 
-The hash algorithm, for those who are interested, is:
+The hash algorithm is defined in the PERL_HASH(hash, key, klen) macro:
 
     i = klen;
     hash = 0;
@@ -301,12 +325,16 @@ The hash algorithm, for those who are interested, is:
 References are a special type of scalar that point to other data types
 (including references).
 
-To create a reference, use the following command:
+To create a reference, use the following functions:
 
-    SV* newRV((SV*) thing);
+    SV* newRV_inc((SV*) thing);
+    SV* newRV_noinc((SV*) thing);
 
-The C<thing> argument can be any of an C<SV*>, C<AV*>, or C<HV*>.  Once
-you have a reference, you can use the following macro to dereference the
+The C<thing> argument can be any of an C<SV*>, C<AV*>, or C<HV*>.  The
+functions are identical except that C<newRV_inc> increments the
+reference count of C<thing>, while C<newRV_noinc> does not.  (For
+historical reasons, "newRV" is a synonym for "newRV_inc".)  Once you
+have a reference, you can use the following macro to dereference the
 reference:
 
     SvRV(SV*)
@@ -318,8 +346,8 @@ To determine if an SV is a reference, you can use the following macro:
 
     SvROK(SV*)
 
-To actually discover what the reference refers to, you must use the following
-macro and then check the value returned.
+To discover what type of value the reference refers to, you must use the
+following macro and then check the value returned.
 
     SvTYPE(SvRV(SV*))
 
@@ -328,10 +356,14 @@ The most useful types that will be returned are:
     SVt_IV    Scalar
     SVt_NV    Scalar
     SVt_PV    Scalar
+    SVt_RV    Scalar
     SVt_PVAV  Array
     SVt_PVHV  Hash
     SVt_PVCV  Code
-    SVt_PVMG  Blessed Scalar
+    SVt_PVGV  Glob (possible a file handle)
+    SVt_PVMG  Blessed or Magical Scalar
+
+    See the sv.h header file for more details.
 
 =head2 Blessed References and Class Objects
 
@@ -363,8 +395,8 @@ if classname is non-null.
        SV* sv_setref_iv(SV* rv, char* classname, IV iv);
        SV* sv_setref_nv(SV* rv, char* classname, NV iv);
 
-Copies pointer (I<not a string!>) into an SV whose reference is rv.
-SV is blessed if classname is non-null.
+Copies the pointer value (I<the address, not the string!>) into an SV whose
+reference is rv.  SV is blessed if classname is non-null.
 
        SV* sv_setref_pv(SV* rv, char* classname, PV iv);
 
@@ -377,228 +409,32 @@ SV is blessed if classname is non-null.
        int sv_isa(SV* sv, char* name);
        int sv_isobject(SV* sv);
 
-=head1 Creating New Variables
+=head2 Creating New Variables
 
-To create a new Perl variable, which can be accessed from your Perl script,
-use the following routines, depending on the variable type.
+To create a new Perl variable with an undef value which can be accessed from
+your Perl script, use the following routines, depending on the variable type.
 
-    SV*  perl_get_sv("varname", TRUE);
-    AV*  perl_get_av("varname", TRUE);
-    HV*  perl_get_hv("varname", TRUE);
+    SV*  perl_get_sv("package::varname", TRUE);
+    AV*  perl_get_av("package::varname", TRUE);
+    HV*  perl_get_hv("package::varname", TRUE);
 
 Notice the use of TRUE as the second parameter.  The new variable can now
 be set, using the routines appropriate to the data type.
 
-There are additional bits that may be OR'ed with the TRUE argument to enable
-certain extra features.  Those bits are:
+There are additional macros whose values may be bitwise OR'ed with the
+C<TRUE> argument to enable certain extra features.  Those bits are:
 
-    0x02  Marks the variable as multiply defined, thus preventing the
-         "Identifier <varname> used only once: possible typo" warning.
-    0x04  Issues a "Had to create <varname> unexpectedly" warning if
-         the variable didn't actually exist.  This is useful if
-         you expected the variable to already exist and want to propagate
-         this warning back to the user.
+    GV_ADDMULTI        Marks the variable as multiply defined, thus preventing the
+               "Indentifier <varname> used only once: possible typo" warning.
+    GV_ADDWARN Issues a "Had to create <varname> unexpectedly" warning if
+               the variable didn't actually exist.  This is useful if
+               you expected the variable to exist already and want to
+               propagate this warning back to the user.
 
 If the C<varname> argument does not contain a package specifier, it is
 created in the current package.
 
-=head1 XSUBs and the Argument Stack
-
-The XSUB mechanism is a simple way for Perl programs to access C subroutines.
-An XSUB routine will have a stack that contains the arguments from the Perl
-program, and a way to map from the Perl data structures to a C equivalent.
-
-The stack arguments are accessible through the C<ST(n)> macro, which returns
-the C<n>'th stack argument.  Argument 0 is the first argument passed in the
-Perl subroutine call.  These arguments are C<SV*>, and can be used anywhere
-an C<SV*> is used.
-
-Most of the time, output from the C routine can be handled through use of
-the RETVAL and OUTPUT directives.  However, there are some cases where the
-argument stack is not already long enough to handle all the return values.
-An example is the POSIX tzname() call, which takes no arguments, but returns
-two, the local timezone's standard and summer time abbreviations.
-
-To handle this situation, the PPCODE directive is used and the stack is
-extended using the macro:
-
-    EXTEND(sp, num);
-
-where C<sp> is the stack pointer, and C<num> is the number of elements the
-stack should be extended by.
-
-Now that there is room on the stack, values can be pushed on it using the
-macros to push IVs, doubles, strings, and SV pointers respectively:
-
-    PUSHi(IV)
-    PUSHn(double)
-    PUSHp(char*, I32)
-    PUSHs(SV*)
-
-And now the Perl program calling C<tzname>, the two values will be assigned
-as in:
-
-    ($standard_abbrev, $summer_abbrev) = POSIX::tzname;
-
-An alternate (and possibly simpler) method to pushing values on the stack is
-to use the macros:
-
-    XPUSHi(IV)
-    XPUSHn(double)
-    XPUSHp(char*, I32)
-    XPUSHs(SV*)
-
-These macros automatically adjust the stack for you, if needed.  Thus, you
-do not need to call C<EXTEND> to extend the stack.
-
-For more information, consult L<perlxs>.
-
-=head1 Localizing Changes
-
-Perl has a very handy construction
-
-  {
-    local $var = 2;
-    ...
-  }
-
-This construction is I<approximately> equivalent to
-
-  {
-    my $oldvar = $var;
-    $var = 2;
-    ...
-    $var = $oldvar;
-  }
-
-The biggest difference is that the first construction would would
-reinstate the initial value of $var, irrespective of how control exits
-the block: C<goto>, C<return>, C<die>/C<eval> etc. It is a little bit
-more efficient as well.
-
-There is a way to achieve a similar task from C via Perl API: create a
-I<pseudo-block>, and arrange for some changes to be automatically
-undone at the end of it, either explicit, or via a non-local exit (via
-die()). A I<block>-like construct is created by a pair of
-C<ENTER>/C<LEAVE> macros (see L<perlcall/EXAMPLE/"Returning a
-Scalar">).  Such a construct may be created specially for some
-important localized task, or an existing one (like boundaries of
-enclosing Perl subroutine/block, or an existing pair for freeing TMPs)
-may be used. (In the second case the overhead of additional
-localization must be almost negligible.) Note that any XSUB is
-automatically enclosed in an C<ENTER>/C<LEAVE> pair.
-
-Inside such a I<pseudo-block> the following service is available:
-
-=over
-
-=item C<SAVEINT(int i)>
-
-=item C<SAVEIV(IV i)>
-
-=item C<SAVEI16(I16 i)>
-
-=item C<SAVEI32(I32 i)>
-
-=item C<SAVELONG(long i)>
-
-These macros arrange things to restore the value of integer variable
-C<i> at the end of enclosing I<pseudo-block>.
-
-=item C<SAVESPTR(p)>
-
-=item C<SAVEPPTR(s)>
-
-These macros arrange things to restore the value of pointers C<s> and
-C<p>. C<p> must be a pointer of a type which survives conversion to
-C<SV*> and back, C<s> should be able to survive conversion to C<char*>
-and back.
-
-=item C<SAVEFREESV(SV *sv)>
-
-The refcount of C<sv> would be decremented at the end of
-I<pseudo-block>. This is similar to C<sv_2mortal>, which should (?) be
-used instead.
-
-=item C<SAVEFREEOP(OP *op)>
-
-The C<OP *> is op_free()ed at the end of I<pseudo-block>.
-
-=item C<SAVEFREEPV(p)>
-
-The chunk of memory which is pointed to by C<p> is Safefree()ed at the
-end of I<pseudo-block>.
-
-=item C<SAVECLEARSV(SV *sv)>
-
-Clears a slot in the current scratchpad which corresponds to C<sv> at
-the end of I<pseudo-block>.
-
-=item C<SAVEDELETE(HV *hv, char *key, I32 length)>
-
-The key C<key> of C<hv> is deleted at the end of I<pseudo-block>. The
-string pointed to by C<key> is Safefree()ed.  If one has a I<key> in
-short-lived storage, the corresponding string may be reallocated like
-this:
-
-  SAVEDELETE(defstash, savepv(tmpbuf), strlen(tmpbuf));
-
-=item C<SAVEDESTRUCTOR(f,p)>
-
-At the end of I<pseudo-block> the function C<f> is called with the
-only argument (of type C<void*>) C<p>.
-
-=item C<SAVESTACK_POS()>
-
-The current offset on the Perl internal stack (cf. C<SP>) is restored
-at the end of I<pseudo-block>.
-
-=back
-
-The following API list contains functions, thus one needs to
-provide pointers to the modifiable data explicitly (either C pointers,
-or Perlish C<GV *>s):
-
-=over
-
-=item C<SV* save_scalar(GV *gv)>
-
-Equivalent to Perl code C<local $gv>.
-
-=item C<AV* save_ary(GV *gv)>
-
-=item C<HV* save_hash(GV *gv)>
-
-Similar to C<save_scalar>, but localize C<@gv> and C<%gv>.
-
-=item C<void save_item(SV *item)>
-
-Duplicates the current value of C<SV>, on the exit from the current
-C<ENTER>/C<LEAVE> I<pseudo-block> will restore the value of C<SV>
-using the stored value.
-
-=item C<void save_list(SV **sarg, I32 maxsarg)>
-
-A variant of C<save_item> which takes multiple arguments via an array
-C<sarg> of C<SV*> of length C<maxsarg>.
-
-=item C<SV* save_svref(SV **sptr)>
-
-Similar to C<save_scalar>, but will reinstate a C<SV *>.
-
-=item C<void save_aptr(AV **aptr)>
-
-=item C<void save_hptr(HV **hptr)>
-
-Similar to C<save_svref>, but localize C<AV *> and C<HV *>.
-
-=item C<void save_nogv(GV *gv)>
-
-Will postpone destruction of a I<stub> glob.
-
-=back
-
-=head1 Mortality
+=head2 Reference Counts and Mortality
 
 Perl uses an reference count-driven garbage collection mechanism. SV's,
 AV's, or HV's (xV for short in the following) start their life with a
@@ -606,38 +442,45 @@ reference count of 1.  If the reference count of an xV ever drops to 0,
 then they will be destroyed and their memory made available for reuse.
 
 This normally doesn't happen at the Perl level unless a variable is
-undef'ed.  At the internal level, however, reference counts can be
+undef'ed or the last variable holding a reference to it is changed or
+overwritten.  At the internal level, however, reference counts can be
 manipulated with the following macros:
 
     int SvREFCNT(SV* sv);
-    void SvREFCNT_inc(SV* sv);
+    SV* SvREFCNT_inc(SV* sv);
     void SvREFCNT_dec(SV* sv);
 
 However, there is one other function which manipulates the reference
-count of its argument.  The C<newRV> function, as you should recall,
-creates a reference to the specified argument.  As a side effect, it
-increments the argument's reference count, which is ok in most
-circumstances.  But imagine you want to return a reference from an XS
+count of its argument.  The C<newRV_inc> function, as you should
+recall, creates a reference to the specified argument.  As a side
+effect, it increments the argument's reference count.  If this is not
+what you want, use C<newRV_noinc> instead.
+
+For example, imagine you want to return a reference from an XSUB
 function.  You create a new SV which initially has a reference count
-of 1.  Then you call C<newRV>, passing the just-created SV.  This returns
-the reference as a new SV, but the reference count of the SV you passed
-to C<newRV> has been incremented to 2.  Now you return the reference and
-forget about the SV.  But Perl hasn't!  Whenever the returned reference
-is destroyed, the reference count of the original SV is decreased to 1
-and nothing happens.  The SV will hang around without any way to access
-it until Perl itself terminates.  This is a memory leak.
-
-The correct procedure, then, is to call C<SvREFCNT_dec> on the SV after
-C<newRV> has returned.  Then, if and when the reference is destroyed,
-the reference count of the SV will go to 0 and also be destroyed, stopping
+of one.  Then you call C<newRV_inc>, passing the just-created SV.
+This returns the reference as a new SV, but the reference count of the
+SV you passed to C<newRV_inc> has been incremented to two.  Now you
+return the reference and forget about the SV.  But Perl hasn't!
+Whenever the returned reference is destroyed, the reference count of
+the original SV is decreased to one and nothing happens.  The SV will
+hang around without any way to access it until Perl itself terminates.
+This is a memory leak.
+
+The correct procedure, then, is to use C<newRV_noinc> instead of
+C<newRV_inc>.  Then, if and when the last reference is destroyed, the
+reference count of the SV will go to 0 and also be destroyed, stopping
 any memory leak.
 
-There are some convenience functions available that can help with this
-process.  These functions introduce the concept of "mortality".  An xV
-that is mortal has had its reference count marked to be decremented,
-but not actually decremented, until the "current context" is left.
-Generally the "current context" means a single Perl statement, such as
-a call to an XSUB function.
+There are some convenience functions available that can help with the
+destruction of old xV objects.  These functions introduce the concept
+of "mortality".  An xV that is mortal has had its reference count
+marked to be decremented, but not actually decremented, until "a short
+time later".  Generally the term "short time later" means a single
+Perl statement, such as a call to an XSUB function.  The actual
+determinant for when mortal xV's have their reference count
+decremented depends on two macros, SAVETMPS and FREETMPS.  Take a look
+at L<perlcall> and L<perlxs> for more details on these macros.
 
 "Mortalization" then is at its simplest a deferred C<SvREFCNT_dec>.
 However, if you mortalize a variable twice, the reference count will
@@ -645,8 +488,7 @@ later be decremented twice.
 
 You should be careful about creating mortal variables.  Strange things
 can happen if you make the same value mortal within multiple contexts,
-or if you make a variable mortal multiple times.  Doing the latter can
-cause a variable to become invalid prematurely.
+or if you make a variable mortal multiple times.
 
 To create a mortal variable, use the functions:
 
@@ -654,25 +496,15 @@ To create a mortal variable, use the functions:
     SV*  sv_2mortal(SV*)
     SV*  sv_mortalcopy(SV*)
 
-The first call creates a mortal SV, the second converts an existing SV to
-a mortal SV, the third creates a mortal copy of an existing SV (possibly
-destroying it in the process).
+The first call creates a mortal SV, the second converts an existing
+SV to a mortal SV (and thus defers a call to C<SvREFCNT_dec>), and the
+third creates a mortal copy of an existing SV.
 
-The mortal routines are not just for SVs -- AVs and HVs can be made mortal
-by passing their address (and casting them to C<SV*>) to the C<sv_2mortal> or
+The mortal routines are not for just SV's -- AV's and HV's can be made
+mortal by passing their address (casted to C<SV*>) to the C<sv_2mortal> or
 C<sv_mortalcopy> routines.
 
-I<From Ilya:>
-Beware that the sv_2mortal() call is eventually equivalent to
-svREFCNT_dec(). A value can happily be mortal in two different contexts,
-and it will be svREFCNT_dec()ed twice, once on exit from these
-contexts. It can also be mortal twice in the same context. This means
-that you should be very careful to make a value mortal exactly as many
-times as it is needed. The value that go to the Perl stack I<should>
-be mortal.
-
-
-=head1 Stashes
+=head2 Stashes and Globs
 
 A stash is a hash table (associative array) that contains all of the
 different objects that are contained within a package.  Each key of the
@@ -689,11 +521,11 @@ objects of that name, including (but not limited to) the following:
     Format
     Subroutine
 
-Perl stores various stashes in a separate GV structure (for global
-variable) but represents them with an HV structure.  The keys in this
-larger GV are the various package names; the values are the C<GV*>s
-which are stashes.  It may help to think of a stash purely as an HV,
-and that the term "GV" means the global variable hash.
+There is a single stash called "defstash" that holds the items that exist
+in the "main" package.  To get at the items in other packages, append the
+string "::" to the package name.  The items in the "Foo" package are in
+the stash "Foo::" in defstash.  The items in the "Bar::Baz" package are
+in the stash "Baz::" in "Bar::"'s stash.
 
 To get the stash pointer for a particular package, use the function:
 
@@ -718,8 +550,8 @@ then use the following to get the package name itself:
 
     char*  HvNAME(HV* stash);
 
-If you need to return a blessed value to your Perl script, you can use the
-following function:
+If you need to bless or re-bless an object you can use the following
+function:
 
     SV*  sv_bless(SV*, HV* stash)
 
@@ -729,14 +561,14 @@ as any other SV.
 
 For more information on references and blessings, consult L<perlref>.
 
-=head1 Magic
+=head2 Magic
 
 [This section still under construction.  Ignore everything here.  Post no
 bills.  Everything not permitted is forbidden.]
 
 Any SV may be magical, that is, it has special features that a normal
 SV does not have.  These features are stored in the SV structure in a
-linked list of C<struct magic>s, typedef'ed to C<MAGIC>.
+linked list of C<struct magic>'s, typedef'ed to C<MAGIC>.
 
     struct magic {
         MAGIC*      mg_moremagic;
@@ -835,8 +667,8 @@ the various routines for the various magical types begin with C<magic_>.
 
 The current kinds of Magic Virtual Tables are:
 
-    mg_type  MGVTBL              Type of magicalness
-    -------  ------              -------------------
+    mg_type  MGVTBL              Type of magic
+    -------  ------              ----------------------------
     \0       vtbl_sv             Regexp???
     A        vtbl_amagic         Operator Overloading
     a        vtbl_amagicelem     Operator Overloading
@@ -849,7 +681,6 @@ The current kinds of Magic Virtual Tables are:
     i        vtbl_isaelem        @ISA array element
     L        0 (but sets RMAGICAL)     Perl Module/Debugger???
     l        vtbl_dbline         Debugger?
-    o        vtbl_collxfrm       Locale Collation
     P        vtbl_pack           Tied Array or Hash
     p        vtbl_packelem       Tied Array or Hash element
     q        vtbl_packelem       Tied Scalar or Handle
@@ -862,13 +693,25 @@ The current kinds of Magic Virtual Tables are:
     *        vtbl_glob           GV???
     #        vtbl_arylen         Array Length
     .        vtbl_pos           $. scalar variable
-    ~        Reserved for extensions, but multiple extensions may clash
+    ~        None                Used by certain extensions
 
 When an upper-case and lower-case letter both exist in the table, then the
 upper-case letter is used to represent some kind of composite type (a list
 or a hash), and the lower-case letter is used to represent an element of
 that composite type.
 
+The '~' magic type is defined specifically for use by extensions and
+will not be used by perl itself. Extensions can use ~ magic to 'attach'
+private information to variables (typically objects).  This is especially
+useful because there is no way for normal perl code to corrupt this
+private information (unlike using extra elements of a hash object).
+
+Note that because multiple extensions may be using ~ magic it is
+important for extensions to take extra care with it.  Typically only
+using it on objects blessed into the same class as the extension
+is sufficient.  It may also be appropriate to add an I32 'signature'
+at the top of the private data area and check that.
+
 =head2 Finding Magic
 
     MAGIC* mg_find(SV*, int type); /* Finds the magic pointer of that type */
@@ -883,7 +726,7 @@ This routine checks to see what types of magic C<sv> has.  If the mg_type
 field is an upper-case letter, then the mg_obj is copied to C<nsv>, but
 the mg_type field is changed to be the lower-case letter.
 
-=head1 Double-Typed SVs
+=head2 Double-Typed SV's
 
 Scalar variables normally contain only one type of value, an integer,
 double, pointer, or reference.  Perl will automatically convert the
@@ -923,7 +766,58 @@ following code:
 If the order of C<sv_setiv> and C<sv_setpv> had been reversed, then the
 macro C<SvPOK_on> would need to be called instead of C<SvIOK_on>.
 
-=head1 Calling Perl Routines from within C Programs
+=head2 XSUB's and the Argument Stack
+
+The XSUB mechanism is a simple way for Perl programs to access C subroutines.
+An XSUB routine will have a stack that contains the arguments from the Perl
+program, and a way to map from the Perl data structures to a C equivalent.
+
+The stack arguments are accessible through the C<ST(n)> macro, which returns
+the C<n>'th stack argument.  Argument 0 is the first argument passed in the
+Perl subroutine call.  These arguments are C<SV*>, and can be used anywhere
+an C<SV*> is used.
+
+Most of the time, output from the C routine can be handled through use of
+the RETVAL and OUTPUT directives.  However, there are some cases where the
+argument stack is not already long enough to handle all the return values.
+An example is the POSIX tzname() call, which takes no arguments, but returns
+two, the local time zone's standard and summer time abbreviations.
+
+To handle this situation, the PPCODE directive is used and the stack is
+extended using the macro:
+
+    EXTEND(sp, num);
+
+where C<sp> is the stack pointer, and C<num> is the number of elements the
+stack should be extended by.
+
+Now that there is room on the stack, values can be pushed on it using the
+macros to push IV's, doubles, strings, and SV pointers respectively:
+
+    PUSHi(IV)
+    PUSHn(double)
+    PUSHp(char*, I32)
+    PUSHs(SV*)
+
+And now the Perl program calling C<tzname>, the two values will be assigned
+as in:
+
+    ($standard_abbrev, $summer_abbrev) = POSIX::tzname;
+
+An alternate (and possibly simpler) method to pushing values on the stack is
+to use the macros:
+
+    XPUSHi(IV)
+    XPUSHn(double)
+    XPUSHp(char*, I32)
+    XPUSHs(SV*)
+
+These macros automatically adjust the stack for you, if needed.  Thus, you
+do not need to call C<EXTEND> to extend the stack.
+
+For more information, consult L<perlxs> and L<perlxstut>.
+
+=head2 Calling Perl Routines from within C Programs
 
 There are four routines that can be used to call a Perl subroutine from
 within a C program.  These four are:
@@ -958,26 +852,30 @@ functions:
     XPUSH*()
     POP*()
 
-For more information, consult L<perlcall>.
+For a detailed description of calling conventions from C to Perl,
+consult L<perlcall>.
 
-=head1 Memory Allocation
+=head2 Memory Allocation
 
-It is strongly suggested that you use the version of malloc that is distributed
-with Perl.  It keeps pools of various sizes of unallocated memory in order to
-more quickly satisfy allocation requests.
-However, on some platforms, it may cause spurious malloc or free errors.
+It is suggested that you use the version of malloc that is distributed
+with Perl.  It keeps pools of various sizes of unallocated memory in
+satisfy allocation requests more quickly.  However, on some platforms, it
+may cause spurious malloc or free errors.
 
     New(x, pointer, number, type);
     Newc(x, pointer, number, type, cast);
     Newz(x, pointer, number, type);
 
-These three macros are used to initially allocate memory.  The first argument
-C<x> was a "magic cookie" that was used to keep track of who called the macro,
-to help when debugging memory problems.  However, the current code makes no
-use of this feature (Larry has switched to using a run-time memory checker),
-so this argument can be any number.
+These three macros are used to allocate memory.
+
+The first argument C<x> was a "magic cookie" that was used to keep track
+of who called the macro, to help when debugging memory problems.  However,
+the current code makes no use of this feature (Larry has switched to using
+a run-time memory checker), so this argument can be any number.
+
+The second argument C<pointer> should be the name of a variable that will
+point to the newly allocated memory.
 
-The second argument C<pointer> will point to the newly allocated memory.
 The third and fourth arguments C<number> and C<type> specify how many of
 the specified type of data structure should be allocated.  The argument
 C<type> is passed to C<sizeof>.  The final argument to C<Newc>, C<cast>,
@@ -1006,9 +904,21 @@ destination starting points.  Perl will move, copy, or zero out C<number>
 instances of the size of the C<type> data structure (using the C<sizeof>
 function).
 
-=head1 Scratchpads
+=head2 PerlIO
 
-=head2 Putting a C value on Perl stack
+The most recent development releases of Perl has been experimenting with
+removing Perl's dependency on the "normal" standard I/O suite and allowing
+other stdio implementations to be used.  This involves creating a new
+abstraction layer that then calls whichever implementation of stdio Perl
+was compiled with.  All XSUB's should now use the functions in the PerlIO
+abstraction layer and not make any assumptions about what kind of stdio
+is being used.
+
+For a complete description of the PerlIO abstraction, consult L<perlapio>.
+
+=head2 Scratchpads
+
+=head3 Putting a C value on Perl stack
 
 A lot of opcodes (this is an elementary operation in the internal perl
 stack machine) put an SV* on the stack. However, as an optimization
@@ -1025,25 +935,25 @@ The macro to put this target on stack is C<PUSHTARG>, and it is
 directly used in some opcodes, as well as indirectly in zillions of
 others, which use it via C<(X)PUSH[pni]>.
 
-=head2 Scratchpads
+=head3 Scratchpads
 
-The question remains on when the SVs which are I<target>s for opcodes
-are created. The answer is that they are created when the current unit
-- a subroutine or a file (for opcodes for statements outside of
-subroutines) - is compiled. During this time a special anonymous Perl
+The question remains on when the SV's which are I<target>s for opcodes
+are created. The answer is that they are created when the current unit --
+a subroutine or a file (for opcodes for statements outside of
+subroutines) -- is compiled. During this time a special anonymous Perl
 array is created, which is called a scratchpad for the current
 unit.
 
-Scratchpad keeps SVs which are lexicals for the current unit and are
+A scratchpad keeps SV's which are lexicals for the current unit and are
 targets for opcodes. One can deduce that an SV lives on a scratchpad
 by looking on its flags: lexicals have C<SVs_PADMY> set, and
 I<target>s have C<SVs_PADTMP> set.
 
-The correspondence between OPs and I<target>s is not 1-to-1. Different
-OPs in the compile tree of the unit can use the same target, if this
+The correspondence between OP's and I<target>s is not 1-to-1. Different
+OP's in the compile tree of the unit can use the same target, if this
 would not conflict with the expected life of the temporary.
 
-=head2 Scratchpads and recursions
+=head3 Scratchpads and recursions
 
 In fact it is not 100% true that a compiled unit contains a pointer to
 the scratchpad AV. In fact it contains a pointer to an AV of
@@ -1057,15 +967,15 @@ for the subroutine-parent (lifespan of which covers the call to the
 child), the parent and the child should have different
 scratchpads. (I<And> the lexicals should be separate anyway!)
 
-So each subroutine is born with an array of scratchpads (of length
-1). On each entry to the subroutine it is checked that the current
+So each subroutine is born with an array of scratchpads (of length 1).
+On each entry to the subroutine it is checked that the current
 depth of the recursion is not more than the length of this array, and
 if it is, new scratchpad is created and pushed into the array.
 
 The I<target>s on this scratchpad are C<undef>s, but they are already
 marked with correct flags.
 
-=head1 API LISTING
+=head2 API LISTING
 
 This is a listing of functions, macros, flags, and variables that may be
 useful to extension writers or that may be found while reading other
@@ -1108,7 +1018,7 @@ Returns the highest index in the array.  Returns -1 if the array is empty.
 
 Creates a new AV and populates it with a list of SVs.  The SVs are copied
 into the array, so they may be freed after the call to av_make.  The new AV
-will have a refcount of 1.
+will have a reference count of 1.
 
        AV*     av_make _((I32 size, SV** svp));
 
@@ -1395,7 +1305,7 @@ Undefines the hash.
 =item isALNUM
 
 Returns a boolean indicating whether the C C<char> is an ascii alphanumeric
-character.
+character or digit.
 
        int isALNUM (char c)
 
@@ -1532,48 +1442,57 @@ memory is zeroed with C<memzero>.
 
 =item newAV
 
-Creates a new AV.  The refcount is set to 1.
+Creates a new AV.  The reference count is set to 1.
 
        AV*     newAV _((void));
 
 =item newHV
 
-Creates a new HV.  The refcount is set to 1.
+Creates a new HV.  The reference count is set to 1.
 
        HV*     newHV _((void));
 
-=item newRV
+=item newRV_inc
 
-Creates an RV wrapper for an SV.  The refcount for the original SV is
+Creates an RV wrapper for an SV.  The reference count for the original SV is
 incremented.
 
-       SV*     newRV _((SV* ref));
+       SV*     newRV_inc _((SV* ref));
+
+For historical reasons, "newRV" is a synonym for "newRV_inc".
+
+=item newRV_noinc
+
+Creates an RV wrapper for an SV.  The reference count for the original
+SV is B<not> incremented.
+
+       SV*     newRV_noinc _((SV* ref));
 
 =item newSV
 
 Creates a new SV.  The C<len> parameter indicates the number of bytes of
-pre-allocated string space the SV should have.  The refcount for the new SV
+pre-allocated string space the SV should have.  The reference count for the new SV
 is set to 1.
 
        SV*     newSV _((STRLEN len));
 
 =item newSViv
 
-Creates a new SV and copies an integer into it.  The refcount for the SV is
+Creates a new SV and copies an integer into it.  The reference count for the SV is
 set to 1.
 
        SV*     newSViv _((IV i));
 
 =item newSVnv
 
-Creates a new SV and copies a double into it.  The refcount for the SV is
+Creates a new SV and copies a double into it.  The reference count for the SV is
 set to 1.
 
        SV*     newSVnv _((NV i));
 
 =item newSVpv
 
-Creates a new SV and copies a string into it.  The refcount for the SV is
+Creates a new SV and copies a string into it.  The reference count for the SV is
 set to 1.  If C<len> is zero then Perl will compute the length.
 
        SV*     newSVpv _((char* s, STRLEN len));
@@ -1583,7 +1502,7 @@ set to 1.  If C<len> is zero then Perl will compute the length.
 Creates a new SV for the RV, C<rv>, to point to.  If C<rv> is not an RV then
 it will be upgraded to one.  If C<classname> is non-null then the new SV will
 be blessed in the specified package.  The new SV is returned and its
-refcount is 1.
+reference count is 1.
 
        SV*     newSVrv _((SV* rv, char* classname));
 
@@ -1848,7 +1767,7 @@ C<SPAGAIN>.
 
 =item SPAGAIN
 
-Refetch the stack pointer.  Used after a callback.  See L<perlcall>.
+Re-fetch the stack pointer.  Used after a callback.  See L<perlcall>.
 
        SPAGAIN;
 
@@ -1922,7 +1841,7 @@ ends.
 =item sv_bless
 
 Blesses an SV into a specified package.  The SV must be an RV.  The package
-must be designated by its stash (see C<gv_stashpv()>).  The refcount of the
+must be designated by its stash (see C<gv_stashpv()>).  The reference count of the
 SV is unaffected.
 
        SV*     sv_bless _((SV* sv, HV* stash));
@@ -1977,13 +1896,13 @@ Set the length of the string which is in the SV.  See C<SvCUR>.
 
 =item sv_dec
 
-Autodecrement of the value in the SV.
+Auto-decrement of the value in the SV.
 
        void    sv_dec _((SV* sv));
 
 =item sv_dec
 
-Autodecrement of the value in the SV.
+Auto-decrement of the value in the SV.
 
        void    sv_dec _((SV* sv));
 
@@ -2016,7 +1935,7 @@ Use C<SvGROW>.
 
 =item sv_inc
 
-Autoincrement of the value in the SV.
+Auto increment of the value in the SV.
 
        void    sv_inc _((SV* sv));
 
@@ -2112,7 +2031,7 @@ Adds magic to an SV.
 =item sv_mortalcopy
 
 Creates a new SV which is a copy of the original SV.  The new SV is marked
-as mortal.  The old SV may become invalid if it was marked as a temporary.
+as mortal.
 
        SV*     sv_mortalcopy _((SV* oldsv));
 
@@ -2124,7 +2043,7 @@ Returns a boolean indicating whether the value is an SV.
 
 =item sv_newmortal
 
-Creates a new SV which is mortal.  The refcount of the SV is set to 1.
+Creates a new SV which is mortal.  The reference count of the SV is set to 1.
 
        SV*     sv_newmortal _((void));
 
@@ -2254,19 +2173,19 @@ Returns a pointer to the string in the SV.  The SV must contain a string.
 
 =item SvREFCNT
 
-Returns the value of the object's refcount.
+Returns the value of the object's reference count.
 
        int SvREFCNT (SV* sv);
 
 =item SvREFCNT_dec
 
-Decrements the refcount of the given SV.
+Decrements the reference count of the given SV.
 
        void SvREFCNT_dec (SV* sv)
 
 =item SvREFCNT_inc
 
-Increments the refcount of the given SV.
+Increments the reference count of the given SV.
 
        void SvREFCNT_inc (SV* sv)
 
@@ -2325,7 +2244,7 @@ Copies an integer into a new SV, optionally blessing the SV.  The C<rv>
 argument will be upgraded to an RV.  That RV will be modified to point to
 the new SV.  The C<classname> argument indicates the package for the
 blessing.  Set C<classname> to C<Nullch> to avoid the blessing.  The new SV
-will be returned and will have a refcount of 1.
+will be returned and will have a reference count of 1.
 
        SV*     sv_setref_iv _((SV *rv, char *classname, IV iv));
 
@@ -2335,7 +2254,7 @@ Copies a double into a new SV, optionally blessing the SV.  The C<rv>
 argument will be upgraded to an RV.  That RV will be modified to point to
 the new SV.  The C<classname> argument indicates the package for the
 blessing.  Set C<classname> to C<Nullch> to avoid the blessing.  The new SV
-will be returned and will have a refcount of 1.
+will be returned and will have a reference count of 1.
 
        SV*     sv_setref_nv _((SV *rv, char *classname, double nv));
 
@@ -2346,7 +2265,7 @@ argument will be upgraded to an RV.  That RV will be modified to point to
 the new SV.  If the C<pv> argument is NULL then C<sv_undef> will be placed
 into the SV.  The C<classname> argument indicates the package for the
 blessing.  Set C<classname> to C<Nullch> to avoid the blessing.  The new SV
-will be returned and will have a refcount of 1.
+will be returned and will have a reference count of 1.
 
        SV*     sv_setref_pv _((SV *rv, char *classname, void* pv));
 
@@ -2362,7 +2281,7 @@ string must be specified with C<n>.  The C<rv> argument will be upgraded to
 an RV.  That RV will be modified to point to the new SV.  The C<classname>
 argument indicates the package for the blessing.  Set C<classname> to
 C<Nullch> to avoid the blessing.  The new SV will be returned and will have
-a refcount of 1.
+a reference count of 1.
 
        SV*     sv_setref_pvn _((SV *rv, char *classname, char* pv, I32 n));
 
@@ -2371,14 +2290,10 @@ Note that C<sv_setref_pv> copies the pointer while this copies the string.
 =item sv_setsv
 
 Copies the contents of the source SV C<ssv> into the destination SV C<dsv>.
-The source SV may be destroyed if it is mortal or temporary.
+The source SV may be destroyed if it is mortal.
 
        void    sv_setsv _((SV* dsv, SV* ssv));
 
-=item SvSetSV
-
-A wrapper around C<sv_setsv>. Safe even if C<dst==ssv>.
-
 =item SvSTASH
 
 Returns the stash of the SV.
@@ -2448,7 +2363,7 @@ This is the C<undef> SV.  Always refer to this as C<&sv_undef>.
 
 =item sv_unref
 
-Unsets the RV status of the SV, and decrements the refcount of whatever was
+Unsets the RV status of the SV, and decrements the reference count of whatever was
 being referenced by the RV.  This can almost be thought of as a reversal of
 C<newSVrv>.  See C<SvROK_off>.
 
@@ -2632,7 +2547,7 @@ destination, C<n> is the number of items, and C<t> is the type.
 
 =back
 
-=head1 AUTHOR
+=head1 EDITOR
 
 Jeff Okamoto <okamoto@corp.hp.com>
 
@@ -2644,4 +2559,4 @@ API Listing by Dean Roehrich <roehrich@cray.com>.
 
 =head1 DATE
 
-Version 23.1: 1996/10/19
+Version 25.2: 1996/12/16
diff --git a/pod/perllocale.pod b/pod/perllocale.pod
new file mode 100644 (file)
index 0000000..a1a5b53
--- /dev/null
@@ -0,0 +1,614 @@
+=head1 NAME
+
+perllocale - Perl locale handling (internationlization)
+
+=head1 DESCRIPTION
+
+Perl supports language-specific notions of data such as "is this a
+letter", "what is the upper-case equivalent of this letter", and
+"which of these letters comes first".  These are important issues,
+especially for languages other than English - but also for English: it
+would be very naÔve to think that C<A-Za-z> defines all the "letters".
+Perl is also aware that some character other than '.' may be preferred
+as a decimal point, and that output date representations may be
+language-specific.
+
+Perl can understand language-specific data via the standardized
+(ISO C, XPG4, POSIX 1.c) method called "the locale system".
+The locale system is controlled per application using a pragma, one
+function call, and several environment variables.
+
+B<NOTE>: This feature is new in Perl 5.004, and does not apply unless
+an application specifically requests it - see L<Backward
+compatibility>.
+
+=head1 PREPARING TO USE LOCALES
+
+If Perl applications are to be able to understand and present your
+data correctly according a locale of your choice, B<all> of the following
+must be true:
+
+=over 4
+
+=item *
+
+B<Your operating system must support the locale system>.  If it does,
+you should find that the C<setlocale> function is a documented part of
+its C library.
+
+=item *
+
+B<Definitions for the locales which you use must be installed>.  You,
+or your system administrator, must make sure that this is the case.
+The available locales, the location in which they are kept, and the
+manner in which they are installed, vary from system to system.  Some
+systems provide only a few, hard-wired, locales, and do not allow more
+to be added; others allow you to add "canned" locales provided by the
+system supplier; still others allow you or the system administrator
+to define and add arbitrary locales.  (You may have to ask your
+supplier to provide canned locales whch are not delivered with your
+operating system.)  Read your system documentation for further
+illumination.
+
+=item *
+
+B<Perl must believe that the locale system is supported>.  If it does,
+C<perl -V:d_setlocale> will say that the value for C<d_setlocale> is
+C<define>.
+
+=back
+
+If you want a Perl application to process and present your data
+according to a particular locale, the application code should include
+the S<C<use locale>> pragma (L<The use locale Pragma>) where
+appropriate, and B<at least one> of the following must be true:
+
+=over 4
+
+=item *
+
+B<The locale-determining environment variables (see L<ENVIRONMENT>) must
+be correctly set up>, either by yourself, or by the person who set up
+your system account, at the time the application is started.
+
+=item *
+
+B<The application must set its own locale> using the method described
+in L<The C<setlocale> function>.
+
+=back
+
+=head1 USING LOCALES
+
+=head2 The use locale pragma
+
+By default, Perl ignores the current locale.  The S<C<use locale>> pragma
+tells Perl to use the current locale for some operations:
+
+=over 4
+
+=item *
+
+B<The comparison operators> (C<lt>, C<le>, C<cmp>, C<ge>, and C<gt>)
+use C<LC_COLLATE>.  The C<sort> function is also affected if it is
+used without an explicit comparison function because it uses C<cmp> by
+default.
+
+B<Note:> The C<eq> and C<ne> operators are unaffected by the locale:
+they always perform a byte-by-byte comparison of their scalar
+arguments.  If you really want to know if two strings - which C<eq>
+may consider different - are equal as far as collation is concerned,
+use something like
+
+    !("space and case ignored" cmp "SpaceAndCaseIgnored")
+
+(which would be true if the collation locale specified a
+dictionary-like ordering).
+
+I<Editor's note:> I am right about C<eq> and C<ne>, aren't I?
+
+=item *
+
+B<Regular expressions and case-modification functions> (C<uc>,
+C<lc>, C<ucfirst>, and C<lcfirst>) use C<LC_CTYPE>
+
+=item *
+
+B<The formatting functions> (C<printf> and C<sprintf>) use
+C<LC_NUMERIC>
+
+=item *
+
+B<The POSIX date formatting function> (C<strftime>) uses C<LC_TIME>.
+
+=back
+
+C<LC_COLLATE>, C<LC_CTYPE>, and so on, are discussed further in
+L<LOCALE CATEGORIES>.
+
+The default behaviour returns with S<C<no locale>> or on reaching the end
+of the enclosing block.
+
+Note that the result of any operation that uses locale information is
+tainted (see L<perlsec.pod>), since locales can be created by
+unprivileged users on some systems.
+
+=head2 The setlocale function
+
+You can switch locales as often as you wish at runtime with the
+C<POSIX::setlocale> function:
+
+        # This functionality not usable prior to Perl 5.004
+        require 5.004;
+
+        # Import locale-handling tool set from POSIX module.
+        # This example uses: setlocale -- the function call
+        #                    LC_CTYPE -- explained below
+        use POSIX qw(locale_h);
+
+        # query and save the old locale.
+        $old_locale = setlocale(LC_CTYPE);
+
+        setlocale(LC_CTYPE, "fr_CA.ISO8859-1");
+        # LC_CTYPE now in locale "French, Canada, codeset ISO 8859-1"
+
+        setlocale(LC_CTYPE, "");
+        # LC_CTYPE now reset to default defined by LC_ALL/LC_CTYPE/LANG
+        # environment variables.  See below for documentation.
+
+        # restore the old locale
+        setlocale(LC_CTYPE, $old_locale);
+
+The first argument of C<setlocale> gives the B<category>, the second
+the B<locale>.  The category tells in what aspect of data processing
+you want to apply locale-specific rules.  Category names are discussed
+in L<LOCALE CATEGORIES> and L<ENVIRONMENT>.  The locale is the name of
+a collection of customization information corresponding to a paricular
+combination of language, country or territory, and codeset.  Read on
+for hints on the naming of locales: not all systems name locales as in
+the example.
+
+If no second argument is provided, the function returns a string
+naming the current locale for the category.  You can use this value as
+the second argument in a subsequent call to C<setlocale>.  If a second
+argument is given and it corresponds to a valid locale, the locale for
+the category is set to that value, and the function returns the
+now-current locale value.  You can use this in a subsequent call to
+C<setlocale>.  (In some implementations, the return value may sometimes
+differ from the value you gave as the second argument - think of it as
+an alias for the value that you gave.)
+
+As the example shows, if the second argument is an empty string, the
+category's locale is returned to the default specified by the
+corresponding environment variables.  Generally, this results in a
+return to the default which was in force when Perl started up: changes
+to the environment made by the application after start-up may or may
+not be noticed, depending on the implementation of your system's C
+library.
+
+If the second argument does not correspond to a valid locale, the
+locale for the category is not changed, and the function returns
+C<undef>.
+
+For further information about the categories, consult
+L<setlocale(3)>.  For the locales available in your system,
+also consult L<setlocale(3)> and see whether it leads you
+to the list of the available locales (search for the C<SEE ALSO>
+section).  If that fails, try the following command lines:
+
+        locale -a
+
+        nlsinfo
+
+        ls /usr/lib/nls/loc
+
+        ls /usr/lib/locale
+
+        ls /usr/lib/nls
+
+and see whether they list something resembling these
+
+        en_US.ISO8859-1         de_DE.ISO8859-1         ru_RU.ISO8859-5
+        en_US                   de_DE                   ru_RU
+        en                      de                      ru
+        english                 german                  russian
+        english.iso88591        german.iso88591         russian.iso88595
+
+Sadly, even though the calling interface for C<setlocale> has been
+standardized, the names of the locales have not.  The form of the name
+is usually I<language_country>B</>I<territory>B<.>I<codeset>, but the
+latter parts are not always present.
+
+Two special locales are worth particular mention: "C" and
+"POSIX".  Currently these are effectively the same locale: the
+difference is mainly that the first one is defined by the C standard
+and the second by the POSIX standard.  What they define is the
+B<default locale> in which every program starts in the absence of
+locale information in its environment.  (The default default locale,
+if you will.)  Its language is (American) English and its character
+codeset ASCII.
+
+B<NOTE>: Not all systems have the "POSIX" locale (not all systems
+are POSIX-conformant), so use "C" when you need explicitly to
+specify this default locale.
+
+=head2 The localeconv function
+
+The C<POSIX::localeconv> function allows you to get particulars of the
+locale-dependent numeric formatting information specified by the
+current C<LC_NUMERIC> and C<LC_MONETARY> locales.  (If you just want
+the name of the current locale for a particular category, use
+C<POSIX::setlocale> with a single parameter - see L<The setlocale
+function>.)
+
+        use POSIX qw(locale_h);
+        use locale;
+
+        # Get a reference to a hash of locale-dependent info
+        $locale_values = localeconv();
+
+        # Output sorted list of the values
+        for (sort keys %$locale_values) {
+                printf "%-20s = %s\n", $_, $locale_values->{$_}
+        }
+
+C<localeconv> takes no arguments, and returns B<a reference to> a
+hash.  The keys of this hash are formatting variable names such as
+C<decimal_point> and C<thousands_sep>; the values are the
+corresponding values.  See L<POSIX (3)/localeconv> for a longer
+example, which lists all the categories an implementation might be
+expected to provide; some provide more and others fewer, however.
+
+I<Editor's note:> I can't work out whether C<POSIX::localeconv>
+correctly obeys C<use locale> and C<no locale>.  In my opinion, it
+should, if only to be consistent with other locale stuff - although
+it's hardly a show-stopper if it doesn't.  Could someone check,
+please?
+
+Here's a simple-minded example program which rewrites its command line
+parameters as integers formatted correctly in the current locale:
+
+        # See comments in previous example
+        require 5.004;
+        use POSIX qw(locale_h);
+        use locale;
+
+        # Get some of locale's numeric formatting parameters
+        my ($thousands_sep, $grouping) =
+            @{localeconv()}{'thousands_sep', 'grouping'};
+
+        # Apply defaults if values are missing
+        $thousands_sep = ',' unless $thousands_sep;
+        $grouping = 3 unless $grouping;
+
+        # Format command line params for current locale
+        for (@ARGV)
+        {
+            $_ = int; # Chop non-integer part
+            1 while
+                s/(\d)(\d{$grouping}($|$thousands_sep))/$1$thousands_sep$2/;
+            print "$_ ";
+        }
+        print "\n";
+
+I<Editor's note:> Like all the examples, this needs testing on systems
+which, unlike mine, have non-toy implementations of locale handling.
+
+=head1 LOCALE CATEGORIES
+
+The subsections which follow descibe basic locale categories.  As well
+as these, there are some combination categories which allow the
+manipulation of of more than one basic category at a time.  See
+L<ENVIRONMENT VARIABLES> for a discussion of these.
+
+=head2 Category LC_COLLATE: Collation
+
+When in the scope of S<C<use locale>>, Perl looks to the B<LC_COLLATE>
+environment variable to determine the application's notions on the
+collation (ordering) of characters.  ('B' follows 'A' in Latin
+alphabets, but where do '¡' and 'Ÿ' belong?)
+
+Here is a code snippet that will tell you what are the alphanumeric
+characters in the current locale, in the locale order:
+
+        use locale;
+        print +(sort grep /\w/, map { chr() } 0..255), "\n";
+
+I<Editor's note:> The original example had C<setlocale(LC_COLLATE, "")>
+prior to C<print ...>.  I think this is wrong: as soon as you utter
+S<C<use locale>>, the default behaviour of C<sort> (well, C<cmp>, really)
+becomes locale-aware.  The locale it's aware of is the current locale
+which, unless you've changed it yourself, is the default locale
+defined by your environment.
+
+Compare this with the characters that you see and their order if you state
+explicitly that the locale should be ignored:
+
+        no locale;
+        print +(sort grep /\w/, map { chr() } 0..255), "\n";
+
+This machine-native collation (which is what you get unless S<C<use
+locale>> has appeared earlier in the same block) must be used for
+sorting raw binary data, whereas the locale-dependent collation of the
+first example is useful for written text.
+
+B<NOTE>: In some locales some characters may have no collation value
+at all - for example, if '-' is such a character, 'relocate' and
+'re-locate' may be considered to be equal to each other, and so sort
+to the same position.
+
+=head2 Category LC_CTYPE: Character Types
+
+When in the scope of S<C<use locale>>, Perl obeys the C<LC_CTYPE> locale
+setting.  This controls the application's notion of which characters
+are alphabetic.  This affects Perl's C<\w> regular expression
+metanotation, which stands for alphanumeric characters - that is,
+alphabetic and numeric characters.  (Consult L<perlre> for more
+information about regular expressions.)  Thanks to C<LC_CTYPE>,
+depending on your locale setting, characters like '', 'Š',
+'þ', and '¯' may be understood as C<\w> characters.
+
+C<LC_CTYPE> also affects the POSIX character-class test functions -
+C<isalpha>, C<islower> and so on.  For example, if you move from the
+"C" locale to a 7-bit Scandinavian one, you may find - possibly to
+your surprise -that "|" moves from the C<ispunct> class to C<isalpha>.
+
+I<Editor's note:> I can't work out whether the C<POSIX::is...> stuff
+correctly obeys C<use locale> and C<no locale>.  In my opinion, they
+should.  Could someone check, please?
+
+B<Note:> A broken or malicious C<LC_CTYPE> locale definition may
+result in clearly ineligible characters being considered to be
+alphanumeric by your application.  For strict matching of (unaccented)
+letters and digits - for example, in command strings - locale-aware
+applications should use C<\w> inside a C<no locale> block.
+
+=head2 Category LC_NUMERIC: Numeric Formatting
+
+When in the scope of S<C<use locale>>, Perl obeys the C<LC_NUMERIC>
+locale information which controls application's idea of how numbers
+should be formatted for human readability by the C<printf>, C<fprintf>,
+and C<write> functions.  String to numeric conversion by the
+C<POSIX::strtod> function is also affected.  In most impementations
+the only effect is to change the character used for the decimal point
+- perhaps from '.'  to ',': these functions aren't aware of such
+niceties as thousands separation and so on.  (See L<The localeconv
+function> if you care about these things.)
+
+I<Editor's note:> I can't work out whether C<POSIX::strtod> correctly
+obeys C<use locale> and C<no locale>.  In my opinion, it should -
+although it's hardly a show-stopper if it doesn't.  Could someone
+check, please?
+
+Note that output produced by C<print> is B<never> affected by the
+current locale: it is independent of whether C<use locale> or C<no
+locale> is in effect, and corresponds to what you'd get from C<printf>
+in the "C" locale.  The same is true for Perl's internal conversions
+between numeric and string formats:
+
+        use POSIX qw(strtod);
+        use locale;
+        $n = 5/2;   # Assign numeric 2.5 to $n
+
+        $a = " $n"; # Locale-independent conversion to string
+
+        print "half five is $n\n";       # Locale-independent output
+
+        printf "half five is %g\n", $n;  # Locale-dependent output
+
+        print "DECIMAL POINT IS COMMA\n" # Locale-dependent conversion
+            if $n == (strtod("2,5"))[0];
+
+=head2 Category LC_MONETARY: Formatting of monetary amounts
+
+The C standard defines the C<LC_MONETARY> category, but no function
+that is affected by its contents.  (Those with experience of standards
+committees will recognise that the working group decided to punt on
+the issue.)  Consequently, Perl takes no notice of it.  If you really
+want to use C<LC_MONETARY>, you can query its contents - see L<The
+localeconv function> - and use the information that it returns in your
+application's own formating of currency amounts.  However, you may
+well find that the information, though voluminous and complex, does
+not quite meet your requirements: currency formatting is a hard nut to
+crack.
+
+=head2 LC_TIME
+
+The output produced by C<POSIX::strftime>, which builds a formatted
+human-readable date/time string, is affected by the current C<LC_TIME>
+locale.  Thus, in a French locale, the output produced by the C<%B>
+format element (full month name) for the first month of the year would
+be "janvier".  Here's how to get a list of the long month names in the
+current locale:
+
+        use POSIX qw(strftime);
+        use locale;
+        for (0..11)
+        {
+            $long_month_name[$_] = strftime("%B", 0, 0, 0, 1, $_, 96);
+        }
+
+I<Editor's note:> Unchecked in "alien" locales: my system can't do
+French...
+
+=head2 Other categories
+
+The remaining locale category, C<LC_MESSAGES> (possibly supplemented by
+others in particular implementations) is not currently used by Perl -
+except possibly to affect the behaviour of library functions called
+by extensions which are not part of the standard Perl distribution.
+
+=head1 ENVIRONMENT
+
+=over 12
+
+=item PERL_BADLANG
+
+A string that controls whether Perl warns in its startup about failed
+locale settings.  This can happen if the locale support in the
+operating system is lacking (broken) is some way.  If this string has
+an integer value differing from zero, Perl will not complain.
+
+B<NOTE>: This is just hiding the warning message.  The message tells
+about some problem in your system's locale support and you should
+investigate what the problem is.
+
+=back
+
+The following environment variables are not specific to Perl: They are
+part of the standardized (ISO C, XPG4, POSIX 1.c) setlocale method to
+control an application's opinion on data.
+
+=over 12
+
+=item LC_ALL
+
+C<LC_ALL> is the "override-all" locale environment variable. If it is
+set, it overrides all the rest of the locale environment variables.
+
+=item LC_CTYPE
+
+In the absence of C<LC_ALL>, C<LC_CTYPE> chooses the character type
+locale.  In the absence of both C<LC_ALL> and C<LC_CTYPE>, C<LANG>
+chooses the character type locale.
+
+=item LC_COLLATE
+
+In the absence of C<LC_ALL>, C<LC_COLLATE> chooses the collation (sorting)
+locale.  In the absence of both C<LC_ALL> and C<LC_COLLATE>, C<LANG>
+chooses the collation locale.
+
+=item LC_MONETARY
+
+In the absence of C<LC_ALL>, C<LC_MONETARY> chooses the montary formatting
+locale.  In the absence of both C<LC_ALL> and C<LC_MONETARY>, C<LANG>
+chooses the monetary formatting locale.
+
+=item LC_NUMERIC
+
+In the absence of C<LC_ALL>, C<LC_NUMERIC> chooses the numeric format
+locale.  In the absence of both C<LC_ALL> and C<LC_NUMERIC>, C<LANG>
+chooses the numeric format.
+
+=item LC_TIME
+
+In the absence of C<LC_ALL>, C<LC_TIME> chooses the date and time formatting
+locale.  In the absence of both C<LC_ALL> and C<LC_TIME>, C<LANG>
+chooses the date and time formatting locale.
+
+=item LANG
+
+C<LANG> is the "catch-all" locale environment variable. If it is set,
+it is used as the last resort after the overall C<LC_ALL> and the
+category-specific C<LC_...>.
+
+=back
+
+=head1 NOTES
+
+=head2 Backward compatibility
+
+Versions of Perl prior to 5.004 ignored locale information, generally
+behaving as if something similar to the C<"C"> locale (see L<The
+setlocale function>) was always in force, even if the program
+environment suggested otherwise.  By default, Perl still behaves this
+way so as to maintain backward compatibility.  If you want a Perl
+application to pay attention to locale information, you B<must> use
+the S<C<use locale>> pragma (see L<The S<C<use locale>> Pragma>) to
+instruct it to do so.
+
+=head2 Sort speed
+
+Comparing and sorting by locale is usually slower than the default
+sorting; factors of 2 to 4 have been observed.  It will also consume
+more memory: while a Perl scalar variable is participating in any
+string comparison or sorting operation and obeying the locale
+collation rules it will take about 3-15 (the exact value depends on
+the operating system and the locale) times more memory than normally.
+These downsides are dictated more by the operating system
+implementation of the locale system than by Perl.
+
+=head2 I18N:Collate
+
+In Perl 5.003 (and later development releases prior to 5.003_06),
+per-locale collation was possible using the C<I18N::Collate> library
+module.  This is now mildly obsolete and should be avoided in new
+applications.  The C<LC_COLLATE> functionality is integrated into the
+Perl core language and one can use locale-specific scalar data
+completely normally - there is no need to juggle with the scalar
+references of C<I18N::Collate>.
+
+=head2 An imperfect standard
+
+Internationalization, as defined in the C and POSIX standards, can be
+criticized as incomplete, ungainly, and having too large a
+granularity.  (Locales apply to a whole process, when it would
+arguably be more useful to have them apply to a single thread, window
+group, or whatever.)  They also have a tendency, like standards
+groups, to divide the world into nations, when we all know that the
+world can equally well be divided into bankers, bikers, gamers, and so
+on.  But, for now, it's the only standard we've got.  This may be
+construed as a bug.
+
+=head2 Freely available locale definitions
+
+There is a large collection of locale definitions at
+C<ftp://dkuug.dk/i18n/WG15-collection>.  You should be aware that they
+are unsupported, and are not claimed to be fit for any purpose.  If
+your system allows the installation of arbitrary locales, you may find
+them useful as they are, or as a basis for the development of your own
+locales.
+
+=head2 i18n and l10n
+
+Internationalization is often abbreviated as B<i18n> because its first
+and last letters are separated by eighteen others.  You can also talk of
+localization (B<l10n>), the process of tailoring an
+internationalizated application for use in a particular locale.
+
+=head1 BUGS
+
+=head2 Broken systems
+
+In certain system environments the operating system's locale support
+is broken and cannot be fixed or used by Perl.  Such deficiencies can
+and will result in mysterious hangs and/or Perl core dumps.  One
+example is IRIX before release 6.2, in which the C<LC_COLLATE> support
+simply does not work.  When confronted with such a system, please
+report in excruciating detail to C<perlbug@perl.com>, and complain to
+your vendor: maybe some bug fixes exist for these problems in your
+operating system.  Sometimes such bug fixes are called an operating
+system upgrade.
+
+=head2 Rendering of this documentation
+
+This manual page contains non-ASCII characters, which should all be
+rendered as accented letters, and which should make some sort of sense
+in context.  If this is not the case, your system is probably not
+using the ISO 8859-1 character set which was used to write them,
+and/or your formatting, display, and printing software are not
+correctly mapping them to your host's character set.  If this annoys
+you, and if you can convince yourself that it is due to a bug in one
+of Perl's various C<pod2>... utilities, by all means report it as a
+Perl bug.  Otherwise, pausing only to curse anyone who ever invented
+yet another character set, see if you can make it handle ISO 8859-1
+sensibly.
+
+=head1 SEE ALSO
+
+L<POSIX (3)/isalnum>, L<POSIX (3)/isalpha>, L<POSIX (3)/isdigit>,
+L<POSIX (3)/isgraph>, L<POSIX (3)/islower>, L<POSIX (3)/isprint>,
+L<POSIX (3)/ispunct>, L<POSIX (3)/isspace>, L<POSIX (3)/isupper>,
+L<POSIX (3)/isxdigit>, L<POSIX (3)/localeconv>, L<POSIX (3)/setlocale>,
+L<POSIX (3)/strtod>
+
+I<Editor's note:> That looks horrible after going through C<pod2man>.
+But I do want to call out all thse sectins by name.  What should I
+have done?
+
+=head1 HISTORY
+
+Perl 5.003's F<perli18n.pod> heavily hacked by Dominic Dunlop.
+
+Last update:
+Mon Dec 16 14:13:10 WET 1996
index c97aac9..37adac7 100644 (file)
@@ -27,7 +27,7 @@ a declaration of the array:
 
 Now you should be very careful that the outer bracket type
 is a round one, that is, parentheses.  That's because you're assigning to
-an @list, so you need parens.  If you wanted there I<not> to be an @LoL,
+an @list, so you need parentheses.  If you wanted there I<not> to be an @LoL,
 but rather just a reference to it, you could do something more like this:
 
     # assign a reference to list of list references
@@ -144,10 +144,10 @@ you'd have to do something like this:
        push @$ref_to_LoL, [ split ];
     } 
 
-Actually, if you were using strict, you'd not only have to declare $ref_to_LoL as
-you had to declare @LoL, but you'd I<also> having to initialize it to a
-reference to an empty list.  (This was a bug in 5.001m that's been fixed
-for the 5.002 release.)
+Actually, if you were using strict, you'd have to declare not only
+$ref_to_LoL as you had to declare @LoL, but you'd I<also> having to
+initialize it to a reference to an empty list.  (This was a bug in 5.001m
+that's been fixed for the 5.002 release.)
 
     my $ref_to_LoL = [];
     while (<>) {
@@ -155,7 +155,7 @@ for the 5.002 release.)
     } 
 
 Ok, now you can add new rows.  What about adding new columns?  If you're
-just dealing with matrices, it's often easiest to use simple assignment:
+dealing with just matrices, it's often easiest to use simple assignment:
 
     for $x (1 .. 10) {
        for $y (1 .. 10) {
@@ -171,13 +171,13 @@ It doesn't matter whether those elements are already
 there or not: it'll gladly create them for you, setting
 intervening elements to C<undef> as need be.
 
-If you just wanted to append to a row, you'd have
+If you wanted just to append to a row, you'd have
 to do something a bit funnier looking:
 
     # add new columns to an existing row
     push @{ $LoL[0] }, "wilma", "betty";
 
-Notice that I I<couldn't> just say:
+Notice that I I<couldn't> say just:
 
     push $LoL[0], "wilma", "betty";  # WRONG!
 
@@ -187,17 +187,17 @@ to push() must be a real array, not just a reference to such.
 =head1 Access and Printing
 
 Now it's time to print your data structure out.  How 
-are you going to do that?  Well, if you only want one
+are you going to do that?  Well, if you want only one
 of the elements, it's trivial:
 
     print $LoL[0][0];
 
 If you want to print the whole thing, though, you can't
-just say 
+say
 
     print @LoL;                # WRONG
 
-because you'll just get references listed, and perl will never
+because you'll get just references listed, and perl will never
 automatically dereference things for you.  Instead, you have to 
 roll yourself a loop or two.  This prints the whole structure,
 using the shell-style for() construct to loop across the outer
@@ -231,7 +231,7 @@ sometimes is easier to take a temporary on your way through:
        }
     }
 
-Hm... that's still a bit ugly.  How about this:
+Hmm... that's still a bit ugly.  How about this:
 
     for $i ( 0 .. $#LoL ) {
        $aref = $LoL[$i];
@@ -266,7 +266,7 @@ That same loop could be replaced with a slice operation:
 but as you might well imagine, this is pretty rough on the reader.
 
 Ah, but what if you wanted a I<two-dimensional slice>, such as having
-$x run from 4..8 and $y run from 7 to 12?  Hm... here's the simple way:
+$x run from 4..8 and $y run from 7 to 12?  Hmm... here's the simple way:
 
     @newLoL = ();
     for ($startx = $x = 4; $x <= 8; $x++) {
index 7cb3a49..4fb5ec8 100644 (file)
@@ -13,11 +13,11 @@ Perl.  The package statement declares the compilation unit as being in the
 given namespace.  The scope of the package declaration is from the
 declaration itself through the end of the enclosing block (the same scope
 as the local() operator).  All further unqualified dynamic identifiers
-will be in this namespace.  A package statement only affects dynamic
+will be in this namespace.  A package statement affects only dynamic
 variables--including those you've used local() on--but I<not> lexical
 variables created with my().  Typically it would be the first declaration
 in a file to be included by the C<require> or C<use> operator.  You can
-switch into a package in more than one place; it merely influences which
+switch into a package in more than one place; it influences merely which
 symbol table is used by the compiler for the rest of that block.  You can
 refer to variables and filehandles in other packages by prefixing the
 identifier with the package name and a double colon:
@@ -39,10 +39,10 @@ It would treat package C<INNER> as a totally separate global package.
 Only identifiers starting with letters (or underscore) are stored in a
 package's symbol table.  All other symbols are kept in package C<main>,
 including all of the punctuation variables like $_.  In addition, the
-identifiers STDIN, STDOUT, STDERR, ARGV, ARGVOUT, ENV, INC and SIG are
+identifiers STDIN, STDOUT, STDERR, ARGV, ARGVOUT, ENV, INC, and SIG are
 forced to be in package C<main>, even when used for other purposes than
 their built-in one.  Note also that, if you have a package called C<m>,
-C<s> or C<y>, then you can't use the qualified form of an identifier
+C<s>, or C<y>, then you can't use the qualified form of an identifier
 because it will be interpreted instead as a pattern match, a substitution,
 or a translation.
 
@@ -62,7 +62,7 @@ temporarily switches back to the C<main> package to evaluate various
 expressions in the context of the C<main> package (or wherever you came
 from).  See L<perldebug>.
 
-See L<perlsub> for other scoping issues related to my() and local(), 
+See L<perlsub> for other scoping issues related to my() and local(),
 or L<perlref> regarding closures.
 
 =head2 Symbol Tables
@@ -119,9 +119,9 @@ Assignment to a typeglob performs an aliasing operation, i.e.,
 
     *dick = *richard;
 
-causes variables, subroutines and file handles accessible via the
+causes variables, subroutines, and file handles accessible via the
 identifier C<richard> to also be accessible via the identifier C<dick>.  If
-you only want to alias a particular variable or subroutine, you can
+you want to alias only a particular variable or subroutine, you can
 assign a reference instead:
 
     *dick = \$richard;
@@ -140,10 +140,10 @@ thing.
        # now use %hashsym normally, and you
        # will affect the caller's %another_hash
        my %nhash = (); # do what you want
-       return \%nhash; 
+       return \%nhash;
     }
 
-On return, the reference wil overwrite the hash slot in the
+On return, the reference will overwrite the hash slot in the
 symbol table specified by the *some_hash typeglob.  This
 is a somewhat tricky way of passing around references cheaply
 when you won't want to have to remember to dereference variables
@@ -197,7 +197,7 @@ order of definition; that is: last in, first out (LIFO).
 
 Inside an C<END> subroutine C<$?> contains the value that the script is
 going to pass to C<exit()>.  You can modify C<$?> to change the exit
-value of the script.  Beware of changing C<$?> by accident (eg, by
+value of the script.  Beware of changing C<$?> by accident (e.g.,, by
 running something via C<system>).
 
 Note that when you use the B<-n> and B<-p> switches to Perl, C<BEGIN>
@@ -208,7 +208,7 @@ and C<END> work just as they do in B<awk>, as a degenerate case.
 There is no special class syntax in Perl, but a package may function
 as a class if it provides subroutines that function as methods.  Such a
 package may also derive some of its methods from another class package
-by listing the other package name in its @ISA array.  
+by listing the other package name in its @ISA array.
 
 For more on this, see L<perlobj>.
 
@@ -225,15 +225,18 @@ symbols.  Or it can do a little of both.
 For example, to start a normal module called Fred, create
 a file called Fred.pm and put this at the start of it:
 
-    package Fred;
-    use Exporter ();
+    package      Fred;
+    use          strict;
+    use          Exporter ();
+    use          vars qw(@ISA @EXPORT @EXPORT_OK);
     @ISA       = qw(Exporter);
-    @EXPORT    = qw(func1 func2);
-    @EXPORT_OK = qw($sally @listabob %harry func3);
+    @EXPORT    = qw(&func1 &func2);
+    @EXPORT_OK = qw($sally @listabob %harry &func3);
+    use                 vars qw($sally @listabob %harry);
 
 Then go on to declare and use your variables in functions
 without any qualifications.
-See L<Exporter> and the I<Perl Modules File> for details on 
+See L<Exporter> and the I<Perl Modules File> for details on
 mechanics and style issues in module creation.
 
 Perl modules are included into your program by saying
@@ -278,7 +281,7 @@ instead of C<use>.  With require you can get into this problem:
     require Cwd;               # make Cwd:: accessible
     $here = Cwd::getcwd();     
 
-    use Cwd;                   # import names from Cwd:: 
+    use Cwd;                   # import names from Cwd::
     $here = getcwd();
 
     require Cwd;               # make Cwd:: accessible
@@ -299,7 +302,7 @@ the module.  If so, these will be entirely transparent to the user of
 the module.  It is the responsibility of the F<.pm> file to load (or
 arrange to autoload) any additional functionality.  The POSIX module
 happens to do both dynamic loading and autoloading, but the user can
-just say C<use POSIX> to get it all.
+say just C<use POSIX> to get it all.
 
 For more information on writing extension modules, see L<perlxs>
 and L<perlguts>.
@@ -315,14 +318,14 @@ because it has a shotgun.
 The module and its user have a contract, part of which is common law,
 and part of which is "written".  Part of the common law contract is
 that a module doesn't pollute any namespace it wasn't asked to.  The
-written contract for the module (AKA documentation) may make other
+written contract for the module (A.K.A. documentation) may make other
 provisions.  But then you know when you C<use RedefineTheWorld> that
 you're redefining the world and willing to take the consequences.
 
 =head1 THE PERL MODULE LIBRARY
 
-A number of modules are included the the Perl distribution.  These are
-described below, and all end in F<.pm>.  You may also discover files in 
+A number of modules are included the Perl distribution.  These are
+described below, and all end in F<.pm>.  You may also discover files in
 the library directory that end in either F<.pl> or F<.ph>.  These are old
 libraries supplied so that old programs that use them still run.  The
 F<.pl> files will all eventually be converted into standard modules, and
@@ -334,7 +337,7 @@ conversion, but it's just a mechanical process, so is far from bulletproof.
 =head2 Pragmatic Modules
 
 They work somewhat like pragmas in that they tend to affect the compilation of
-your program, and thus will usually only work well when used within a
+your program, and thus will usually work well only when used within a
 C<use>, or C<no>.  Most of these are locally scoped, so an inner BLOCK
 may countermand any of these by saying:
 
@@ -343,7 +346,7 @@ may countermand any of these by saying:
 
 which lasts until the end of that BLOCK.
 
-Unlike the pragrmas that effect the C<$^H> hints variable, the C<use
+Unlike the pragmas that effect the C<$^H> hints variable, the C<use
 vars> and C<use subs> declarations are not BLOCK-scoped.  They allow
 you to pre-declare a variables or subroutines within a particular
 <I>file</I> rather than just a block.  Such declarations are effective
@@ -354,6 +357,11 @@ The following pragmas are defined (and have their own documentation).
 
 =over 12
 
+=item blib
+
+manipulate @INC at compile time to use MakeMaker's uninstalled version
+of a package
+
 =item diagnostics
 
 force verbose warning diagnostics
@@ -370,13 +378,17 @@ request less of something from the compiler
 
 manipulate @INC at compile time
 
+=item locale
+
+use or ignore current locale for built-in operations (see L<perli18n>)
+
 =item ops
 
-restrict unsafe operations when compiling
+restrict named opcodes when compiling or running Perl code
 
 =item overload
 
-package for overloading perl operations
+overload basic Perl operations
 
 =item sigtrap
 
@@ -388,11 +400,11 @@ restrict unsafe constructs
 
 =item subs
 
-predeclare sub names
+pre-declare sub names
 
 =item vars
 
-predeclare global variable names
+pre-declare global variable names
 
 =back
 
@@ -424,6 +436,10 @@ benchmark running times of code
 
 warn of errors (from perspective of caller)
 
+=item Class::Template
+
+struct/member template builder
+
 =item Config
 
 access Perl configuration information
@@ -446,7 +462,7 @@ supply object methods for directory handles
 
 =item DynaLoader
 
-Dynamically load C libraries into Perl code
+dynamically load C libraries into Perl code
 
 =item English
 
@@ -462,7 +478,7 @@ implements default import method for modules
 
 =item ExtUtils::Embed
 
-Utilities for embedding Perl in C/C++ applications
+utilities for embedding Perl in C/C++ applications
 
 =item ExtUtils::Install
 
@@ -472,6 +488,18 @@ install files from here to there
 
 determine libraries to use and how to use them
 
+=item ExtUtils::MM_OS2
+
+methods to override UN*X behaviour in ExtUtils::MakeMaker
+
+=item ExtUtils::MM_Unix
+
+methods used by ExtUtils::MakeMaker
+
+=item ExtUtils::MM_VMS
+
+methods to override UN*X behaviour in ExtUtils::MakeMaker
+
 =item ExtUtils::MakeMaker
 
 create an extension Makefile
@@ -480,10 +508,6 @@ create an extension Makefile
 
 utilities to write and check a MANIFEST file
 
-=item ExtUtils::Miniperl
-
-write the C code for perlmain.c
-
 =item ExtUtils::Mkbootstrap
 
 make a bootstrap file for use by DynaLoader
@@ -492,21 +516,21 @@ make a bootstrap file for use by DynaLoader
 
 write linker options files for dynamic extension
 
-=item ExtUtils::MM_OS2
+=item ExtUtils::testlib
 
-methods to override UN*X behaviour in ExtUtils::MakeMaker
+add blib/* directories to @INC
 
-=item ExtUtils::MM_Unix
+=item CPAN
 
-methods used by ExtUtils::MakeMaker
+interface to Comprehensive Perl Archive Network
 
-=item ExtUtils::MM_VMS
+=item CPAN::FirstTime
 
-methods to override UN*X behaviour in ExtUtils::MakeMaker
+create a CPAN configuration file
 
-=item ExtUtils::testlib
+=item CPAN::Nox
 
-add blib/* directories to @INC
+run CPAN while avoiding compiled extensions
 
 =item Fatal
 
@@ -518,39 +542,47 @@ load the C Fcntl.h defines
 
 =item File::Basename
 
-parse file specifications
-
-=item FileCache
-
-keep more files open than the system permits
+split a pathname into pieces
 
 =item File::CheckTree
 
 run many filetest checks on a tree
 
+=item File::Compare
+
+compare files or filehandles
+
 =item File::Copy
 
-Copy files or filehandles
+copy files or filehandles
 
 =item File::Find
 
 traverse a file tree
 
-=item FileHandle
-
-supply object methods for filehandles
-
 =item File::Path
 
 create or remove a series of directories
 
+=item File::stat
+
+by-name interface to Perl's built-in stat() functions
+
+=item FileCache
+
+keep more files open than the system permits
+
+=item FileHandle
+
+supply object methods for filehandles
+
 =item FindBin
 
 locate directory of original perl script
 
 =item GDBM_File
 
-access to the gdbm library.
+access to the gdbm library
 
 =item Getopt::Long
 
@@ -616,13 +648,41 @@ complex numbers and associated mathematical functions
 
 tied access to ndbm files
 
+=item Net::FTP
+
+File Transfer Protocol client
+
 =item Net::Ping
 
 check a host for upness
 
+=item Net::Netrc
+
+parser for ".netrc" files a la Berkeley UNIX
+
+=item Net::Socket
+
+support class for Net::FTP
+
+=item Net::hostent
+
+by-name interface to Perl's built-in gethost*() functions
+
+=item Net::netent
+
+by-name interface to Perl's built-in getnet*() functions
+
+=item Net::protoent
+
+by-name interface to Perl's built-in getproto*() functions
+
+=item Net::servent
+
+by-name interface to Perl's built-in getserv*() functions
+
 =item Opcode
 
-disable named opcodes when compiling perl code
+disable named opcodes when compiling or running perl code
 
 =item Pod::Text
 
@@ -630,16 +690,16 @@ convert POD data to formatted ASCII text
 
 =item POSIX
 
-interface to IEEE Std 1003.1
-
-=item Safe
-
-compile and execute code in restricted compartments
+interface to IEEE Standard 1003.1
 
 =item SDBM_File
 
 tied access to sdbm files
 
+=item Safe
+
+compile and execute code in restricted compartments
+
 =item Search::Dict
 
 search for key in dictionary file
@@ -674,7 +734,7 @@ interface to the UNIX syslog(3) calls
 
 =item Term::Cap
 
-Perl termcap interface
+termcap interface
 
 =item Term::Complete
 
@@ -682,7 +742,7 @@ word completion module
 
 =item Term::ReadLine
 
-interface to various readline packages. 
+interface to various C<readline> packages
 
 =item Test::Harness
 
@@ -698,7 +758,7 @@ parse text into an array of tokens
 
 =item Text::Soundex
 
-implementation of the Soundex Algorithm as Described by Knuth
+implementation of the Soundex Algorithm as described by Knuth
 
 =item Text::Tabs
 
@@ -712,6 +772,10 @@ line wrapping to form simple paragraphs
 
 base class definitions for tied hashes
 
+=item Tie::RefHash
+
+base class definitions for tied hashes with references as keys
+
 =item Tie::Scalar
 
 base class definitions for tied scalars
@@ -724,10 +788,30 @@ fixed-table-size, fixed-key-length hashing
 
 efficiently compute time from local and GMT time
 
+=item Time::gmtime
+
+by-name interface to Perl's built-in gmtime() function
+
+=item Time::localtime
+
+by-name interface to Perl's built-in localtime() function
+
+=item Time::tm
+
+internal object used by Time::gmtime and Time::localtime
+
 =item UNIVERSAL
 
 base class for ALL classes (blessed references)
 
+=item User::grent
+
+by-name interface to Perl's built-in getgr*() functions
+
+=item User::pwent
+
+by-name interface to Perl's built-in getpw*() functions
+
 =back
 
 To find out I<all> the modules installed on your system, including
@@ -745,7 +829,7 @@ dynamically loaded into Perl if and when you need them.  Supported
 extension modules include the Socket, Fcntl, and POSIX modules.
 
 Many popular C extension modules do not come bundled (at least, not
-completely) due to their size, volatility, or simply lack of time for
+completely) due to their sizes, volatility, or simply lack of time for
 adequate testing and configuration across the multitude of platforms on
 which Perl was beta-tested.  You are encouraged to look for them in
 archie(1L), the Perl FAQ or Meta-FAQ, the WWW page, and even with their
@@ -755,13 +839,13 @@ disposition.
 =head1 CPAN
 
 CPAN stands for the Comprehensive Perl Archive Network.  This is a globally
-replicated collection of all known Perl materials, including hundreds 
+replicated collection of all known Perl materials, including hundreds
 of unbundled modules.  Here are the major categories of modules:
 
 =over
 
 =item *
-Language Extensions and Documentation Tools 
+Language Extensions and Documentation Tools
 
 =item *
 Development Support
@@ -788,16 +872,16 @@ Interfaces to / Emulations of Other Programming Languages
 File Names, File Systems and File Locking (see also File Handles)
 
 =item *
-String Processing, Language Text Processing, Parsing and Searching
+String Processing, Language Text Processing, Parsing, and Searching
 
 =item *
-Option, Argument, Parameter and Configuration File Processing
+Option, Argument, Parameter, and Configuration File Processing
 
 =item *
 Internationalization and Locale
 
 =item *
-Authentication, Security and Encryption
+Authentication, Security, and Encryption
 
 =item *
 World Wide Web, HTML, HTTP, CGI, MIME
@@ -809,7 +893,7 @@ Server and Daemon Utilities
 Archiving and Compression
 
 =item *
-Images, Pixmap and Bitmap Manipulation, Drawing and Graphing
+Images, Pixmap and Bitmap Manipulation, Drawing, and Graphing
 
 =item *
 Mail and Usenet News
@@ -898,15 +982,15 @@ ftp://ftp.is.co.za/programming/perl/CPAN/
 
 =back
 
-For an up-to-date listing of CPAN sites, 
+For an up-to-date listing of CPAN sites,
 see F<http://www.perl.com/perl/CPAN> or F<ftp://ftp.perl.com/perl/>.
 
-=head1 Modules: Creation, Use and Abuse
+=head1 Modules: Creation, Use, and Abuse
 
 (The following section is borrowed directly from Tim Bunce's modules
 file, available at your nearest CPAN site.)
 
-Perl 5 implements a class using a package, but the presence of a
+Perl implements a class using a package, but the presence of a
 package doesn't imply the presence of a class.  A package is just a
 namespace.  A class is a package that provides subroutines that can be
 used as methods.  A method is just a subroutine that expects, as its
@@ -944,9 +1028,9 @@ scheme as the original author.
 
 Use blessed references.  Use the two argument form of bless to bless
 into the class name given as the first parameter of the constructor,
-e.g.:
+e.g.,:
 
- sub new { 
+ sub new {
        my $class = shift;
        return bless {}, $class;
  }
@@ -954,7 +1038,7 @@ e.g.:
 or even this if you'd like it to be used as either a static
 or a virtual method.
 
- sub new { 
+ sub new {
        my $self  = shift;
        my $class = ref($self) || $self;
        return bless {}, $class;
@@ -1021,7 +1105,7 @@ or nature of a variable. For example:
  $no_caps_here    function scope my() or local() variables
 
 Function and method names seem to work best as all lowercase.
-E.g., C<$obj-E<gt>as_string()>.
+e.g.,, C<$obj-E<gt>as_string()>.
 
 You can use a leading underscore to indicate that a variable or
 function should not be used outside the package that defined it.
@@ -1039,11 +1123,11 @@ short or common names to reduce the risk of name clashes.
 Generally anything not exported is still accessible from outside the
 module using the ModuleName::item_name (or C<$blessed_ref-E<gt>method>)
 syntax.  By convention you can use a leading underscore on names to
-informally indicate that they are 'internal' and not for public use.
+indicate informally that they are 'internal' and not for public use.
 
 (It is actually possible to get private functions by saying:
 C<my $subref = sub { ... };  &$subref;>.  But there's no way to call that
-directly as a method, since a method must have a name in the symbol
+directly as a method, because a method must have a name in the symbol
 table.)
 
 As a general rule, if the module is trying to be object oriented
@@ -1052,12 +1136,12 @@ then export nothing. If it's just a collection of functions then
 
 =item Select a name for the module.
 
-This name should be as descriptive, accurate and complete as
+This name should be as descriptive, accurate, and complete as
 possible.  Avoid any risk of ambiguity. Always try to use two or
 more whole words.  Generally the name should reflect what is special
 about what the module does rather than how it does it.  Please use
-nested module names to informally group or categorise a module.
-A module should have a very good reason not to have a nested name.
+nested module names to group informally or categorize a module.
+There should be a very good reason for a module not to have a nested name.
 Module names should begin with a capital letter.
 
 Having 57 modules all called Sort will not make life easy for anyone
@@ -1137,16 +1221,16 @@ Copying, ToDo etc.
 
 =item Adding a Copyright Notice.
 
-How you choose to licence your work is a personal decision.
+How you choose to license your work is a personal decision.
 The general mechanism is to assert your Copyright and then make
 a declaration of how others may copy/use/modify your work.
 
 Perl, for example, is supplied with two types of license: The GNU
-GPL and The Artistic License (see the files README, Copying and
+GPL and The Artistic License (see the files README, Copying, and
 Artistic).  Larry has good reasons for NOT just using the GNU GPL.
 
-My personal recommendation, out of respect for Larry, Perl and the
-perl community at large is to simply state something like:
+My personal recommendation, out of respect for Larry, Perl, and the
+perl community at large is to state something simply like:
 
  Copyright (c) 1995 Your Name. All rights reserved.
  This program is free software; you can redistribute it and/or
@@ -1160,8 +1244,8 @@ Remember to include the other words in addition to the Copyright.
 
 To be fully compatible with the Exporter and MakeMaker modules you
 should store your module's version number in a non-my package
-variable called $VERSION.  This should be a valid floating point 
-number with at least two digits after the decimal (ie hundredths,
+variable called $VERSION.  This should be a floating point
+number with at least two digits after the decimal (i.e., hundredths,
 e.g, C<$VERSION = "0.01">).  Don't use a "1.3.2" style version.
 See Exporter.pm in Perl5.001m or later for details.
 
@@ -1178,7 +1262,7 @@ Usenet newsgroup.  This will at least ensure very wide once-off
 distribution.
 
 If possible you should place the module into a major ftp archive and
-include details of it's location in your announcement.
+include details of its location in your announcement.
 
 Some notes about ftp archives: Please use a long descriptive file
 name which includes the version number. Most incoming directories
@@ -1195,10 +1279,10 @@ Follow the instructions and links on
 
    http://franz.ww.tu-berlin.de/modulelist
 
-or upload to one of these sites: 
+or upload to one of these sites:
 
    ftp://franz.ww.tu-berlin.de/incoming
-   ftp://ftp.cis.ufl.edu/incoming  
+   ftp://ftp.cis.ufl.edu/incoming
 
 and notify upload@franz.ww.tu-berlin.de.
 
@@ -1289,8 +1373,7 @@ fragment of code built on top of the reusable modules. In these cases
 the application could invoked as:
 
      perl -e 'use Module::Name; method(@ARGV)' ...
-or   
+or
      perl -mModule::Name ...    (in perl5.002)
 
 =back
-
diff --git a/pod/perlnews.pod b/pod/perlnews.pod
new file mode 100644 (file)
index 0000000..7e6e626
--- /dev/null
@@ -0,0 +1,642 @@
+=head1 NAME
+
+perlnews - what's new for perl5.004
+
+=head1 DESCRIPTION
+
+This document describes differences between the 5.003 release (as
+documented in I<Programming Perl>, second edition--the Camel Book) and
+this one.
+
+=head1 Supported Environments
+
+Perl5.004 builds out of the box on Unix, Plan9, LynxOS, VMS, OS/2,
+QNX, and AmigaOS.
+
+=head1 Core Changes
+
+Most importantly, many bugs were fixed.  See the F<Changes>
+file in the distribution for details.
+
+=head2 Compilation Option: Binary Compatibility With 5.003
+
+There is a new Configure question that asks if you want to maintain
+binary compatibility with Perl 5.003.  If you choose binary
+compatibility, you do not have to recompile your extensions, but you
+might have symbol conflicts if you embed Perl in another application.
+
+=head2 Internal Change: FileHandle Deprecated
+
+Filehandles are now stored internally as type IO::Handle.
+Although C<use FileHandle> and C<*STDOUT{FILEHANDLE}>
+are still supported for backwards compatibility
+C<use IO::Handle> (or C<IO::Seekable> or C<IO::File>) and
+C<*STDOUT{IO}> are the way of the future.
+
+=head2 Internal Change: Safe Module Absorbed into Opcode
+
+A new Opcode module subsumes 5.003's Safe module.  The Safe
+interface is still available, so existing scripts should still
+work, but users are encouraged to read the new Opcode documentation.
+
+=head2 Internal Change: PerlIO internal IO abstraction interface.
+
+It is now possible to build Perl with AT&T's sfio IO package
+instead of stdio.  See L<perlapio> for more details, and
+the F<INSTALL> file for how to use it.
+
+=head2 New and Changed Built-in Variables
+
+=over
+
+=item $^E
+
+Extended error message under some platforms ($EXTENDED_OS_ERROR
+if you C<use English>).
+
+=item $^H
+
+The current set of syntax checks enabled by C<use strict>.  See the
+documentation of C<strict> for more details.  Not actually new, but
+newly documented.
+Because it is intended for internal use by Perl core components,
+there is no C<use English> long name for this variable.
+
+=item $^M
+
+By default, running out of memory it is not trappable.  However, if
+compiled for this, Perl may use the contents of C<$^M> as an emergency
+pool after die()ing with this message.  Suppose that your Perl were
+compiled with -DEMERGENCY_SBRK and used Perl's malloc.  Then
+
+    $^M = 'a' x (1<<16);
+
+would allocate 64K buffer for use when in emergency.
+See the F<INSTALL> file for information on how to enable this option.
+As a disincentive to casual use of this advanced feature,
+there is no C<use English> long name for this variable.
+
+=back
+
+=head2 New and Changed Built-in Functions
+
+=over
+
+=item delete on slices
+
+This now works.  (e.g. C<delete @ENV{'PATH', 'MANPATH'}>)
+
+=item flock
+
+is now supported on more platforms, and prefers fcntl
+to lockf when emulating.
+
+=item keys as an lvalue
+
+As an lvalue, C<keys> allows you to increase the number of hash buckets
+allocated for the given associative array.  This can gain you a measure
+of efficiency if you know the hash is going to get big.  (This is
+similar to pre-extending an array by assigning a larger number to
+$#array.)  If you say
+
+    keys %hash = 200;
+
+then C<%hash> will have at least 200 buckets allocated for it.  These
+buckets will be retained even if you do C<%hash = ()>; use C<undef
+%hash> if you want to free the storage while C<%hash> is still in scope.
+You can't shrink the number of buckets allocated for the hash using
+C<keys> in this way (but you needn't worry about doing this by accident,
+as trying has no effect).
+
+=item my() in Control Structures
+
+You can now use my() (with or without the parentheses) in the control
+expressions of control structures such as:
+
+    while (my $line = <>) {
+        $line = lc $line;
+    } continue {
+        print $line;
+    }
+
+    if ((my $answer = <STDIN>) =~ /^yes$/i) {
+        user_agrees();
+    } elsif ($answer =~ /^no$/i) {
+        user_disagrees();
+    } else {
+        chomp $answer;
+        die "'$answer' is neither 'yes' nor 'no'";
+    }
+
+Also, you can declare a foreach loop control variable as lexical by
+preceding it with the word "my".  For example, in:
+
+    foreach my $i (1, 2, 3) {
+        some_function();
+    }
+
+$i is a lexical variable, and the scope of $i extends to the end of
+the loop, but not beyond it.
+
+Note that you still cannot use my() on global punctuation variables
+such as $_ and the like.
+
+=item unpack() and pack()
+
+A new format 'w' represents a BER compressed integer (as defined in
+ASN.1).  Its format is a sequence of one or more bytes, each of which
+provides seven bits of the total value, with the most significant
+first.  Bit eight of each byte is set, except for the last byte, in
+which bit eight is clear.
+
+=item use VERSION
+
+If the first argument to C<use> is a number, it is treated as a version
+number instead of a module name.  If the version of the Perl interpreter
+is less than VERSION, then an error message is printed and Perl exits
+immediately.  This is often useful if you need to check the current
+Perl version before C<use>ing library modules which have changed in
+incompatible ways from older versions of Perl.  (We try not to do
+this more than we have to.)
+
+=item use Module VERSION LIST
+
+If the VERSION argument is present between Module and LIST, then the
+C<use> will fail if the $VERSION variable in package Module is
+less than VERSION.
+
+Note that there is not a comma after the version!
+
+=item prototype(FUNCTION)
+
+Returns the prototype of a function as a string (or C<undef> if the
+function has no prototype).  FUNCTION is a reference to or the name of the
+function whose prototype you want to retrieve.
+(Not actually new; just never documented before.)
+
+=item $_ as Default
+
+Functions documented in the Camel to default to $_ now in
+fact do, and all those that do are so documented in L<perlfunc>.
+
+=back
+
+=head2 New Built-in Methods
+
+The C<UNIVERSAL> package automatically contains the following methods that
+are inherited by all other classes:
+
+=over 4
+
+=item isa(CLASS)
+
+C<isa> returns I<true> if its object is blessed into a sub-class of C<CLASS>
+
+C<isa> is also exportable and can be called as a sub with two arguments. This
+allows the ability to check what a reference points to. Example:
+
+    use UNIVERSAL qw(isa);
+
+    if(isa($ref, 'ARRAY')) {
+       ...
+    }
+
+=item can(METHOD)
+
+C<can> checks to see if its object has a method called C<METHOD>,
+if it does then a reference to the sub is returned; if it does not then
+I<undef> is returned.
+
+=item VERSION( [NEED] )
+
+C<VERSION> returns the version number of the class (package). If the
+NEED argument is given then it will check that the current version is
+not less than NEED and die if this is not the case. This method is
+normally called as a class method. This method is also called when the
+C<VERSION> form of C<use> is used.
+
+    use A 1.2 qw(some imported subs);
+
+    A->VERSION( 1.2 );
+    $ref->is_instance();    # True
+
+=item class()
+
+C<class> returns the class name of its object.
+
+=item is_instance()
+
+C<is_instance> returns true if its object is an instance of some
+class, false if its object is the class (package) itself. Example
+
+    A->is_instance();       # False
+
+    $var = 'A';
+    $var->is_instance();    # False
+
+    $ref = bless [], 'A';
+    $ref->is_instance();    # True
+
+=back
+
+B<NOTE:> C<can> directly uses Perl's internal code for method lookup, and
+C<isa> uses a very similar method and cache-ing strategy. This may cause
+strange effects if the Perl code dynamically changes @ISA in any package.
+
+You may add other methods to the UNIVERSAL class via Perl or XS code.
+You do not need to C<use UNIVERSAL> in order to make these methods
+available to your program.  This is necessary only if you wish to
+have C<isa> available as a plain subroutine in the current package.
+
+=head2 TIEHANDLE Now Supported
+
+=over
+
+=item TIEHANDLE classname, LIST
+
+This is the constructor for the class.  That means it is expected to
+return an object of some sort. The reference can be used to
+hold some internal information.
+
+    sub TIEHANDLE { print "<shout>\n"; my $i; bless \$i, shift }
+
+=item PRINT this, LIST
+
+This method will be triggered every time the tied handle is printed to.
+Beyond its self reference it also expects the list that was passed to
+the print function.
+
+    sub PRINT { $r = shift; $$r++; print join($,,map(uc($_),@_)),$\ }
+
+=item READLINE this
+
+This method will be called when the handle is read from. The method
+should return undef when there is no more data.
+
+    sub READLINE { $r = shift; "PRINT called $$r times\n"; }
+
+=item DESTROY this
+
+As with the other types of ties, this method will be called when the
+tied handle is about to be destroyed. This is useful for debugging and
+possibly for cleaning up.
+
+    sub DESTROY { print "</shout>\n" }
+
+=back
+
+=head1 Pragmata
+
+Three new pragmatic modules exist:
+
+=over
+
+=item use blib
+
+Looks for MakeMaker-like I<'blib'> directory structure starting in
+I<dir> (or current directory) and working back up to five levels of
+parent directories.
+
+Intended for use on command line with B<-M> option as a way of testing
+arbitrary scripts against an uninstalled version of a package.
+
+=item use locale
+
+Tells the compiler to enable (or disable) the use of POSIX locales for
+built-in operations.
+
+When C<use locale> is in effect, the current LC_CTYPE locale is used
+for regular expressions and case mapping; LC_COLLATE for string
+ordering; and LC_NUMERIC for numeric formating in printf and sprintf
+(but B<not> in print).  LC_NUMERIC is always used in write, since
+lexical scoping of formats is problematic at best.
+
+Each C<use locale> or C<no locale> affects statements to the end of
+the enclosing BLOCK or, if not inside a BLOCK, to the end of the
+current file.  Locales can be switched and queried with
+POSIX::setlocale().
+
+See L<perllocale> for more information.
+
+=item use ops
+
+Restricts unsafe operations when compiling.
+
+=back
+
+=head1 Modules
+
+=head2 Module Information Summary
+
+Brand new modules:
+
+    IO.pm                Top-level interface to IO::* classes
+    IO/File.pm           IO::File extension Perl module
+    IO/Handle.pm         IO::Handle extension Perl module
+    IO/Pipe.pm           IO::Pipe extension Perl module
+    IO/Seekable.pm       IO::Seekable extension Perl module
+    IO/Select.pm         IO::Select extension Perl module
+    IO/Socket.pm         IO::Socket extension Perl module
+
+    Opcode.pm            Disable named opcodes when compiling Perl code
+
+    ExtUtils/Embed.pm    Utilities for embedding Perl in C programs
+    ExtUtils/testlib.pm  Fixes up @INC to use just-built extension
+
+    Fatal.pm             Make do-or-die equivalents of functions
+    FindBin.pm           Find path of currently executing program
+
+    Class/Template.pm    Structure/member template builder
+    File/stat.pm         Object-oriented wrapper around CORE::stat
+    Net/hostent.pm       Object-oriented wrapper around CORE::gethost*
+    Net/netent.pm        Object-oriented wrapper around CORE::getnet*
+    Net/protoent.pm      Object-oriented wrapper around CORE::getproto*
+    Net/servent.pm       Object-oriented wrapper around CORE::getserv*
+    Time/gmtime.pm       Object-oriented wrapper around CORE::gmtime
+    Time/localtime.pm    Object-oriented wrapper around CORE::localtime
+    Time/tm.pm           Perl implementation of "struct tm" for {gm,local}time
+    User/grent.pm        Object-oriented wrapper around CORE::getgr*
+    User/pwent.pm        Object-oriented wrapper around CORE::getpw*
+
+    UNIVERSAL.pm         Base class for *ALL* classes
+
+=head2 IO
+
+The IO module provides a simple mechanism to load all of the IO modules at one
+go.  Currently this includes:
+
+     IO::Handle
+     IO::Seekable
+     IO::File
+     IO::Pipe
+     IO::Socket
+
+For more information on any of these modules, please see its
+respective documentation.
+
+=head2 Math::Complex
+
+The Math::Complex module has been totally rewritten, and now supports
+more operations.  These are overloaded:
+
+     + - * / ** <=> neg ~ abs sqrt exp log sin cos atan2 "" (stringify)
+
+And these functions are now exported:
+
+    pi i Re Im arg
+    log10 logn cbrt root
+    tan cotan asin acos atan acotan
+    sinh cosh tanh cotanh asinh acosh atanh acotanh
+    cplx cplxe
+
+=head2 Overridden Built-ins
+
+Many of the Perl built-ins returning lists now have
+object-oriented overrides.  These are:
+
+    File::stat
+    Net::hostent
+    Net::netent
+    Net::protoent
+    Net::servent
+    Time::gmtime
+    Time::localtime
+    User::grent
+    User::pwent
+
+For example, you can now say
+
+    use File::stat;
+    use User::pwent;
+    $his = (stat($filename)->st_uid == pwent($whoever)->pw_uid);
+
+=head1 Efficiency Enhancements
+
+All hash keys with the same string are only allocated once, so
+even if you have 100 copies of the same hash, the immutable keys
+never have to be re-allocated.
+
+Functions that do nothing but return a fixed value are now inlined.
+
+=head1 Documentation Changes
+
+Many of the base and library pods were updated.  These
+new pods are included in section 1:
+
+=over 4
+
+=item L<perli18n>
+
+Internationalization.
+
+=item L<perlapio>
+
+Perl internal IO abstraction interface.
+
+=item L<perltoot>
+
+Tutorial on Perl OO programming.
+
+=item L<perldebug>
+
+Although not new, this has been massively updated.
+
+=item L<perlsec>
+
+Although not new, this has been massively updated.
+
+=back
+
+=head1 New Diagnostics
+
+Several new conditions will trigger warnings that were
+silent before.  Some only affect certain platforms.
+The following new warnings and errors
+outline these:
+
+=over 4
+
+=item "my" variable %s masks earlier declaration in same scope
+
+(S) A lexical variable has been redeclared in the same scope, effectively
+eliminating all access to the previous instance.  This is almost always
+a typographical error.  Note that the earlier variable will still exist
+until the end of the scope or until all closure referents to it are
+destroyed.
+
+=item Allocation too large: %lx
+
+(X) You can't allocate more than 64K on an MSDOS machine.
+
+=item Allocation too large
+
+(F) You can't allocate more than 2^31+"small amount" bytes.
+
+=item Attempt to free non-existent shared string
+
+(P) Perl maintains a reference counted internal table of strings to
+optimize the storage and access of hash keys and other strings.  This
+indicates someone tried to decrement the reference count of a string
+that can no longer be found in the table.
+
+=item Attempt to use reference as lvalue in substr
+
+(W) You supplied a reference as the first argument to substr() used
+as an lvalue, which is pretty strange.  Perhaps you forgot to
+dereference it first.  See L<perlfunc/substr>.
+
+=item Unsupported function fork
+
+(F) Your version of executable does not support forking.
+
+Note that under some systems, like OS/2, there may be different flavors of
+Perl executables, some of which may support fork, some not. Try changing
+the name you call Perl by to C<perl_>, C<perl__>, and so on.
+
+=item Ill-formed logical name |%s| in prime_env_iter
+
+(W) A warning peculiar to VMS.  A logical name was encountered when preparing
+to iterate over %ENV which violates the syntactic rules governing logical
+names.  Since it cannot be translated normally, it is skipped, and will not
+appear in %ENV.  This may be a benign occurrence, as some software packages
+might directly modify logical name tables and introduce non-standard names,
+or it may indicate that a logical name table has been corrupted.
+
+=item Integer overflow in hex number
+
+(S) The literal hex number you have specified is too big for your
+architecture. On a 32-bit architecture the largest hex literal is
+0xFFFFFFFF.
+
+=item Integer overflow in octal number
+
+(S) The literal octal number you have specified is too big for your
+architecture. On a 32-bit architecture the largest octal literal is
+037777777777.
+
+=item Null picture in formline
+
+(F) The first argument to formline must be a valid format picture
+specification.  It was found to be empty, which probably means you
+supplied it an uninitialized value.  See L<perlform>.
+
+=item Offset outside string
+
+(F) You tried to do a read/write/send/recv operation with an offset
+pointing outside the buffer.  This is difficult to imagine.
+The sole exception to this is that C<sysread()>ing past the buffer
+will extend the buffer and zero pad the new area.
+
+=item Out of memory!
+
+(X|F) The malloc() function returned 0, indicating there was insufficient
+remaining memory (or virtual memory) to satisfy the request.
+
+The request was judged to be small, so the possibility to trap it
+depends on the way Perl was compiled.  By default it is not trappable.
+However, if compiled for this, Perl may use the contents of C<$^M> as
+an emergency pool after die()ing with this message.  In this case the
+error is trappable I<once>.
+
+=item Out of memory during request for %s
+
+(F) The malloc() function returned 0, indicating there was insufficient
+remaining memory (or virtual memory) to satisfy the request. However,
+the request was judged large enough (compile-time default is 64K), so
+a possibility to shut down by trapping this error is granted.
+
+=item Possible attempt to put comments in qw() list
+
+(W) You probably wrote something like this:
+
+    qw( a # a comment
+        b # another comment
+      ) ;
+
+when you should have written this:
+
+    qw( a
+        b
+      ) ;
+
+=item Possible attempt to separate words with commas
+
+(W) You probably wrote something like this:
+
+    qw( a, b, c );
+
+when you should have written this:
+
+    qw( a b c );
+
+=item untie attempted while %d inner references still exist
+
+(W) A copy of the object returned from C<tie> (or C<tied>) was still
+valid when C<untie> was called.
+
+=item Got an error from DosAllocMem:
+
+(P) An error peculiar to OS/2. Most probably you use an obsolete version
+of Perl, and should not happen anyway.
+
+=item Malformed PERLLIB_PREFIX
+
+(F) An error peculiar to OS/2. PERLLIB_PREFIX should be of the form
+
+    prefix1;prefix2
+
+or
+
+    prefix1 prefix2
+
+with non-empty prefix1 and prefix2. If C<prefix1> is indeed a prefix of
+a builtin library search path, prefix2 is substituted. The error may appear
+if components are not found, or are too long. See L<perlos2/"PERLLIB_PREFIX">.
+
+=item PERL_SH_DIR too long
+
+(F) An error peculiar to OS/2. PERL_SH_DIR is the directory to find the
+C<sh>-shell in. See L<perlos2/"PERL_SH_DIR">.
+
+=item Process terminated by SIG%s
+
+(W) This is a standard message issued by OS/2 applications, while *nix
+applications die in silence. It is considered a feature of the OS/2
+port. One can easily disable this by appropriate sighandlers, see
+L<perlipc/"Signals">.  See L<perlos2/"Process terminated by SIGTERM/SIGINT">.
+
+=back
+
+=head1 BUGS
+
+If you find what you think is a bug, you might check the headers
+of recently posted articles 
+in the comp.lang.perl.misc newsgroup.  There may also be
+information at http://www.perl.com/perl/, the Perl Home Page.
+
+If you believe you have an unreported bug, please run the B<perlbug>
+program included with your release.  Make sure you trim your bug
+down to a tiny but sufficient test case.  Your bug report, along
+with the output of C<perl -V>, will be sent off to perlbug@perl.com
+to be analysed by the Perl porting team.
+
+=head1 SEE ALSO
+
+The F<Changes> file for exhaustive details on what changed.
+
+The F<INSTALL> file for how to build Perl.  This file has been
+significantly updated for 5.004, so even veteran users should
+look through it.
+
+The F<README> file for general stuff.
+
+The F<Copying> file for copyright information.
+
+=head1 HISTORY
+
+Constructed by Tom Christiansen, grabbing material with permission
+from innumerable contributors, with kibitzing by more than a few Perl
+porters.
+
+Last update:
+Wed Dec 18 16:18:27 EST 1996
index 691ce8b..1d13d90 100644 (file)
@@ -4,10 +4,13 @@ perlobj - Perl objects
 
 =head1 DESCRIPTION
 
-First of all, you need to understand what references are in Perl.  See
-L<perlref> for that.  
+First of all, you need to understand what references are in Perl.
+See L<perlref> for that.  Second, if you still find the following
+reference work too complicated, a tutorial on object-oriented programming
+in Perl can be found in L<perltoot>.
 
-Here are three very simple definitions that you should find reassuring.
+If you're still with us, then 
+here are three very simple definitions that you should find reassuring.
 
 =over 4
 
@@ -44,7 +47,7 @@ constructor:
 The C<{}> constructs a reference to an anonymous hash containing no 
 key/value pairs.  The bless() takes that reference and tells the object
 it references that it's now a Critter, and returns the reference.
-This is for convenience, since the referenced object itself knows that
+This is for convenience, because the referenced object itself knows that
 it has been blessed, and its reference to it could have been returned 
 directly, like this:
 
@@ -65,7 +68,7 @@ that wish to call methods in the class as part of the construction:
     }
 
 If you care about inheritance (and you should; see
-L<perlmod/"Modules: Creation, Use and Abuse">),
+L<perlmod/"Modules: Creation, Use, and Abuse">),
 then you want to use the two-arg form of bless
 so that your constructors may be inherited:
 
@@ -94,17 +97,17 @@ object into:
 Within the class package, the methods will typically deal with the
 reference as an ordinary reference.  Outside the class package,
 the reference is generally treated as an opaque value that may
-only be accessed through the class's methods.
+be accessed only through the class's methods.
 
 A constructor may re-bless a referenced object currently belonging to
 another class, but then the new class is responsible for all cleanup
-later.  The previous blessing is forgotten, as an object may only
-belong to one class at a time.  (Although of course it's free to 
+later.  The previous blessing is forgotten, as an object may belong
+to only one class at a time.  (Although of course it's free to 
 inherit methods from many classes.)
 
 A clarification:  Perl objects are blessed.  References are not.  Objects
 know which package they belong to.  References do not.  The bless()
-function simply uses the reference in order to find the object.  Consider
+function uses the reference to find the object.  Consider
 the following example:
 
     $a = {};
@@ -118,7 +121,7 @@ operated on the object and not on the reference.
 =head2 A Class is Simply a Package
 
 Unlike say C++, Perl doesn't provide any special syntax for class
-definitions.  You just use a package as a class by putting method
+definitions.  You use a package as a class by putting method
 definitions into the class.
 
 There is a special array within each package called @ISA which says
@@ -143,7 +146,7 @@ supplied in the UNIVERSAL class; see L<"Default UNIVERSAL methods"> for
 more details.)  If that doesn't work, Perl finally gives up and
 complains.
 
-Perl classes only do method inheritance.  Data inheritance is left
+Perl classes do only method inheritance.  Data inheritance is left
 up to the class itself.  By and large, this is not a problem in Perl,
 because most classes model the attributes of their object using
 an anonymous hash, which serves as its own little namespace to be
@@ -163,9 +166,9 @@ the two C++ method types they most closely resemble.)
 A class method expects a class name as the first argument.  It
 provides functionality for the class as a whole, not for any individual
 object belonging to the class.  Constructors are typically class
-methods.  Many class methods simply ignore their first argument, since
+methods.  Many class methods simply ignore their first argument, because
 they already know what package they're in, and don't care what package
-they were invoked via.  (These aren't necessarily the same, since
+they were invoked via.  (These aren't necessarily the same, because
 class methods follow the inheritance tree just like ordinary instance
 methods.)  Another typical use for class methods is to look up an
 object by name:
@@ -224,7 +227,7 @@ Indirect object method calls are parsed using the same rule as list
 operators: "If it looks like a function, it is a function".  (Presuming
 for the moment that you think two words in a row can look like a
 function name.  C++ programmers seem to think so with some regularity,
-especially when the first word is "new".)  Thus, the parens of
+especially when the first word is "new".)  Thus, the parentheses of
 
     new Critter ('Barney', 1.5, 70)
 
@@ -246,8 +249,8 @@ call, being sure to pass the requisite first argument explicitly:
     $fred =  MyCritter::find("Critter", "Fred");
     MyCritter::display($fred, 'Height', 'Weight');
 
-Note however, that this does not do any inheritance.  If you merely
-wish to specify that Perl should I<START> looking for a method in a
+Note however, that this does not do any inheritance.  If you wish
+merely to specify that Perl should I<START> looking for a method in a
 particular package, use an ordinary method call, but qualify the method
 name with the package like this:
 
@@ -255,13 +258,13 @@ name with the package like this:
     $fred->MyCritter::display('Height', 'Weight');
 
 If you're trying to control where the method search begins I<and> you're
-executing in the class itself, then you may use the SUPER pseudoclass,
+executing in the class itself, then you may use the SUPER pseudo class,
 which says to start looking in your base class's @ISA list without having
-to explicitly name it:
+to name it explicitly:
 
     $self->SUPER::display('Height', 'Weight');
 
-Please note that the C<SUPER::> construct is I<only> meaningful within the
+Please note that the C<SUPER::> construct is meaningful I<only> within the
 class.
 
 Sometimes you want to call a method when you don't know the method name
@@ -344,9 +347,9 @@ your class.  It will automatically be called at the appropriate moment,
 and you can do any extra cleanup you need to do.
 
 Perl doesn't do nested destruction for you.  If your constructor
-reblessed a reference from one of your base classes, your DESTROY may
-need to call DESTROY for any base classes that need it.  But this only
-applies to reblessed objects--an object reference that is merely
+re-blessed a reference from one of your base classes, your DESTROY may
+need to call DESTROY for any base classes that need it.  But this applies
+to only re-blessed objects--an object reference that is merely
 I<CONTAINED> in the current object will be freed and destroyed
 automatically when the current object is freed.
 
@@ -367,7 +370,7 @@ are equivalent, but AB and CD are different:
 
 =head2 Summary
 
-That's about all there is to it.  Now you just need to go off and buy a
+That's about all there is to it.  Now you need just to go off and buy a
 book about object-oriented design methodology, and bang your forehead
 with it for the next six months or so.
 
@@ -413,7 +416,7 @@ When an interpreter thread finally shuts down (usually when your program
 exits), then a rather costly but complete mark-and-sweep style of garbage
 collection is performed, and everything allocated by that thread gets
 destroyed.  This is essential to support Perl as an embedded or a
-multithreadable language.  For example, this program demonstrates Perl's
+multi-threadable language.  For example, this program demonstrates Perl's
 two-phased garbage collection:
 
     #!/usr/bin/perl 
@@ -462,7 +465,7 @@ garbage collector reaching the unreachable.
 Objects are always destructed, even when regular refs aren't and in fact
 are destructed in a separate pass before ordinary refs just to try to
 prevent object destructors from using refs that have been themselves
-destructed.  Plain refs are only garbage collected if the destruct level
+destructed.  Plain refs are only garbage-collected if the destruct level
 is greater than 0.  You can test the higher levels of global destruction
 by setting the PERL_DESTRUCT_LEVEL environment variable, presuming
 C<-DDEBUGGING> was enabled during perl build time.
@@ -472,6 +475,8 @@ at a future date.
 
 =head1 SEE ALSO
 
+A kinder, gentler tutorial on object-oriented programming in Perl can 
+be found in L<perltoot>.
 You should also check out L<perlbot> for other object tricks, traps, and tips, 
 as well as L<perlmod> for some style guides on constructing both modules
 and classes.
index 5645234..a75cb49 100644 (file)
@@ -43,7 +43,7 @@ In the following sections, these operators are covered in precedence order.
 =head2 Terms and List Operators (Leftward)
 
 Any TERM is of highest precedence of Perl.  These includes variables,
-quote and quotelike operators, any expression in parentheses,
+quote and quote-like operators, any expression in parentheses,
 and any function whose arguments are parenthesized.  Actually, there
 aren't really functions in this sense, just list operators and unary
 operators behaving as functions because you put parentheses around
@@ -66,7 +66,7 @@ the commas on the right of the sort are evaluated before the sort, but
 the commas on the left are evaluated after.  In other words, list
 operators tend to gobble up all the arguments that follow them, and
 then act like a simple TERM with regard to the preceding expression.
-Note that you have to be careful with parens:
+Note that you have to be careful with parentheses:
 
     # These evaluate exit before doing the print:
     print($foo, exit); # Obviously not what you want.
@@ -88,7 +88,7 @@ Also parsed as terms are the C<do {}> and C<eval {}> constructs, as
 well as subroutine and method calls, and the anonymous 
 constructors C<[]> and C<{}>.
 
-See also L<Quote and Quotelike Operators> toward the end of this section,
+See also L<Quote and Quote-Like Operators> toward the end of this section,
 as well as L<"I/O Operators">.
 
 =head2 The Arrow Operator
@@ -104,16 +104,16 @@ containing the method name, and the left side must either be an object
 (a blessed reference) or a class name (that is, a package name).
 See L<perlobj>.
 
-=head2 Autoincrement and Autodecrement
+=head2 Auto-increment and Auto-decrement
 
 "++" and "--" work as in C.  That is, if placed before a variable, they
 increment or decrement the variable before returning the value, and if
 placed after, increment or decrement the variable after returning the value.
 
-The autoincrement operator has a little extra built-in magic to it.  If
+The auto-increment operator has a little extra built-in magic to it.  If
 you increment a variable that is numeric, or that has ever been used in
 a numeric context, you get a normal increment.  If, however, the
-variable has only been used in string contexts since it was set, and
+variable has been used in only string contexts since it was set, and
 has a value that is not null and matches the pattern
 C</^[a-zA-Z]*[0-9]*$/>, the increment is done as a string, preserving each
 character within its range, with carry:
@@ -123,7 +123,7 @@ character within its range, with carry:
     print ++($foo = 'Az');     # prints 'Ba'
     print ++($foo = 'zz');     # prints 'aaa'
 
-The autodecrement operator is not magical.
+The auto-decrement operator is not magical.
 
 =head2 Exponentiation
 
@@ -134,7 +134,7 @@ internally.)
 
 =head2 Symbolic Unary Operators
 
-Unary "!" performs logical negation, i.e. "not".  See also C<not> for a lower
+Unary "!" performs logical negation, i.e., "not".  See also C<not> for a lower
 precedence version of this.
 
 Unary "-" performs arithmetic negation if the operand is numeric.  If
@@ -144,7 +144,7 @@ starts with a plus or minus, a string starting with the opposite sign
 is returned.  One effect of these rules is that C<-bareword> is equivalent
 to C<"-bareword">.
 
-Unary "~" performs bitwise negation, i.e. 1's complement.
+Unary "~" performs bitwise negation, i.e., 1's complement.
 (See also L<Integer Arithmetic>.)
 
 Unary "+" has no effect whatsoever, even on strings.  It is useful
@@ -167,7 +167,7 @@ supposed to be searched, substituted, or translated instead of the default
 $_.  The return value indicates the success of the operation.  (If the
 right argument is an expression rather than a search pattern,
 substitution, or translation, it is interpreted as a search pattern at run
-time.  This is less efficient than an explicit search, since the pattern
+time.  This is less efficient than an explicit search, because the pattern
 must be compiled every time the expression is evaluated--unless you've
 used C</o>.)
 
@@ -185,7 +185,7 @@ Binary "%" computes the modulus of the two numbers.
 Binary "x" is the repetition operator.  In a scalar context, it
 returns a string consisting of the left operand repeated the number of
 times specified by the right operand.  In a list context, if the left
-operand is a list in parens, it repeats the list.
+operand is a list in parentheses, it repeats the list.
 
     print '-' x 80;            # print row of dashes
 
@@ -389,7 +389,7 @@ As a list operator:
     @foo = @foo[$#foo-4 .. $#foo];     # slice last 5 items
 
 The range operator (in a list context) makes use of the magical
-autoincrement algorithm if the operands are strings.  You
+auto-increment algorithm if the operands are strings.  You
 can say
 
     @alphabet = ('A' .. 'Z');
@@ -506,14 +506,14 @@ It's the equivalent of "!" except for the very low precedence.
 
 Binary "and" returns the logical conjunction of the two surrounding
 expressions.  It's equivalent to && except for the very low
-precedence.  This means that it short-circuits: i.e. the right
+precedence.  This means that it short-circuits: i.e., the right
 expression is evaluated only if the left expression is true.
 
 =head2 Logical or and Exclusive Or
 
 Binary "or" returns the logical disjunction of the two surrounding
 expressions.  It's equivalent to || except for the very low
-precedence.  This means that it short-circuits: i.e. the right
+precedence.  This means that it short-circuits: i.e., the right
 expression is evaluated only if the left expression is false.
 
 Binary "xor" returns the exclusive-OR of the two surrounding expressions.
@@ -540,7 +540,7 @@ Type casting operator.
 
 =back
 
-=head2 Quote and Quotelike Operators
+=head2 Quote and Quote-like Operators
 
 While we usually think of quotes as literal values, in Perl they
 function as operators, providing various kinds of interpolating and
@@ -587,13 +587,13 @@ pattern from the variables.  If this is not what you want, use C<\Q> to
 interpolate a variable literally.
 
 Apart from the above, there are no multiple levels of interpolation.  In
-particular, contrary to the expectations of shell programmers, backquotes
+particular, contrary to the expectations of shell programmers, back-quotes
 do I<NOT> interpolate within double quotes, nor do single quotes impede
 evaluation of variables when used within double quotes.
 
-=head2 Regexp Quotelike Operators
+=head2 Regexp Quote-Like Operators
 
-Here are the quotelike operators that apply to pattern
+Here are the quote-like operators that apply to pattern
 matching and related activities.
 
 =over 8
@@ -602,7 +602,7 @@ matching and related activities.
 
 This is just like the C</pattern/> search, except that it matches only
 once between calls to the reset() operator.  This is a useful
-optimization when you only want to see the first occurrence of
+optimization when you want to see only the first occurrence of
 something in each file of a set of files, for instance.  Only C<??>
 patterns local to the current package are reset.
 
@@ -622,10 +622,10 @@ L<perlre>.
 
 Options are:
 
-    g  Match globally, i.e. find all occurrences.
+    g  Match globally, i.e., find all occurrences.
     i  Do case-insensitive pattern matching.
     m  Treat string as multiple lines.
-    o  Only compile pattern once.
+    o  Compile pattern only once.
     s  Treat string as single line.
     x  Use extended regular expressions.
 
@@ -649,7 +649,7 @@ successfully executed regular expression is used instead.
 
 If used in a context that requires a list value, a pattern match returns a
 list consisting of the subexpressions matched by the parentheses in the
-pattern, i.e. (C<$1>, $2, $3...).  (Note that here $1 etc. are also set, and
+pattern, i.e., (C<$1>, $2, $3...).  (Note that here $1 etc. are also set, and
 that this differs from Perl 4's behavior.)  If the match fails, a null
 array is returned.  If the match succeeds, but there were no parentheses,
 a list value of (1) is returned.
@@ -672,8 +672,8 @@ Examples:
     if (($F1, $F2, $Etc) = ($foo =~ /^(\S+)\s+(\S+)\s*(.*)/))
 
 This last example splits $foo into the first two words and the
-remainder of the line, and assigns those three fields to $F1, $F2 and
-$Etc.  The conditional is true if any variables were assigned, i.e. if
+remainder of the line, and assigns those three fields to $F1, $F2, and
+$Etc.  The conditional is true if any variables were assigned, i.e., if
 the pattern matched.
 
 The C</g> modifier specifies global pattern matching--that is, matching
@@ -695,7 +695,7 @@ beginning.  Examples:
     ($one,$five,$fifteen) = (`uptime` =~ /(\d+\.\d+)/g);
 
     # scalar context
-    $/ = ""; $* = 1;  # $* deprecated in Perl 5
+    $/ = ""; $* = 1;  # $* deprecated in modern perls
     while ($paragraph = <>) {
        while ($paragraph =~ /[a-z]['")]*[.!?]+['")]*\s/g) {
            $sentences++;
@@ -759,13 +759,13 @@ made.  Otherwise it returns false (specifically, the empty string).
 If no string is specified via the C<=~> or C<!~> operator, the C<$_>
 variable is searched and modified.  (The string specified with C<=~> must
 be a scalar variable, an array element, a hash element, or an assignment
-to one of those, i.e. an lvalue.)
+to one of those, i.e., an lvalue.)
 
 If the delimiter chosen is single quote, no variable interpolation is
 done on either the PATTERN or the REPLACEMENT.  Otherwise, if the
 PATTERN contains a $ that looks like a variable rather than an
 end-of-string test, the variable will be interpolated into the pattern
-at run-time.  If you only want the pattern compiled once the first time
+at run-time.  If you want the pattern compiled only once the first time
 the variable is interpolated, use the C</o> option.  If the pattern
 evaluates to a null string, the last successfully executed regular
 expression is used instead.  See L<perlre> for further explanation on these.
@@ -773,20 +773,20 @@ expression is used instead.  See L<perlre> for further explanation on these.
 Options are:
 
     e  Evaluate the right side as an expression.
-    g  Replace globally, i.e. all occurrences.
+    g  Replace globally, i.e., all occurrences.
     i  Do case-insensitive pattern matching.
     m  Treat string as multiple lines.
-    o  Only compile pattern once.
+    o  Compile pattern only once.
     s  Treat string as single line.
     x  Use extended regular expressions.
 
 Any non-alphanumeric, non-whitespace delimiter may replace the
 slashes.  If single quotes are used, no interpretation is done on the
 replacement string (the C</e> modifier overrides this, however).  Unlike
-Perl 4, Perl 5 treats backticks as normal delimiters; the replacement
+Perl 4, Perl 5 treats back-ticks as normal delimiters; the replacement
 text is not evaluated as a command.  If the
 PATTERN is delimited by bracketing quotes, the REPLACEMENT has its own
-pair of quotes, which may or may not be bracketing quotes, e.g.
+pair of quotes, which may or may not be bracketing quotes, e.g.,
 C<s(foo)(bar)> or C<sE<lt>fooE<gt>/bar/>.  A C</e> will cause the
 replacement portion to be interpreter as a full-fledged Perl expression
 and eval()ed right then and there.  It is, however, syntax checked at
@@ -829,10 +829,10 @@ Examples:
     s/([^ ]*) *([^ ]*)/$2 $1/; # reverse 1st two fields
 
 Note the use of $ instead of \ in the last example.  Unlike 
-B<sed>, we only use the \E<lt>I<digit>E<gt> form in the left hand side.
+B<sed>, we use the \E<lt>I<digit>E<gt> form in only the left hand side.
 Anywhere else it's $E<lt>I<digit>E<gt>.
 
-Occasionally, you can't just use a C</g> to get all the changes
+Occasionally, you can't use just a C</g> to get all the changes
 to occur.  Here are two common cases:
 
     # put commas in the right places in an integer
@@ -852,10 +852,10 @@ with the corresponding character in the replacement list.  It returns
 the number of characters replaced or deleted.  If no string is
 specified via the =~ or !~ operator, the $_ string is translated.  (The
 string specified with =~ must be a scalar variable, an array element,
-or an assignment to one of those, i.e. an lvalue.)  For B<sed> devotees,
+or an assignment to one of those, i.e., an lvalue.)  For B<sed> devotees,
 C<y> is provided as a synonym for C<tr>.  If the SEARCHLIST is
 delimited by bracketing quotes, the REPLACEMENTLIST has its own pair of
-quotes, which may or may not be bracketing quotes, e.g. C<tr[A-Z][a-z]>
+quotes, which may or may not be bracketing quotes, e.g., C<tr[A-Z][a-z]>
 or C<tr(+-*/)/ABCD/>.
 
 Options:
@@ -920,7 +920,7 @@ an eval():
 =head2 I/O Operators
 
 There are several I/O operators you should know about.  
-A string is enclosed by backticks (grave accents) first undergoes
+A string is enclosed by back-ticks (grave accents) first undergoes
 variable substitution just like a double quoted string.  It is then
 interpreted as a command, and the output of that command is the value
 of the pseudo-literal, like in a shell.  In a scalar context, a single
@@ -933,7 +933,7 @@ of C<$?>).  Unlike in B<csh>, no translation is done on the return
 data--newlines remain newlines.  Unlike in any of the shells, single
 quotes do not hide variable names in the command from interpretation.
 To pass a $ through to the shell you need to hide it with a backslash.
-The generalized form of backticks is C<qx//>.  (Because backticks
+The generalized form of back-ticks is C<qx//>.  (Because back-ticks
 always undergo shell expansion as well, see L<perlsec> for 
 security concerns.)
 
@@ -954,8 +954,8 @@ write.)  Anyway, the following lines are equivalent to each other:
     print while defined($_ = <STDIN>);
     print while <STDIN>;
 
-The filehandles STDIN, STDOUT and STDERR are predefined.  (The
-filehandles C<stdin>, C<stdout> and C<stderr> will also work except in
+The filehandles STDIN, STDOUT, and STDERR are predefined.  (The
+filehandles C<stdin>, C<stdout>, and C<stderr> will also work except in
 packages, where they would be interpreted as local identifiers rather
 than global.)  Additional filehandles may be created with the open()
 function.  See L<perlfunc/open()> for details on this.
@@ -989,9 +989,9 @@ is equivalent to the following Perl-like pseudo code:
 
 except that it isn't so cumbersome to say, and will actually work.  It
 really does shift array @ARGV and put the current filename into variable
-$ARGV.  It also uses filehandle I<ARGV> internally--E<lt>E<gt> is just a synonym
-for E<lt>ARGVE<gt>, which is magical.  (The pseudo code above doesn't work
-because it treats E<lt>ARGVE<gt> as non-magical.)
+$ARGV.  It also uses filehandle I<ARGV> internally--E<lt>E<gt> is just a
+synonym for E<lt>ARGVE<gt>, which is magical.  (The pseudo code above
+doesn't work because it treats E<lt>ARGVE<gt> as non-magical.)
 
 You can modify @ARGV before the first E<lt>E<gt> as long as the array ends up
 containing the list of filenames you really want.  Line numbers (C<$.>)
@@ -1018,7 +1018,7 @@ this it will assume you are processing another @ARGV list, and if you
 haven't set @ARGV, will input from STDIN.
 
 If the string inside the angle brackets is a reference to a scalar
-variable (e.g. E<lt>$fooE<gt>), then that variable contains the name of the
+variable (e.g., E<lt>$fooE<gt>), then that variable contains the name of the
 filehandle to input from, or a reference to the same.  For example:
 
     $fh = \*STDIN;
@@ -1055,11 +1055,11 @@ machine.)  Of course, the shortest way to do the above is:
     chmod 0644, <*.c>;
 
 Because globbing invokes a shell, it's often faster to call readdir() yourself
-and just do your own grep() on the filenames.  Furthermore, due to its current
+and do your own grep() on the filenames.  Furthermore, due to its current
 implementation of using a shell, the glob() routine may get "Arg list too 
 long" errors (unless you've installed tcsh(1L) as F</bin/csh>).
 
-A glob only evaluates its (embedded) argument when it is starting a new
+A glob evaluates its (embedded) argument only when it is starting a new
 list.  All values must be read before it will start over.  In a list
 context this isn't important, because you automatically get them all
 anyway.  In a scalar context, however, the operator returns the next value
@@ -1126,5 +1126,5 @@ The bitwise operators ("&", "|", "^", "~", "<<", and ">>") always
 produce integral results.  However, C<use integer> still has meaning
 for them.  By default, their results are interpreted as unsigned
 integers.  However, if C<use integer> is in effect, their results are
-interpeted as signed integers.  For example, C<~0> usually evaluates
+interpreted as signed integers.  For example, C<~0> usually evaluates
 to a large integral value.  However, C<use integer; ~0> is -1.
index 3722e2c..dcf615d 100644 (file)
@@ -94,10 +94,10 @@ here and in commands:
     S<text>     text contains non-breaking spaces
     C<code>    literal code 
     L<name>     A link (cross reference) to name
-                   L<name>             manpage
-                   L<name/ident>       item in manpage
-                   L<name/"sec">       section in other manpage
-                   L<"sec">            section in this manpage
+                   L<name>             manual page
+                   L<name/ident>       item in manual page
+                   L<name/"sec">       section in other manual page
+                   L<"sec">            section in this manual page
                                        (the quotes are optional)
                    L</"sec">           ditto
     F<file>    Used for filenames
@@ -117,7 +117,7 @@ to look like paragraphs (block format), so that they stand out
 visually, and so that I could run them through fmt easily to reformat
 them (that's F7 in my version of B<vi>).  I wanted the translator (and not
 me) to worry about whether " or ' is a left quote or a right quote
-within filled text, and I wanted it to leave the quotes alone dammit in
+within filled text, and I wanted it to leave the quotes alone, dammit, in
 verbatim mode, so I could slurp in a working program, shift it over 4
 spaces, and have it print out, er, verbatim.  And presumably in a
 constant width font.
index c4dbac6..ce054ec 100644 (file)
@@ -5,7 +5,7 @@ perlre - Perl regular expressions
 =head1 DESCRIPTION
 
 This page describes the syntax of regular expressions in Perl.  For a
-description of how to actually I<use> regular expressions in matching
+description of how to I<use> regular expressions in matching
 operations, plus various examples of the same, see C<m//> and C<s///> in
 L<perlop>.
 
@@ -22,7 +22,7 @@ Do case-insensitive pattern matching.
 =item m   
 
 Treat string as multiple lines.  That is, change "^" and "$" from matching
-only at the very start or end of the string to the start or end of any
+at only the very start or end of the string to the start or end of any
 line anywhere within the string,
 
 =item s   
@@ -45,7 +45,7 @@ The C</x> modifier itself needs a little more explanation.  It tells
 the regular expression parser to ignore whitespace that is neither
 backslashed nor within a character class.  You can use this to break up
 your regular expression into (slightly) more readable parts.  The C<#>
-character is also treated as a metacharacter introducing a comment,
+character is also treated as a meta-character introducing a comment,
 just as in ordinary Perl code.  This also means that if you want real
 whitespace or C<#> characters in the pattern that you'll have to either
 escape them or encode them using octal or hex escapes.  Taken together,
@@ -63,7 +63,7 @@ See L<Version 8 Regular Expressions> for details.
 In particular the following metacharacters have their standard I<egrep>-ish
 meanings:
 
-    \  Quote the next metacharacter
+    \  Quote the next meta-character
     ^  Match the beginning of the line
     .  Match any character (except newline)
     $  Match the end of the line (or before newline at the end)
@@ -71,8 +71,8 @@ meanings:
     () Grouping
     [] Character class
 
-By default, the "^" character is guaranteed to match only at the
-beginning of the string, the "$" character only at the end (or before the
+By default, the "^" character is guaranteed to match at only the
+beginning of the string, the "$" character at only the end (or before the
 newline at the end) and Perl does certain optimizations with the
 assumption that the string contains only one line.  Embedded newlines
 will not be matched by "^" or "$".  You may, however, wish to treat a
@@ -80,7 +80,7 @@ string as a multi-line buffer, such that the "^" will match after any
 newline within the string, and "$" will match before any newline.  At the
 cost of a little more overhead, you can do this by using the /m modifier
 on the pattern match operator.  (Older programs did this by setting C<$*>,
-but this practice is deprecated in Perl 5.)
+but this practice is now deprecated.)
 
 To facilitate multi-line substitutions, the "." character never matches a
 newline unless you use the C</s> modifier, which in effect tells Perl to pretend
@@ -102,7 +102,7 @@ as a regular character.)  The "*" modifier is equivalent to C<{0,}>, the "+"
 modifier to C<{1,}>, and the "?" modifier to C<{0,1}>.  n and m are limited
 to integral values less than 65536.
 
-By default, a quantified subpattern is "greedy", that is, it will match as
+By default, a quantified sub-pattern is "greedy", that is, it will match as
 many times as possible without causing the rest of the pattern not to match.  
 The standard quantifiers are all "greedy", in that they match as many
 occurrences as possible (given a particular starting location) without
@@ -117,7 +117,7 @@ Note that the meanings don't change, just the "gravity":
     {n,}?  Match at least n times
     {n,m}? Match at least n but not more than m times
 
-Since patterns are processed as double quoted strings, the following
+Because patterns are processed as double quoted strings, the following
 also work:
 
     \t         tab                   (HT, TAB)
@@ -147,15 +147,15 @@ In addition, Perl defines the following:
 
 Note that C<\w> matches a single alphanumeric character, not a whole
 word.  To match a word you'd need to say C<\w+>.  You may use C<\w>,
-C<\W>, C<\s>, C<\S>, C<\d> and C<\D> within character classes (though not
+C<\W>, C<\s>, C<\S>, C<\d>, and C<\D> within character classes (though not
 as either end of a range).
 
 Perl defines the following zero-width assertions:
 
     \b Match a word boundary
     \B Match a non-(word boundary)
-    \A Match only at beginning of string
-    \Z Match only at end of string (or before newline at the end)
+    \A Match at only beginning of string
+    \Z Match at only end of string (or before newline at the end)
     \G Match only where previous m//g left off
 
 A word boundary (C<\b>) is defined as a spot between two characters that
@@ -175,13 +175,13 @@ outside the current pattern, this should not be relied upon.  See the
 WARNING below.) The scope of $E<lt>digitE<gt> (and C<$`>, C<$&>, and C<$'>)
 extends to the end of the enclosing BLOCK or eval string, or to the next
 successful pattern match, whichever comes first.  If you want to use
-parentheses to delimit a subpattern (e.g. a set of alternatives) without
+parentheses to delimit a subpattern (e.g., a set of alternatives) without
 saving it as a subpattern, follow the ( with a ?:.
 
 You may have as many parentheses as you wish.  If you have more
 than 9 substrings, the variables $10, $11, ... refer to the
 corresponding substring.  Within the pattern, \10, \11, etc. refer back
-to substrings if there have been at least that many left parens before
+to substrings if there have been at least that many left parentheses before
 the backreference.  Otherwise (for backward compatibility) \10 is the
 same as \010, a backspace, and \11 the same as \011, a tab.  And so
 on.  (\1 through \9 are always backreferences.)
@@ -203,9 +203,9 @@ You will note that all backslashed metacharacters in Perl are
 alphanumeric, such as C<\b>, C<\w>, C<\n>.  Unlike some other regular expression
 languages, there are no backslashed symbols that aren't alphanumeric.
 So anything that looks like \\, \(, \), \E<lt>, \E<gt>, \{, or \} is always
-interpreted as a literal character, not a metacharacter.  This makes it
+interpreted as a literal character, not a meta-character.  This makes it
 simple to quote a string that you want to use for a pattern but that
-you are afraid might contain metacharacters.  Simply quote all the
+you are afraid might contain metacharacters.  Quote simply all the
 non-alphanumeric characters:
 
     $pattern =~ s/(\W)/\\$1/g;
@@ -216,11 +216,11 @@ is to say
 
     /$unquoted\Q$quoted\E$unquoted/
 
-Perl 5 defines a consistent extension syntax for regular expressions.
-The syntax is a pair of parens with a question mark as the first thing
-within the parens (this was a syntax error in Perl 4).  The character
-after the question mark gives the function of the extension.  Several
-extensions are already supported:
+Perl defines a consistent extension syntax for regular expressions.
+The syntax is a pair of parentheses with a question mark as the first
+thing within the parentheses (this was a syntax error in older
+versions of Perl).  The character after the question mark gives the
+function of the extension.  Several extensions are already supported:
 
 =over 10
 
@@ -268,7 +268,7 @@ easier just to say:
 One or more embedded pattern-match modifiers.  This is particularly
 useful for patterns that are specified in a table somewhere, some of
 which want to be case sensitive, and some of which don't.  The case
-insensitive ones merely need to include C<(?i)> at the front of the
+insensitive ones need to include merely C<(?i)> at the front of the
 pattern.  For example:
 
     $pattern = "foobar";
@@ -390,11 +390,10 @@ As you see, this can be a bit tricky.  It's important to realize that a
 regular expression is merely a set of assertions that gives a definition
 of success.  There may be 0, 1, or several different ways that the
 definition might succeed against a particular string.  And if there are
-multiple ways it might succeed, you need to understand backtracking in
-order to know which variety of success you will achieve.
+multiple ways it might succeed, you need to understand backtracking to know which variety of success you will achieve.
 
 When using lookahead assertions and negations, this can all get even
-tricker.  Imagine you'd like to find a sequence of nondigits not 
+tricker.  Imagine you'd like to find a sequence of non-digits not 
 followed by "123".  You might try to write that as
 
        $_ = "ABC123";
@@ -421,12 +420,12 @@ This prints
     3: got AB
     4: got ABC
 
-You might have expected test 3 to fail because it just seems to a more
+You might have expected test 3 to fail because it seems to a more
 general purpose version of test 1.  The important difference between
 them is that test 3 contains a quantifier (C<\D*>) and so can use
 backtracking, whereas test 1 will not.  What's happening is
 that you've asked "Is it true that at the start of $x, following 0 or more
-nondigits, you have something that's not 123?"  If the pattern matcher had
+non-digits, you have something that's not 123?"  If the pattern matcher had
 let C<\D*> expand to "ABC", this would have caused the whole pattern to
 fail.  
 The search engine will initially match C<\D*> with "ABC".  Then it will
@@ -437,7 +436,7 @@ in the hope of matching the complete regular expression.
 
 Well now, 
 the pattern really, I<really> wants to succeed, so it uses the
-standard regexp backoff-and-retry and lets C<\D*> expand to just "AB" this
+standard regexp back-off-and-retry and lets C<\D*> expand to just "AB" this
 time.  Now there's indeed something following "AB" that is not
 "123".  It's in fact "C123", which suffices.
 
@@ -477,10 +476,10 @@ it would take literally forever--or until you ran out of stack space.
 In case you're not familiar with the "regular" Version 8 regexp
 routines, here are the pattern-matching rules not described above.
 
-Any single character matches itself, unless it is a I<metacharacter>
+Any single character matches itself, unless it is a I<meta-character>
 with a special meaning described here or above.  You can cause
 characters which normally function as metacharacters to be interpreted
-literally by prefixing them with a "\" (e.g. "\." matches a ".", not any
+literally by prefixing them with a "\" (e.g., "\." matches a ".", not any
 character; "\\" matches a "\").  A series of characters matches that
 series of characters in the target string, so the pattern C<blurfl>
 would match "blurfl" in the target string.
@@ -492,13 +491,13 @@ in the list.  Within a list, the "-" character is used to specify a
 range, so that C<a-z> represents all the characters between "a" and "z",
 inclusive.
 
-Characters may be specified using a metacharacter syntax much like that
+Characters may be specified using a meta-character syntax much like that
 used in C: "\n" matches a newline, "\t" a tab, "\r" a carriage return,
 "\f" a form feed, etc.  More generally, \I<nnn>, where I<nnn> is a string
 of octal digits, matches the character whose ASCII value is I<nnn>.
 Similarly, \xI<nn>, where I<nn> are hexadecimal digits, matches the
 character whose ASCII value is I<nn>. The expression \cI<x> matches the
-ASCII character control-I<x>.  Finally, the "." metacharacter matches any
+ASCII character control-I<x>.  Finally, the "." meta-character matches any
 character except "\n" (unless you use C</s>).
 
 You can specify a series of alternatives for a pattern using "|" to
@@ -513,14 +512,14 @@ start and end.  Note however that "|" is interpreted as a literal with
 square brackets, so if you write C<[fee|fie|foe]> you're really only
 matching C<[feio|]>.
 
-Within a pattern, you may designate subpatterns for later reference by
+Within a pattern, you may designate sub-patterns for later reference by
 enclosing them in parentheses, and you may refer back to the I<n>th
-subpattern later in the pattern using the metacharacter \I<n>.
-Subpatterns are numbered based on the left to right order of their
+sub-pattern later in the pattern using the meta-character \I<n>.
+Sub-patterns are numbered based on the left to right order of their
 opening parenthesis.  Note that a backreference matches whatever
-actually matched the subpattern in the string being examined, not the
-rules for that subpattern.  Therefore, C<(0|0x)\d*\s\1\d*> will
-match "0x1234 0x4321",but not "0x1234 01234", since subpattern 1
+actually matched the sub-pattern in the string being examined, not the
+rules for that sub-pattern.  Therefore, C<(0|0x)\d*\s\1\d*> will
+match "0x1234 0x4321",but not "0x1234 01234", because sub-pattern 1
 actually matched "0x", even though the rule C<0|0x> could
 potentially match the leading 0 in the second number.
 
@@ -532,7 +531,7 @@ Some people get too used to writing things like
 
 This is grandfathered for the RHS of a substitute to avoid shocking the
 B<sed> addicts, but it's a dirty habit to get into.  That's because in
-PerlThink, the right-hand side of a C<s///> is a double-quoted string.  C<\1> in
+PerlThink, the righthand side of a C<s///> is a double-quoted string.  C<\1> in
 the usual double-quoted string means a control-A.  The customary Unix
 meaning of C<\1> is kludged in for C<s///>.  However, if you get into the habit
 of doing that, you get yourself into trouble if you then add an C</e>
index 5303c3a..bbbe57f 100644 (file)
@@ -7,9 +7,9 @@ perlref - Perl references and nested data structures
 Before release 5 of Perl it was difficult to represent complex data
 structures, because all references had to be symbolic, and even that was
 difficult to do when you wanted to refer to a variable rather than a
-symbol table entry.  Perl 5 not only makes it easier to use symbolic
+symbol table entry.  Perl not only makes it easier to use symbolic
 references to variables, but lets you have "hard" references to any piece
-of data.  Any scalar may hold a hard reference.  Since arrays and hashes
+of data.  Any scalar may hold a hard reference.  Because arrays and hashes
 contain scalars, you can now easily build arrays of arrays, arrays of
 hashes, hashes of arrays, arrays of hashes of functions, and so on.
 
@@ -25,7 +25,7 @@ references to objects that have been officially "blessed" into a class package.)
 
 
 A symbolic reference contains the name of a variable, just as a
-symbolic link in the filesystem merely contains the name of a file.  
+symbolic link in the filesystem contains merely the name of a file.  
 The C<*glob> notation is a kind of symbolic reference.  Hard references
 are more like hard links in the file system: merely another way
 at getting at the same underlying object, irrespective of its name.
@@ -44,7 +44,7 @@ References can be constructed several ways.
 
 By using the backslash operator on a variable, subroutine, or value.
 (This works much like the & (address-of) operator works in C.)  Note
-that this typically creates I<ANOTHER> reference to a variable, since
+that this typically creates I<ANOTHER> reference to a variable, because
 there's already a reference to the variable in the symbol table.  But
 the symbol table reference might go away, and you'll still have the
 reference that the backslash returned.  Here are some examples:
@@ -55,9 +55,11 @@ reference that the backslash returned.  Here are some examples:
     $coderef   = \&handler;
     $globref   = \*foo;
 
-It isn't possible to create a reference to an IO handle (filehandle or
+It isn't possible to create a true reference to an IO handle (filehandle or
 dirhandle) using the backslash operator.  See the explanation of the
-*foo{THING} syntax below.
+*foo{THING} syntax below.  (However, you're apt to find Perl code
+out there using globrefs as though they were IO handles, which is 
+grandfathered into continued functioning.)
 
 =item 2.
 
@@ -167,7 +169,7 @@ newprint() I<despite> the fact that the "my $x" has seemingly gone out of
 scope by the time the anonymous subroutine runs.  That's what closure
 is all about.
 
-This only applies to lexical variables, by the way.  Dynamic variables
+This applies to only lexical variables, by the way.  Dynamic variables
 continue to work as they have always worked.  Closure is not something
 that most Perl programmers need trouble themselves about to begin with.
 
@@ -186,7 +188,7 @@ named new(), but don't have to be:
 =item 6.
 
 References of the appropriate type can spring into existence if you
-dereference them in a context that assumes they exist.  Since we haven't
+dereference them in a context that assumes they exist.  Because we haven't
 talked about dereferencing yet, we can't show you any examples yet.
 
 =item 7.
@@ -209,8 +211,13 @@ IO handle, used for file handles (L<perlfunc/open>), sockets
 (L<perlfunc/opendir>).  For compatibility with previous versions of
 Perl, *foo{FILEHANDLE} is a synonym for *foo{IO}.
 
-The use of *foo{IO} is the best way to pass bareword filehandles into
-or out of subroutines, or to store them in larger data structures.
+*foo{THING} returns undef if that particular THING hasn't been used yet,
+except in the case of scalars.  *foo{SCALAR} returns a reference to an
+anonymous scalar if $foo hasn't been used yet.  This might change in a
+future release.
+
+The use of *foo{IO} is the best way to pass bareword filehandles into or
+out of subroutines, or to store them in larger data structures.
 
     splutter(*STDOUT{IO});
     sub splutter {
@@ -224,9 +231,18 @@ or out of subroutines, or to store them in larger data structures.
        return scalar <$fh>;
     }
 
-The best way to do this used to be to use the entire *foo typeglob (or a
-reference to it), so you'll probably come across old code which does it
-that way.
+Beware, though, that you can't do this with a routine which is going to
+open the filehandle for you, because *HANDLE{IO} will be undef if HANDLE
+hasn't been used yet.  Use \*HANDLE for that sort of thing instead.
+
+Using \*HANDLE (or *HANDLE) is another way to use and store non-bareword
+filehandles (before 5.002 it was the only way).  The two methods are
+largely interchangeable, you can do
+
+    splutter(\*STDOUT);
+    $rec = get_rec(\*STDIN);
+
+with the above subroutine definitions.
 
 =back
 
@@ -282,7 +298,7 @@ subscripted expressions:
 Because of being able to omit the curlies for the simple case of C<$$x>,
 people often make the mistake of viewing the dereferencing symbols as
 proper operators, and wonder about their precedence.  If they were,
-though, you could use parens instead of braces.  That's not the case.
+though, you could use parentheses instead of braces.  That's not the case.
 Consider the difference below; case 0 is a short-hand version of case 1,
 I<NOT> case 2:
 
@@ -348,7 +364,7 @@ reference is pointing to.  See L<perlfunc>.
 The bless() operator may be used to associate a reference with a package
 functioning as an object class.  See L<perlobj>.
 
-A typeglob may be dereferenced the same way a reference can, since
+A typeglob may be dereferenced the same way a reference can, because
 the dereference syntax always indicates the kind of reference desired.
 So C<${*foo}> and C<${\$foo}> both indicate the same scalar variable.
 
@@ -447,7 +463,7 @@ subscripting a hash.  So now, instead of writing
 
     $array{ "aaa" }{ "bbb" }{ "ccc" }
 
-you can just write
+you can write just
 
     $array{ aaa }{ bbb }{ ccc }
 
@@ -464,7 +480,7 @@ makes it more than a bareword:
     $array{ shift @_ }
 
 The B<-w> switch will warn you if it interprets a reserved word as a string.
-But it will no longer warn you about using lowercase words, since the
+But it will no longer warn you about using lowercase words, because the
 string is effectively quoted.
 
 =head1 WARNING
index c69a03e..083b567 100644 (file)
@@ -33,7 +33,7 @@ Contained in the file specified by the first filename on the command line.
 
 =item 3.
 
-Passed in implicitly via standard input.  This only works if there are
+Passed in implicitly via standard input.  This works only if there are
 no filename arguments--to pass arguments to a STDIN script you
 must explicitly specify a "-" for the script name.
 
@@ -46,11 +46,11 @@ scans for the first line starting with #! and containing the word
 embedded in a larger message.  (In this case you would indicate the end
 of the script using the __END__ token.)
 
-As of Perl 5, the #! line is always examined for switches as the line is
-being parsed.  Thus, if you're on a machine that only allows one argument
-with the #! line, or worse, doesn't even recognize the #! line, you still
-can get consistent switch behavior regardless of how Perl was invoked,
-even if B<-x> was used to find the beginning of the script.
+The #! line is always examined for switches as the line is being
+parsed.  Thus, if you're on a machine that allows only one argument
+with the #! line, or worse, doesn't even recognize the #! line, you
+still can get consistent switch behavior regardless of how Perl was
+invoked, even if B<-x> was used to find the beginning of the script.
 
 Because many operating systems silently chop off kernel interpretation of
 the #! line after 32 characters, some switches may be passed in on the
@@ -67,8 +67,8 @@ The sequences "-*" and "- " are specifically ignored so that you could,
 if you were so inclined, say
 
     #!/bin/sh -- # -*- perl -*- -p
-    eval 'exec perl $0 -S ${1+"$@"}'
-       if 0;
+    eval 'exec /usr/bin/perl $0 -S ${1+"$@"}'
+        if $running_under_some_shell;
 
 to let Perl see the B<-p> switch.
 
@@ -109,7 +109,7 @@ can say this:
     find . -name '*.bak' -print0 | perl -n0e unlink
 
 The special value 00 will cause Perl to slurp files in paragraph mode.
-The value 0777 will cause Perl to slurp files whole since there is no
+The value 0777 will cause Perl to slurp files whole because there is no
 legal character with that value.
 
 =item B<-a>
@@ -133,7 +133,7 @@ An alternate delimiter may be specified using B<-F>.
 
 causes Perl to check the syntax of the script and then exit without
 executing it.  Actually, it I<will> execute C<BEGIN>, C<END>, and C<use> blocks,
-since these are considered as occurring outside the execution of 
+because these are considered as occurring outside the execution of 
 your program.
 
 =item B<-d>
@@ -151,10 +151,10 @@ Devel::DProf profiler.  See L<perldebug>.
 =item B<-D>I<list>
 
 sets debugging flags.  To watch how it executes your script, use
-B<-D14>.  (This only works if debugging is compiled into your
+B<-D14>.  (This works only if debugging is compiled into your
 Perl.)  Another nice value is B<-D1024>, which lists your compiled
 syntax tree.  And B<-D512> displays compiled regular expressions. As an
-alternative specify a list of letters instead of numbers (e.g. B<-D14> is
+alternative specify a list of letters instead of numbers (e.g., B<-D14> is
 equivalent to B<-Dtls>):
 
         1  p  Tokenizing and Parsing
@@ -186,7 +186,7 @@ Make sure to use semicolons where you would in a normal program.
 =item B<-F>I<pattern>
 
 specifies the pattern to split on if B<-a> is also in effect.  The
-pattern may be surrounded by C<//>, C<""> or C<''>, otherwise it will be
+pattern may be surrounded by C<//>, C<"">, or C<''>, otherwise it will be
 put in single quotes.
 
 =item B<-h>
@@ -330,9 +330,9 @@ the implicit loop, just as in awk.
 =item B<-P>
 
 causes your script to be run through the C preprocessor before
-compilation by Perl.  (Since both comments and cpp directives begin
+compilation by Perl.  (Because both comments and cpp directives begin
 with the # character, you should avoid starting comments with any words
-recognized by the C preprocessor such as "if", "else" or "define".)
+recognized by the C preprocessor such as "if", "else", or "define".)
 
 =item B<-s>
 
@@ -353,7 +353,7 @@ this is used to emulate #! startup on machines that don't support #!,
 in the following manner:
 
     #!/usr/bin/perl
-    eval "exec /usr/bin/perl -S $0 $*"
+    eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
            if $running_under_some_shell;
 
 The system ignores the first line and feeds the script to /bin/sh,
@@ -365,15 +365,15 @@ script if necessary.  After Perl locates the script, it parses the
 lines and ignores them because the variable $running_under_some_shell
 is never true.  A better construct than C<$*> would be C<${1+"$@"}>, which
 handles embedded spaces and such in the filenames, but doesn't work if
-the script is being interpreted by csh.  In order to start up sh rather
+the script is being interpreted by csh.  To start up sh rather
 than csh, some systems may have to replace the #! line with a line
 containing just a colon, which will be politely ignored by Perl.  Other
 systems can't control that, and need a totally devious construct that
-will work under any of csh, sh or Perl, such as the following:
+will work under any of csh, sh, or Perl, such as the following:
 
        eval '(exit $?0)' && eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
        & eval 'exec /usr/bin/perl -S $0 $argv:q'
-               if 0;
+               if $running_under_some_shell;
 
 =item B<-T>
 
@@ -419,7 +419,7 @@ Prints to STDOUT the value of the named configuration variable.
 prints warnings about variable names that are mentioned only once, and
 scalar variables that are used before being set.  Also warns about
 redefined subroutines, and references to undefined filehandles or
-filehandles opened readonly that you are attempting to write on.  Also
+filehandles opened read-only that you are attempting to write on.  Also
 warns you if you use values as a number that doesn't look like numbers, using
 an array as though it were a scalar, if
 your subroutines recurse more than 100 deep, and innumerable other things.
@@ -432,8 +432,8 @@ garbage will be discarded until the first line that starts with #! and
 contains the string "perl".  Any meaningful switches on that line will
 be applied (but only one group of switches, as with normal #!
 processing).  If a directory name is specified, Perl will switch to
-that directory before running the script.  The B<-x> switch only
-controls the the disposal of leading garbage.  The script must be
+that directory before running the script.  The B<-x> switch controls
+only the disposal of leading garbage.  The script must be
 terminated with C<__END__> if there is trailing garbage to be ignored (the
 script can process any or all of the trailing garbage via the DATA
 filehandle if desired).
index facdded..2b69727 100644 (file)
@@ -1,4 +1,3 @@
-
 =head1 NAME
 
 perlsec - Perl security
@@ -17,7 +16,7 @@ Perl automatically enables a set of special security checks, called I<taint
 mode>, when it detects its program running with differing real and effective
 user or group IDs.  The setuid bit in Unix permissions is mode 04000, the
 setgid bit mode 02000; either or both may be set.  You can also enable taint
-mode explicitly by using the the B<-T> command line flag. This flag is
+mode explicitly by using the B<-T> command line flag. This flag is
 I<strongly> suggested for server programs and any program run on behalf of
 someone else, such as a CGI script.
 
@@ -33,7 +32,7 @@ You may not use data derived from outside your program to affect something
 else outside your program--at least, not by accident.  All command-line
 arguments, environment variables, and file input are marked as "tainted".
 Tainted data may not be used directly or indirectly in any command that
-invokes a subshell, nor in any command that modifies files, directories,
+invokes a sub-shell, nor in any command that modifies files, directories,
 or processes.  Any variable set within an expression that has previously
 referenced a tainted value itself becomes tainted, even if it is logically
 impossible for the tainted value to influence the variable.  Because
@@ -102,9 +101,9 @@ taintedness.  Instead, the slightly more efficient and conservative
 approach is used that if any tainted value has been accessed within the
 same expression, the whole expression is considered tainted.
 
-But testing for taintedness only gets you so far.  Sometimes you just have
+But testing for taintedness gets you only so far.  Sometimes you have just
 to clear your data's taintedness.  The only way to bypass the tainting
-mechanism is by referencing subpatterns from a regular expression match.
+mechanism is by referencing sub-patterns from a regular expression match.
 Perl presumes that if you reference a substring using $1, $2, etc., that
 you knew what you were doing when you wrote the pattern.  That means using
 a bit of thought--don't just blindly untaint anything, or you defeat the
@@ -123,7 +122,7 @@ or a dot.
        die "Bad data in $data";        # log this somewhere
     }
 
-This is fairly secure since C</\w+/> doesn't normally match shell
+This is fairly secure because C</\w+/> doesn't normally match shell
 metacharacters, nor are dot, dash, or at going to mean something special
 to the shell.  Use of C</.+/> would have been insecure in theory because
 it lets everything through, but Perl doesn't check for that.  The lesson
@@ -156,7 +155,7 @@ prevent stupid mistakes, not to remove the need for thought.
 Perl does not call the shell to expand wild cards when you pass B<system>
 and B<exec> explicit parameter lists instead of strings with possible shell
 wildcards in them.  Unfortunately, the B<open>, B<glob>, and
-backtick functions provide no such alternate calling convention, so more
+back-tick functions provide no such alternate calling convention, so more
 subterfuge will be required.  
 
 Perl provides a reasonably safe way to open a file or pipe from a setuid
@@ -168,11 +167,11 @@ environment variables, umasks, current working directories, back to the
 originals or known safe values.  Then the child process, which no longer
 has any special permissions, does the B<open> or other system call.
 Finally, the child passes the data it managed to access back to the
-parent.  Since the file or pipe was opened in the child while running
+parent.  Because the file or pipe was opened in the child while running
 under less privilege than the parent, it's not apt to be tricked into
 doing something it shouldn't.
 
-Here's a way to do backticks reasonably safely.  Notice how the B<exec> is
+Here's a way to do back-ticks reasonably safely.  Notice how the B<exec> is
 not called with a string that the shell could expand.  This is by far the
 best way to call something that might be subjected to shell escapes: just
 never call the shell at all.  By the time we get to the B<exec>, tainting
index 46c17dd..734b9ad 100644 (file)
@@ -32,7 +32,7 @@ Opening curly on same line as keyword, if possible, otherwise line up.
 
 =item *
 
-Space before the opening curly of a multiline BLOCK.
+Space before the opening curly of a multi-line BLOCK.
 
 =item *
 
@@ -64,7 +64,7 @@ Uncuddled elses.
 
 =item *
 
-No space between function name and its opening paren.
+No space between function name and its opening parenthesis.
 
 =item *
 
@@ -76,7 +76,7 @@ Long lines broken after an operator (except "and" and "or").
 
 =item *
 
-Space after last paren matching on current line.
+Space after last parenthesis matching on current line.
 
 =item *
 
@@ -117,7 +117,7 @@ is better than
 
     $verbose && print "Starting analysis\n";
 
-since the main point isn't whether the user typed B<-v> or not.
+because the main point isn't whether the user typed B<-v> or not.
 
 Similarly, just because an operator lets you assume default arguments
 doesn't mean that you have to make use of the defaults.  The defaults
@@ -135,7 +135,7 @@ schmuck bounce on the % key in B<vi>.
 
 Even if you aren't in doubt, consider the mental welfare of the person
 who has to maintain the code after you, and who will probably put
-parens in the wrong place.
+parentheses in the wrong place.
 
 =item *
 
@@ -189,7 +189,7 @@ Package names are sometimes an exception to this rule.  Perl informally
 reserves lowercase module names for "pragma" modules like C<integer> and
 C<strict>.  Other modules should begin with a capital letter and use mixed
 case, but probably without underscores due to limitations in primitive
-filesystems' representations of module names as files that must fit into a
+file systems' representations of module names as files that must fit into a
 few sparse bites.
 
 =item *
@@ -216,9 +216,9 @@ Don't use slash as a delimiter when your regexp has slashes or backslashes.
 =item *
 
 Use the new "and" and "or" operators to avoid having to parenthesize
-list operators so much, and to reduce the incidence of punctuational
+list operators so much, and to reduce the incidence of punctuation
 operators like C<&&> and C<||>.  Call your subroutines as if they were
-functions or list operators to avoid excessive ampersands and parens.
+functions or list operators to avoid excessive ampersands and parentheses.
 
 =item *
 
index 1c3a3c0..6bd3fe8 100644 (file)
@@ -22,8 +22,8 @@ To import subroutines:
 
 To call subroutines:
 
-    NAME(LIST);           # & is optional with parens.
-    NAME LIST;    # Parens optional if predeclared/imported.
+    NAME(LIST);           # & is optional with parentheses.
+    NAME LIST;    # Parentheses optional if pre-declared/imported.
     &NAME;        # Passes current @_ to subroutine.
 
 =head1 DESCRIPTION
@@ -105,7 +105,7 @@ Use array assignment to a local list to name your formal arguments:
     }
 
 This also has the effect of turning call-by-reference into call-by-value,
-since the assignment copies the values.  Otherwise a function is free to
+because the assignment copies the values.  Otherwise a function is free to
 do in-place modifications of @_ and change its caller's values.
 
     upcase_in($v1, $v2);  # this changes $v1 and $v2
@@ -149,13 +149,14 @@ Because like its flat incoming parameter list, the return list is also
 flat.  So all you have managed to do here is stored everything in @a and
 made @b an empty list.  See L</"Pass by Reference"> for alternatives.
 
-A subroutine may be called using the "&" prefix.  The "&" is optional in
-Perl 5, and so are the parens if the subroutine has been predeclared.
-(Note, however, that the "&" is I<NOT> optional when you're just naming
-the subroutine, such as when it's used as an argument to defined() or
-undef().  Nor is it optional when you want to do an indirect subroutine
-call with a subroutine name or reference using the C<&$subref()> or
-C<&{$subref}()> constructs.  See L<perlref> for more on that.)
+A subroutine may be called using the "&" prefix.  The "&" is optional
+in modern Perls, and so are the parentheses if the subroutine has been
+pre-declared.  (Note, however, that the "&" is I<NOT> optional when
+you're just naming the subroutine, such as when it's used as an
+argument to defined() or undef().  Nor is it optional when you want to
+do an indirect subroutine call with a subroutine name or reference
+using the C<&$subref()> or C<&{$subref}()> constructs.  See L<perlref>
+for more on that.)
 
 Subroutines may be called recursively.  If a subroutine is called using
 the "&" form, the argument list is optional, and if omitted, no @_ array is
@@ -190,7 +191,7 @@ A "my" declares the listed variables to be confined (lexically) to the
 enclosing block, conditional (C<if/unless/elsif/else>), loop
 (C<for/foreach/while/until/continue>), subroutine, C<eval>, or
 C<do/require/use>'d file.  If more than one value is listed, the list
-must be placed in parens.  All listed elements must be legal lvalues.
+must be placed in parentheses.  All listed elements must be legal lvalues.
 Only alphanumeric identifiers may be lexically scoped--magical
 builtins like $/ must currently be localized with "local" instead.
 
@@ -226,11 +227,11 @@ change whether those variables is viewed as a scalar or an array.  So
     my ($foo) = <STDIN>;
     my @FOO = <STDIN>;
 
-both supply a list context to the righthand side, while
+both supply a list context to the right-hand side, while
 
     my $foo = <STDIN>;
 
-supplies a scalar context.  But the following only declares one variable:
+supplies a scalar context.  But the following declares only one variable:
 
     my $foo, $bar = 1;
 
@@ -282,7 +283,7 @@ but not beyond it.
 modifiers appended to simple statements.  Such modifiers are not
 control structures and have no effect on scoping.)
 
-The C<foreach> loop defaults to dynamically scoping its index variable
+The C<foreach> loop defaults to scoping its index variable dynamically
 (in the manner of C<local>; see below).  However, if the index
 variable is prefixed with the keyword "my", then it is lexically
 scoped instead.  Thus in the loop
@@ -328,8 +329,8 @@ lexical of the same name is also visible:
 
 That will print out 20 and 10.
 
-You may declare "my" variables at the outer most scope of a file to
-totally hide any such identifiers from the outside world.  This is similar
+You may declare "my" variables at the outermost scope of a file to
+hide any such identifiers totally from the outside world.  This is similar
 to C's static variables at the file level.  To do this with a subroutine
 requires the use of a closure (anonymous function).  If a block (such as
 an eval(), function, or C<package>) wants to create a private subroutine
@@ -341,7 +342,7 @@ variable containing an anonymous sub reference:
     &$secret_sub();
 
 As long as the reference is never returned by any function within the
-module, no outside module can see the subroutine, since its name is not in
+module, no outside module can see the subroutine, because its name is not in
 any package's symbol table.  Remember that it's not I<REALLY> called
 $some_pack::secret_version or anything; it's just $secret_version,
 unqualified and unqualifiable.
@@ -370,7 +371,7 @@ If this function is being sourced in from a separate file
 via C<require> or C<use>, then this is probably just fine.  If it's
 all in the main program, you'll need to arrange for the my() 
 to be executed early, either by putting the whole block above
-your pain program, or more likely, merely placing a BEGIN 
+your pain program, or more likely, placing merely a BEGIN 
 sub around it to make sure it gets executed before your program
 starts to run:
 
@@ -406,15 +407,15 @@ Synopsis:
     local *merlyn = \$randal;   # just alias $merlyn, not @merlyn etc 
 
 A local() modifies its listed variables to be local to the enclosing
-block, (or subroutine, C<eval{}> or C<do>) and I<any called from
+block, (or subroutine, C<eval{}>, or C<do>) and I<any called from
 within that block>.  A local() just gives temporary values to global
 (meaning package) variables.  This is known as dynamic scoping.  Lexical
 scoping is done with "my", which works more like C's auto declarations.
 
 If more than one variable is given to local(), they must be placed in
-parens.  All listed elements must be legal lvalues.  This operator works
+parentheses.  All listed elements must be legal lvalues.  This operator works
 by saving the current values of those variables in its argument list on a
-hidden stack and restoring them upon exiting the block, subroutine or
+hidden stack and restoring them upon exiting the block, subroutine, or
 eval.  This means that called subroutines can also reference the local
 variable, but not the global one.  The argument list may be assigned to if
 desired, which allows you to initialize your local variables.  (If no
@@ -449,7 +450,7 @@ as a scalar or an array.  So
     local($foo) = <STDIN>;
     local @FOO = <STDIN>;
 
-both supply a list context to the righthand side, while
+both supply a list context to the right-hand side, while
 
     local $foo = <STDIN>;
 
@@ -466,12 +467,12 @@ Sometimes you don't want to pass the value of an array to a subroutine
 but rather the name of it, so that the subroutine can modify the global
 copy of it rather than working with a local copy.  In perl you can
 refer to all objects of a particular name by prefixing the name
-with a star: C<*foo>.  This is often known as a "typeglob", since the
+with a star: C<*foo>.  This is often known as a "typeglob", because the
 star on the front can be thought of as a wildcard match for all the
 funny prefix characters on variables and subroutines and such.
 
 When evaluated, the typeglob produces a scalar value that represents
-all the objects of that name, including any filehandle, format or
+all the objects of that name, including any filehandle, format, or
 subroutine.  When assigned to, it causes the name mentioned to refer to
 whatever "*" value was assigned to it.  Example:
 
@@ -488,11 +489,11 @@ Note that scalars are already passed by reference, so you can modify
 scalar arguments without using this mechanism by referring explicitly
 to C<$_[0]> etc.  You can modify all the elements of an array by passing
 all the elements as scalars, but you have to use the * mechanism (or
-the equivalent reference mechanism) to push, pop or change the size of
+the equivalent reference mechanism) to push, pop, or change the size of
 an array.  It will certainly be faster to pass the typeglob (or reference).
 
 Even if you don't want to modify an array, this mechanism is useful for
-passing multiple arrays in a single LIST, since normally the LIST
+passing multiple arrays in a single LIST, because normally the LIST
 mechanism will merge all the array values so that you can't extract out
 the individual arrays.  For more on typeglobs, see
 L<perldata/"Typeglobs and FileHandles">.
@@ -534,9 +535,9 @@ list of keys occurring in all the hashes passed to it:
        return grep { $seen{$_} == @_ } keys %seen;
     } 
 
-So far, we're just using the normal list return mechanism.
+So far, we're using just the normal list return mechanism.
 What happens if you want to pass or return a hash?  Well, 
-if you're only using one of them, or you don't mind them 
+if you're using only one of them, or you don't mind them 
 concatenating, then the normal calling convention is ok, although
 a little expensive.  
 
@@ -546,7 +547,7 @@ Where people get into trouble is here:
 or
     (%a, %b) = func(%c, %d);
 
-That syntax simply won't work.  It just sets @a or %a and clears the @b or
+That syntax simply won't work.  It sets just @a or %a and clears the @b or
 %b.  Plus the function didn't get passed into two separate arrays or
 hashes: it got one long list in @_, as always.
 
@@ -581,7 +582,38 @@ It turns out that you can actually do this also:
 
 Here we're using the typeglobs to do symbol table aliasing.  It's
 a tad subtle, though, and also won't work if you're using my()
-variables, since only globals (well, and local()s) are in the symbol table.
+variables, because only globals (well, and local()s) are in the symbol table.
+
+If you're passing around filehandles, you could usually just use the bare
+typeglob, like *STDOUT, but typeglobs references would be better because
+they'll still work properly under C<use strict 'refs'>.  For example:
+
+    splutter(\*STDOUT);
+    sub splutter {
+       my $fh = shift;
+       print $fh "her um well a hmmm\n";
+    }
+
+    $rec = get_rec(\*STDIN);
+    sub get_rec {
+       my $fh = shift;
+       return scalar <$fh>;
+    }
+
+Another way to do this is using *HANDLE{IO}, see L<perlref> for usage
+and caveats.
+
+If you're planning on generating new filehandles, you could do this:
+
+    sub openit {
+       my $name = shift;
+       local *FH;
+       return open (FH, $path) ? \*FH : undef;
+    } 
+
+Although that will actually produce a small memory leak.  See the bottom
+of L<perlfunc/open()> for a somewhat cleaner way using the IO::Handle
+package.
 
 =head2 Prototypes
 
@@ -591,7 +623,7 @@ As of the 5.002 release of perl, if you declare
 
 then mypush() takes arguments exactly like push() does.  The declaration
 of the function to be called must be visible at compile time.  The prototype
-only affects the interpretation of new-style calls to the function, where
+affects only the interpretation of new-style calls to the function, where
 new-style is defined as not using the C<&> character.  In other words,
 if you call it like a builtin function, then it behaves like a builtin
 function.  If you call it like an old-fashioned subroutine, then it
@@ -600,10 +632,10 @@ this rule that prototypes have no influence on subroutine references
 like C<\&foo> or on indirect subroutine calls like C<&{$subref}>.
 
 Method calls are not influenced by prototypes either, because the
-function to be called is indeterminate at compile time, since it depends
+function to be called is indeterminate at compile time, because it depends
 on inheritance.
 
-Since the intent is primarily to let you define subroutines that work
+Because the intent is primarily to let you define subroutines that work
 like builtin commands, here are the prototypes for some other functions
 that parse almost exactly like the corresponding builtins.
 
@@ -644,7 +676,7 @@ A semicolon separates mandatory arguments from optional arguments.
 Note how the last three examples above are treated specially by the parser.
 mygrep() is parsed as a true list operator, myrand() is parsed as a
 true unary operator with unary precedence the same as rand(), and
-mytime() is truly argumentless, just like time().  That is, if you
+mytime() is truly without arguments, just like time().  That is, if you
 say
 
     mytime +2;
@@ -674,7 +706,7 @@ That prints "unphooey".  (Yes, there are still unresolved
 issues having to do with the visibility of @_.  I'm ignoring that
 question for the moment.  (But note that if we make @_ lexically
 scoped, those anonymous subroutines can act like closures... (Gee,
-is this sounding a little Lispish?  (Nevermind.))))
+is this sounding a little Lispish?  (Never mind.))))
 
 And here's a reimplementation of grep:
 
@@ -715,23 +747,23 @@ returning a list:
 Then you've just supplied an automatic scalar() in front of their
 argument, which can be more than a bit surprising.  The old @foo
 which used to hold one thing doesn't get passed in.  Instead,
-the func() now gets passed in 1, that is, the number of elments
+the func() now gets passed in 1, that is, the number of elements
 in @foo.  And the split() gets called in a scalar context and
 starts scribbling on your @_ parameter list.
 
-This is all very powerful, of course, and should only be used in moderation
+This is all very powerful, of course, and should be used only in moderation
 to make the world a better place.  
 
 =head2 Overriding Builtin Functions
 
-Many builtin functions may be overridden, though this should only be
-tried occasionally and for good reason.  Typically this might be
+Many builtin functions may be overridden, though this should be tried
+only occasionally and for good reason.  Typically this might be
 done by a package attempting to emulate missing builtin functionality
 on a non-Unix system.
 
-Overriding may only be done by importing the name from a
+Overriding may be done only by importing the name from a
 module--ordinary predeclaration isn't good enough.  However, the
-C<subs> pragma (compiler directive) lets you, in effect, predeclare subs
+C<subs> pragma (compiler directive) lets you, in effect, pre-declare subs
 via the import syntax, and these names may then override the builtin ones:
 
     use subs 'chdir', 'chroot', 'chmod', 'chown';
@@ -739,7 +771,7 @@ via the import syntax, and these names may then override the builtin ones:
     sub chdir { ... }
 
 Library modules should not in general export builtin names like "open"
-or "chdir" as part of their default @EXPORT list, since these may
+or "chdir" as part of their default @EXPORT list, because these may
 sneak into someone else's namespace and change the semantics unexpectedly.
 Instead, if the module adds the name to the @EXPORT_OK list, then it's
 possible for a user to import the name explicitly, but not implicitly.
@@ -784,7 +816,7 @@ should just call system() with those arguments.  All you'd do is this:
     who('am', 'i');
     ls('-l');
 
-In fact, if you preclare the functions you want to call that way, you don't
+In fact, if you pre-declare the functions you want to call that way, you don't
 even need the parentheses:
 
     use subs qw(date who ls);
index b0f77f4..9cf39a3 100644 (file)
@@ -35,7 +35,7 @@ take effect at compile time.  Typically all the declarations are put at
 the beginning or the end of the script.  However, if you're using 
 lexically-scoped private variables created with my(), you'll have to make sure
 your format or subroutine definition is within the same block scope
-as the my if you expect to to be able to access those private variables.
+as the my if you expect to be able to access those private variables.
 
 Declaring a subroutine allows a subroutine name to be used as if it were a
 list operator from that point forward in the program.  You can declare a
@@ -63,7 +63,7 @@ The only kind of simple statement is an expression evaluated for its
 side effects.  Every simple statement must be terminated with a
 semicolon, unless it is the final statement in a block, in which case
 the semicolon is optional.  (A semicolon is still encouraged there if the
-block takes up more than one line, since you may eventually add another line.)
+block takes up more than one line, because you may eventually add another line.)
 Note that there are some operators like C<eval {}> and C<do {}> that look
 like compound statements, but aren't (they're just TERMs in an expression), 
 and thus need an explicit termination if used as the last item in a statement.
@@ -91,7 +91,7 @@ can write loops like:
     } until $line  eq ".\n";
 
 See L<perlfunc/do>.  Note also that the loop control
-statements described later will I<NOT> work in this construct, since
+statements described later will I<NOT> work in this construct, because
 modifiers don't take loop labels.  Sorry.  You can always wrap
 another block around it to do that sort of thing.
 
@@ -128,7 +128,7 @@ all do the same thing:
     open(FOO) ? 'hi mom' : die "Can't open $FOO: $!";
                        # a bit exotic, that last one
 
-The C<if> statement is straightforward.  Since BLOCKs are always
+The C<if> statement is straightforward.  Because BLOCKs are always
 bounded by curly brackets, there is never any ambiguity about which
 C<if> an C<else> goes with.  If you use C<unless> in place of C<if>,
 the sense of the test is reversed.
@@ -322,7 +322,7 @@ do it:
 See how much easier this is?  It's cleaner, safer, and faster.  It's
 cleaner because it's less noisy.  It's safer because if code gets added
 between the inner and outer loops later on, the new code won't be
-accidentally executed, the C<next> explicitly iterates the other loop
+accidentally executed.  The C<next> explicitly iterates the other loop
 rather than merely terminating the inner one.  And it's faster because
 Perl executes a C<foreach> statement more rapidly than it would the
 equivalent C<for> loop.
@@ -496,7 +496,7 @@ and your documentation text freely, as in
        .........
     } 
 
-Note that pod translators should only look at paragraphs beginning 
+Note that pod translators should look at only paragraphs beginning 
 with a pod directive (it makes parsing easier), whereas the compiler
 actually knows to look for pod escapes even in the middle of a 
 paragraph.  This means that the following secret stuff will be
index 7c43141..7624881 100644 (file)
@@ -13,8 +13,8 @@ perltie - how to hide an object class in a simple variable
 =head1 DESCRIPTION
 
 Prior to release 5.0 of Perl, a programmer could use dbmopen()
-to magically connect an on-disk database in the standard Unix dbm(3x)
-format to a %HASH in their program.  However, their Perl was either
+to connect an on-disk database in the standard Unix dbm(3x)
+format magically to a %HASH in their program.  However, their Perl was either
 built with one particular dbm library or another, but not both, and
 you couldn't extend this mechanism to other packages or types of variables.
 
@@ -33,12 +33,12 @@ In the tie() call, C<VARIABLE> is the name of the variable to be
 enchanted.  C<CLASSNAME> is the name of a class implementing objects of
 the correct type.  Any additional arguments in the C<LIST> are passed to
 the appropriate constructor method for that class--meaning TIESCALAR(),
-TIEARRAY(), TIEHASH() or TIEHANDLE().  (Typically these are arguments
+TIEARRAY(), TIEHASH(), or TIEHANDLE().  (Typically these are arguments
 such as might be passed to the dbminit() function of C.) The object
 returned by the "new" method is also returned by the tie() function,
 which would be useful if you wanted to access other methods in
 C<CLASSNAME>. (You don't actually have to return a reference to a right
-"type" (e.g. HASH or C<CLASSNAME>) so long as it's a properly blessed
+"type" (e.g., HASH or C<CLASSNAME>) so long as it's a properly blessed
 object.)  You can also retrieve a reference to the underlying object
 using the tied() function.
 
@@ -105,8 +105,8 @@ variable C<$^W> to see whether to emit a bit of noise anyway.
 
 This method will be triggered every time the tied variable is accessed
 (read).  It takes no arguments beyond its self reference, which is the
-object representing the scalar we're dealing with.  Since in this case
-we're just using a SCALAR ref for the tied scalar object, a simple $$self
+object representing the scalar we're dealing with.  Because in this case
+we're using just a SCALAR ref for the tied scalar object, a simple $$self
 allows the method to get at the real value stored there.  In our example
 below, that real value is the process ID to which we've tied our variable.
 
@@ -160,7 +160,7 @@ argument--the new value the user is trying to assign.
 =item DESTROY this
 
 This method will be triggered when the tied variable needs to be destructed.
-As with other object classes, such a method is seldom necessary, since Perl
+As with other object classes, such a method is seldom necessary, because Perl
 deallocates its moribund object's memory for you automatically--this isn't
 C++, you know.  We'll use a DESTROY method here for debugging purposes only.
 
@@ -173,7 +173,7 @@ C++, you know.  We'll use a DESTROY method here for debugging purposes only.
 =back
 
 That's about all there is to it.  Actually, it's more than all there
-is to it, since we've done a few nice things here for the sake
+is to it, because we've done a few nice things here for the sake
 of completeness, robustness, and general aesthetics.  Simpler
 TIESCALAR classes are certainly possible.
 
@@ -253,7 +253,7 @@ As you may have noticed, the name of the FETCH method (et al.) is the same
 for all accesses, even though the constructors differ in names (TIESCALAR
 vs TIEARRAY).  While in theory you could have the same class servicing
 several tied types, in practice this becomes cumbersome, and it's easiest
-to simply keep them at one tie type per class.
+to keep them at simply one tie type per class.
 
 =item STORE this, index, value
 
@@ -303,8 +303,8 @@ value pairs.  FIRSTKEY and NEXTKEY implement the keys() and each()
 functions to iterate over all the keys.  And DESTROY is called when the
 tied variable is garbage collected.
 
-If this seems like a lot, then feel free to merely inherit
-from the standard Tie::Hash module for most of your methods, redefining only
+If this seems like a lot, then feel free to inherit from
+merely the standard Tie::Hash module for most of your methods, redefining only
 the interesting ones.  See L<Tie::Hash> for details.
 
 Remember that Perl distinguishes between a key not existing in the hash,
@@ -313,8 +313,8 @@ C<undef>.  The two possibilities can be tested with the C<exists()> and
 C<defined()> functions.
 
 Here's an example of a somewhat interesting tied hash class:  it gives you
-a hash representing a particular user's dotfiles.  You index into the hash
-with the name of the file (minus the dot) and you get back that dotfile's
+a hash representing a particular user's dot files.  You index into the hash
+with the name of the file (minus the dot) and you get back that dot file's
 contents.  For example:
 
     use DotFiles;
@@ -323,7 +323,7 @@ contents.  For example:
          $dot{login}   =~ /MANPATH/ ||
          $dot{cshrc}   =~ /MANPATH/    )
     {
-       print "you seem to set your manpath\n";
+       print "you seem to set your MANPATH\n";
     }
 
 Or here's another sample of using our tied class:
@@ -347,7 +347,7 @@ whose dot files this object represents
 
 =item HOME
 
-where those dotfiles live
+where those dot files live
 
 =item CLOBBER
 
@@ -355,7 +355,7 @@ whether we should try to change or remove those dot files
 
 =item LIST
 
-the hash of dotfile names and content mappings
+the hash of dot file names and content mappings
 
 =back
 
@@ -367,7 +367,7 @@ Here's the start of F<Dotfiles.pm>:
     my $DEBUG = 0;
     sub debug { $DEBUG = @_ ? shift : 1 }
 
-For our example, we want to able to emit debugging info to help in tracing
+For our example, we want to be able to emit debugging info to help in tracing
 during development.  We keep also one convenience function around
 internally to help print out warnings; whowasi() returns the function name
 that calls it.
@@ -413,7 +413,7 @@ Here's the constructor:
 
 It's probably worth mentioning that if you're going to filetest the
 return values out of a readdir, you'd better prepend the directory
-in question.  Otherwise, since we didn't chdir() there, it would
+in question.  Otherwise, because we didn't chdir() there, it would
 have been testing the wrong file.  
 
 =item FETCH this, key
@@ -445,7 +445,7 @@ Here's the fetch for our DotFiles example.
 
 It was easy to write by having it call the Unix cat(1) command, but it
 would probably be more portable to open the file manually (and somewhat
-more efficient).  Of course, since dot files are a Unixy concept, we're
+more efficient).  Of course, because dot files are a Unixy concept, we're
 not that concerned.
 
 =item STORE this, key, value
@@ -526,14 +526,14 @@ the caller whether the file was successfully deleted.
 This method is triggered when the whole hash is to be cleared, usually by
 assigning the empty list to it.
 
-In our example, that would remove all the user's dotfiles!  It's such a
+In our example, that would remove all the user's dot files!  It's such a
 dangerous thing that they'll have to set CLOBBER to something higher than
 1 to make it happen.
 
     sub CLEAR    {
        carp &whowasi if $DEBUG;
        my $self = shift;
-       croak "@{[&whowasi]}: won't remove all dotfiles for $self->{USER}"
+       croak "@{[&whowasi]}: won't remove all dot files for $self->{USER}"
            unless $self->{CLOBBER} > 1;
        my $dot;
        foreach $dot ( keys %{$self->{LIST}}) {
@@ -574,8 +574,8 @@ second argument which is the last key that had been accessed.  This is
 useful if you're carrying about ordering or calling the iterator from more
 than one sequence, or not really storing things in a hash anywhere.
 
-For our example, we're using a real hash so we'll just do the simple
-thing, but we'll have to indirect through the LIST field.
+For our example, we're using a real hash so we'll do just the simple
+thing, but we'll have to go through the LIST field indirectly.
 
     sub NEXTKEY  {
        carp &whowasi if $DEBUG;
@@ -628,9 +628,9 @@ In our example we're going to create a shouting handle.
 
 This is the constructor for the class.  That means it is expected to
 return a blessed reference of some sort. The reference can be used to
-hold some internal information. We won't use it in out example.
+hold some internal information.
 
-    sub TIEHANDLE { print "<shout>\n"; my $i; bless \$i, shift }
+    sub TIEHANDLE { print "<shout>\n"; my $r; bless \$r, shift }
 
 =item PRINT this, LIST
 
@@ -680,7 +680,7 @@ You cannot easily tie a multilevel data structure (such as a hash of
 hashes) to a dbm file.  The first problem is that all but GDBM and
 Berkeley DB have size limitations, but beyond that, you also have problems
 with how references are to be represented on disk.  One experimental
-module that does attempt to partially address this need is the MLDBM
+module that does attempt to address this need partially is the MLDBM
 module.  Check your nearest CPAN site as described in L<perlmod> for
 source code to MLDBM.
 
index 7c16f94..2821fa3 100644 (file)
@@ -6,7 +6,7 @@ perltoc - perl documentation table of contents
 =head1 DESCRIPTION
 
 This page provides a brief table of contents for the rest of the Perl
-documentation set.  It is meant to be be quickly scanned or grepped
+documentation set.  It is meant to be scanned quickly or grepped
 through to locate the proper section you're looking for.
 
 =head1 BASIC DOCUMENTATION
@@ -144,7 +144,7 @@ HOME, LOGDIR, PATH, PERL5LIB, PERL5DB, PERLLIB
 =item The Arrow Operator
 
 
-=item Autoincrement and Autodecrement
+=item Auto-increment and Auto-decrement
 
 
 =item Exponentiation
@@ -215,10 +215,10 @@ HOME, LOGDIR, PATH, PERL5LIB, PERL5DB, PERLLIB
 
 unary &, unary *, (TYPE)
 
-=item Quote and Quotelike Operators
+=item Quote and Quote-like Operators
 
 
-=item Regexp Quotelike Operators
+=item Regexp Quote-like Operators
 
 
 ?PATTERN?, m/PATTERN/gimosx, /PATTERN/gimosx, q/STRING/, C<'STRING'>,
@@ -1748,7 +1748,7 @@ C<overload::Method(obj,op)>
 
 
 
-=head2 sigtrap - Perl pragma to enable stack backtrace on unexpected
+=head2 sigtrap - Perl pragma to enable stack back-trace on unexpected
 signals
 
 =item SYNOPSIS
@@ -1773,7 +1773,7 @@ C<strict refs>, C<strict vars>, C<strict subs>
 
 
 
-=head2 subs - Perl pragma to predeclare sub names
+=head2 subs - Perl pragma to pre-declare sub names
 
 =item SYNOPSIS
 
@@ -1784,7 +1784,7 @@ C<strict refs>, C<strict vars>, C<strict subs>
 
 
 
-=head2 vars - Perl pragma to predeclare global variable names
+=head2 vars - Perl pragma to pre-declare global variable names
 
 =item SYNOPSIS
 
@@ -2167,7 +2167,7 @@ maybe_command_in_dirs, maybe_command, perl_script
 
 guess_name, init_main, init_dirscan, init_others, find_perl
 
-=item Methods to actually produce chunks of text for the Makefile
+=item Methods to produce chunks of text for the Makefile
 
 
 post_initialize, const_config, constants, const_loadlibs, const_cccmd,
@@ -3157,8 +3157,8 @@ TIESCALAR classname, LIST, FETCH this, STORE this, value, DESTROY this
 
 =head1 AUXILIARY DOCUMENTATION
 
-Here should be listed all the extra program's docs, but they don't all
-have man pages yet:
+Here should be listed all the extra program's documentation, but they don't all
+have manual pages yet:
 
 =item a2p
 
diff --git a/pod/perltoot.pod b/pod/perltoot.pod
new file mode 100644 (file)
index 0000000..3fdedc2
--- /dev/null
@@ -0,0 +1,1779 @@
+=head1 NAME
+
+perltoot - Tom's object-oriented tutorial for perl
+
+=head1 DESCRIPTION
+
+Object-oriented programming is a big seller these days.  Some managers
+would rather have objects than sliced bread.  Why is that?  What's so
+special about an object?  Just what I<is> an object anyway?
+
+An object is nothing but a way of tucking away complex behaviours into
+a neat little easy-to-use bundle.  (This is what professors call
+abstraction.) Smart people who have nothing to do but sit around for
+weeks on end figuring out really hard problems make these nifty
+objects that even regular people can use. (This is what professors call
+software reuse.)  Users (well, programmers) can play with this little
+bundle all they want, but they aren't to open it up and mess with the
+insides.  Just like an expensive piece of hardware, the contract says
+that you void the warranty if you muck with the cover.  So don't do that.
+
+The heart of objects is the class, a protected little private namespace
+full of data and functions.  A class is a set of related routines that
+addresses some problem area.  You can think of it as a user-defined type.
+The Perl package mechanism, also used for more traditional modules,
+is used for class modules as well.  Objects "live" in a class, meaning
+that they belong to some package.
+
+More often than not, the class provides the user with little bundles.
+These bundles are objects.  They know whose class they belong to,
+and how to behave.  Users ask the class to do something, like "give
+me an object."  Or they can ask one of these objects to do something.
+Asking a class to do something for you is calling a I<class method>.
+Asking an object to do something for you is calling an I<object method>.
+Asking either a class (usually) or an object (sometimes) to give you
+back an object is calling a I<constructor>, which is just a
+kind of method.
+
+That's all well and good, but how is an object different from any other
+Perl data type?  Just what is an object I<really>; that is, what's its
+fundamental type?  The answer to the first question is easy.  An object
+is different from any other data type in Perl in one and only one way:
+you may dereference it using not merely string or numeric subscripts
+as with simple arrays and hashes, but with named subroutine calls.
+In a word, with I<methods>.
+
+The answer to the second question is that it's a reference, and not just
+any reference, mind you, but one whose referent has been I<bless>()ed
+into a particular class (read: package).  What kind of reference?  Well,
+the answer to that one is a bit less concrete.  That's because in Perl
+the designer of the class can employ any sort of reference they'd like
+as the underlying intrinsic data type.  It could be a scalar, an array,
+or a hash reference.  It could even be a code reference.  But because
+of its inherent flexibility, an object is usually a hash reference.
+
+=head1 Creating a Class
+
+Before you create a class, you need to decide what to name it.  That's
+because the class (package) name governs the name of the file used to
+house it, just as with regular modules.  Then, that class (package)
+should provide one or more ways to generate objects.  Finally, it should
+provide mechanisms to allow users of its objects to indirectly manipulate
+these objects from a distance.
+
+For example, let's make a simple Person class module.  It gets stored in
+the file Person.pm.  If it were called a Happy::Person class, it would
+be stored in the file Happy/Person.pm, and its package would become
+Happy::Person instead of just Person.  (On a personal computer not
+running Unix or Plan 9, but something like MacOS or VMS, the directory
+separator may be different, but the principle is the same.)  Do not assume
+any formal relationship between modules based on their directory names.
+This is merely a grouping convenience, and has no effect on inheritance,
+variable accessibility, or anything else.
+
+For this module we aren't going to use Exporter, because we're
+a well-behaved class module that doesn't export anything at all.
+In order to manufacture objects, a class needs to have a I<constructor
+method>.  A constructor gives you back not just a regular data type,
+but a brand-new object in that class.  This magic is taken care of by
+the bless() function, whose sole purpose is to enable its referent to
+be used as an object.  Remember: being an object really means nothing
+more than that methods may now be called against it.
+
+While a constructor may be named anything you'd like, most Perl
+programmers seem to like to call theirs new().  However, new() is not
+a reserved word, and a class is under no obligation to supply such.
+Some programmers have also been known to use a function with
+the same name as the class as the constructor.
+
+=head2 Object Representation
+
+By far the most common mechanism used in Perl to represent a Pascal
+record, a C struct, or a C++ class an anonymous hash.  That's because a
+hash has an arbitrary number of data fields, each conveniently accessed by
+an arbitrary name of your own devising.
+
+If you were just doing a simple
+struct-like emulation, you would likely go about it something like this:
+
+    $rec = {
+        name  => "Jason",
+        age   => 23,
+        peers => [ "Norbert", "Rhys", "Phineas"],
+    };
+
+If you felt like it, you could add a bit of visual distinction
+by up-casing the hash keys:
+
+    $rec = {
+        NAME  => "Jason",
+        AGE   => 23,
+        PEERS => [ "Norbert", "Rhys", "Phineas"],
+    };
+
+And so you could get at C<$rec-E<gt>{NAME}> to find "Jason", or
+C<@{ $rec-E<gt>{PEERS} }> to get at "Norbert", "Rhys", and "Phineas".
+(Have you ever noticed how many 23-year-old programmers seem to
+be named "Jason" these days? :-)
+
+This same model is often used for classes, although it is not considered
+the pinnacle of programming propriety for folks from outside the
+class to come waltzing into an object, brazenly accessing its data
+members directly.  Generally speaking, an object should be considered
+an opaque cookie that you use I<object methods> to access.  Visually,
+methods look like you're dereffing a reference using a function name
+instead of brackets or braces.
+
+=head2 Class Interface
+
+Some languages provide a formal syntactic interface to a class's methods,
+but Perl does not.  It relies on you to read the documentation of each
+class.  If you try to call an undefined method on an object, Perl won't
+complain, but the program will trigger an exception while it's running.
+Likewise, if you call a method expecting a prime number as its argument
+with an even one instead, you can't expect the compiler to catch this.
+(Well, you can expect it all you like, but it's not going to happen.)
+
+Let's suppose you have a well-educated user of your Person class,
+someone who has read the docs that explain the prescribed
+interface.  Here's how they might use the Person class:
+
+    use Person;
+
+    $him = Person->new();
+    $him->name("Jason");
+    $him->age(23);
+    $him->peers( "Norbert", "Rhys", "Phineas" );
+
+    push @All_Recs, $him;  # save object in array for later
+
+    printf "%s is %d years old.\n", $him->name, $him->age;
+    print "His peers are: ", join(", ", $him->peers), "\n";
+
+    printf "Last rec's name is %s\n", $All_Recs[-1]->name;
+
+As you can see, the user of the class doesn't know (or at least, has no
+business paying attention to the fact) that the object has one particular
+implementation or another.  The interface to the class and its objects
+is exclusively via methods, and that's all the user of the class should
+ever play with.
+
+=head2 Constructors and Instance Methods
+
+Still, I<someone> has to know what's in the object.  And that someone is
+the class.  It implements methods that the programmer uses to access
+the object.  Here's how to implement the Person class using the standard
+hash-ref-as-an-object idiom.  We'll make a class method called new() to
+act as the constructor, and three object methods called name(), age(), and
+peers() to get at per-object data hidden away in our anonymous hash.
+
+    package Person;
+    use strict;
+
+    ##################################################
+    ## the object constructor (simplistic version)  ##
+    ##################################################
+    sub new {
+        my $self  = {};
+        $self->{NAME}   = undef;
+        $self->{AGE}    = undef;
+        $self->{PEERS}  = [];
+        bless($self);           # but see below
+        return $self;
+    }
+
+    ##############################################
+    ## methods to access per-object data        ##
+    ##                                          ##
+    ## With args, they set the value.  Without  ##
+    ## any, they only retrieve it/them.         ##
+    ##############################################
+
+    sub name {
+        my $self = shift;
+        if (@_) { $self->{NAME} = shift }
+        return $self->{NAME};
+    }
+
+    sub age {
+        my $self = shift;
+        if (@_) { $self->{AGE} = shift }
+        return $self->{AGE};
+    }
+
+    sub peers {
+        my $self = shift;
+        if (@_) { @{ $self->{PEERS} } = @_ }
+        return @{ $self->{PEERS} };
+    }
+
+    1;  # so the require or use succeeds
+
+We've created three methods to access an object's data, name(), age(),
+and peers().  These are all substantially similar.  If called with an
+argument, they set the appropriate field; otherwise they return the
+value held by that field, meaning the value of that hash key.
+
+=head2 Planning for the Future: Better Constructors
+
+Even though at this point you may not even know what it means, someday
+you're going to worry about inheritance.  (You can safely ignore this
+for now and worry about it later if you'd like.)  To ensure that this
+all works out smoothly, you must use the double-argument form of bless().
+The second argument is the class into which the referent will be blessed.
+By not assuming our own class as the default second argument and instead
+using the class passed into us, we make our constructor inheritable.
+
+While we're at it, let's make our constructor a bit more flexible.
+Rather than being uniquely a class method, we'll set it up so that
+it can be called as either a class method I<or> an object
+method.  That way you can say:
+
+    $me  = Person->new();
+    $him = $me->new();
+
+To do this, all we have to do is check whether what was passed in
+was a reference or not.  If so, we were invoked as an object method,
+and we need to extract the package (class) using the ref() function.
+If not, we just use the string passed in as the package name
+for blessing our referent.
+
+    sub new {
+        my $proto = shift;
+        my $class = ref($proto) || $proto;
+        my $self  = {};
+        $self->{NAME}   = undef;
+        $self->{AGE}    = undef;
+        $self->{PEERS}  = [];
+        bless ($self, $class);
+        return $self;
+    }
+
+That's about all there is for constructors.  These methods bring objects
+to life, returning neat little opaque bundles to the user to be used in
+subsequent method calls.
+
+=head2 Destructors
+
+Every story has a beginning and an end.  The beginning of the object's
+story is its constructor, explicitly called when the object comes into
+existence.  But the ending of its story is the I<destructor>, a method
+implicitly called when an object leaves this life.  Any per-object
+clean-up code is placed in the destructor, which must (in Perl) be called
+DESTROY.
+
+If constructors can have arbitrary names, then why not destructors?
+Because while a constructor is explicitly called, a destructor is not.
+Destruction happens automatically via Perl's garbage collection (GC)
+system, which is a quick but somewhat lazy reference-based GC system.
+To know what to call, Perl insists that the destructor be named DESTROY.
+
+Why is DESTROY in all caps?  Perl on occasion uses purely upper-case
+function names as a convention to indicate that the function will
+be automatically called by Perl in some way.  Others that are called
+implicitly include BEGIN, END, AUTOLOAD, plus all methods used by
+tied objects, described in L<perltie>.
+
+In really good object-oriented programming languages, the user doesn't
+care when the destructor is called.  It just happens when it's supposed
+to.  In low-level languages without any GC at all, there's no way to
+depend on this happening at the right time, so the programmer must
+explicitly call the destructor to clean up memory and state, crossing
+their fingers that it's the right time to do so.   Unlike C++, an
+object destructor is nearly never needed in Perl, and even when it is,
+explicit invocation is uncalled for.  In the case of our Person class,
+we don't need a destructor because Perl takes care of simple matters
+like memory deallocation.
+
+The only situation where Perl's reference-based GC won't work is
+when there's a circularity in the data structure, such as:
+
+    $this->{WHATEVER} = $this;
+
+In that case, you must delete the self-reference manually if you expect
+your program not to leak memory.  While admittedly error-prone, this is
+the best we can do right now.  Nonetheless, rest assured that when your
+program is finished, its objects' destructors are all duly called.
+So you are guaranteed that an object I<eventually> gets properly
+destroyed, except in the unique case of a program that never exits.
+(If you're running Perl embedded in another application, this full GC
+pass happens a bit more frequently--whenever a thread shuts down.)
+
+=head2 Other Object Methods
+
+The methods we've talked about so far have either been constructors or
+else simple "data methods", interfaces to data stored in the object.
+These are a bit like an object's data members in the C++ world, except
+that strangers don't access them as data.  Instead, they should only
+access the object's data indirectly via its methods.  This is an
+important rule: in Perl, access to an object's data should I<only>
+be made through methods.
+
+Perl doesn't impose restrictions on who gets to use which methods.
+The public-versus-private distinction is by convention, not syntax.
+(Well, unless you use the Alias module described below in L</"Data Members
+as Variables">.)  Occasionally you'll see method names beginning or ending
+with an underscore or two.  This marking is a convention indicating
+that the methods are private to that class alone and sometimes to its
+closest acquaintances, its immediate subclasses.  But this distinction
+is not enforced by Perl itself.  It's up to the programmer to behave.
+
+There's no reason to limit methods to those that simply access data.
+Methods can do anything at all.  The key point is that they're invoked
+against an object or a class.  Let's say we'd like object methods that
+do more than fetch or set one particular field.
+
+    sub exclaim {
+        my $self = shift;
+        return sprintf "Hi, I'm %s, age %d, working with %s",
+            $self->{NAME}, $self->{AGE}, join(", ", $self->{PEERS});
+    }
+
+Or maybe even one like this:
+
+    sub happy_birthday {
+        my $self = shift;
+        return ++$self->{AGE};
+    }
+
+Some might argue that one should go at these this way:
+
+    sub exclaim {
+        my $self = shift;
+        return sprintf "Hi, I'm %s, age %d, working with %s",
+            $self->name, $self->age, join(", ", $self->peers);
+    }
+
+    sub happy_birthday {
+        my $self = shift;
+        return $self->age( $self->age() + 1 );
+    }
+
+But since these methods are all executing in the class itself, this
+may not be critical.  There are trade-offs to be made.  Using direct
+hash access is faster (about an order of magnitude faster, in fact), and
+it's more convenient when you want to interpolate in strings.  But using
+methods (the external interface) internally shields not just the users of
+your class but even you yourself from changes in your data representation.
+
+=head1 Class Data
+
+What about "class data", data items common to each object in a class?
+What would you want that for?  Well, in your Person class, you might
+like to keep track of the total people alive.  How do you implement that?
+
+You I<could> make it a global variable called $Person::Census.  But about
+only reason you'd do that would be if you I<wanted> people to be able to
+get at your class data directly.  They could just say $Person::Census
+and play around with it.  Maybe this is ok in your design scheme.
+You might even conceivably want to make it an exported variable.  To be
+exportable, a variable must be a (package) global.  If this were a
+traditional module rather than an object-oriented one, you might do that.
+
+While this approach is expected in most traditional modules, it's
+generally considered rather poor form in most object modules.  In an
+object module, you should set up a protective veil to separate interface
+from implementation.  So provide a class method to access class data
+just as you provide object methods to access object data.
+
+So, you I<could> still keep $Census as a package global and rely upon
+others to honor the contract of the module and therefore not play around
+with its implementation.  You could even be supertricky and make $Census a
+tied object as described in L<perltie>, thereby intercepting all accesses.
+
+But more often than not, you just want to make your class data a
+file-scoped lexical.  To do so, simply put this at the top of the file:
+
+    my $Census = 0;
+
+Even though the scope of a my() normally expires when the block in which
+it was declared is done (in this case the whole file being required or
+used), Perl's deep binding of lexical variables guarantees that the
+variable will not be deallocated, remaining accessible to functions
+declared within that scope.  This doesn't work with global variables
+given temporary values via local(), though.
+
+Irrespective of whether you leave $Census a package global or make
+it instead a file-scoped lexical, you should make these
+changes to your Person::new() constructor:
+
+    sub new {
+        my $proto = shift;
+        my $class = ref($proto) || $proto;
+        my $self  = {};
+        $Census++;
+        $self->{NAME}   = undef;
+        $self->{AGE}    = undef;
+        $self->{PEERS}  = [];
+        bless ($self, $class);
+        return $self;
+    }
+
+    sub population {
+        return $Census;
+    }
+
+Now that we've done this, we certainly do need a destructor so that
+when Person is destroyed, the $Census goes down.  Here's how
+this could be done:
+
+    sub DESTROY { --$Census }
+
+Notice how there's no memory to deallocate in the destructor?  That's
+something that Perl takes care of for you all by itself.
+
+=head2 Accessing Class Data
+
+It turns out that this is not really a good way to go about handling
+class data.  A good scalable rule is that I<you must never reference class
+data directly from an object method>.  Otherwise you aren't building a
+scalable, inheritable class.  The object must be the rendezvous point
+for all operations, especially from an object method.  The globals
+(class data) would in some sense be in the "wrong" package in your
+derived classes.  In Perl, methods execute in the context of the class
+they were defined in, I<not> that of the object that triggered them.
+Therefore, namespace visibility of package globals in methods is unrelated
+to inheritance.
+
+Got that?  Maybe not.  Ok, let's say that some other class "borrowed"
+(well, inherited) the DESTROY method as it was defined above.  When those
+objects are destructed, the original $Census variable will be altered,
+not the one in the new class's package namespace.  Perhaps this is what
+you want, but probably it isn't.
+
+Here's how to fix this.  We'll store a reference to the data in the
+value accessed by the hash key "_CENSUS".  Why the underscore?  Well,
+mostly because an initial underscore already conveys strong feelings
+of magicalness to a C programmer.  It's really just a mnemonic device
+to remind ourselves that this field is special and not to be used as
+a public data member in the same way that NAME, AGE, and PEERS are.
+(Because we've been developing this code under the strict pragma, prior
+to 5.004 we'll have to quote the field name.)
+
+    sub new {
+        my $proto = shift;
+        my $class = ref($proto) || $proto;
+        my $self  = {};
+        $self->{NAME}     = undef;
+        $self->{AGE}      = undef;
+        $self->{PEERS}    = [];
+        # "private" data
+        $self->{"_CENSUS"} = \$Census;
+        bless ($self, $class);
+        ++ ${ $self->{"_CENSUS"} };
+        return $self;
+    }
+
+    sub population {
+        my $self = shift;
+        if (ref $self) {
+            return ${ $self->{"_CENSUS"} };
+        } else {
+            return $Census;
+        }
+    }
+
+    sub DESTROY {
+        my $self = shift;
+        -- ${ $self->{"_CENSUS"} };
+    }
+
+=head2 Debugging Methods
+
+It's common for a class to have a debugging mechanism.  For example,
+you might want to see when objects are created or destroyed.  To do that,
+add a debugging variable as a file-scoped lexical.  For this, we'll pull
+in the standard Carp module to emit our warnings and fatal messages.
+That way messages will come out with the caller's filename and
+line number instead of our own; if we wanted them to be from our own
+perspective, we'd just use die() and warn() directly instead of croak()
+and carp() respectively.
+
+    use Carp;
+    my $Debugging = 0;
+
+Now add a new class method to access the variable.
+
+    sub debug {
+        my $class = shift;
+        if (ref $class)  { confess "Class method called as object method" }
+        unless (@_ == 1) { confess "usage: CLASSNAME->debug(level)" }
+        $Debugging = shift;
+    }
+
+Now fix up DESTROY to murmur a bit as the moribund object expires:
+
+    sub DESTROY {
+        my $self = shift;
+        if ($Debugging) { carp "Destroying $self " . $self->name }
+        -- ${ $self->{"_CENSUS"} };
+    }
+
+One could conceivably make a per-object debug state.  That
+way you could call both of these:
+
+    Person->debug(1);   # entire class
+    $him->debug(1);     # just this object
+
+To do so, we need our debugging method to be a "bimodal" one, one that
+works on both classes I<and> objects.  Therefore, adjust the debug()
+and DESTROY methods as follows:
+
+    sub debug {
+        my $self = shift;
+        confess "usage: thing->debug(level)"    unless @_ == 1;
+        my $level = shift;
+        if (ref($self))  {
+            $self->{"_DEBUG"} = $level;                # just myself
+        } else {
+            $Debugging        = $level;         # whole class
+        }
+    }
+
+    sub DESTROY {
+        my $self = shift;
+        if ($Debugging || $self->{"_DEBUG"}) {
+            carp "Destroying $self " . $self->name;
+        }
+        -- ${ $self->{"_CENSUS"} };
+    }
+
+What happens if a derived class (which we'll all C<Employee>) inherits
+methods from this person one?  Then C<Employee-&gt;debug()> when called
+as a class method manipulates $Person::Debugging not $Employee::Debugging.
+
+=head2 Class Destructors
+
+The object destructor handles the death of each distinct object.  But sometimes
+you want a bit of cleanup when the entire class is shut down, which
+currently only happens when the program exits.  To make such a
+I<class destructor>, create a function in that class's package named
+END.  This works just like the END function in traditional modules,
+meaning that it gets called whenever your program exits unless it execs
+or dies of an uncaught signal.  For example,
+
+    sub END {
+        if ($Debugging) {
+            print "All persons are going away now.\n";
+        }
+    }
+
+When the program exits, all the class destructors (END functions) are
+be called in the opposite order that they were loaded in (LIFO order).
+
+=head2 Documenting the Interface
+
+And there you have it: we've just shown you the I<implementation> of this
+Person class.  Its I<interface> would be its documentation.  Usually this
+means putting it in pod ("plain old documentation") format right there
+in the same file.  In our Person example, we would place the following
+docs anywhere in the Person.pm file.  Even though it looks mostly like
+code, it's not.  It's embedded documentation such as would be used by
+the pod2man, pod2html, or pod2text programs.  The Perl compiler ignores
+pods entirely, just as the translators ignore code.  Here's an example of
+some pods describing the informal interface:
+
+    =head1 NAME
+
+    Person - class to implement people
+
+    =head1 SYNOPSIS
+
+     use Person;
+
+     #################
+     # class methods #
+     #################
+     $ob    = Person->new;
+     $count = Person->population;
+
+     #######################
+     # object data methods #
+     #######################
+
+     ### get versions ###
+         $who   = $ob->name;
+         $years = $ob->age;
+         @pals  = $ob->peers;
+
+     ### set versions ###
+         $ob->name("Jason");
+         $ob->age(23);
+         $ob->peers( "Norbert", "Rhys", "Phineas" );
+
+     ########################
+     # other object methods #
+     ########################
+
+     $phrase = $ob->exclaim;
+     $ob->happy_birthday;
+
+    =head1 DESCRIPTION
+
+    The Person class implements dah dee dah dee dah....
+
+That's all there is to the matter of interface versus implementation.
+A programmer who opens up the module and plays around with all the private
+little shiny bits that were safely locked up behind the interface contract
+has voided the warranty, and you shouldn't worry about their fate.
+
+=head1 Aggregation
+
+Suppose you later want to change the class to implement better names.
+Perhaps you'd like to support both given names (called Christian names,
+irrespective of one's religion) and family names (called surnames), plus
+nicknames and titles.  If users of your Person class have been properly
+accessing it through its documented interface, then you can easily change
+the underlying implementation.  If they haven't, then they lose and
+it's their fault for breaking the contract and voiding their warranty.
+
+To do this, we'll make another class, this one called Fullname.  What's
+the Fullname class look like?  To answer that question, you have to
+first figure out how you want to use it.  How about we use it this way:
+
+    $him = Person->new();
+    $him->fullname->title("St");
+    $him->fullname->christian("Thomas");
+    $him->fullname->surname("Aquinas");
+    $him->fullname->nickname("Tommy");
+    printf "His normal name is %s\n", $him->name;
+    printf "But his real name is %s\n", $him->fullname->as_string;
+
+Ok.  To do this, we'll change Person::new() so that it supports
+a full name field this way:
+
+    sub new {
+        my $proto = shift;
+        my $class = ref($proto) || $proto;
+        my $self  = {};
+        $self->{FULLNAME} = Fullname->new();
+        $self->{AGE}      = undef;
+        $self->{PEERS}    = [];
+        $self->{"_CENSUS"} = \$Census;
+        bless ($self, $class);
+        ++ ${ $self->{"_CENSUS"} };
+        return $self;
+    }
+
+    sub fullname {
+        my $self = shift;
+        return $self->{FULLNAME};
+    }
+
+Then to support old code, define Person::name() this way:
+
+    sub name {
+        my $self = shift;
+        return $self->{FULLNAME}->nickname(@_)
+          ||   $self->{FULLNAME}->christian(@_);
+    }
+
+Here's the Fullname class.  We'll use the same technique
+of using a hash reference to hold data fields, and methods
+by the appropriate name to access them:
+
+    package Fullname;
+    use strict;
+
+    sub new {
+        my $proto = shift;
+        my $class = ref($proto) || $proto;
+        my $self  = {
+            TITLE       => undef,
+            CHRISTIAN   => undef,
+            SURNAME     => undef,
+            NICK        => undef,
+        };
+        bless ($self, $class);
+        return $self;
+    }
+
+    sub christian {
+        my $self = shift;
+        if (@_) { $self->{CHRISTIAN} = shift }
+        return $self->{CHRISTIAN};
+    }
+
+    sub surname {
+        my $self = shift;
+        if (@_) { $self->{SURNAME} = shift }
+        return $self->{SURNAME};
+    }
+
+    sub nickname {
+        my $self = shift;
+        if (@_) { $self->{NICK} = shift }
+        return $self->{NICK};
+    }
+
+    sub title {
+        my $self = shift;
+        if (@_) { $self->{TITLE} = shift }
+        return $self->{TITLE};
+    }
+
+    sub as_string {
+        my $self = shift;
+        my $name = join(" ", @$self{'CHRISTIAN', 'SURNAME'});
+        if ($self->{TITLE}) {
+            $name = $self->{TITLE} . " " . $name;
+        }
+        return $name;
+    }
+
+    1;
+
+Finally, here's the test program:
+
+    #!/usr/bin/perl -w
+    use strict;
+    use Person;
+    sub END { show_census() }
+
+    sub show_census ()  {
+        printf "Current population: %d\n", Person->population;
+    }
+
+    Person->debug(1);
+
+    show_census();
+
+    my $him = Person->new();
+
+    $him->fullname->christian("Thomas");
+    $him->fullname->surname("Aquinas");
+    $him->fullname->nickname("Tommy");
+    $him->fullname->title("St");
+    $him->age(1);
+
+    printf "%s is really %s.\n", $him->name, $him->fullname;
+    printf "%s's age: %d.\n", $him->name, $him->age;
+    $him->happy_birthday;
+    printf "%s's age: %d.\n", $him->name, $him->age;
+
+    show_census();
+
+=head1 Inheritance
+
+Object-oriented programming systems all support some notion of
+inheritance.  Inheritance means allowing one class to piggy-back on
+top of another one so you don't have to write the same code again and
+again.  It's about software reuse, and therefore related to Laziness,
+the principal virtue of a programmer.  (The import/export mechanisms in
+traditional modules are also a form of code reuse, but a simpler one than
+the true inheritance that you find in object modules.)
+
+Sometimes the syntax of inheritance is built into the core of the
+language, and sometimes it's not.  Perl has no special syntax for
+specifying the class (or classes) to inherit from.  Instead, it's all
+strictly in the semantics.  Each package can have a variable called @ISA,
+which governs (method) inheritance.  If you try to call a method on an
+object or class, and that method is not found in that object's package,
+Perl then looks to @ISA for other packages to go looking through in
+search of the missing method.
+
+Like the special per-package variables recognized by Exporter (such as
+@EXPORT, @EXPORT_OK, @EXPORT_FAIL, %EXPORT_TAGS, and $VERSION), the @ISA
+array I<must> be a package-scoped global and not a file-scoped lexical
+created via my().  Most classes have just one item in their @ISA array.
+In this case, we have what's called "single inheritance", or SI for short.
+
+Consider this class:
+
+    package Employee;
+    use Person;
+    @ISA = ("Person");
+    1;
+
+Not a lot to it, eh?  All it's doing so far is loading in another
+class and stating that this one will inherit methods from that
+other class if need be.  We have given it none of its own methods.
+We rely upon an Employee to behave just like a Person.
+
+Setting up an empty class like this is called the "empty subclass test";
+that is, making a derived class that does nothing but inherit from a
+base class.  If the original base class has been designed properly,
+then the new derived class can be used as a drop-in replacement for the
+old one.  This means you should be able to write a program like this:
+
+    use Employee
+    my $empl = Employee->new();
+    $empl->name("Jason");
+    $empl->age(23);
+    printf "%s is age %d.\n", $empl->name, $empl->age;
+
+By proper design, we mean always using the two-argument form of bless(),
+avoiding direct access of global data, and not exporting anything.  If you
+look back at the Person::new() function we defined above, we were careful
+to do that.  There's a bit of package data used in the constructor,
+but the reference to this is stored on the object itself and all other
+methods access package data via that reference, so we should be ok.
+
+What do we mean by the Person::new() function -- isn't that actually
+a method?  Well, in principle, yes.  A method is just a function that
+expects as its first argument a class name (package) or object
+(blessed reference).   Person::new() is the function that both the
+C<Person-E<gt>new()> method and the C<Employee-E<gt>new()> method end
+up calling.  Understand that while a method call looks a lot like a
+function call, they aren't really quite the same, and if you treat them
+as the same, you'll very soon be left with nothing but broken programs.
+First, the actual underlying calling conventions are different: method
+calls get an extra argument.  Second, function calls don't do inheritance,
+but methods do.
+
+        Method Call             Resulting Function Call
+        -----------             ------------------------
+        Person->new()           Person::new("Person")
+        Employee->new()         Person::new("Employee")
+
+So don't use function calls when you mean to call a method.
+
+If an employee is just a Person, that's not all too very interesting.
+So let's add some other methods.  We'll give our employee
+data fields to access their salary, their employee ID, and their
+start date.
+
+If you're getting a little tired of creating all these nearly identical
+methods just to get at the object's data, do not despair.  Later,
+we'll describe several different convenience mechanisms for shortening
+this up.  Meanwhile, here's the straight-forward way:
+
+    sub salary {
+        my $self = shift;
+        if (@_) { $self->{SALARY} = shift }
+        return $self->{SALARY};
+    }
+
+    sub id_number {
+        my $self = shift;
+        if (@_) { $self->{ID} = shift }
+        return $self->{ID};
+    }
+
+    sub start_date {
+        my $self = shift;
+        if (@_) { $self->{START_DATE} = shift }
+        return $self->{START_DATE};
+    }
+
+=head2 Overridden Methods
+
+What happens when both a derived class and its base class have the same
+method defined?  Well, then you get the derived class's version of that
+method.  For example, let's say that we want the peers() method called on
+an employee to act a bit differently.  Instead of just returning the list
+of peer names, let's return slightly different strings.  So doing this:
+
+    $empl->peers("Peter", "Paul", "Mary");
+    printf "His peers are: %s\n", join(", ", $empl->peers);
+
+will produce:
+
+    His peers are: PEON=PETER, PEON=PAUL, PEON=MARY
+
+To do this, merely add this definition into the Employee.pm file:
+
+    sub peers {
+        my $self = shift;
+        if (@_) { @{ $self->{PEERS} } = @_ }
+        return map { "PEON=\U$_" } @{ $self->{PEERS} };
+    }
+
+There, we've just demonstrated the high-falutin' concept known in certain
+circles as I<polymorphism>.  We've taken on the form and behaviour of
+an existing object, and then we've altered it to suit our own purposes.
+This is a form of Laziness.  (Getting polymorphed is also what happens
+when the wizard decides you'd look better as a frog.)
+
+Every now and then you'll want to have a method call trigger both its
+derived class (also know as "subclass") version as well as its base class
+(also known as "superclass") version.  In practice, constructors and
+destructors are likely to want to do this, and it probably also makes
+sense in the debug() method we showed previously.
+
+To do this, add this to Employee.pm:
+
+    use Carp;
+    my $Debugging = 0;
+
+    sub debug {
+        my $self = shift;
+        confess "usage: thing->debug(level)"    unless @_ == 1;
+        my $level = shift;
+        if (ref($self))  {
+            $self->{"_DEBUG"} = $level;
+        } else {
+            $Debugging = $level;            # whole class
+        }
+        Person::debug($self, $Debugging);   # don't really do this
+    }
+
+As you see, we turn around and call the Person package's debug() function.
+But this is far too fragile for good design.  What if Person doesn't
+have a debug() function, but is inheriting I<its> debug() method
+from elsewhere?  It would have been slightly better to say
+
+    Person->debug($Debugging);
+
+But even that's got too much hard-coded.  It's somewhat better to say
+
+    $self->Person::debug($Debugging);
+
+Which is a funny way to say to start looking for a debug() method up
+in Person.  This strategy is more often seen on overridden object methods
+than on overridden class methods.
+
+There is still something a bit off here.  We've hard-coded our
+superclass's name.  This in particular is bad if you change which classes
+you inherit from, or add others.  Fortunately, the pseudoclass SUPER
+comes to the rescue here.
+
+    $class->SUPER::debug($Debugging);
+
+This way it starts looking in my class's @ISA.  This only makes sense
+from I<within> a method call, though.  Don't try to access anything
+in SUPER:: from anywhere else, because it doesn't exist outside
+an overridden method call.
+
+Things are getting a bit complicated here.  Have we done anything
+we shouldn't?  As before, one way to test whether we're designing
+a decent class is via the empty subclass test.  Since we already have
+an Employee class that we're trying to check, we'd better get a new
+empty subclass that can derive from Employee.  Here's one:
+
+    package Boss;
+    use Employee;        # :-)
+    @ISA = qw(Employee);
+
+And here's the test program:
+
+    #!/usr/bin/perl -w
+    use strict;
+    use Boss;
+    Boss->debug(1);
+
+    my $boss = Boss->new();
+
+    $boss->fullname->title("Don");
+    $boss->fullname->surname("Pichon Alvarez");
+    $boss->fullname->christian("Federico Jesus");
+    $boss->fullname->nickname("Fred");
+
+    $boss->age(47);
+    $boss->peers("Frank", "Felipe", "Faust");
+
+    printf "%s is age %d.\n", $boss->fullname, $boss->age;
+    printf "His peers are: %s\n", join(", ", $boss->peers);
+
+Running it, we see that we're still ok.  If you'd like to dump out your
+object in a nice format, somewhat like the way the 'x' command works in
+the debugger, you could use the Data::Dumper module from CPAN this way:
+
+    use Data::Dumper;
+    print "Here's the boss:\n";
+    print Dumper($boss);
+
+Which shows us something like this:
+
+    Here's the boss:
+    $VAR1 = bless( {
+        _CENSUS => \1,
+        FULLNAME => bless( {
+                             TITLE => 'Don',
+                             SURNAME => 'Pichon Alvarez',
+                             NICK => 'Fred',
+                             CHRISTIAN => 'Federico Jesus'
+                           }, 'Fullname' ),
+        AGE => 47,
+        PEERS => [
+                   'Frank',
+                   'Felipe',
+                   'Faust'
+                 ]
+       }, 'Boss' );
+
+Hm.... something's missing there.  What about the salary, start date,
+and ID fields?  Well, we never set them to anything, even undef, so they
+don't show up in the hash's keys.  The Employee class has no new() method
+of its own, and the new() method in Person doesn't know about Employees.
+(Nor should it: proper OO design dictates that a subclass be allowed to
+know about its immediate superclass, but never vice-versa.)  So let's
+fix up Employee::new() this way:
+
+    sub new {
+        my $proto = shift;
+        my $class = ref($proto) || $proto;
+        my $self  = $class->SUPER::new();
+        $self->{SALARY}        = undef;
+        $self->{ID}            = undef;
+        $self->{START_DATE}    = undef;
+        bless ($self, $class);          # reconsecrate
+        return $self;
+    }
+
+Now if you dump out an Employee or Boss object, you'll find
+that new fields show up there now.
+
+=head2 Multiple Inheritance
+
+Ok, at the risk of confusing beginners and annoying OO gurus, it's
+time to confess that Perl's object system includes that controversial
+notion known as multiple inheritance, or MI for short.  All this means
+is that rather than having just one parent class who in turn might
+itself have a parent class, etc., that you can directly inherit from
+two or more parents.  It's true that some uses of MI can get you into
+trouble, although hopefully not quite so much trouble with Perl as with
+dubiously-OO languages like C++.
+
+The way it works is actually pretty simple: just put more than one package
+name in your @ISA array.  When it comes time for Perl to go finding
+methods for your object, it looks at each of these packages in order.
+Well, kinda.  It's actually a fully recursive, depth-first order.
+Consider a bunch of @ISA arrays like this:
+
+    @First::ISA    = qw( Alpha );
+    @Second::ISA   = qw( Beta );
+    @Third::ISA    = qw( First Second );
+
+If you have an object of class Third:
+
+    my $ob = Third->new();
+    $ob->spin();
+
+How do we find a spin() method (or a new() method for that matter)?
+Because the search is depth-first, classes will be looked up
+in the following order: Third, First, Alpha, Second, and Beta.
+
+In practice, few class modules have been seen that actually
+make use of MI.  One nearly always chooses simple containership of
+one class within another over MI.  That's why our Person
+object I<contained> a Fullname object.  That doesn't mean
+it I<was> one.
+
+However, there is one particular area where MI in Perl is rampant:
+borrowing another class's class methods.  This is rather common,
+especially with some bundled "objectless" classes,
+like Exporter, DynaLoader, AutoLoader, and SelfLoader.  These classes
+do not provide constructors; they exist only so you may inherit their
+class methods.  (It's not entirely clear why inheritance was done
+here rather than traditional module importation.)
+
+For example, here is the POSIX module's @ISA:
+
+    package POSIX;
+    @ISA = qw(Exporter DynaLoader);
+
+The POSIX module isn't really an object module, but then,
+neither are Exporter or DynaLoader.  They're just lending their
+classes' behaviours to POSIX.
+
+Why don't people use MI for object methods much?  One reason is that
+it can have complicated side-effects.  For one thing, your inheritance
+graph (no longer a tree) might converge back to the same base class.
+Although Perl guards against recursive inheritance, merely having parents
+who are related to each other via a common ancestor, incestuous though
+it sounds, is not forbidden.  What if in our Third class shown above we
+wanted its new() method to also call both overridden constructors in its
+two parent classes?  The SUPER notation would only find the first one.
+Also, what about if the Alpha and Beta classes both had a common ancestor,
+like Nought?  If you kept climbing up the inheritance tree calling
+overridden methods, you'd end up calling Nought::new() twice,
+which might well be a bad idea.
+
+=head2 UNIVERSAL: The Root of All Objects
+
+Wouldn't it be convenient if all objects were rooted at some ultimate
+base class?  That way you could give every object common methods without
+having to go and add it to each and every @ISA.  Well, it turns out that
+you can.  You don't see it, but Perl tacitly and irrevocably assumes
+that there's an extra element at the end of @ISA: the class UNIVERSAL.
+In 5.003, there were no predefined methods there, but you could put
+whatever you felt like into it.
+
+However, as of 5.004 (or some subversive releases, like 5.003_08),
+UNIVERSAL has some methods in it already.  These are built-in to your Perl
+binary, so they don't take any extra time to load.  Predefined methods
+include isa(), can(), and VERSION().  isa() tells you whether an object or
+class "is" another one without having to traverse the hierarchy yourself:
+
+   $has_io = $fd->isa("IO::Handle");
+   $itza_handle = IO::Socket->isa("IO::Handle");
+
+The can() method, called against that object or class, reports back
+whether its string argument is a callable method name in that class.
+In fact, it gives you back a function reference to that method:
+
+   $his_print_method = $obj->can('as_string');
+
+Finally, the VERSION method checks whether the class (or the object's
+class) has a package global called $VERSION that's high enough, as in:
+
+    Some_Module->VERSION(3.0);
+    $his_vers = $ob->VERSION();
+
+However, we don't usually call VERSION ourselves.  (Remember that an all
+upper-case function name is a Perl convention that indicates that the
+function will be automatically used by Perl in some way.)  In this case,
+it happens when you say
+
+    use Some_Module 3.0;
+
+If you wanted to add versioning to your Person class explained
+above, just add this to Person.pm:
+
+    use vars qw($VERSION);
+    $VERSION = '1.1';
+
+and then in Employee.pm could you can say
+
+    use Employee 1.1;
+
+And it would make sure that you have at least that version number or
+higher available.   This is not the same as loading in that exact version
+number.  No mechanism currently exists for concurrent installation of
+multiple versions of a module.  Lamentably.
+
+=head1 Alternate Object Representations
+
+Nothing requires objects to be implemented as hash references.  An object
+can be any sort of reference so long as its referent has been suitably
+blessed.  That means scalar, array, and code references are also fair
+game.
+
+A scalar would work if the object has only one datum to hold.  An array
+would work for most cases, but makes inheritance a bit dodgy because
+you have to invent new indices for the derived classes.
+
+=head2 Arrays as Objects
+
+If the user of your class honors the contract and sticks to the advertised
+interface, then you can change its underlying interface if you feel
+like it.  Here's another implementation that conforms to the same
+interface specification.  This time we'll use an array reference
+instead of a hash reference to represent the object.
+
+    package Person;
+    use strict;
+
+    my($NAME, $AGE, $PEERS) = ( 0 .. 2 );
+
+    ############################################
+    ## the object constructor (array version) ##
+    ############################################
+    sub new {
+        my $self = [];
+        $self->[$NAME]   = undef;  # this is unnecessary
+        $self->[$AGE]    = undef;  # as it this
+        $self->[$PEERS]  = [];     # but this isn't, really
+        bless($self);
+        return $self;
+    }
+
+    sub name {
+        my $self = shift;
+        if (@_) { $self->[$NAME] = shift }
+        return $self->[$NAME];
+    }
+
+    sub age {
+        my $self = shift;
+        if (@_) { $self->[$AGE] = shift }
+        return $self->[$AGE];
+    }
+
+    sub peers {
+        my $self = shift;
+        if (@_) { @{ $self->[$PEERS] } = @_ }
+        return @{ $self->[$PEERS] };
+    }
+
+    1;  # so the require or use succeeds
+
+You might guess that the array access will be a lot faster than the
+hash access, but they're actually comparable.  The array is a little
+bit faster, but not more than ten or fifteen percent, even when you
+replace the variables above like $AGE with literal numbers, like 1.
+A bigger difference between the two approaches can be found in memory use.
+A hash representation takes up more memory than an array representation
+because you have to allocation memory for the keys as well as the values.
+However, it really isn't that bad, especially since as of 5.004,
+memory is only allocated once for a given hash key, no matter how many
+hashes have that key.  It's expected that sometime in the future, even
+these differences will fade into obscurity as more efficient underlying
+representations are devised.
+
+Still, the tiny edge in speed (and somewhat larger one in memory)
+is enough to make some programmers choose an array representation
+for simple classes.  There's still a little problem with
+scalability, though, because later in life when you feel
+like creating subclasses, you'll find that hashes just work
+out better.
+
+=head2 Closures as Objects
+
+Using a code reference to represent an object offers some fascinating
+possibilities.  We can create a new anonymous function (closure) who
+alone in all the world can see the object's data.  This is because we
+put the data into an anonymous hash that's lexically visible only to
+the closure we create, bless, and return as the object.  This object's
+methods turn around and call the closure as a regular subroutine call,
+passing it the field we want to affect.  (Yes,
+the double-function call is slow, but if you wanted fast, you wouldn't
+be using objects at all, eh? :-)
+
+Use would be similar to before:
+
+    use Person;
+    $him = Person->new();
+    $him->name("Jason");
+    $him->age(23);
+    $him->peers( [ "Norbert", "Rhys", "Phineas" ] );
+    printf "%s is %d years old.\n", $him->name, $him->age;
+    print "His peers are: ", join(", ", @{$him->peers}), "\n";
+
+but the implementation would be radically, perhaps even sublimely
+different:
+
+    package Person;
+
+    sub new {
+        my $that  = shift;
+        my $class = ref($that) || $that;
+        my $self = {
+           NAME  => undef,
+           AGE   => undef,
+           PEERS => [],
+        };
+        my $closure = sub {
+           my $field = shift;
+           if (@_) { $self->{$field} = shift }
+           return    $self->{$field};
+       };
+       bless($closure, $class);
+       return $closure;
+    }
+
+    sub name   { &{ $_[0] }("NAME",  @_[ 1 .. $#_ ] ) }
+    sub age    { &{ $_[0] }("AGE",   @_[ 1 .. $#_ ] ) }
+    sub peers  { &{ $_[0] }("PEERS", @_[ 1 .. $#_ ] ) }
+
+    1;
+
+Because this object is hidden behind a code reference, it's probably a bit
+mysterious to those whose background is more firmly rooted in standard
+procedural or object-based programming languages than in functional
+programming languages whence closures derive.  The object
+created and returned by the new() method is itself not a data reference
+as we've seen before.  It's an anonymous code reference that has within
+it access to a specific version (lexical binding and instantiation)
+of the object's data, which are stored in the private variable $self.
+Although this is the same function each time, it contains a different
+version of $self.
+
+When a method like C<$him-E<gt>name("Jason")> is called, its implicit
+zeroth argument is as the invoking object just as it is with all method
+calls.  But in this case, it's our code reference (something like a
+function pointer in C++, but with deep binding of lexical variables).
+There's not a lot to be done with a code reference beyond calling it, so
+that's just what we do when we say C<&{$_[0]}>.  This is just a regular
+function call, not a method call.  The initial argument is the string
+"NAME", and any remaining arguments are whatever had been passed to the
+method itself.
+
+Once we're executing inside the closure that had been created in new(),
+the $self hash reference suddenly becomes visible.  The closure grabs
+its first argument ("NAME" in this case because that's what the name()
+method passed it), and uses that string to subscript into the private
+hash hidden in its unique version of $self.
+
+Nothing under the sun will allow anyone outside the executing method to
+be able to get at this hidden data.  Well, nearly nothing.  You I<could>
+single step through the program using the debugger and find out the
+pieces while you're in the method, but everyone else is out of luck.
+
+There, if that doesn't excite the Scheme folks, then I just don't know
+what will.  Translation of this technique into C++, Java, or any other
+braindead-static language is left as a futile exercise for aficionados
+of those camps.
+
+You could even add a bit of nosiness via the caller() function and
+make the closure refuse to operate unless called via its own package.
+This would no doubt satisfy certain fastidious concerns of programming
+police and related puritans.
+
+If you were wondering when Hubris, the third principle virtue of a
+programmer, would come into play, here you have it. (More seriously,
+Hubris is just the pride in craftsmanship that comes from having written
+a sound bit of well-designed code.)
+
+=head1 AUTOLOAD: Proxy Methods
+
+Autoloading is a way to intercept calls to undefined methods.  An autoload
+routine may choose to create a new function on the fly, either loaded
+from disk or perhaps just eval()ed right there.  This define-on-the-fly
+strategy is why it's called autoloading.
+
+But that's only one possible approach.  Another one is to just
+have the autoloaded method itself directly provide the
+requested service.  When used in this way, you may think
+of autoloaded methods as "proxy" methods.
+
+When Perl tries to call an undefined function in a particular package
+and that function is not defined, it looks for a function in
+that same package called AUTOLOAD.  If one exists, it's called
+with the same arguments as the original function would have had.
+The fully-qualified name of the function is stored in that package's
+global variable $AUTOLOAD.  Once called, the function can do anything
+it would like, including defining a new function by the right name, and
+then doing a really fancy kind of C<goto> right to it, erasing itself
+from the call stack.
+
+What does this have to do with objects?  After all, we keep talking about
+functions, not methods.  Well, since a method is just a function with
+an extra argument and some fancier semantics about where it's found,
+we can use autoloading for methods, too.  Perl doesn't start looking
+for an AUTOLOAD method until it has exhausted the recursive hunt up
+through @ISA, though.  Some programmers have even been known to define
+a UNIVERSAL::AUTOLOAD method to trap unresolved method calls to any
+kind of object.
+
+=head2 Autoloaded Data Methods
+
+You probably began to get a little suspicious about the duplicated
+code way back earlier when we first showed you the Person class, and
+then later the Employee class.  Each method used to access the
+hash fields looked virtually identical.  This should have tickled
+that great programming virtue, Impatience, but for the time,
+we let Laziness win out, and so did nothing.  Proxy methods can cure
+this.
+
+Instead of writing a new function every time we want a new data field,
+we'll use the autoload mechanism to generate (actually, mimic) methods on
+the fly.  To verify that we're accessing a valid member, we will check
+against an C<_permitted> (pronounced "under-permitted") field, which
+is a reference to a file-scoped lexical (like a C file static) hash of permitted fields in this record
+called %fields.  Why the underscore?  For the same reason as the _CENSUS
+field we once used: as a marker that means "for internal use only".
+
+Here's what the module initialization code and class
+constructor will look like when taking this approach:
+
+    package Person;
+    use Carp;
+    use vars qw($AUTOLOAD);  # it's a package global
+
+    my %fields = (
+       name        => undef,
+       age         => undef,
+       peers       => undef,
+    );
+
+    sub new {
+       my $that  = shift;
+       my $class = ref($that) || $that;
+       my $self  = {
+           _permitted => \%fields,
+           %fields,
+       };
+       bless $self, $class;
+       return $self;
+    }
+
+If we wanted our record to have default values, we could fill those in
+where current we have C<undef> in the %fields hash.
+
+Notice how we saved a reference to our class data on the object itself?
+Remember that it's important to access class data through the object
+itself instead of having any method reference %fields directly, or else
+you won't have a decent inheritance.
+
+The real magic, though, is going to reside in our proxy method, which
+will handle all calls to undefined methods for objects of class Person
+(or subclasses of Person).  It has to be called AUTOLOAD.  Again, it's
+all caps because it's called for us implicitly by Perl itself, not by
+a user directly.
+
+    sub AUTOLOAD {
+       my $self = shift;
+       my $type = ref($self)
+                   or croak "$self is not an object";
+
+       my $name = $AUTOLOAD;
+       $name =~ s/.*://;   # strip fully-qualified portion
+
+       unless (exists $self->{_permitted}->{$name} ) {
+           croak "Can't access `$name' field in class $type";
+       }
+
+       if (@_) {
+           return $self->{$name} = shift;
+       } else {
+           return $self->{$name};
+       }
+    }
+
+Pretty nifty, eh?  All we have to do to add new data fields
+is modify %fields.  No new functions need be written.
+
+I could have avoided the C<_permitted> field entirely, but I
+wanted to demonstrate how to store a reference to class data on the
+object so you wouldn't have to access that class data 
+directly from an object method.
+
+=head2 Inherited Autoloaded Data Methods
+
+But what about inheritance?  Can we define our Employee
+class similarly?  Yes, so long as we're careful enough.
+
+Here's how to be careful:
+
+    package Employee;
+    use Person;
+    use strict;
+    use vars qw(@ISA);
+    @ISA = qw(Person);
+
+    my %fields = (
+       id          => undef,
+       salary      => undef,
+    );
+
+    sub new {
+       my $that  = shift;
+       my $class = ref($that) || $that;
+       my $self = bless $that->SUPER::new(), $class;
+       my($element);
+       foreach $element (keys %fields) {
+           $self->{_permitted}->{$element} = $fields{$element};
+       }
+       @{$self}{keys %fields} = values %fields;
+       return $self;
+    }
+
+Once we've done this, we don't even need to have an
+AUTOLOAD function in the Employee package, because
+we'll grab Person's version of that via inheritance,
+and it will all work out just fine.
+
+=head1 Metaclassical Tools
+
+Even though proxy methods can provide a more convenient approach to making
+more struct-like classes than tediously coding up data methods as
+functions, it still leaves a bit to be desired.  For one thing, it means
+you have to handle bogus calls that you don't mean to trap via your proxy.
+It also means you have to be quite careful when dealing with inheritance,
+as detailed above.
+
+Perl programmers have responded to this by creating several different
+class construction classes.  These metaclasses are classes
+that create other classes.  A couple worth looking at are
+Class::Template and Alias.  These and other related metaclasses can be
+found in the modules directory on CPAN.
+
+=head2 Class::Template
+
+One of the older ones is Class::Template.  In fact, its syntax and
+interface were sketched out long before perl5 even solidified into a
+real thing.  What it does is provide you a way to "declare"
+a class as having objects whose fields are of a specific type.
+The function that does this is called, not surprisingly
+enough, struct().
+
+Here's a simple example of using it:
+
+    use Class::Template qw(struct);
+    use Jobbie;  # user-defined; see below
+
+    struct 'Fred' => {
+        one        => '$',
+        many       => '@',
+        profession => Jobbie,  # calls Jobbie->new()
+    };
+
+    $ob = Fred->new;
+    $ob->one("hmmmm");
+
+    $ob->many(0, "here");
+    $ob->many(1, "you");
+    $ob->many(2, "go");
+    print "Just set: ", $ob->many(2), "\n";
+
+    $ob->profession->salary(10_000);
+
+You can declare types in the struct to be basic Perl types, or
+user-defined types (classes).  User types will be initialized by calling
+that class's new() method.
+
+Here's a real-world example of using struct generation.  Let's say you
+wanted to override Perl's idea of gethostbyname() and gethostbyaddr() so
+that they would return objects that acted like C structures.  We don't
+care about high-falutin' OO gunk.  All we want is for these objects to
+act like structs in the C sense.
+
+    use Socket;
+    use Net::hostent;
+    $h = gethostbyname("perl.com");  # object return
+    printf "perl.com's real name is %s, address %s\n",
+       $h->name, inet_ntoa($h->addr);
+
+Here's how to do this using the Class::Template module.
+The crux is going to be this call:
+
+    struct 'Net::hostent' => [         # note bracket
+       name       => '$',
+       aliases    => '@',
+       addrtype   => '$',
+       'length'   => '$',
+       addr_list  => '@',
+     ];
+
+Which creates object methods of those names and types.
+It even creates a new() method for us.
+
+We could also have implemented our object this way:
+
+    struct 'Net::hostent' => {         # note brace
+       name       => '$',
+       aliases    => '@',
+       addrtype   => '$',
+       'length'   => '$',
+       addr_list  => '@',
+     };
+
+and then Class::Template would have used an anonymous hash as the object
+type, instead of an anonymous array.  The array is faster and smaller,
+but the hash works out better if you eventually want to do inheritance.
+Since for this struct-like object we aren't planning on inheritance,
+this time we'll opt for better speed and size over better flexibility.
+
+Here's the whole implementation:
+
+    package Net::hostent;
+    use strict;
+
+    BEGIN {
+       use Exporter   ();
+       use vars       qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
+       @ISA         = qw(Exporter);
+       @EXPORT      = qw(gethostbyname gethostbyaddr gethost);
+       @EXPORT_OK   = qw(
+                          $h_name         @h_aliases
+                          $h_addrtype     $h_length
+                          @h_addr_list    $h_addr
+                      );
+       %EXPORT_TAGS = ( FIELDS => [ @EXPORT_OK, @EXPORT ] );
+    }
+    use vars      @EXPORT_OK;
+
+    use Class::Template qw(struct);
+    struct 'Net::hostent' => [
+       name        => '$',
+       aliases     => '@',
+       addrtype    => '$',
+       'length'    => '$',
+       addr_list   => '@',
+    ];
+
+    sub addr { shift->addr_list->[0] }
+
+    sub populate (@) {
+       return unless @_;
+       my $hob = new();  # Class::Template made this!
+       $h_name     =    $hob->[0]              = $_[0];
+       @h_aliases  = @{ $hob->[1] } = split ' ', $_[1];
+       $h_addrtype =    $hob->[2]              = $_[2];
+       $h_length   =    $hob->[3]              = $_[3];
+       $h_addr     =                             $_[4];
+       @h_addr_list = @{ $hob->[4] } =         @_[ (4 .. $#_) ];
+       return $hob;
+    }
+
+    sub gethostbyname ($)  { populate(CORE::gethostbyname(shift)) }
+
+    sub gethostbyaddr ($;$) {
+       my ($addr, $addrtype);
+       $addr = shift;
+       require Socket unless @_;
+       $addrtype = @_ ? shift : Socket::AF_INET();
+       populate(CORE::gethostbyaddr($addr, $addrtype))
+    }
+
+    sub gethost($) {
+       if ($_[0] =~ /^\d+(?:\.\d+(?:\.\d+(?:\.\d+)?)?)?$/) {
+          require Socket;
+          &gethostbyaddr(Socket::inet_aton(shift));
+       } else {
+          &gethostbyname;
+       }
+    }
+
+    1;
+
+We've snuck in quite a fair bit of other concepts besides just dynamic
+class creation, like overriding core functions, import/export bits,
+function prototyping, and short-cut function call via C<&whatever>.
+These all mostly make sense from the perspective of a traditional module,
+but as you can see, we can also use them in an object module.
+
+You can look at other object-based, struct-like overrides of core
+functions in the 5.004 release of Perl in File::stat, Net::hostent,
+Net::netent, Net::protoent, Net::servent, Time::gmtime, Time::localtime,
+User::grent, and User::pwent.  These modules have a final component
+that's all lower-case, by convention reserved for compiler pragmas,
+because they affect the compilation and change a built-in function.
+They also have the type names that a C programmer would most expect.
+
+=head2 Data Members as Variables
+
+If you're used to C++ objects, then you're accustomed to being able to
+get at an object's data members as simple variables from within a method.
+The Alias module provides for this, as well as a good bit more, such
+as the possibility of private methods that the object can call but folks
+outside the class cannot.
+
+Here's an example of creating a Person using the Alias module.
+When you update these magical instance variables, you automatically
+update value fields in the hash.  Convenient, eh?
+
+    package Person;
+
+    # this is the same as before...
+    sub new {
+        my $that  = shift;
+        my $class = ref($that) || $that;
+        my $self = {
+           NAME  => undef,
+           AGE   => undef,
+           PEERS => [],
+       };
+       bless($self, $class);
+       return $self;
+    }
+
+    use Alias qw(attr);
+    use vars qw($NAME $AGE $PEERS);
+
+    sub name {
+       my $self = attr shift;
+       if (@_) { $NAME = shift; }
+       return    $NAME;
+    }
+
+    sub age {
+       my $self = attr shift;
+       if (@_) { $AGE = shift; }
+       return    $AGE;
+    }
+
+    sub peers {
+       my $self = attr shift;
+       if (@_) { @PEERS = @_; }
+       return    @PEERS;
+    }
+
+    sub exclaim {
+        my $self = attr shift;
+        return sprintf "Hi, I'm %s, age %d, working with %s",
+            $NAME, $AGE, join(", ", @PEERS);
+    }
+
+    sub happy_birthday {
+        my $self = attr shift;
+        return ++$AGE;
+    }
+
+The need for the C<use vars> declaration is because what Alias does
+is play with package globals with the same name as the fields.  To use
+globals while C<use strict> is in effect, you have to pre-declare them.
+These package variables are localized to the block enclosing the attr()
+call just as if you'd used a local() on them.  However, that means that
+they're still considered global variables with temporary values, just
+as with any other local().
+
+It would be nice to combine Alias with
+something like Class::Template or Class::MethodMaker.
+
+=head2 NOTES
+
+=head2 Object Terminology
+
+In the various OO literature, it seems that a lot of different words
+are used to describe only a few different concepts.  If you're not
+already an object programmer, then you don't need to worry about all
+these fancy words.  But if you are, then you might like to know how to
+get at the same concepts in Perl.
+
+For example, it's common to call an object an I<instance> of a class
+and to call those objects' methods I<instance methods>.  Data fields
+peculiar to each object are often called I<instance data> or I<object
+attributes>, and data fields common to all members of that class are
+I<class data>, I<class attributes>, or I<static data members>.
+
+Also, I<base class>, I<generic class>, and I<superclass> all describe
+the same notion, whereas I<derived class>, I<specific class>, and
+I<subclass> describe the other related one.
+
+C++ programmers have I<static methods> and I<virtual methods>,
+but Perl only has I<class methods> and I<object methods>.
+Actually, Perl only has methods.  Whether a method gets used
+as a class or object method is by usage only.  You could accidentally
+call a class method (one expecting a string argument) on an
+object (one expecting a reference), or vice versa.
+
+>From the C++ perspective, all methods in Perl are virtual.
+This, by the way, is why they are never checked for function
+prototypes in the argument list as regular built-in and user-defined
+functions can be.
+
+Because a class is itself something of an object, Perl's classes can be
+taken as describing both a "class as meta-object" (also called I<object
+factory>) philosophy and the "class as type definition" (I<declaring>
+behaviour, not I<defining> mechanism) idea.  C++ supports the latter
+notion, but not the former.
+
+=head1 SEE ALSO
+
+The following man pages will doubtless provide more
+background for this one:
+L<perlmod>,
+L<perlref>,
+L<perlobj>,
+L<perlbot>,
+L<perltie>,
+and
+L<overload>.
+
+=head1 COPYRIGHT
+
+I I<really> hate to have to say this, but recent unpleasant
+experiences have mandated its inclusion:
+
+    Copyright 1996 Tom Christiansen.  All Rights Reserved.
+
+This work derives in part from the second edition of I<Programming Perl>.
+Although destined for release as a man page with the standard Perl
+distribution, it is not public domain (nor is any of Perl and its docset:
+publishers beware).  It's expected to someday make its way into a revision
+of the Camel Book.  While it is copyright by me with all rights reserved,
+permission is granted to freely distribute verbatim copies of this
+document provided that no modifications outside of formatting be made,
+and that this notice remain intact.  You are permitted and encouraged to
+use its code and derivatives thereof in your own source code for fun or
+for profit as you see fit.  But so help me, if in six months I find some
+book out there with a hacked-up version of this material in it claiming to
+be written by someone else, I'll tell all the world that you're a jerk.
+Furthermore, your lawyer will meet my lawyer (or O'Reilly's) over lunch
+to arrange for you to receive your just deserts.  Count on it.
+
+=head2 Acknowledgments
+
+Thanks to
+Larry Wall,
+Roderick Schertler,
+Gurusamy Sarathy,
+Dean Roehrich,
+Raphael Manfredi,
+Brent Halsey,
+Greg Bacon,
+Brad Appleton,
+and many others for their helpful comments.
index e85f5c9..391c98b 100644 (file)
@@ -101,8 +101,8 @@ basically incompatible with C.)
 =item *
 
 The concatenation operator is ".", not the null string.  (Using the
-null string would render C</pat/ /pat/> unparsable, since the third slash
-would be interpreted as a division operator--the tokener is in fact
+null string would render C</pat/ /pat/> unparsable, because the third slash
+would be interpreted as a division operator--the tokenizer is in fact
 slightly context sensitive for operators like "/", "?", and "E<gt>".
 And in fact, "." itself can be the beginning of a number.)
 
@@ -183,7 +183,7 @@ Comments begin with "#", not "/*".
 =item *
 
 You can't take the address of anything, although a similar operator
-in Perl 5 is the backslash, which creates a reference.
+in Perl is the backslash, which creates a reference.
 
 =item *
 
@@ -231,18 +231,18 @@ Sharp shell programmers should take note of the following:
 
 =item *
 
-The backtick operator does variable interpolation without regard to
+The back-tick operator does variable interpolation without regard to
 the presence of single quotes in the command.
 
 =item *
 
-The backtick operator does no translation of the return value, unlike B<csh>.
+The back-tick operator does no translation of the return value, unlike B<csh>.
 
 =item *
 
 Shells (especially B<csh>) do several levels of substitution on each
-command line.  Perl does substitution only in certain constructs
-such as double quotes, backticks, angle brackets, and search patterns.
+command line.  Perl does substitution in only certain constructs
+such as double quotes, back-ticks, angle brackets, and search patterns.
 
 =item *
 
@@ -275,16 +275,16 @@ context than they do in a scalar one.  See L<perldata> for details.
 =item *
 
 Avoid barewords if you can, especially all lower-case ones.
-You can't tell just by looking at it whether a bareword is 
+You can't tell by just looking at it whether a bareword is 
 a function or a string.  By using quotes on strings and 
-parens on function calls, you won't ever get them confused.
+parentheses on function calls, you won't ever get them confused.
 
 =item *
 
 You cannot discern from mere inspection which built-ins
 are unary operators (like chop() and chdir()) 
 and which are list operators (like print() and unlink()).
-(User-defined subroutines can B<only> be list operators, never
+(User-defined subroutines can be B<only> list operators, never
 unary ones.)  See L<perlop>.
 
 =item *
@@ -296,7 +296,7 @@ you might expect to do not.
 =item *
 
 The E<lt>FHE<gt> construct is not the name of the filehandle, it is a readline
-operation on that handle.  The data read is only assigned to $_ if the
+operation on that handle.  The data read is assigned to $_ only if the
 file read is the sole condition in a while loop:
 
     while (<FH>)      { }
@@ -332,7 +332,7 @@ external name is still an alias for the original.
 
 =back
 
-=head2 Perl4 to Perl5  Traps
+=head2 Perl4 to Perl5 Traps
 
 Practicing Perl4 Programmers should take note of the following 
 Perl4-to-Perl5 specific traps.
@@ -419,7 +419,7 @@ for C<$_> itself (and C<@_>, etc.).
 =item * Deprecation 
 
 Double-colon is now a valid package separator in a variable name.  Thus these
-behave differently in perl4 vs. perl5, since the packages don't exist.
+behave differently in perl4 vs. perl5, because the packages don't exist.
 
     $a=1;$b=2;$c=3;$var=4;
     print "$a::$b::$c ";
@@ -652,9 +652,9 @@ Formatted output and significant digits
 
 =item * Numerical
 
-This specific item has been deleted.  It demonstrated how the autoincrement
+This specific item has been deleted.  It demonstrated how the auto-increment
 operator would not catch when a number went over the signed int limit.  Fixed
-in 5.003_04.  But always be wary when using large ints.  If in doubt:
+in 5.003_04.  But always be wary when using large integers.  If in doubt:
 
    use Math::BigInt;
 
@@ -795,7 +795,7 @@ The behavior is slightly different for:
 
 Variable suicide behavior is more consistent under Perl 5.
 Perl5 exhibits the same behavior for associative arrays and scalars,
-that perl4 exhibits only for scalars.
+that perl4 exhibits for only scalars.
 
     $aGlobal{ "aKey" } = "global value";
     print "MAIN:", $aGlobal{"aKey"}, "\n";
@@ -953,8 +953,8 @@ now works as a C programmer would expect.
 
     open FOO || die;
 
-is now incorrect.  You need parens around the filehandle.
-Otherwise, perl5 leaves the statement as it's default precedence:
+is now incorrect.  You need parentheses around the filehandle.
+Otherwise, perl5 leaves the statement as its default precedence:
 
     open(FOO || die);
  
@@ -1055,8 +1055,8 @@ Also see L<Numerical Traps> for another example of this new feature.
 
 =item * Regular Expression
 
-C<s`lhs`rhs`> (using backticks) is now a normal substitution, with no 
-backtick expansion
+C<s`lhs`rhs`> (using back-ticks) is now a normal substitution, with no 
+back-tick expansion
 
     $string = "";
     $string =~ s`^`hostname`;
@@ -1187,7 +1187,7 @@ on the handler _not_ being reset will have to be reworked.
 =item * (SysV)
 
 Under SysV OS's, C<seek()> on a file opened to append C<E<gt>E<gt>> now does 
-the right thing w.r.t. the fopen() man page. e.g. - When a file is opened
+the right thing w.r.t. the fopen() man page. e.g., - When a file is opened
 for append,  it  is  impossible to overwrite information already in
 the file.
 
index b0e2cf3..a049e9d 100644 (file)
@@ -7,7 +7,7 @@ perlvar - Perl predefined variables
 =head2 Predefined Names
 
 The following names have special meaning to Perl.  Most of the
-punctuational names have reasonable mnemonics, or analogues in one of
+punctuation names have reasonable mnemonics, or analogues in one of
 the shells.  Nevertheless, if you wish to use the long variable names,
 you just need to say
 
@@ -51,7 +51,7 @@ a reference, you'll raise a run-time exception.
 The default input and pattern-searching space.  The following pairs are
 equivalent:
 
-    while (<>) {...}   # only equivalent in while!
+    while (<>) {...}   # equivalent in only while!
     while ($_ = <>) {...}
 
     /^Subject:/
@@ -108,7 +108,7 @@ test.  Note that outside of a C<while> test, this will not happen.
 
 =item $E<lt>I<digit>E<gt>
 
-Contains the subpattern from the corresponding set of parentheses in
+Contains the sub-pattern from the corresponding set of parentheses in
 the last pattern matched, not counting patterns matched in nested
 blocks that have been exited already.  (Mnemonic: like \digit.)
 These variables are all read-only.
@@ -162,15 +162,15 @@ This variable is read-only.
 
 =item $*
 
-Set to 1 to do multiline matching within a string, 0 to tell Perl
+Set to 1 to do multi-line matching within a string, 0 to tell Perl
 that it can assume that strings contain a single line, for the purpose
 of optimizing pattern matches.  Pattern matches on strings containing
 multiple newlines can produce confusing results when "C<$*>" is 0.  Default
 is 0.  (Mnemonic: * matches multiple things.)  Note that this variable
-only influences the interpretation of "C<^>" and "C<$>".  A literal newline can
+influences the interpretation of only "C<^>" and "C<$>".  A literal newline can
 be searched for even when C<$* == 0>.
 
-Use of "C<$*>" is deprecated in Perl 5.
+Use of "C<$*>" is deprecated in modern perls.
 
 =item input_line_number HANDLE EXPR
 
@@ -182,7 +182,7 @@ Use of "C<$*>" is deprecated in Perl 5.
 
 The current input line number for the last file handle from
 which you read (or performed a C<seek> or C<tell> on).  An
-explicit close on a filehandle resets the line number.  Since
+explicit close on a filehandle resets the line number.  Because
 "C<E<lt>E<gt>>" never does an explicit close, line numbers increase
 across ARGV files (but see examples under eof()).  Localizing C<$.> has
 the effect of also localizing Perl's notion of "the last read
@@ -221,8 +221,8 @@ delimit line boundaries when quoting poetry.)
 
 If set to nonzero, forces a flush after every write or print on the
 currently selected output channel.  Default is 0 (regardless of whether
-the channel is actually buffered by the system or not; C<$|> only tells
-you whether you've asked Perl to explicitly flush after each write). 
+the channel is actually buffered by the system or not; C<$|> tells you
+only whether you've asked Perl explicitly to flush after each write). 
 Note that STDOUT will typically be line buffered if output is to the
 terminal and block buffered otherwise.  Setting this variable is useful
 primarily when you are outputting to a pipe, such as when you are running
@@ -239,8 +239,8 @@ has no effect on input buffering.
 =item $,
 
 The output field separator for the print operator.  Ordinarily the
-print operator simply prints out the comma separated fields you
-specify.  In order to get behavior more like B<awk>, set this variable
+print operator simply prints out the comma-separated fields you
+specify.  To get behavior more like B<awk>, set this variable
 as you would set B<awk>'s OFS variable to specify what is printed
 between fields.  (Mnemonic: what is printed when there is a , in your
 print statement.)
@@ -254,9 +254,9 @@ print statement.)
 =item $\
 
 The output record separator for the print operator.  Ordinarily the
-print operator simply prints out the comma separated fields you
-specify, with no trailing newline or record separator assumed.  In
-order to get behavior more like B<awk>, set this variable as you would
+print operator simply prints out the comma-separated fields you
+specify, with no trailing newline or record separator assumed.
+To get behavior more like B<awk>, set this variable as you would
 set B<awk>'s ORS variable to specify what is printed at the end of the
 print.  (Mnemonic: you set "C<$\>" instead of adding \n at the end of the
 print.  Also, it's just like C<$/>, but it's what you get "back" from
@@ -299,7 +299,7 @@ keys contain binary data there might not be any safe value for "C<$;>".
 semi-semicolon.  Yeah, I know, it's pretty lame, but "C<$,>" is already
 taken for something more important.)
 
-Consider using "real" multi-dimensional arrays in Perl 5.
+Consider using "real" multi-dimensional arrays.
 
 =item $OFMT
 
@@ -313,7 +313,7 @@ of the macro DBL_DIG from your system's F<float.h>.  This is different from
 B<awk>'s default OFMT setting of %.6g, so you need to set "C<$#>"
 explicitly to get B<awk>'s value.  (Mnemonic: # is the number sign.)
 
-Use of "C<$#>" is deprecated in Perl 5.
+Use of "C<$#>" is deprecated.
 
 =item format_page_number HANDLE EXPR
 
@@ -379,7 +379,7 @@ poetry is a part of a line.)
 
 =item $^L
 
-What formats output to perform a formfeed.  Default is \f.
+What formats output to perform a form feed.  Default is \f.
 
 =item $ACCUMULATOR
 
@@ -396,7 +396,7 @@ L<perlfunc/formline()>.
 
 =item $?
 
-The status returned by the last pipe close, backtick (C<``>) command,
+The status returned by the last pipe close, back-tick (C<``>) command,
 or system() operator.  Note that this is the status word returned by
 the wait() system call, so the exit value of the subprocess is actually
 (C<$? E<gt>E<gt> 8>).  Thus on many systems, C<$? & 255> gives which signal,
@@ -418,7 +418,7 @@ all the usual caveats.  (This means that you shouldn't depend on the
 value of "C<$!>" to be anything in particular unless you've gotten a
 specific error return indicating a system error.)  If used in a string
 context, yields the corresponding system error string.  You can assign
-to "C<$!>" in order to set I<errno> if, for instance, you want "C<$!>" to return the
+to "C<$!>" to set I<errno> if, for instance, you want "C<$!>" to return the
 string for error I<n>, or you want to set the exit value for the die()
 operator.  (Mnemonic: What just went bang?)
 
@@ -429,7 +429,7 @@ operator.  (Mnemonic: What just went bang?)
 More specific information about the last system error than that
 provided by C<$!>, if available.  (If not, it's just C<$!> again, except under
 OS/2.)
-At the moment, this differs from C<$!> only under VMS and OS/2, where it
+At the moment, this differs from C<$!> under only VMS and OS/2, where it
 provides the VMS status value from the last system error, and OS/2 error
 code of the last call to OS/2 API which was not directed via CRT.  The
 caveats mentioned in the description of C<$!> apply here, too.
@@ -481,7 +481,7 @@ The effective uid of this process.  Example:
     ($<,$>) = ($>,$<); # swap real and effective uid
 
 (Mnemonic: it's the uid you went I<TO>, if you're running setuid.)  Note:
-"C<$E<lt>>" and "C<$E<gt>>" can only be swapped on machines supporting setreuid().
+"C<$E<lt>>" and "C<$E<gt>>" can be swapped on only machines supporting setreuid().
 
 =item $REAL_GROUP_ID
 
@@ -510,10 +510,11 @@ which may be the same as the first number.  (Mnemonic: parentheses are
 used to I<GROUP> things.  The effective gid is the group that's I<RIGHT> for
 you, if you're running setgid.)
 
-Note: "C<$E<lt>>", "C<$E<gt>>", "C<$(>" and "C<$)>" can only be set on machines
-that support the corresponding I<set[re][ug]id()> routine.  "C<$(>" and "C<$)>" 
-can only be swapped on machines supporting setregid().   Because Perl doesn't
-currently use initgroups(), you can't set your group vector to multiple groups.
+Note: "C<$E<lt>>", "C<$E<gt>>", "C<$(>" and "C<$)>" can be set only on
+machines that support the corresponding I<set[re][ug]id()> routine.  "C<$(>"
+and "C<$)>" can be swapped on only machines supporting setregid().  Because
+Perl doesn't currently use initgroups(), you can't set your group vector to
+multiple groups.
 
 =item $PROGRAM_NAME
 
@@ -612,7 +613,7 @@ it.
 =item $^T
 
 The time at which the script began running, in seconds since the
-epoch (beginning of 1970).  The values returned by the B<-M>, B<-A> 
+epoch (beginning of 1970).  The values returned by the B<-M>, B<-A>,
 and B<-C> filetests are
 based on this value.
 
@@ -637,7 +638,7 @@ contains the name of the current file when reading from E<lt>E<gt>.
 
 The array @ARGV contains the command line arguments intended for the
 script.  Note that C<$#ARGV> is the generally number of arguments minus
-one, since C<$ARGV[0]> is the first argument, I<NOT> the command name.  See
+one, because C<$ARGV[0]> is the first argument, I<NOT> the command name.  See
 "C<$0>" for the command name.
 
 =item @INC
@@ -647,8 +648,8 @@ be evaluated by the C<do EXPR>, C<require>, or C<use> constructs.  It
 initially consists of the arguments to any B<-I> command line switches,
 followed by the default Perl library, probably F</usr/local/lib/perl>,
 followed by ".", to represent the current directory.  If you need to
-modify this at runtime, you should use the C<use lib> pragma in order
-to also get the machine-dependent library properly loaded:
+modify this at runtime, you should use the C<use lib> pragma
+to get the machine-dependent library properly loaded also:
 
     use lib '/mypath/libdir/';
     use SomeMod;
@@ -684,7 +685,7 @@ signals.  Example:
     $SIG{'INT'} = 'DEFAULT';   # restore default action
     $SIG{'QUIT'} = 'IGNORE';   # ignore SIGQUIT
 
-The %SIG array only contains values for the signals actually set within
+The %SIG array contains values for only the signals actually set within
 the Perl script.  Here are some other examples:
 
     $SIG{PIPE} = Plumber;       # SCARY!!
index 6a898a5..cc83c8b 100644 (file)
@@ -560,7 +560,7 @@ the following statement.
 
 =head2 Returning Undef And Empty Lists
 
-Occasionally the programmer will want to simply return
+Occasionally the programmer will want to return simply
 C<undef> or an empty list if a function fails rather than a
 separate status value.  The rpcb_gettime() function offers
 just this situation.  If the function succeeds we would like
@@ -631,7 +631,7 @@ other C<XSRETURN> macros.
 
 The REQUIRE: keyword is used to indicate the minimum version of the
 B<xsubpp> compiler needed to compile the XS module.  An XS module which
-contains the following statement will only compile with B<xsubpp> version
+contains the following statement will compile with only B<xsubpp> version
 1.922 or greater:
 
        REQUIRE: 1.922
@@ -664,7 +664,7 @@ terminate the code block.
 =head2 The VERSIONCHECK: Keyword
 
 The VERSIONCHECK: keyword corresponds to B<xsubpp>'s C<-versioncheck> and
-C<-noversioncheck> options.  This keyword overrides the commandline
+C<-noversioncheck> options.  This keyword overrides the command line
 options.  Version checking is enabled by default.  When version checking is
 enabled the XS module will attempt to verify that its version matches the
 version of the PM module.
@@ -680,7 +680,7 @@ To disable version checking:
 =head2 The PROTOTYPES: Keyword
 
 The PROTOTYPES: keyword corresponds to B<xsubpp>'s C<-prototypes> and
-C<-noprototypes> options.  This keyword overrides the commandline options.
+C<-noprototypes> options.  This keyword overrides the command-line options.
 Prototypes are enabled by default.  When prototypes are enabled XSUBs will
 be given Perl prototypes.  This keyword may be used multiple times in an XS
 module to enable and disable prototypes for different parts of the module.
@@ -844,7 +844,7 @@ C<&> through, so the function call looks like C<rpcb_gettime(host, &timep)>.
 =head2 Inserting Comments and C Preprocessor Directives
 
 C preprocessor directives are allowed within BOOT:, PREINIT: INIT:,
-CODE:, PPCODE: and CLEANUP: blocks, as well as outside the functions.
+CODE:, PPCODE:, and CLEANUP: blocks, as well as outside the functions.
 Comments are allowed anywhere after the MODULE keyword.  The compiler
 will pass the preprocessor directives through untouched and will remove
 the commented lines.
index 0c6cf3f..501a348 100644 (file)
@@ -10,8 +10,8 @@ L<perlxs>.
 
 This tutorial starts with very simple examples and becomes more complex,
 with each new example adding new features.  Certain concepts may not be
-completely explained until later in the tutorial in order to slowly ease
-the reader into building extensions.
+completely explained until later in the tutorial to ease the
+reader slowly into building extensions.
 
 =head2 VERSION CAVEAT
 
@@ -63,7 +63,7 @@ Some systems may have installed Perl version 5 as "perl5".
 =head2 DYNAMIC VERSUS STATIC
 
 It is commonly thought that if a system does not have the capability to
-dynamically load a library, you cannot build XSUBs.  This is incorrect.
+load a library dynamically, you cannot build XSUBs.  This is incorrect.
 You I<can> build them, but you must link the XSUB's subroutines with the
 rest of Perl, creating a new executable.  This situation is similar to
 Perl 4.
@@ -227,7 +227,7 @@ Now re-run make to rebuild our new shared library.
 Now perform the same steps as before, generating a Makefile from the
 Makefile.PL file, and running make.
 
-In order to test that our extension works, we now need to look at the
+To test that our extension works, we now need to look at the
 file test.pl.  This file is set up to imitate the same kind of testing
 structure that Perl itself has.  Within the test script, you perform a
 number of tests to confirm the behavior of the extension, printing "ok"
@@ -446,7 +446,7 @@ section on the argument stack.
 =head2 WARNING
 
 In general, it's not a good idea to write extensions that modify their input
-parameters, as in Example 3.  However, in order to better accommodate calling
+parameters, as in Example 3.  However, to accommodate better calling
 pre-existing C routines, which often do modify their input parameters,
 this behavior is tolerated.  The next example will show how to do this.
 
@@ -577,7 +577,7 @@ and add the following lines to the end of the script:
        print &Mytest2::foo(1, 2, "0.0") == 7 ? "ok 3\n" : "not ok 3\n";
        print abs(&Mytest2::foo(0, 0, "-3.4") - 0.6) <= 0.01 ? "ok 4\n" : "not ok 4\n";
 
-(When dealing with floating-point comparisons, it is often useful to not check
+(When dealing with floating-point comparisons, it is often useful not to check
 for equality, but rather the difference being below a certain epsilon factor,
 0.01 in this case)
 
@@ -607,7 +607,7 @@ C<constant> routine.
 
 The .pm file has exported the name TESTVAL in the @EXPORT array.  This
 could lead to name clashes.  A good rule of thumb is that if the #define
-is only going to be used by the C routines themselves, and not by the user,
+is going to be used by only the C routines themselves, and not by the user,
 they should be removed from the @EXPORT array.  Alternately, if you don't
 mind using the "fully qualified name" of a variable, you could remove most
 or all of the items in the @EXPORT array.
@@ -620,12 +620,12 @@ processed at all by h2xs.  There is no good solution to this right now.
 =back
 
 We've also told Perl about the library that we built in the mylib
-subdirectory.  That required only the addition of the MYEXTLIB variable
+subdirectory.  That required the addition of only the MYEXTLIB variable
 to the WriteMakefile call and the replacement of the postamble subroutine
 to cd into the subdirectory and run make.  The Makefile.PL for the
 library is a bit more complicated, but not excessively so.  Again we
 replaced the postamble subroutine to insert our own code.  This code
-simply specified that the library to be created here was a static
+specified simply that the library to be created here was a static
 archive (as opposed to a dynamically loadable library) and provided the
 commands to build it.
 
@@ -696,7 +696,7 @@ Sometimes you might want to provide some extra methods or subroutines
 to assist in making the interface between Perl and your extension simpler
 or easier to understand.  These routines should live in the .pm file.
 Whether they are automatically loaded when the extension itself is loaded
-or only loaded when called depends on where in the .pm file the subroutine
+or loaded only when called depends on where in the .pm file the subroutine
 definition is placed.
 
 =head2 DOCUMENTING YOUR EXTENSION
index ced8478..b41e0c3 100644 (file)
@@ -25,14 +25,15 @@ print "Extracting $file (with variable substitutions)\n";
 # You can use $Config{...} to use Configure variables.
 
 print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
+$Config{startperl}
+    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
 !GROK!THIS!
 
 # In the following, perl variables are not expanded during extraction.
 
 print OUT <<'!NO!SUBS!';
-eval 'exec perl -S $0 ${1+"$@"}'
-        if $running_under_some_shell;
+
 #
 # pod2html - convert pod format to html
 # Version 1.15
index 602364e..ebace22 100644 (file)
@@ -25,9 +25,9 @@ print "Extracting $file (with variable substitutions)\n";
 # You can use $Config{...} to use Configure variables.
 
 print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
-    eval 'exec perl -S \$0 "\$@"'
-       if 0;
+$Config{startperl}
+    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
 !GROK!THIS!
 
 # In the following, perl variables are not expanded during extraction.
index 0a51fc8..68121e4 100644 (file)
@@ -25,14 +25,14 @@ print "Extracting $file (with variable substitutions)\n";
 # You can use $Config{...} to use Configure variables.
 
 print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
+$Config{startperl}
+    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
 !GROK!THIS!
 
 # In the following, perl variables are not expanded during extraction.
 
 print OUT <<'!NO!SUBS!';
-eval 'exec perl -S $0 "$@"'
-    if 0;
 
 =head1 NAME
 
index 4919807..033a0d8 100644 (file)
@@ -25,9 +25,9 @@ print "Extracting $file (with variable substitutions)\n";
 # You can use $Config{...} to use Configure variables.
 
 print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
-    eval 'exec perl -S \$0 "\$@"'
-       if 0;
+$Config{startperl}
+    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
 !GROK!THIS!
 
 # In the following, perl variables are not expanded during extraction.
diff --git a/pp.c b/pp.c
index 4663466..ab1816d 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -142,28 +142,8 @@ PP(pp_rv2gv)
            sv = (SV*)gv_fetchpv(sym, TRUE, SVt_PVGV);
        }
     }
-    if (op->op_private & OPpLVAL_INTRO) {
-       GP *ogp = GvGP(sv);
-
-       SSCHECK(3);
-       SSPUSHPTR(SvREFCNT_inc(sv));
-       SSPUSHPTR(ogp);
-       SSPUSHINT(SAVEt_GP);
-
-       if (op->op_flags & OPf_SPECIAL) {
-           GvGP(sv)->gp_refcnt++;              /* will soon be assigned */
-           GvINTRO_on(sv);
-       }
-       else {
-           GP *gp;
-           Newz(602,gp, 1, GP);
-           GvGP(sv) = gp;
-           GvREFCNT(sv) = 1;
-           GvSV(sv) = NEWSV(72,0);
-           GvLINE(sv) = curcop->cop_line;
-           GvEGV(sv) = (GV*)sv;
-       }
-    }
+    if (op->op_private & OPpLVAL_INTRO)
+       save_gp((GV*)sv, !(op->op_flags & OPf_SPECIAL));
     SETs(sv);
     RETURN;
 }
@@ -208,7 +188,7 @@ PP(pp_rv2sv)
     if (op->op_flags & OPf_MOD) {
        if (op->op_private & OPpLVAL_INTRO)
            sv = save_scalar((GV*)TOPs);
-       else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV))
+       else if (op->op_private & OPpDEREF)
            provide_ref(op, sv);
     }
     SETs(sv);
@@ -234,7 +214,12 @@ PP(pp_pos)
     dSP; dTARGET; dPOPss;
     
     if (op->op_flags & OPf_MOD) {
-       LvTYPE(TARG) = '<';
+       if (SvTYPE(TARG) < SVt_PVLV) {
+           sv_upgrade(TARG, SVt_PVLV);
+           sv_magic(TARG, Nullsv, '.', Nullch, 0);
+       }
+
+       LvTYPE(TARG) = '.';
        LvTARG(TARG) = sv;
        PUSHs(TARG);    /* no SvSETMAGIC */
        RETURN;
@@ -279,10 +264,8 @@ PP(pp_prototype)
 
     ret = &sv_undef;
     cv = sv_2cv(TOPs, &stash, &gv, FALSE);
-    if (cv && SvPOK(cv)) {
-       char *p = SvPVX(cv);
-       ret = sv_2mortal(newSVpv(p ? p : "", SvLEN(cv)));
-    }
+    if (cv && SvPOK(cv))
+       ret = sv_2mortal(newSVpv(SvPVX(cv), SvCUR(cv)));
     SETs(ret);
     RETURN;
 }
@@ -290,12 +273,10 @@ PP(pp_prototype)
 PP(pp_anoncode)
 {
     dSP;
-    CV* cv = (CV*)cSVOP->op_sv;
-    EXTEND(SP,1);
-
+    CV* cv = (CV*)curpad[op->op_targ];
     if (CvCLONE(cv))
        cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
-
+    EXTEND(SP,1);
     PUSHs((SV*)cv);
     RETURN;
 }
@@ -1328,7 +1309,7 @@ PP(pp_srand)
        _ckvmssts(sys$gettim(when));
        anum = when[0] ^ when[1];
 #else
-#  if defined(I_SYS_TIME) && !defined(PLAN9)
+#  ifdef HAS_GETTIMEOFDAY
        struct timeval when;
        gettimeofday(&when,(struct timezone *) 0);
        anum = when.tv_sec ^ when.tv_usec;
@@ -1516,12 +1497,13 @@ PP(pp_substr)
                else
                    sv_setpvn(sv,"",0); /* avoid lexical reincarnation */
            }
+
            if (SvTYPE(TARG) < SVt_PVLV) {
                sv_upgrade(TARG, SVt_PVLV);
                sv_magic(TARG, Nullsv, 'x', Nullch, 0);
            }
 
-           LvTYPE(TARG) = 's';
+           LvTYPE(TARG) = 'x';
            LvTARG(TARG) = sv;
            LvTARGOFF(TARG) = pos;
            LvTARGLEN(TARG) = rem; 
@@ -1974,17 +1956,35 @@ PP(pp_delete)
 {
     dSP;
     SV *sv;
-    SV *tmpsv = POPs;
-    HV *hv = (HV*)POPs;
-    STRLEN len;
-    if (SvTYPE(hv) != SVt_PVHV) {
-       DIE("Not a HASH reference");
+    HV *hv;
+
+    if (op->op_private & OPpSLICE) {
+       dMARK; dORIGMARK;
+       hv = (HV*)POPs;
+       if (SvTYPE(hv) != SVt_PVHV)
+           DIE("Not a HASH reference");
+       while (++MARK <= SP) {
+           sv = hv_delete_ent(hv, *MARK,
+                       (op->op_private & OPpLEAVE_VOID ? G_DISCARD : 0), 0);
+           *MARK = sv ? sv : &sv_undef;
+       }
+       if (GIMME != G_ARRAY) {
+           MARK = ORIGMARK;
+           *++MARK = *SP;
+           SP = MARK;
+       }
+    }
+    else {
+       SV *keysv = POPs;
+       hv = (HV*)POPs;
+       if (SvTYPE(hv) != SVt_PVHV)
+           DIE("Not a HASH reference");
+       sv = hv_delete_ent(hv, keysv,
+                       (op->op_private & OPpLEAVE_VOID ? G_DISCARD : 0), 0);
+       if (!sv)
+           sv = &sv_undef;
+       PUSHs(sv);
     }
-    sv = hv_delete_ent(hv, tmpsv,
-       (op->op_private & OPpLEAVE_VOID ? G_DISCARD : 0), 0);
-    if (!sv)
-       RETPUSHUNDEF;
-    PUSHs(sv);
     RETURN;
 }
 
@@ -2116,7 +2116,6 @@ PP(pp_anonlist)
 PP(pp_anonhash)
 {
     dSP; dMARK; dORIGMARK;
-    STRLEN len;
     HV* hv = (HV*)sv_2mortal((SV*)newHV());
 
     while (MARK < SP) {
@@ -3567,6 +3566,7 @@ PP(pp_pack)
                        *--in = div128(norm, &done) | 0x80;
                    result[len - 1] &= 0x7F; /* clear continue bit */
                    sv_catpvn(cat, in, (result + len) - in);
+                   Safefree(result);
                    SvREFCNT_dec(norm); /* free norm */
                 }
                else if (SvNOKp(fromstr)) {
index 962cf04..78e1c99 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -859,7 +859,7 @@ I32 startingblock;
        switch (cx->cx_type) {
        case CXt_SUBST:
            if (dowarn)
-               warn("Exiting substitition via %s", op_name[op->op_type]);
+               warn("Exiting substitution via %s", op_name[op->op_type]);
            break;
        case CXt_SUB:
            if (dowarn)
@@ -1636,8 +1636,10 @@ PP(pp_goto)
                        for ( ;ix > 0; ix--) {
                            if (svp[ix] != &sv_undef) {
                                char *name = SvPVX(svp[ix]);
-                               if (SvFLAGS(svp[ix]) & SVf_FAKE) {
-                                   /* outer lexical? */
+                               if ((SvFLAGS(svp[ix]) & SVf_FAKE)
+                                   || *name == '&')
+                               {
+                                   /* outer lexical or anon code */
                                    av_store(newpad, ix,
                                        SvREFCNT_inc(oldpad[ix]) );
                                }
@@ -2362,13 +2364,12 @@ SV *sv;
            skipspaces++;
            arg -= skipspaces;
            if (arg) {
-               if (postspace) {
+               if (postspace)
                    *fpc++ = FF_SPACE;
-                   postspace = FALSE;
-               }
                *fpc++ = FF_LITERAL;
                *fpc++ = arg;
            }
+           postspace = FALSE;
            if (s <= send)
                skipspaces--;
            if (skipspaces) {
index 4b9ba00..fb28bfe 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -217,7 +217,7 @@ PP(pp_padsv)
     if (op->op_flags & OPf_MOD) {
        if (op->op_private & OPpLVAL_INTRO)
            SAVECLEARSV(curpad[op->op_targ]);
-        else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV))
+        else if (op->op_private & OPpDEREF)
            provide_ref(op, curpad[op->op_targ]);
     }
     RETURN;
@@ -725,6 +725,8 @@ PP(pp_aassign)
            SP = lastrelem;
        else
            SP = firstrelem + (lastlelem - firstlelem);
+       while (relem <= SP)
+           *relem++ = &sv_undef;
        RETURN;
     }
     else {
@@ -786,7 +788,7 @@ PP(pp_match)
     }
     if (!rx->nparens && !global)
        gimme = G_SCALAR;                       /* accidental array context? */
-    safebase = (gimme == G_ARRAY) || global;
+    safebase = (((gimme == G_ARRAY) || global) && !sawampersand);
     if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) {
        SAVEINT(multiline);
        multiline = pm->op_pmflags & PMf_MULTILINE;
@@ -795,7 +797,7 @@ PP(pp_match)
 play_it_again:
     if (global && rx->startp[0]) {
        t = s = rx->endp[0];
-       if (s > strend)
+       if (s >= strend)
            goto nope;
        minmatch = (s == rx->startp[0]);
     }
@@ -868,6 +870,7 @@ play_it_again:
        }
        if (global) {
            truebase = rx->subbeg;
+           strend = rx->subend;
            if (rx->startp[0] && rx->startp[0] == rx->endp[0])
                ++rx->endp[0];
            goto play_it_again;
@@ -885,7 +888,7 @@ play_it_again:
                mg = mg_find(TARG, 'g');
            }
            if (rx->startp[0]) {
-               mg->mg_len = rx->endp[0] - truebase;
+               mg->mg_len = rx->endp[0] - rx->subbeg;
                if (rx->startp[0] == rx->endp[0])
                    mg->mg_flags |= MGf_MINMATCH;
                else
@@ -903,6 +906,8 @@ yup:
     curpm = pm;
     if (pm->op_pmflags & PMf_ONCE)
        pm->op_pmflags |= PMf_USED;
+    Safefree(rx->subbase);
+    rx->subbase = Nullch;
     if (global) {
        rx->subbeg = truebase;
        rx->subend = strend;
@@ -913,8 +918,6 @@ yup:
     if (sawampersand) {
        char *tmps;
 
-       if (rx->subbase)
-           Safefree(rx->subbase);
        tmps = rx->subbase = savepvn(t, strend-t);
        rx->subbeg = tmps;
        rx->subend = tmps + (strend-t);
@@ -1234,9 +1237,13 @@ PP(pp_helem)
     if (lval) {
        if (!he || HeVAL(he) == &sv_undef)
            DIE(no_helem, SvPV(keysv, na));
-       if (op->op_private & OPpLVAL_INTRO)
-           save_svref(&HeVAL(he));
-       else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV))
+       if (op->op_private & OPpLVAL_INTRO) {
+           if (HvNAME(hv) && isGV(HeVAL(he)))
+               save_gp((GV*)HeVAL(he), !(op->op_flags & OPf_SPECIAL));
+           else
+               save_svref(&HeVAL(he));
+       }
+       else if (op->op_private & OPpDEREF)
            provide_ref(op, HeVAL(he));
     }
     PUSHs(he ? HeVAL(he) : &sv_undef);
@@ -1300,7 +1307,7 @@ PP(pp_iter)
 {
     dSP;
     register CONTEXT *cx;
-    SV *sv;
+    SV* sv;
     AV* av;
 
     EXTEND(sp, 1);
@@ -1314,13 +1321,26 @@ PP(pp_iter)
     if (cx->blk_loop.iterix >= AvFILL(av))
        RETPUSHNO;
 
-    if (sv = AvARRAY(av)[++cx->blk_loop.iterix]) {
+    if (sv = AvARRAY(av)[++cx->blk_loop.iterix])
        SvTEMP_off(sv);
-       *cx->blk_loop.itervar = sv;
-    }
     else
-       *cx->blk_loop.itervar = &sv_undef;
-
+       sv = &sv_undef;
+    if (av != curstack && SvIMMORTAL(sv)) {
+       SV *lv = cx->blk_loop.iterlval;
+       if (lv)
+           SvREFCNT_dec(LvTARG(lv));
+       else {
+           lv = cx->blk_loop.iterlval = newSVsv(sv);
+           sv_upgrade(lv, SVt_PVLV);
+           sv_magic(lv, Nullsv, 'y', Nullch, 0);
+           LvTYPE(lv) = 'y';
+       }
+       LvTARG(lv) = SvREFCNT_inc(av);
+       LvTARGOFF(lv) = cx->blk_loop.iterix;
+       LvTARGLEN(lv) = 1;
+       sv = (SV*)lv;
+    }
+    *cx->blk_loop.itervar = sv;
     RETPUSHYES;
 }
 
@@ -1370,7 +1390,7 @@ PP(pp_subst)
        pm = curpm;
        rx = pm->op_pmregexp;
     }
-    safebase = ((!rx || !rx->nparens) && !sawampersand);
+    safebase = (!rx->nparens && !sawampersand);
     if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) {
        SAVEINT(multiline);
        multiline = pm->op_pmflags & PMf_MULTILINE;
@@ -1518,7 +1538,7 @@ PP(pp_subst)
     else
        c = Nullch;
     if (pregexec(rx, s, strend, orig, 0,
-      SvSCREAM(TARG) ? TARG : Nullsv, safebase)) {
+                SvSCREAM(TARG) ? TARG : Nullsv, safebase)) {
     long_way:
        if (force_on_match) {
            force_on_match = 0;
@@ -1550,8 +1570,7 @@ PP(pp_subst)
                sv_catpvn(dstr, c, clen);
            if (once)
                break;
-       } while (pregexec(rx, s, strend, orig, s == m, Nullsv,
-           safebase));
+       } while (pregexec(rx, s, strend, orig, s == m, Nullsv, safebase));
        sv_catpvn(dstr, s, strend - s);
 
        (void)SvOOK_off(TARG);
@@ -1831,7 +1850,8 @@ PP(pp_entersub)
        if (CvDEPTH(cv) < 2)
            (void)SvREFCNT_inc(cv);
        else {  /* save temporaries on recursion? */
-           if (CvDEPTH(cv) == 100 && dowarn)
+           if (CvDEPTH(cv) == 100 && dowarn 
+               && !(perldb && cv == GvCV(DBsub)))
                warn("Deep recursion on subroutine \"%s\"",GvENAME(CvGV(cv)));
            if (CvDEPTH(cv) > AvFILL(padlist)) {
                AV *av;
@@ -1842,9 +1862,10 @@ PP(pp_entersub)
                for ( ;ix > 0; ix--) {
                    if (svp[ix] != &sv_undef) {
                        char *name = SvPVX(svp[ix]);
-                       if (SvFLAGS(svp[ix]) & SVf_FAKE) { /* outer lexical? */
-                           av_store(newpad, ix,
-                               SvREFCNT_inc(oldpad[ix]) );
+                       if ((SvFLAGS(svp[ix]) & SVf_FAKE) /* outer lexical? */
+                           || *name == '&')              /* anonymous code? */
+                       {
+                           av_store(newpad, ix, SvREFCNT_inc(oldpad[ix]));
                        }
                        else {                          /* our own lexical */
                            if (*name == '@')
@@ -1929,7 +1950,7 @@ PP(pp_aelem)
            DIE(no_aelem, elem);
        if (op->op_private & OPpLVAL_INTRO)
            save_svref(svp);
-       else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV))
+       else if (op->op_private & OPpDEREF)
            provide_ref(op, *svp);
     }
     PUSHs(svp ? *svp : &sv_undef);
@@ -1946,9 +1967,25 @@ SV* sv;
     if (!SvOK(sv)) {
        if (SvREADONLY(sv))
            croak(no_modify);
-       (void)SvUPGRADE(sv, SVt_RV);
-       SvRV(sv) = (op->op_private & OPpDEREF_HV ?
-                   (SV*)newHV() : (SV*)newAV());
+       if (SvTYPE(sv) < SVt_RV)
+           sv_upgrade(sv, SVt_RV);
+       else if (SvTYPE(sv) >= SVt_PV) {
+           (void)SvOOK_off(sv);
+           Safefree(SvPVX(sv));
+           SvLEN(sv) = SvCUR(sv) = 0;
+       }
+       switch (op->op_private & OPpDEREF)
+       {
+       case OPpDEREF_SV:
+           SvRV(sv) = newSV(0);
+           break;
+       case OPpDEREF_AV:
+           SvRV(sv) = (SV*)newAV();
+           break;
+       case OPpDEREF_HV:
+           SvRV(sv) = (SV*)newHV();
+           break;
+       }
        SvROK_on(sv);
        SvSETMAGIC(sv);
     }
index 9b30adb..5e096fe 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -284,11 +284,13 @@ PP(pp_open)
 
     if (MAXARG > 1)
        sv = POPs;
-    else if (SvTYPE(TOPs) == SVt_PVGV)
-       sv = GvSV(TOPs);
-    else
+    if (!isGV(TOPs))
        DIE(no_usym, "filehandle");
+    if (MAXARG <= 1)
+       sv = GvSV(TOPs);
     gv = (GV*)POPs;
+    if (!isGV(gv))
+       DIE(no_usym, "filehandle");
     if (GvIOp(gv))
        IoFLAGS(GvIOp(gv)) &= ~IOf_UNTAINT;
     tmps = SvPV(sv, len);
@@ -2271,11 +2273,21 @@ PP(pp_fttext)
     STDCHAR tbuf[512];
     register STDCHAR *s;
     register IO *io;
-    SV *sv;
+    register SV *sv;
+    GV *gv;
 
-    if (op->op_flags & OPf_REF) {
+    if (op->op_flags & OPf_REF)
+       gv = cGVOP->op_gv;
+    else if (isGV(TOPs))
+       gv = (GV*)POPs;
+    else if (SvROK(TOPs) && isGV(SvRV(TOPs)))
+       gv = (GV*)SvRV(POPs);
+    else
+       gv = Nullgv;
+
+    if (gv) {
        EXTEND(SP, 1);
-       if (cGVOP->op_gv == defgv) {
+       if (gv == defgv) {
            if (statgv)
                io = GvIO(statgv);
            else {
@@ -2284,13 +2296,17 @@ PP(pp_fttext)
            }
        }
        else {
-           statgv = cGVOP->op_gv;
+           statgv = gv;
+           laststatval = -1;
            sv_setpv(statname, "");
            io = GvIO(statgv);
        }
        if (io && IoIFP(io)) {
-          if (PerlIO_has_base(IoIFP(io))) {
-           Fstat(PerlIO_fileno(IoIFP(io)), &statcache);
+           if (! PerlIO_has_base(IoIFP(io)))
+               DIE("-T and -B not implemented on filehandles");
+           laststatval = Fstat(PerlIO_fileno(IoIFP(io)), &statcache);
+           if (laststatval < 0)
+               RETPUSHUNDEF;
            if (S_ISDIR(statcache.st_mode))     /* handle NFS glitch */
                if (op->op_type == OP_FTTEXT)
                    RETPUSHNO;
@@ -2308,10 +2324,6 @@ PP(pp_fttext)
            /* sfio can have large buffers - limit to 512 */
            if (len > 512)
                len = 512;
-         }
-          else {
-           DIE("-T and -B not implemented on filehandles");
-         }
        }
        else {
            if (dowarn)
@@ -2323,9 +2335,10 @@ PP(pp_fttext)
     }
     else {
        sv = POPs;
+      really_filename:
        statgv = Nullgv;
+       laststatval = -1;
        sv_setpv(statname, SvPV(sv, na));
-      really_filename:
 #ifdef HAS_OPEN3
        i = open(SvPV(sv, na), O_RDONLY, 0);
 #else
@@ -2336,7 +2349,9 @@ PP(pp_fttext)
                warn(warn_nl, "open");
            RETPUSHUNDEF;
        }
-       Fstat(i, &statcache);
+       laststatval = Fstat(i, &statcache);
+       if (laststatval < 0)
+           RETPUSHUNDEF;
        len = read(i, tbuf, 512);
        (void)close(i);
        if (len <= 0) {
diff --git a/proto.h b/proto.h
index 787ebcf..cbf38d4 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -178,7 +178,8 @@ I32 looks_like_number _((SV* sv));
 int    magic_clearenv  _((SV* sv, MAGIC* mg));
 int    magic_clearpack _((SV* sv, MAGIC* mg));
 int    magic_clearsig  _((SV* sv, MAGIC* mg));
-int    magic_existspack        _((SV* sv, MAGIC* mg));
+int    magic_existspack _((SV* sv, MAGIC* mg));
+int    magic_freevivary _((SV* sv, MAGIC* mg));
 int    magic_get       _((SV* sv, MAGIC* mg));
 int    magic_getarylen _((SV* sv, MAGIC* mg));
 int    magic_getpack   _((SV* sv, MAGIC* mg));
@@ -210,11 +211,14 @@ int       magic_setsubstr _((SV* sv, MAGIC* mg));
 int    magic_settaint  _((SV* sv, MAGIC* mg));
 int    magic_setuvar   _((SV* sv, MAGIC* mg));
 int    magic_setvec    _((SV* sv, MAGIC* mg));
+int    magic_setvivary _((SV* sv, MAGIC* mg));
 int    magic_wipepack  _((SV* sv, MAGIC* mg));
 void   magicname _((char* sym, char* name, I32 namlen));
 int    main _((int argc, char** argv, char** env));
 void   markstack_grow _((void));
+#ifdef USE_LOCALE_COLLATE
 char*  mem_collxfrm _((const char *s, STRLEN len, STRLEN *xlen));
+#endif
 char*  mess _((char* pat, va_list* args));
 int    mg_clear _((SV* sv));
 int    mg_copy _((SV *, SV *, char *, I32));
@@ -227,13 +231,15 @@ int       mg_set _((SV* sv));
 OP*    mod _((OP* op, I32 type));
 char*  moreswitches _((char* s));
 OP *   my _(( OP *));
+#if !defined(HAS_BCOPY) || !defined(HAS_SAFE_BCOPY)
 char*  my_bcopy _((char* from, char* to, I32 len));
+#endif
 #if !defined(HAS_BZERO) && !defined(HAS_MEMSET)
 char*  my_bzero _((char* loc, I32 len));
 #endif
 void   my_exit _((U32 status)) __attribute__((noreturn));
 I32    my_lstat _((void));
-#ifndef HAS_MEMCMP
+#if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP)
 I32    my_memcmp _((char* s1, char* s2, I32 len));
 #endif
 I32    my_pclose _((PerlIO* ptr));
@@ -380,6 +386,7 @@ void        save_destructor _((void (*f)(void*), void* p));
 void   save_freesv _((SV* sv));
 void   save_freeop _((OP* op));
 void   save_freepv _((char* pv));
+void   save_gp _((GV* gv, I32 empty));
 HV*    save_hash _((GV* gv));
 void   save_hptr _((HV** hptr));
 void   save_I16 _((I16* intp));
@@ -431,7 +438,9 @@ void        sv_clean_objs _((void));
 void   sv_clear _((SV* sv));
 I32    sv_cmp _((SV* sv1, SV* sv2));
 I32    sv_cmp_locale _((SV* sv1, SV* sv2));
+#ifdef USE_LOCALE_COLLATE
 char*  sv_collxfrm _((SV* sv, STRLEN* nxp));
+#endif
 void   sv_dec _((SV* sv));
 void   sv_dump _((SV* sv));
 bool   sv_derived_from _((SV* sv, char* name));
index da3097e..292f960 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -524,24 +524,16 @@ got_it:
     prog->subbeg = strbeg;
     prog->subend = strend;
     prog->exec_tainted = regtainted;
-    if (!safebase && (prog->nparens || sawampersand)) {
+
+    /* make sure $`, $&, $', and $digit will work later */
+    if (!safebase && (strbeg != prog->subbase)) {
        I32 i = strend - startpos + (stringarg - strbeg);
-       if (safebase) {                 /* no need for $digit later */
-           s = strbeg;
-           prog->subend = s+i;
-       }
-       else if (strbeg != prog->subbase) {
-           s = savepvn(strbeg,i);      /* so $digit will work later */
-           if (prog->subbase)
-               Safefree(prog->subbase);
-           prog->subbeg = prog->subbase = s;
-           prog->subend = s+i;
-       }
-       else {
-           prog->subbeg = s = prog->subbase;
-           prog->subend = s+i;
-       }
-       s += (stringarg - strbeg);
+       s = savepvn(strbeg, i);
+       Safefree(prog->subbase);
+       prog->subbase = s;
+       prog->subbeg = prog->subbase;
+       prog->subend = prog->subbase + i;
+       s = prog->subbase + (stringarg - strbeg);
        for (i = 0; i <= prog->nparens; i++) {
            if (prog->endp[i]) {
                prog->startp[i] = s + (prog->startp[i] - startpos);
@@ -727,8 +719,9 @@ char *prog;
                sayNO;
            if (regeol - locinput < ln)
                sayNO;
-           if (ln > 1 && ((OP(scan) == EXACTF)
-                          ? ibcmp : ibcmp_locale)(s, locinput, ln) != 0)
+           if (ln > 1 && (OP(scan) == EXACTF
+                          ? ibcmp(s, locinput, ln)
+                          : ibcmp_locale(s, locinput, ln)))
                sayNO;
            locinput += ln;
            nextchar = UCHARAT(locinput);
@@ -885,6 +878,7 @@ char *prog;
                 * that we can try again after backing off.
                 */
 
+               CHECKPOINT cp;
                CURCUR* cc = regcc;
                n = cc->cur + 1;        /* how many we know we matched */
                reginput = locinput;
@@ -923,8 +917,12 @@ char *prog;
                if (cc->minmod) {
                    regcc = cc->oldcc;
                    ln = regcc->cur;
-                   if (regmatch(cc->next))
+                   cp = regcppush(cc->parenfloor);
+                   if (regmatch(cc->next)) {
+                       regcpblow(cp);
                        sayYES; /* All done. */
+                   }
+                   regcppop();
                    regcc->cur = ln;
                    regcc = cc;
 
@@ -935,8 +933,12 @@ char *prog;
                    reginput = locinput;
                    cc->cur = n;
                    cc->lastloc = locinput;
-                   if (regmatch(cc->scan))
+                   cp = regcppush(cc->parenfloor);
+                   if (regmatch(cc->scan)) {
+                       regcpblow(cp);
                        sayYES;
+                   }
+                   regcppop();
                    cc->cur = n - 1;
                    sayNO;
                }
@@ -944,11 +946,13 @@ char *prog;
                /* Prefer scan over next for maximal matching. */
 
                if (n < cc->max) {      /* More greed allowed? */
-                   regcppush(cc->parenfloor);
+                   cp = regcppush(cc->parenfloor);
                    cc->cur = n;
                    cc->lastloc = locinput;
-                   if (regmatch(cc->scan))
+                   if (regmatch(cc->scan)) {
+                       regcpblow(cp);
                        sayYES;
+                   }
                    regcppop();         /* Restore some previous $<digit>s? */
                    reginput = locinput;
                }
diff --git a/scope.c b/scope.c
index d2dac1c..afdcf44 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -143,27 +143,30 @@ GV *gv;
     return sv;
 }
 
-#ifdef INLINED_ELSEWHERE
 void
-save_gp(gv)
+save_gp(gv, empty)
 GV *gv;
+I32 empty;
 {
-    register GP *gp;
-    GP *ogp = GvGP(gv);
-
     SSCHECK(3);
     SSPUSHPTR(SvREFCNT_inc(gv));
-    SSPUSHPTR(ogp);
+    SSPUSHPTR(GvGP(gv));
     SSPUSHINT(SAVEt_GP);
 
-    Newz(602,gp, 1, GP);
-    GvGP(gv) = gp;
-    GvREFCNT(gv) = 1;
-    GvSV(gv) = NEWSV(72,0);
-    GvLINE(gv) = curcop->cop_line;
-    GvEGV(gv) = gv;
+    if (empty) {
+       register GP *gp;
+       Newz(602, gp, 1, GP);
+       GvGP(gv) = gp;
+       GvREFCNT(gv) = 1;
+       GvSV(gv) = NEWSV(72,0);
+       GvLINE(gv) = curcop->cop_line;
+       GvEGV(gv) = gv;
+    }
+    else {
+       GvGP(gv)->gp_refcnt++;
+       GvINTRO_on(gv);
+    }
 }
-#endif
 
 SV*
 save_svref(sptr)
diff --git a/sv.c b/sv.c
index 85c65bf..95c3340 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -375,6 +375,9 @@ sv_free_arenas()
        if (!SvFAKE(sva))
            Safefree((void *)sva);
     }
+
+    sv_arenaroot = 0;
+    sv_root = 0;
 }
 
 static XPVIV*
@@ -2386,6 +2389,9 @@ I32 namlen;
     case 'x':
        mg->mg_virtual = &vtbl_substr;
        break;
+    case 'y':
+       mg->mg_virtual = &vtbl_vivary;
+       break;
     case '*':
        mg->mg_virtual = &vtbl_glob;
        break;
@@ -2611,7 +2617,7 @@ register SV *sv;
                SvROK_off(ret);
                SvREFCNT(sv) = 0;
            } else {
-               croak("panic: dangling references in DESTROY");
+               croak("DESTROY created new reference to dead object");
            }
        }
     }
@@ -2619,7 +2625,10 @@ register SV *sv;
        mg_free(sv);
     switch (SvTYPE(sv)) {
     case SVt_PVIO:
-       io_close((IO*)sv);
+       if (IoIFP(sv) != PerlIO_stdin() &&
+           IoIFP(sv) != PerlIO_stdout() &&
+           IoIFP(sv) != PerlIO_stderr())
+         io_close((IO*)sv);
        Safefree(IoTOP_NAME(sv));
        Safefree(IoFMT_NAME(sv));
        Safefree(IoBOTTOM_NAME(sv));
@@ -3406,6 +3415,19 @@ SV *ref;
     return sv;
 }
 
+#ifdef CRIPPLED_CC
+SV *
+newRV_noinc(ref)
+SV *ref;
+{
+    register SV *sv;
+
+    sv = newRV(ref);
+    SvREFCNT_dec(ref);
+    return sv;
+}
+#endif /* CRIPPLED_CC */
+
 /* make an exact duplicate of old */
 
 SV *
diff --git a/sv.h b/sv.h
index d90e85e..36fa72d 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -80,8 +80,6 @@ struct io {
                                    (Sv && ++SvREFCNT(Sv)), (SV*)Sv)
 #define SvREFCNT_dec(sv)       sv_free((SV*)sv)
 #endif
-#define newRV_noinc(sv)        ((Sv = newRV(sv)), \
-                                   (--SvREFCNT(sv)), (SV*)Sv)
 
 #define SVTYPEMASK     0xff
 #define SvTYPE(sv)     ((sv)->sv_flags & SVTYPEMASK)
@@ -549,6 +547,13 @@ I32 SvTRUE _((SV *));
 
 #endif /* CRIPPLED_CC */
 
+#define newRV_inc(sv)  newRV(sv)
+#ifdef CRIPPLED_CC
+SV *newRV_noinc _((SV *));
+#else
+#define newRV_noinc(sv)        ((Sv = newRV(sv)), --SvREFCNT(SvRV(Sv)), Sv)
+#endif
+
 /* the following macro updates any magic values this sv is associated with */
 
 #define SvSETMAGIC(x) if (SvSMAGICAL(x)) mg_set(x)
index 038a73c..11836f1 100755 (executable)
@@ -64,12 +64,19 @@ print "ok 10\n";
 
 ($rd,$wr) = FileHandle::pipe;
 
-if (fork) {
- $wr->close;
- print $rd->getline;
+if ($^O eq 'VMS' || $^O eq 'os2') {
+  $wr->autoflush;
+  $wr->printf("ok %d\n",11);
+  print $rd->getline;
 }
 else {
- $rd->close;
- $wr->printf("ok %d\n",11);
- exit(0);
+  if (fork) {
+   $wr->close;
+   print $rd->getline;
+  }
+  else {
+   $rd->close;
+   $wr->printf("ok %d\n",11);
+   exit(0);
+  }
 }
index 010cbf1..4e00566 100755 (executable)
@@ -2,11 +2,13 @@
 
 # $RCSfile: delete.t,v $$Revision: 4.1 $$Date: 92/08/07 18:27:44 $
 
-print "1..7\n";
+print "1..16\n";
 
 $foo{1} = 'a';
 $foo{2} = 'b';
 $foo{3} = 'c';
+$foo{4} = 'd';
+$foo{5} = 'e';
 
 $foo = delete $foo{2};
 
@@ -14,9 +16,21 @@ if ($foo eq 'b') {print "ok 1\n";} else {print "not ok 1 $foo\n";}
 if ($foo{2} eq '') {print "ok 2\n";} else {print "not ok 2 $foo{2}\n";}
 if ($foo{1} eq 'a') {print "ok 3\n";} else {print "not ok 3\n";}
 if ($foo{3} eq 'c') {print "ok 4\n";} else {print "not ok 4\n";}
+if ($foo{4} eq 'd') {print "ok 5\n";} else {print "not ok 5\n";}
+if ($foo{5} eq 'e') {print "ok 6\n";} else {print "not ok 6\n";}
+
+@foo = delete @foo{4, 5};
+
+if (@foo == 2) {print "ok 7\n";} else {print "not ok 7 ", @foo+0, "\n";}
+if ($foo[0] eq 'd') {print "ok 8\n";} else {print "not ok 8 ", $foo[0], "\n";}
+if ($foo[1] eq 'e') {print "ok 9\n";} else {print "not ok 9 ", $foo[1], "\n";}
+if ($foo{4} eq '') {print "ok 10\n";} else {print "not ok 10 $foo{4}\n";}
+if ($foo{5} eq '') {print "ok 11\n";} else {print "not ok 11 $foo{5}\n";}
+if ($foo{1} eq 'a') {print "ok 12\n";} else {print "not ok 12\n";}
+if ($foo{3} eq 'c') {print "ok 13\n";} else {print "not ok 13\n";}
 
 $foo = join('',values(foo));
-if ($foo eq 'ac' || $foo eq 'ca') {print "ok 5\n";} else {print "not ok 5\n";}
+if ($foo eq 'ac' || $foo eq 'ca') {print "ok 14\n";} else {print "not ok 14\n";}
 
 foreach $key (keys foo) {
     delete $foo{$key};
@@ -26,7 +40,7 @@ $foo{'foo'} = 'x';
 $foo{'bar'} = 'y';
 
 $foo = join('',values(foo));
-if ($foo eq 'xy' || $foo eq 'yx') {print "ok 6\n";} else {print "not ok 6\n";}
+print +($foo eq 'xy' || $foo eq 'yx') ? "ok 15\n" : "not ok 15\n";
 
 $refhash{"top"}->{"foo"} = "FOO";
 $refhash{"top"}->{"bar"} = "BAR";
@@ -34,4 +48,4 @@ $refhash{"top"}->{"bar"} = "BAR";
 delete $refhash{"top"}->{"bar"};
 @list = keys %{$refhash{"top"}};
 
-print "@list" eq "foo" ? "ok 7\n" : "not ok 7 @list\n";
+print "@list" eq "foo" ? "ok 16\n" : "not ok 16 @list\n";
index e69de29..6b21c66 100755 (executable)
@@ -0,0 +1,90 @@
+#!./perl
+
+#
+# test recursive functions.
+#
+
+print "1..23\n";
+
+sub gcd ($$) {
+    return gcd($_[0] - $_[1], $_[1]) if ($_[0] > $_[1]);
+    return gcd($_[0], $_[1] - $_[0]) if ($_[0] < $_[1]);
+    $_[0];
+}
+
+sub factorial ($) {
+    $_[0] < 2 ? 1 : $_[0] * factorial($_[0] - 1);
+}
+
+sub fibonacci ($) {
+    $_[0] < 2 ? 1 : fibonacci($_[0] - 2) + fibonacci($_[0] - 1);
+}
+
+# Highly recursive, highly aggressive.
+# Kids, don't try this at home.
+# For example ackermann(4,0) will take quite a long time.
+#
+# In fact, the current Perl, 5.004, will complain loudly:
+# "Deep recursion on subroutine." (see perldiag) when
+# computing the ackermann(4,0) because the recursion will
+# become so deep (>100 levels) that Perl suspects the script
+# has been lost in an infinite recursion.
+
+sub ackermann ($$) {
+    return $_[1] + 1               if ($_[0] == 0);
+    return ackermann($_[0] - 1, 1) if ($_[1] == 0);
+    ackermann($_[0] - 1, ackermann($_[0], $_[1] - 1));
+}
+
+# Highly recursive, highly boring.
+
+sub takeuchi ($$$) {
+    $_[1] < $_[0] ?
+       takeuchi(takeuchi($_[0] - 1, $_[1], $_[2]),
+                takeuchi($_[1] - 1, $_[2], $_[0]),
+                takeuchi($_[2] - 1, $_[0], $_[1]))
+           : $_[2];
+}
+
+print 'not ' unless (($d = gcd(1147, 1271)) == 31);
+print "ok 1\n";
+print "# gcd(1147, 1271) = $d\n";
+
+print 'not ' unless (($d = gcd(1908, 2016)) == 36);
+print "ok 2\n";
+print "# gcd(1908, 2016) = $d\n";
+
+print 'not ' unless (($f = factorial(10)) == 3628800);
+print "ok 3\n";
+print "# factorial(10) = $f\n";
+
+print 'not ' unless (($f = factorial(factorial(3))) == 720);
+print "ok 4\n";
+print "# factorial(factorial(3)) = $f\n";
+
+print 'not ' unless (($f = fibonacci(10)) == 89);
+print "ok 5\n";
+print "# fibonacci(10) = $f\n";
+
+print 'not ' unless (($f = fibonacci(fibonacci(7))) == 17711);
+print "ok 6\n";
+print "# fibonacci(fibonacci(7)) = $f\n";
+
+$i = 7;
+
+@ack = qw(1 2 3 4 2 3 4 5 3 5 7 9 5 13 29 61);
+
+for $x (0..3) { 
+    for $y (0..3) {
+       $a = ackermann($x, $y);
+       print 'not ' unless ($a == shift(@ack));
+       print "ok ", $i++, "\n";
+       print "# ackermann($x, $y) = $a\n";
+    }
+}
+
+($x, $y, $z) = (18, 12, 6);
+
+print 'not ' unless (($t = takeuchi($x, $y, $z)) == $z + 1);
+print "ok ", $i++, "\n";
+print "# takeuchi($x, $y, $z) = $t\n";
index 0ec3168..b018b6c 100755 (executable)
@@ -116,8 +116,9 @@ if (! -b '.') {print "ok 34\n";} else {print "not ok 34\n";}
 $cnt = $uid = 0;
 
 die "Can't run op/stat.t test 35 without pwd working" unless $cwd;
-print ("not ok 35\n"), goto tty_test unless -d '/usr/bin';
-chdir '/usr/bin' || die "Can't cd to /usr/bin";
+($bin) = grep {-d} qw(/bin /usr/bin)
+    or print ("not ok 35\n"), goto tty_test;
+chdir $bin || die "Can't cd to $bin: $!";
 while (defined($_ = <*>)) {
     $cnt++;
     $uid++ if -u;
diff --git a/util.c b/util.c
index f5c7659..d14a117 100644 (file)
--- a/util.c
+++ b/util.c
@@ -111,10 +111,11 @@ MEM_SIZE size;
 #endif /* !defined(STANDARD_C) && !defined(HAS_REALLOC_PROTOTYPE) */
 
 #ifdef HAS_64K_LIMIT 
-       if (size > 0xffff) {
-               PerlIO_printf(PerlIO_stderr(), "Reallocation too large: %lx\n", size) FLUSH;
-               my_exit(1);
-       }
+    if (size > 0xffff) {
+       PerlIO_printf(PerlIO_stderr(),
+                     "Reallocation too large: %lx\n", size) FLUSH;
+       my_exit(1);
+    }
 #endif /* HAS_64K_LIMIT */
     if (!where)
        croak("Null realloc");
@@ -174,10 +175,11 @@ MEM_SIZE size;
     Malloc_t ptr;
 
 #ifdef HAS_64K_LIMIT
-       if (size * count > 0xffff) {
-               PerlIO_printf(PerlIO_stderr(), "Allocation too large: %lx\n", size * count) FLUSH;
-               my_exit(1);
-       }
+    if (size * count > 0xffff) {
+       PerlIO_printf(PerlIO_stderr(),
+                     "Allocation too large: %lx\n", size * count) FLUSH;
+       my_exit(1);
+    }
 #endif /* HAS_64K_LIMIT */
 #ifdef DEBUGGING
     if ((long)size < 0 || (long)count < 0)
@@ -501,29 +503,33 @@ perl_new_numeric(newnum)
 #endif /* USE_LOCALE_NUMERIC */
 }
 
-#ifdef USE_LOCALE_NUMERIC
-
 void
 perl_set_numeric_standard()
 {
+#ifdef USE_LOCALE_NUMERIC
+
     if (! numeric_standard) {
        setlocale(LC_NUMERIC, "C");
        numeric_standard = TRUE;
        numeric_local = FALSE;
     }
+
+#endif /* USE_LOCALE_NUMERIC */
 }
 
 void
 perl_set_numeric_local()
 {
+#ifdef USE_LOCALE_NUMERIC
+
     if (! numeric_local) {
        setlocale(LC_NUMERIC, numeric_name);
        numeric_standard = FALSE;
        numeric_local = TRUE;
     }
-}
 
 #endif /* USE_LOCALE_NUMERIC */
+}
 
 
 /*
@@ -542,8 +548,9 @@ perl_init_i18nl10n(printwarn)
 
 #ifdef USE_LOCALE
 
+#ifdef LC_ALL
     char *lc_all     = getenv("LC_ALL");
-    char *lang       = getenv("LANG");
+#endif /* LC_ALL */
 #ifdef USE_LOCALE_CTYPE
     char *lc_ctype   = getenv("LC_CTYPE");
     char *curctype   = NULL;
@@ -556,122 +563,152 @@ perl_init_i18nl10n(printwarn)
     char *lc_numeric = getenv("LC_NUMERIC");
     char *curnum     = NULL;
 #endif /* USE_LOCALE_NUMERIC */
+    char *lang       = getenv("LANG");
     bool setlocale_failure = FALSE;
-    char *subloc;
 
 #ifdef LC_ALL
-    subloc = NULL;
+
     if (! setlocale(LC_ALL, ""))
        setlocale_failure = TRUE;
-#else
-    subloc = "";
-#endif /* LC_ALL */
+    else {
+#ifdef USE_LOCALE_CTYPE
+       curctype = setlocale(LC_CTYPE, Nullch);
+#endif /* USE_LOCALE_CTYPE */
+#ifdef USE_LOCALE_COLLATE
+       curcoll = setlocale(LC_COLLATE, Nullch);
+#endif /* USE_LOCALE_COLLATE */
+#ifdef USE_LOCALE_NUMERIC
+       curnum = setlocale(LC_NUMERIC, Nullch);
+#endif /* USE_LOCALE_NUMERIC */
+    }
+
+#else /* !LC_ALL */
 
 #ifdef USE_LOCALE_CTYPE
-    if (! (curctype = setlocale(LC_CTYPE, subloc)))
+    if (! (curctype = setlocale(LC_CTYPE, "")))
        setlocale_failure = TRUE;
 #endif /* USE_LOCALE_CTYPE */
 #ifdef USE_LOCALE_COLLATE
-    if (! (curcoll = setlocale(LC_COLLATE, subloc)))
+    if (! (curcoll = setlocale(LC_COLLATE, "")))
        setlocale_failure = TRUE;
 #endif /* USE_LOCALE_COLLATE */
 #ifdef USE_LOCALE_NUMERIC
-    if (! (curnum = setlocale(LC_NUMERIC, subloc)))
+    if (! (curnum = setlocale(LC_NUMERIC, "")))
        setlocale_failure = TRUE;
 #endif /* USE_LOCALE_NUMERIC */
 
-    if (setlocale_failure && (lc_all || lang)) {
-       char *perl_badlang;
+#endif /* LC_ALL */
+
+    if (setlocale_failure) {
+       char *p;
+       bool locwarn = (printwarn > 1 || 
+                       printwarn &&
+                       (!(p = getenv("PERL_BADLANG")) || atoi(p)));
 
-       if (printwarn > 1 || 
-           printwarn &&
-           (!(perl_badlang = getenv("PERL_BADLANG")) || atoi(perl_badlang))) {
-         
+       if (locwarn) {
+#ifdef LC_ALL
+  
+           PerlIO_printf(PerlIO_stderr(),
+              "perl: warning: Setting locale failed.\n");
+
+#else /* !LC_ALL */
+  
            PerlIO_printf(PerlIO_stderr(),
               "perl: warning: Setting locale failed for the categories:\n\t");
 #ifdef USE_LOCALE_CTYPE
            if (! curctype)
-               PerlIO_printf(PerlIO_stderr(), "USE_LOCALE_CTYPE ");
+               PerlIO_printf(PerlIO_stderr(), "LC_CTYPE ");
 #endif /* USE_LOCALE_CTYPE */
 #ifdef USE_LOCALE_COLLATE
            if (! curcoll)
-               PerlIO_printf(PerlIO_stderr(), "USE_LOCALE_COLLATE ");
+               PerlIO_printf(PerlIO_stderr(), "LC_COLLATE ");
 #endif /* USE_LOCALE_COLLATE */
 #ifdef USE_LOCALE_NUMERIC
            if (! curnum)
-               PerlIO_printf(PerlIO_stderr(), "USE_LOCALE_NUMERIC ");
+               PerlIO_printf(PerlIO_stderr(), "LC_NUMERIC ");
 #endif /* USE_LOCALE_NUMERIC */
            PerlIO_printf(PerlIO_stderr(), "\n");
 
+#endif /* LC_ALL */
+
            PerlIO_printf(PerlIO_stderr(),
                "perl: warning: Please check that your locale settings:\n");
 
+#ifdef LC_ALL
            PerlIO_printf(PerlIO_stderr(),
                          "\tLC_ALL = %c%s%c,\n",
                          lc_all ? '"' : '(',
                          lc_all ? lc_all : "unset",
                          lc_all ? '"' : ')');
-#ifdef USE_LOCALE_CTYPE
-           if (! curctype)
-               PerlIO_printf(PerlIO_stderr(),
-                             "\tLC_CTYPE = %c%s%c,\n",
-                             lc_ctype ? '"' : '(',
-                             lc_ctype ? lc_ctype : "unset",
-                             lc_ctype ? '"' : ')');
-#endif /* USE_LOCALE_CTYPE */
-#ifdef USE_LOCALE_COLLATE
-           if (! curcoll)
-               PerlIO_printf(PerlIO_stderr(),
-                             "\tLC_COLLATE = %c%s%c,\n",
-                             lc_collate ? '"' : '(',
-                             lc_collate ? lc_collate : "unset",
-                             lc_collate ? '"' : ')');
-#endif /* USE_LOCALE_COLLATE */
-#ifdef USE_LOCALE_NUMERIC
-           if (! curnum)
-               PerlIO_printf(PerlIO_stderr(),
-                             "\tLC_NUMERIC = %c%s%c,\n",
-                             lc_numeric ? '"' : '(',
-                             lc_numeric ? lc_numeric : "unset",
-                             lc_numeric ? '"' : ')');
-#endif /* USE_LOCALE_NUMERIC */
+#endif /* LC_ALL */
+
+           {
+             char **e;
+             for (e = environ; *e; e++) {
+                 if (strnEQ(*e, "LC_", 3)
+                       && strnNE(*e, "LC_ALL=", 7)
+                       && (p = strchr(*e, '=')))
+                     PerlIO_printf(PerlIO_stderr(), "\t%.*s = \"%s\",\n",
+                                   (p - *e), *e, p + 1);
+             }
+           }
+
            PerlIO_printf(PerlIO_stderr(),
                          "\tLANG = %c%s%c\n",
-                         lang ? '"' : ')',
+                         lang ? '"' : '(',
                          lang ? lang : "unset",
                          lang ? '"' : ')');
 
            PerlIO_printf(PerlIO_stderr(),
                          "    are supported and installed on your system.\n");
+       }
 
+#ifdef LC_ALL
+
+       if (setlocale(LC_ALL, "C")) {
+           if (locwarn)
+               PerlIO_printf(PerlIO_stderr(),
+      "perl: warning: Falling back to the standard locale (\"C\").\n");
            ok = 0;
        }
+       else {
+           if (locwarn)
+               PerlIO_printf(PerlIO_stderr(),
+      "perl: warning: Failed to fall back to the standard locale (\"C\").\n");
+           ok = -1;
+       }
 
-#ifdef LC_ALL
-       if (setlocale_failure) {
-           PerlIO_printf(PerlIO_stderr(),
-                       "perl: warning: Falling back to the \"C\" locale.\n");
-           if (setlocale(LC_ALL, "C")) {
+#else /* ! LC_ALL */
+
+       if (0
 #ifdef USE_LOCALE_CTYPE
-               curctype = "C";
+           || !(curctype || setlocale(LC_CTYPE, "C"))
 #endif /* USE_LOCALE_CTYPE */
 #ifdef USE_LOCALE_COLLATE
-               curcoll = "C";
+           || !(curcoll || setlocale(LC_COLLATE, "C"))
 #endif /* USE_LOCALE_COLLATE */
 #ifdef USE_LOCALE_NUMERIC
-               curnum = "C";
+           || !(curnum || setlocale(LC_NUMERIC, "C"))
 #endif /* USE_LOCALE_NUMERIC */
-           }
-           else {
+           )
+       {
+           if (locwarn)
                PerlIO_printf(PerlIO_stderr(),
-                 "perl: warning: Failed to fall back to the \"C\" locale.\n");
-               ok = -1;
-           }
+      "perl: warning: Cannot fall back to the standard locale (\"C\").\n");
+           ok = -1;
        }
-#else /* ! LC_ALL */
-       PerlIO_printf(PerlIO_stderr(),
-                  "perl: warning: Cannot fall back to the \"C\" locale.\n");
+
 #endif /* ! LC_ALL */
+
+#ifdef USE_LOCALE_CTYPE
+       curctype = setlocale(LC_CTYPE, Nullch);
+#endif /* USE_LOCALE_CTYPE */
+#ifdef USE_LOCALE_COLLATE
+       curcoll = setlocale(LC_COLLATE, Nullch);
+#endif /* USE_LOCALE_COLLATE */
+#ifdef USE_LOCALE_NUMERIC
+       curnum = setlocale(LC_NUMERIC, Nullch);
+#endif /* USE_LOCALE_NUMERIC */
     }
 
 #ifdef USE_LOCALE_CTYPE
@@ -696,7 +733,7 @@ int
 perl_init_i18nl14n(printwarn)  
     int printwarn;
 {
-    perl_init_i18nl10n(printwarn);
+    return perl_init_i18nl10n(printwarn);
 }
 
 #ifdef USE_LOCALE_COLLATE
@@ -1034,7 +1071,7 @@ mess(pat, args)
     }
     va_end(*args);
 
-    if (s[-1] != '\n') {
+    if (!(s > s_start && s[-1] == '\n')) {
        if (dirty)
            strcpy(s, " during global destruction.\n");
        else {
@@ -1551,8 +1588,8 @@ VTOH(vtohs,short)
 VTOH(vtohl,long)
 #endif
 
-#if  (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) \
-     && !defined(VMS)  /* VMS' my_popen() is in VMS.c, same with OS/2. */
+    /* VMS' my_popen() is in VMS.c, same with OS/2. */
+#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS)
 PerlIO *
 my_popen(cmd,mode)
 char   *cmd;
@@ -1809,9 +1846,8 @@ Sigsave_t *save;
 
 #endif /* !HAS_SIGACTION */
 
-
-#if  (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) \
-     && !defined(VMS)  /* VMS' my_popen() is in VMS.c */
+    /* VMS' my_pclose() is in VMS.c; same with OS/2 */
+#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS)
 I32
 my_pclose(ptr)
 PerlIO *ptr;
index 33947c8..958dc03 100644 (file)
@@ -4,16 +4,16 @@ PERL = ../miniperl
 # Files to be built with variable substitution after miniperl is
 # available.  Dependencies handled manually below (for now).
 
-pl = c2ph.PL h2ph.PL h2xs.PL perlbug.PL perldoc.PL
-
-pl = c2ph.PL h2ph.PL h2xs.PL perlbug.PL perldoc.PL pl2pm.PL
-plextract  = c2ph h2ph h2xs perlbug perldoc pl2pm
+pl = c2ph.PL h2ph.PL h2xs.PL perlbug.PL perldoc.PL pl2pm.PL splain.PL
+plextract  = c2ph h2ph h2xs perlbug perldoc pl2pm splain
 
 all: $(plextract)
 
 $(plextract):
        $(PERL) -I../lib $@.PL
 
+splain: ../lib/diagnostics.pm
+
 clean:
 
 realclean:
index 97d17af..5f4523a 100644 (file)
@@ -25,9 +25,9 @@ print "Extracting $file (with variable substitutions)\n";
 # You can use $Config{...} to use Configure variables.
 
 print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
-    eval 'exec perl -S \$0 "\$@"'
-       if 0;
+$Config{startperl}
+    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
 !GROK!THIS!
 
 # In the following, perl variables are not expanded during extraction.
index 22161b9..1b2ce31 100644 (file)
@@ -26,10 +26,9 @@ print "Extracting $file (with variable substitutions)\n";
 # You can use $Config{...} to use Configure variables.
 
 print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
-    eval 'exec perl -S \$0 "\$@"'
-       if 0;
-
+$Config{startperl}
+    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
 !GROK!THIS!
 
 # In the following, perl variables are not expanded during extraction.
@@ -55,6 +54,10 @@ $inif = 0;
 @ARGV = ('-') unless @ARGV;
 
 foreach $file (@ARGV) {
+    # Recover from header files with unbalanced cpp directives
+    $t = '';
+    $tab = 0;
+
     if ($file eq '-') {
        open(IN, "-");
        open(OUT, ">-");
@@ -103,7 +106,7 @@ foreach $file (@ARGV) {
                        $args = "local($args) = \@_;\n$t    ";
                    }
                    s/^\s+//;
-                   do expr();
+                   expr();
                    $new =~ s/(["\\])/\\$1/g;
                    if ($t ne '') {
                        $new =~ s/(['\\])/\\$1/g;
@@ -117,7 +120,7 @@ foreach $file (@ARGV) {
                }
                else {
                    s/^\s+//;
-                   do expr();
+                   expr();
                    $new = 1 if $new eq '';
                    if ($t ne '') {
                        $new =~ s/(['\\])/\\$1/g;
@@ -145,7 +148,7 @@ foreach $file (@ARGV) {
            elsif (s/^if\s+//) {
                $new = '';
                $inif = 1;
-               do expr();
+               expr();
                $inif = 0;
                print OUT $t,"if ($new) {\n";
                $tab += 4;
@@ -154,7 +157,7 @@ foreach $file (@ARGV) {
            elsif (s/^elif\s+//) {
                $new = '';
                $inif = 1;
-               do expr();
+               expr();
                $inif = 0;
                $tab -= 4;
                $t = "\t" x ($tab / 8) . ' ' x ($tab % 8);
@@ -194,10 +197,31 @@ sub expr {
            }
            next;
        };
-       s/^sizeof\s*\(([^)]+)\)/{$1}/ && do {
-           $new .= '$sizeof';
-           next;
-       };
+        # replace "sizeof(foo)" with "{foo}"
+        # also, remove * (C dereference operator) to avoid perl syntax
+        # problems.  Where the %sizeof array comes from is anyone's
+        # guess (c2ph?), but this at least avoids fatal syntax errors.
+        # Behavior is undefined if sizeof() delimiters are unbalanced.
+        # This code was modified to able to handle constructs like this:
+        #   sizeof(*(p)), which appear in the HP-UX 10.01 header files.
+        s/^sizeof\s*\(// && do {
+            $new .= '$sizeof';
+            my $lvl = 1;  # already saw one open paren
+            # tack { on the front, and skip it in the loop
+            $_ = "{" . "$_";
+            my $index = 1;
+            # find balanced closing paren
+            while ($index <= length($_) && $lvl > 0) {
+                $lvl++ if substr($_, $index, 1) eq "(";
+                $lvl-- if substr($_, $index, 1) eq ")";
+                $index++;
+            }
+            # tack } on the end, replacing )
+            substr($_, $index - 1, 1) = "}";
+            # remove pesky * operators within the sizeof argument
+            substr($_, 0, $index - 1) =~ s/\*//g;
+            next;
+        };
        s/^([_a-zA-Z]\w*)//     && do {
            $id = $1;
            if ($id eq 'struct') {
index 7e54d49..73df801 100644 (file)
@@ -25,9 +25,9 @@ print "Extracting $file (with variable substitutions)\n";
 # You can use $Config{...} to use Configure variables.
 
 print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
-    eval 'exec perl -S \$0 "\$@"'
-       if 0;
+$Config{startperl}
+    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
 !GROK!THIS!
 
 # In the following, perl variables are not expanded during extraction.
index f136372..7f894d8 100644 (file)
@@ -25,9 +25,9 @@ print "Extracting $file (with variable substitutions)\n";
 # You can use $Config{...} to use Configure variables.
 
 print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
-    eval 'exec perl -S \$0 "\$@"'
-       if 0;
+$Config{startperl}
+    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
 !GROK!THIS!
 
 # In the following, perl variables are not expanded during extraction.
index 8c5e0c9..e0f8a43 100644 (file)
@@ -25,9 +25,9 @@ print "Extracting $file (with variable substitutions)\n";
 # You can use $Config{...} to use Configure variables.
 
 print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
-    eval 'exec perl -S \$0 "\$@"'
-       if 0;
+$Config{startperl}
+    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
 
 \@pagers = ();
 push \@pagers, "$Config{'pager'}" if -x "$Config{'pager'}";
index 60e66f8..8d47481 100644 (file)
@@ -25,9 +25,9 @@ print "Extracting $file (with variable substitutions)\n";
 # You can use $Config{...} to use Configure variables.
 
 print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
-    eval 'exec perl -S \$0 "\$@"'
-       if 0;
+$Config{startperl}
+    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
 !GROK!THIS!
 
 # In the following, perl variables are not expanded during extraction.
diff --git a/utils/splain.PL b/utils/splain.PL
new file mode 100644 (file)
index 0000000..53954db
--- /dev/null
@@ -0,0 +1,47 @@
+#!/usr/local/bin/perl
+
+use Config;
+use File::Basename qw(&basename &dirname);
+
+# List explicitly here the variables you want Configure to
+# generate.  Metaconfig only looks for shell variables, so you
+# have to mention them as if they were shell variables, not
+# %Config entries:
+#  $startperl
+#  $perlpath
+#  $eunicefix
+
+# This forces PL files to create target in same directory as PL file.
+# This is so that make depend always knows where to find PL derivatives.
+chdir(dirname($0));
+($file = basename($0)) =~ s/\.PL$//;
+$file =~ s/\.pl$//
+       if ($^O eq 'VMS' or $^O eq 'os2');  # "case-forgiving"
+
+# Open input file before creating output file.
+$IN = '../lib/diagnostics.pm';
+open IN or die "Can't open $IN: $!\n";
+
+# Create output file.
+open OUT,">$file" or die "Can't create $file: $!";
+
+print "Extracting $file (with variable substitutions)\n";
+
+# In this section, perl variables will be expanded during extraction.
+# You can use $Config{...} to use Configure variables.
+
+print OUT <<"!GROK!THIS!";
+$Config{startperl}
+    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
+!GROK!THIS!
+
+while (<IN>) {
+    print OUT unless /^package diagnostics/;
+}
+
+close IN;
+
+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 ':';
index 7b9d2b5..3622ad9 100644 (file)
@@ -1,4 +1,4 @@
-#> This file produced from Descrip.MMS by mms2make.pl
+#> This file produced from descrip.mms by mms2make.pl
 #> Lines beginning with "#>" were commented out during the
 #> conversion process.  For more information, see mms2make.pl
 #>
 #### Start of system configuration section. ####
 
 
+#> .ifdef AXE
 # File type to use for object files
+#> O = .abj
 # File type to use for object libraries
+#> OLB = .alb
 # File type to use for executable images
+#> E = .axe
+#> .else
 # File type to use for object files
 O = .obj
 # File type to use for object libraries
 OLB = .olb
 # File type to use for executable images
 E = .exe
+#> .endif
 
+#> .ifdef __AXP__
+#> DECC = 1
+#> ARCH = VMS_AXP
+#> OBJVAL = $(O)
+#> .else
 ARCH = VMS_VAX
 OBJVAL = $@
+#> .endif
 
 # Updated by fndvers.com -- do not edit by hand
-PERL_VERSION = 5_00307#
+PERL_VERSION = 5_00311#
 
 
 ARCHDIR =  [.lib.$(ARCH).$(PERL_VERSION)]
@@ -40,19 +52,51 @@ ARCHCORE = [.lib.$(ARCH).$(PERL_VERSION).CORE]
 ARCHAUTO = [.lib.$(ARCH).$(PERL_VERSION).auto]
 
 
+#> .ifdef DECC_PIPES_BROKEN
+#> PIPES_BROKEN = 1
+#> .endif
 
 
+#> .ifdef GNUC
+#> .first:
+#>     @ $$@[.vms]fndvers.com "" "" "[.vms]Makefile"
+#>     @ If f$$TrnLnm("Sys").eqs."" Then Define/NoLog SYS GNU_CC_Include:[VMS]
+#> CC = gcc
 # -fno-builtin avoids bug in gcc up to version 2.6.2 which can destroy
 # data when memcpy() is called on large (>64 kB) blocks of memory
 # (fixed in gcc 2.6.3)
+#> XTRACCFLAGS = /Obj=$@/NoCase_Hack/Optimize=2/CC1="""""-fno-builtin"""""
+#> DBGSPECFLAGS =
+#> XTRADEF = ,GNUC_ATTRIBUTE_CHECK
+#> XTRAOBJS =
+#> LIBS1 = GNU_CC:[000000]GCCLIB.OLB/Library
+#> LIBS2 = sys$$Share:VAXCRTL/Shareable
+#> POSIX =
+#> .else
 XTRAOBJS = 
 LIBS1 = $(XTRAOBJS)
 DBGSPECFLAGS = /Show=(Source,Include,Expansion)
+#> .ifdef decc
 # Some versions of DECCRTL on AXP have a bug in chdir() which causes the change
 # to persist after the image exits, even when this was not requested, iff
 # SYSNAM is enabled.  This is fixed in CSC Patch # AXPACRT04_061, but turning
 # off SYSNAM for the MM[SK] subprocess doesn't hurt anything, so we do it
 # just in case.
+#> .first:
+#>     @ Set Process/Privilege=(NoSYSNAM)
+#>     @ $$@[.vms]fndvers.com "" "" "[.vms]Makefile"
+#>     @ If f$$TrnLnm("Sys").eqs."" .and. f$$TrnLnm("DECC$System_Include").nes."" Then Define/NoLog SYS DECC$System_Include
+#> .ifdef __AXP__
+#>     @ If f$$TrnLnm("Sys").eqs."" .and. f$$TrnLnm("DECC$System_Include").eqs."" Then Define/NoLog SYS sys$$Library
+#> .else
+#>     @ If f$$TrnLnm("Sys").eqs."" .and. f$$TrnLnm("DECC$System_Include").eqs."" Then Define/NoLog SYS DECC$Library_Include
+#> .endif
+#> 
+#> LIBS2 = 
+#> XTRACCFLAGS = /Include=[]/Standard=Relaxed_ANSI/Prefix=All/Obj=$(OBJVAL)
+#> XTRADEF =
+#> POSIX = POSIX
+#> .else # VAXC
 .first:
        @ $$@[.vms]fndvers.com "" "" "[.vms]Makefile"
        @ If f$$TrnLnm("Sys").eqs."" .and. f$$TrnLnm("VAXC$Include").eqs."" Then Define/NoLog SYS sys$$Library
@@ -61,15 +105,34 @@ DBGSPECFLAGS = /Show=(Source,Include,Expansion)
 XTRACCFLAGS = /Include=[]/Object=$(O)
 XTRADEF =
 LIBS2 = sys$$Share:VAXCRTL/Shareable
+POSIX =
+#> .endif
+#> .endif
 
 
+#> .ifdef __DEBUG__
+#> DBGCCFLAGS = /List/Debug/NoOpt$(DBGSPECFLAGS)
+#> DBGLINKFLAGS = /Trace/Debug/Map/Full/Cross
+#> DBG = DBG
+#> .else
 DBGCCFLAGS = /NoList
 DBGLINKFLAGS = /NoMap
 DBG = 
+#> .endif
 
+#> .ifdef SOCKET
+#> SOCKDEF = ,VMS_DO_SOCKETS
+#> SOCKLIB = SocketShr/Share
 # N.B. the targets for $(SOCKC) and $(SOCKH) assume that the permanent
 # copies live in [.vms], and the `clean' target will delete copies of
 # these files in the current default directory.
+#> SOCKC = sockadapt.c
+#> SOCKH = sockadapt.h
+#> SOCKCLIS = ,$(SOCKC)
+#> SOCKHLIS = ,$(SOCKH)
+#> SOCKOBJ = ,sockadapt$(O)
+#> SOCKPM = [.lib]Socket.pm
+#> .else
 SOCKDEF =
 SOCKLIB =
 SOCKC =
@@ -78,6 +141,7 @@ SOCKCLIS =
 SOCKHLIS =
 SOCKOBJ =
 SOCKPM =
+#> .endif
 
 # C preprocessor manifest "DEBUGGING" ==> perl -D, not the VMS debugger
 CFLAGS = /Define=(DEBUGGING$(SOCKDEF)$(XTRADEF))$(XTRACCFLAGS)$(DBGCCFLAGS)
@@ -104,8 +168,13 @@ MYEXT = DynaLoader
 # there are any object files specified
 # These must be built separately, or you must add rules below to build them
 myextobj = [.ext.dynaloader]dl_vms$(O),
+#> .ifdef SOCKET
+#> EXT = $(MYEXT) Socket
+#> extobj = $(myextobj) [.ext.socket]socket$(O), 
+#> .else
 EXT = $(MYEXT)
 extobj = $(myextobj)
+#> .endif
 
 
 #### End of system configuration section. ####
@@ -138,13 +207,19 @@ ac6 = $(ARCHCORE)pp.h $(ARCHCORE)proto.h $(ARCHCORE)regcomp.h $(ARCHCORE)perlio.
 ac7 = $(ARCHCORE)regexp.h $(ARCHCORE)scope.h $(ARCHCORE)sv.h $(ARCHCORE)util.h
 ac8 = $(ARCHCORE)vmsish.h $(ARCHCORE)$(DBG)libperl$(OLB) $(ARCHCORE)perlshr_attr.opt
 ac9 = $(ARCHCORE)$(DBG)perlshr_bld.opt
+#> .ifdef SOCKET
+#> acs = $(ARCHCORE)$(SOCKH)
+#> .else
 acs =
+#> .endif
 
 CRTL = []crtl.opt
 CRTLOPTS =,$(CRTL)/Options
 
 .suffixes:
 
+#> .ifdef LINK_ONLY
+#> .else
 .suffixes: $(O) .c .xs
 
 .xs.c :
@@ -157,13 +232,14 @@ CRTLOPTS =,$(CRTL)/Options
 .xs$(O) :
        $(XSUBPP) $< >$(MMS$SOURCE_NAME).c
        $(CC) $(CFLAGS) $(MMS$SOURCE_NAME).c
+#> .endif
 
 
 all : base extras libmods utils podxform archcorefiles preplibrary perlpods
        @ $(NOOP)
 base : miniperl perl
        @ $(NOOP)
-extras : Fcntl FileHandle IO Opcode libmods utils podxform
+extras : Fcntl IO Opcode $(POSIX) libmods utils podxform
        @ $(NOOP)
 libmods : [.lib]Config.pm $(ARCHDIR)Config.pm [.lib]DynaLoader.pm [.lib.VMS]Filespec.pm 
        @ $(NOOP)
@@ -208,7 +284,11 @@ perl : $(DBG)perl$(E)
        @ Continue
 $(DBG)perl$(E) : perlmain$(O), $(DBG)perlshr$(E), $(MINIPERL_EXE)
        @ $$@[.vms]genopt "PerlShr.Opt/Write" "|" "''f$$Environment("Default")'$(DBG)PerlShr$(E)/Share"
+#> .ifdef gnuc
+#>     Link $(LINKFLAGS)/Exe=$@ perlmain$(O), perlshr.opt/Option, perlshr_attr.opt/Option, crtl.opt/Option
+#> .else
        Link $(LINKFLAGS)/Exe=$@ perlmain$(O), perlshr.opt/Option, perlshr_attr.opt/Option
+#> .endif
 
 $(DBG)perlshr$(E) : $(DBG)libperl$(OLB) $(extobj) $(DBG)perlshr_xtras.ts
        Link /NoTrace$(LINKFLAGS)/Share=$@ $(extobj) []$(DBG)perlshr_bld.opt/Option, perlshr_attr.opt/Option
@@ -218,8 +298,18 @@ $(DBG)perlshr$(E) : $(DBG)libperl$(OLB) $(extobj) $(DBG)perlshr_xtras.ts
 #  perlshr_gbl*.mar, perlshr_gbl*$(O) - VAX only
 # The song and dance with gen_shrfls.opt accomodates DCL's 255 character
 # line length limit.
+#> .ifdef PIPES_BROKEN
 # This is a backup target used only with older versions of the DECCRTL which
 # can't deal with pipes properly.  See ReadMe.VMS for details.
+#> $(DBG)perlshr_xtras.ts : perl.h config.h vmsish.h proto.h [.vms]gen_shrfls.pl $(MINIPERL_EXE) $(MAKEFILE) $(CRTL)
+#>     $(CC) $(CFLAGS)/NoObject/NoList/PreProcess=perl.i perl.h
+#>     @ $(MINIPERL) -e "print join('|',@ARGV),'|';" "~~NOCC~~perl.i~~$(CC)$(CFLAGS)" >gen_shrfls.opt
+#>     @ $(MINIPERL) -e "print join('|',@ARGV);" "$(O)" "$(DBG)" "$(OLB)" "$(EXT)" "$(CRTL)" >>gen_shrfls.opt
+#>     $(MINIPERL) [.vms]gen_shrfls.pl -f gen_shrfls.opt
+#>     @ Delete/NoLog/NoConfirm perl.i;, gen_shrfls.opt;
+#>     @ If f$$Search("$(DBG)perlshr_xtras.ts").nes."" Then Delete/NoLog/NoConfirm $(DBG)perlshr_xtras.ts;*
+#>     @ Copy _NLA0: $(DBG)perlshr_xtras.ts
+#> .else
 $(DBG)perlshr_xtras.ts : perl.h config.h vmsish.h proto.h [.vms]gen_shrfls.pl $(MINIPERL_EXE) $(MAKEFILE) $(CRTL)
        @ $(MINIPERL) -e "print join('|',@ARGV),'|';" "$(CC)$(CFLAGS)" >gen_shrfls.opt
        @ $(MINIPERL) -e "print join('|',@ARGV);" "$(O)" "$(DBG)" "$(OLB)" "$(EXT)" "$(CRTL)" >>gen_shrfls.opt
@@ -227,6 +317,7 @@ $(DBG)perlshr_xtras.ts : perl.h config.h vmsish.h proto.h [.vms]gen_shrfls.pl $(
        @ Delete/NoLog/NoConfirm gen_shrfls.opt;
        @ If f$$Search("$(DBG)perlshr_xtras.ts").nes."" Then Delete/NoLog/NoConfirm $(DBG)perlshr_xtras.ts;*
        @ Copy _NLA0: $(DBG)perlshr_xtras.ts
+#> .endif
 
 $(ARCHDIR)config.pm : [.lib]config.pm
        Create/Directory $(ARCHDIR)
@@ -282,43 +373,43 @@ Opcode : [.lib]Opcode.pm [.lib]ops.pm [.lib]Safe.pm [.lib.auto.Opcode]Opcode$(E)
 [.ext.Opcode]Makefile : [.ext.Opcode]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E)
        $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Opcode]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]"
 
-FileHandle : [.lib]FileHandle.pm [.lib.auto.FileHandle]FileHandle$(E)
+Fcntl : [.lib]Fcntl.pm [.lib.auto.Fcntl]Fcntl$(E)
        @ $(NOOP)
 
-[.lib]FileHandle.pm : [.ext.FileHandle]Makefile
+[.lib]Fcntl.pm : [.ext.Fcntl]Makefile
        @ If f$$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto]
-       @ Set Default [.ext.FileHandle]
+       @ Set Default [.ext.Fcntl]
        $(MMS)
        @ Set Default [--]
 
-[.lib.auto.FileHandle]FileHandle$(E) : [.ext.FileHandle]Makefile
-       @ Set Default [.ext.FileHandle]
+[.lib.auto.Fcntl]Fcntl$(E) : [.ext.Fcntl]Makefile
+       @ Set Default [.ext.Fcntl]
        $(MMS)
        @ Set Default [--]
 
 # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C<chdir>
 # ${@} necessary to distract different versions of MM[SK]/make
-[.ext.FileHandle]Makefile : [.ext.FileHandle]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E)
-       $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.FileHandle]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]"
+[.ext.Fcntl]Makefile : [.ext.Fcntl]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E)
+       $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Fcntl]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]"
 
-Fcntl : [.lib]Fcntl.pm [.lib.auto.Fcntl]Fcntl$(E)
+POSIX : [.lib]POSIX.pm [.lib.auto.POSIX]POSIX$(E)
        @ $(NOOP)
 
-[.lib]Fcntl.pm : [.ext.Fcntl]Makefile
+[.lib]POSIX.pm : [.ext.POSIX]Makefile
        @ If f$$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto]
-       @ Set Default [.ext.Fcntl]
+       @ Set Default [.ext.POSIX]
        $(MMS)
        @ Set Default [--]
 
-[.lib.auto.Fcntl]Fcntl$(E) : [.ext.Fcntl]Makefile
-       @ Set Default [.ext.Fcntl]
+[.lib.auto.POSIX]POSIX$(E) : [.ext.POSIX]Makefile
+       @ Set Default [.ext.POSIX]
        $(MMS)
        @ Set Default [--]
 
 # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C<chdir>
 # ${@} necessary to distract different versions of MM[SK]/make
-[.ext.Fcntl]Makefile : [.ext.Fcntl]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E)
-       $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Fcntl]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]"
+[.ext.POSIX]Makefile : [.ext.POSIX]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E)
+       $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.POSIX]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]"
 
 IO : [.lib]IO.pm [.lib.IO]File.pm [.lib.IO]Handle.pm [.lib.IO]Pipe.pm [.lib.IO]Seekable.pm [.lib.IO]Socket.pm [.lib.auto.IO]IO$(E)
        @ $(NOOP)
@@ -558,6 +649,30 @@ printconfig :
        @ $$@[.vms]make_command $(MMS) $(MMSQUALIFIERS) $(MMSTARGETS)
        @ $$@[.vms]myconfig "$(CC)" "$(CFLAGS)" "$(LINKFLAGS)" "$(LIBS1)" "$(LIBS2)" "$(SOCKLIB)" "$(EXT)" "$(DBG)"
 
+#> .ifdef SOCKET
+#> 
+#> .ifdef LINK_ONLY
+#> .else
+#> $(SOCKOBJ) : $(SOCKC) $(SOCKH)
+#> 
+#> [.ext.Socket]Socket$(O) : [.ext.Socket]Socket.c
+#>     $(CC) $(CFLAGS) /Object=$@ [.ext.Socket]Socket.c
+#> 
+#> [.ext.Socket]Socket.c : [.ext.Socket]Socket.xs $(MINIPERL_EXE)
+#>     $(XSUBPP) [.ext.Socket]Socket.xs >$@
+#> .endif # !LINK_ONLY
+#> 
+#> vmsish.h : $(SOCKH)
+#> 
+#> $(SOCKC) : [.vms]$(SOCKC)
+#>     Copy/Log/NoConfirm [.vms]$(SOCKC) []$(SOCKC)
+#> 
+#> $(SOCKH) : [.vms]$(SOCKH)
+#>     Copy/Log/NoConfirm [.vms]$(SOCKH) []$(SOCKH)
+#> 
+#> [.lib]Socket.pm : [.ext.Socket]Socket.pm
+#>     Copy/Log/NoConfirm [.ext.Socket]Socket.pm $@
+#> .endif
 
 # The following three header files are generated automatically
 #      keywords.h :    keywords.pl
@@ -589,8 +704,11 @@ perly.h : [.vms]perly_h.vms
 #      rename y.tab.h perly.h
 #      $(INSTPERL) [.vms]vms_yfix.pl perly.c perly.h [.vms]perly_c.vms [.vms]perly_h.vms
 
+#> .ifdef LINK_ONLY
+#> .else
 perly$(O) : perly.c, perly.h, $(h)
        $(CC) $(CFLAGS) perly.c
+#> .endif
 
 test : all
        - @[.VMS]Test.Com "$(E)"
@@ -684,6 +802,11 @@ $(ARCHCORE)util.h : util.h
 $(ARCHCORE)vmsish.h : vmsish.h
        @ If f$$Search("$(ARCHDIR)CORE.dir").eqs."" Then Create/Directory $(ARCHCORE)
        Copy/Log vmsish.h $@
+#> .ifdef SOCKET
+#> $(ARCHCORE)$(SOCKH) : $(SOCKH)
+#>     @ If f$$Search("$(ARCHDIR)CORE.dir").eqs."" Then Create/Directory $(ARCHCORE)
+#>     Copy/Log $(SOCKH) $@
+#> .endif
 $(ARCHCORE)$(DBG)libperl$(OLB) : $(DBG)libperl$(OLB) $(DBG)perlshr_xtras.ts
        @ If f$$Search("$(ARCHDIR)CORE.dir").eqs."" Then Create/Directory $(ARCHCORE)
        Copy/Log $(DBG)libperl$(OLB) $@
@@ -697,6 +820,8 @@ $(ARCHAUTO)time.stamp :
        @ If f$$Search("$(ARCHDIR)auto.dir").eqs."" Then Create/Directory $(ARCHAUTO)
        @ If f$$Search("$@").eqs."" Then Copy/NoConfirm _NLA0: $(MMS$TARGET)
 
+#> .ifdef LINK_ONLY
+#> .else
 # AUTOMATICALLY GENERATED MAKE DEPENDENCIES--PUT NOTHING BELOW THIS LINE
 av$(O) : EXTERN.h
 av$(O) : av.c
@@ -1369,6 +1494,7 @@ globals$(O) : scope.h
 globals$(O) : sv.h
 globals$(O) : vmsish.h
 globals$(O) : util.h
+#> .endif # !LINK_ONLY
 
 config.h : [.vms]config.vms
        Copy/Log/NoConfirm [.vms]config.vms []config.h
@@ -1389,9 +1515,9 @@ cleanlis :
        - If f$$Search("*.Map").nes."" Then Delete/NoConfirm/Log *.Map;*
 
 tidy : cleanlis
-       - If f$$Search("*.Opt;-1").nes."" Then Purge/NoConfirm/Log *.Opt
-       - If f$$Search("*$(O);-1").nes."" Then Purge/NoConfirm/Log *$(O)
-       - If f$$Search("*$(E);-1").nes."" Then Purge/NoConfirm/Log *$(E)
+       - If f$$Search("[...]*.Opt;-1").nes."" Then Purge/NoConfirm/Log [...]*.Opt
+       - If f$$Search("[...]*$(O);-1").nes."" Then Purge/NoConfirm/Log [...]*$(O)
+       - If f$$Search("[...]*$(E);-1").nes."" Then Purge/NoConfirm/Log [...]*$(E)
        - If f$$Search("Config.H;-1").nes."" Then Purge/NoConfirm/Log Config.H
        - If f$$Search("Config.SH;-1").nes."" Then Purge/NoConfirm/Log Config.SH
        - If f$$Search("perly.c;-1").nes."" Then Purge/NoConfirm/Log perly.c
@@ -1415,7 +1541,8 @@ tidy : cleanlis
        - If f$$Search("[.Lib.VMS]*.*;-1").nes."" Then Purge/NoConfirm/Log [.Lib.VMS]*.*
        - If f$$Search("[.Lib.Pod]*.Pod;-1").nes."" Then Purge/NoConfirm/Log [.Lib.Pod]*.Pod
        - If f$$Search("$(ARCHCORE)*.*").nes."" Then Purge/NoConfirm/Log $(ARCHCORE)*.*
-       - If f$$Search("[.utils]*.;-1").nes."" Then Purge/NoConfirm/Log [.utils]*.
+       - If f$$Search("[.utils]*.;-1").nes."" Then Purge/NoConfirm/Log [.utils]*./Exclude=Makefile.
+       - If f$$Search("[.lib]perlbug.;-1").nes."" Then Purge/NoConfirm/Log [.lib]perlbug.
        - If f$$Search("[.lib.pod]*.;-1").nes."" Then Purge/NoConfirm/Log [.lib.pod]*.
 
 clean : tidy
@@ -1431,6 +1558,11 @@ clean : tidy
        Set Default [.ext.Opcode]
        - $(MMS) clean
        Set Default [--]
+#> .ifdef DECC
+#>     Set Default [.ext.POSIX]
+#>     - $(MMS) clean
+#>     Set Default [--]
+#> .endif
        - If f$$Search("*.Opt").nes."" Then Delete/NoConfirm/Log *.Opt;*/Exclude=PerlShr_*.Opt
        - If f$$Search("*$(O);*") .nes."" Then Delete/NoConfirm/Log *$(O);*
        - If f$$Search("Config.H").nes."" Then Delete/NoConfirm/Log Config.H;*
@@ -1464,6 +1596,11 @@ realclean : clean
        Set Default [.ext.Opcode]
        - $(MMS) realclean
        Set Default [--]
+#> .ifdef DECC
+#>     Set Default [.ext.POSIX]
+#>     - $(MMS) realclean
+#>     Set Default [--]
+#> .endif
        - If f$$Search("*$(OLB)").nes."" Then Delete/NoConfirm/Log *$(OLB);*
        - If f$$Search("*.Opt").nes."" Then Delete/NoConfirm/Log *.Opt;*
        - $(MINIPERL) -e "use File::Path; rmtree(['lib/auto','lib/VMS','lib/$(ARCH)'],1,0);"
@@ -1473,7 +1610,7 @@ realclean : clean
        - If f$$Search("[.Lib]perlbug.").nes."" Then Delete/NoConfirm/Log [.Lib]perlbug.;*
        - If f$$Search("$(ARCHDIR)Config.pm").nes."" Then Delete/NoConfirm/Log $(ARCHDIR)Config.pm;*
        - If f$$Search("[.lib.ExtUtils]Miniperl.pm").nes."" Then Delete/NoConfirm/Log [.lib.ExtUtils]Miniperl.pm;*
-       - If f$$Search("[.utils]*.").nes."" Then Delete/NoConfirm/Log [.utils]*.;*
+       - If f$$Search("[.utils]*.").nes."" Then Delete/NoConfirm/Log [.utils]*.;*/Exclude=Makefile.
        - If f$$Search("[.lib.pod]*.pod").nes."" Then Delete/NoConfirm/Log [.lib.pod]*.pod;*
        - If f$$Search("[.lib.pod]perldoc.").nes."" Then Delete/NoConfirm/Log [.lib.pod]perldoc.;*
        - If f$$Search("[.lib.pod]pod2*.").nes."" Then Delete/NoConfirm/Log [.lib.pod]pod2*.;*
index 607e2d6..b86cbd5 100644 (file)
@@ -65,7 +65,7 @@ OBJVAL = $(MMS$TARGET_NAME)$(O)
 .endif
 
 # Updated by fndvers.com -- do not edit by hand
-PERL_VERSION = 5_00310#
+PERL_VERSION = 5_00311#
 
 
 ARCHDIR =  [.lib.$(ARCH).$(PERL_VERSION)]
@@ -270,7 +270,7 @@ all : base extras libmods utils podxform archcorefiles preplibrary perlpods
        @ $(NOOP)
 base : miniperl perl
        @ $(NOOP)
-extras : Fcntl FileHandle IO Opcode $(POSIX) libmods utils podxform
+extras : Fcntl IO Opcode $(POSIX) libmods utils podxform
        @ $(NOOP)
 libmods : [.lib]Config.pm $(ARCHDIR)Config.pm [.lib]DynaLoader.pm [.lib.VMS]Filespec.pm 
        @ $(NOOP)
@@ -404,25 +404,6 @@ Opcode : [.lib]Opcode.pm [.lib]ops.pm [.lib]Safe.pm [.lib.auto.Opcode]Opcode$(E)
 [.ext.Opcode]Descrip.MMS : [.ext.Opcode]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E)
        $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Opcode]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]"
 
-FileHandle : [.lib]FileHandle.pm [.lib.auto.FileHandle]FileHandle$(E)
-       @ $(NOOP)
-
-[.lib]FileHandle.pm : [.ext.FileHandle]Descrip.MMS
-       @ If F$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto]
-       @ Set Default [.ext.FileHandle]
-       $(MMS)
-       @ Set Default [--]
-
-[.lib.auto.FileHandle]FileHandle$(E) : [.ext.FileHandle]Descrip.MMS
-       @ Set Default [.ext.FileHandle]
-       $(MMS)
-       @ Set Default [--]
-
-# Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C<chdir>
-# ${@} necessary to distract different versions of MM[SK]/make
-[.ext.FileHandle]Descrip.MMS : [.ext.FileHandle]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E)
-       $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.FileHandle]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]"
-
 Fcntl : [.lib]Fcntl.pm [.lib.auto.Fcntl]Fcntl$(E)
        @ $(NOOP)
 
@@ -1591,7 +1572,7 @@ tidy : cleanlis
        - If F$Search("[.Lib.VMS]*.*;-1").nes."" Then Purge/NoConfirm/Log [.Lib.VMS]*.*
        - If F$Search("[.Lib.Pod]*.Pod;-1").nes."" Then Purge/NoConfirm/Log [.Lib.Pod]*.Pod
        - If F$Search("$(ARCHCORE)*.*").nes."" Then Purge/NoConfirm/Log $(ARCHCORE)*.*
-       - If F$Search("[.utils]*.;-1").nes."" Then Purge/NoConfirm/Log [.utils]*.
+       - If F$Search("[.utils]*.;-1").nes."" Then Purge/NoConfirm/Log [.utils]*./Exclude=Makefile.
        - If F$Search("[.lib]perlbug.;-1").nes."" Then Purge/NoConfirm/Log [.lib]perlbug.
        - If F$Search("[.lib.pod]*.;-1").nes."" Then Purge/NoConfirm/Log [.lib.pod]*.
 
@@ -1660,7 +1641,7 @@ realclean : clean
        - If F$Search("[.Lib]perlbug.").nes."" Then Delete/NoConfirm/Log [.Lib]perlbug.;*
        - If F$Search("$(ARCHDIR)Config.pm").nes."" Then Delete/NoConfirm/Log $(ARCHDIR)Config.pm;*
        - If F$Search("[.lib.ExtUtils]Miniperl.pm").nes."" Then Delete/NoConfirm/Log [.lib.ExtUtils]Miniperl.pm;*
-       - If F$Search("[.utils]*.").nes."" Then Delete/NoConfirm/Log [.utils]*.;*
+       - If F$Search("[.utils]*.").nes."" Then Delete/NoConfirm/Log [.utils]*.;*/Exclude=Makefile.
        - If F$Search("[.lib.pod]*.pod").nes."" Then Delete/NoConfirm/Log [.lib.pod]*.pod;*
        - If F$Search("[.lib.pod]perldoc.").nes."" Then Delete/NoConfirm/Log [.lib.pod]perldoc.;*
        - If F$Search("[.lib.pod]pod2*.").nes."" Then Delete/NoConfirm/Log [.lib.pod]pod2*.;*
diff --git a/vms/ext/DCLsym/0README.txt b/vms/ext/DCLsym/0README.txt
new file mode 100644 (file)
index 0000000..9dc721d
--- /dev/null
@@ -0,0 +1,21 @@
+VMS::DCLsym is an extension to Perl 5 which allows it to manipulate DCL symbols
+via an object-oriented or tied-hash interface.
+
+In order to build the extension, just say
+
+$ Perl Makefile.PL
+$ MMK
+
+in the directory containing the source files.  Once it's built, you can run the
+test script by saying
+
+$ Perl "-Iblib" test.pl
+
+Finally, if you want to make it part of your regular Perl library, you can say
+$ MMK install
+
+If you have any problems or suggestions, please feel free to let me know.
+
+Regards,
+Charles Bailey  bailey@genetics.upenn.edu
+17-Aug-1995
diff --git a/vms/ext/DCLsym/DCLsym.pm b/vms/ext/DCLsym/DCLsym.pm
new file mode 100644 (file)
index 0000000..057951d
--- /dev/null
@@ -0,0 +1,268 @@
+package VMS::DCLsym;
+
+use Carp;
+use DynaLoader;
+use vars qw( @ISA $VERSION );
+use strict;
+
+# Package globals
+@ISA = ( 'DynaLoader' );
+$VERSION = '1.01';
+my(%Locsyms) = ( ':ID' => 'LOCAL' );
+my(%Gblsyms) = ( ':ID' => 'GLOBAL');
+my $DoCache = 1;
+my $Cache_set = 0;
+
+
+#====> OO methods
+
+sub new {
+  my($pkg,$type) = @_;
+  bless { TYPE => $type }, $pkg;
+}
+
+sub DESTROY { }
+
+sub getsym {
+  my($self,$name) = @_;
+  my($val,$table);
+
+  if (($val,$table) = _getsym($name)) {
+    if ($table eq 'GLOBAL') { $Gblsyms{$name} = $val; }
+    else                    { $Locsyms{$name} = $val; }
+  }
+  wantarray ? ($val,$table) : $val;
+}
+
+sub setsym {
+  my($self,$name,$val,$table) = @_;
+
+  $table = $self->{TYPE} unless $table;
+  if (_setsym($name,$val,$table)) {
+    if ($table eq 'GLOBAL') { $Gblsyms{$name} = $val; }
+    else                    { $Locsyms{$name} = $val; }
+    1;
+  }
+  else { 0; }
+}
+  
+sub delsym {
+  my($self,$name,$table) = @_;
+
+  $table = $self->{TYPE} unless $table;
+  if (_delsym($name,$table)) {
+    if ($table eq 'GLOBAL') { delete $Gblsyms{$name}; }
+    else                    { delete $Locsyms{$name}; }
+    1;
+  }
+  else { 0; }
+}
+
+sub clearcache {
+  my($self,$perm) = @_;
+  my($old);
+
+  $Cache_set = 0;
+  %Locsyms = ( ':ID' => 'LOCAL');
+  %Gblsyms = ( ':ID' => 'GLOBAL');
+  $old = $DoCache;
+  $DoCache = $perm if defined($perm);
+  $old;
+}
+
+#====> TIEHASH methods
+
+sub TIEHASH {
+  $_[0]->new(@_);
+}
+
+sub FETCH {
+  my($self,$name) = @_;
+  if    ($name eq ':GLOBAL') { $self->{TYPE} eq 'GLOBAL'; }
+  elsif ($name eq ':LOCAL' ) { $self->{TYPE} eq 'LOCAL';  }
+  else                       { scalar($self->getsym($name)); }
+}
+
+sub STORE {
+  my($self,$name,$val) = @_;
+  if    ($name eq ':GLOBAL') { $self->{TYPE} = 'GLOBAL'; }
+  elsif ($name eq ':LOCAL' ) { $self->{TYPE} = 'LOCAL';  }
+  else                       { $self->setsym($name,$val); }
+}
+
+sub DELETE {
+  my($self,$name) = @_;
+
+  $self->delsym($name);
+}
+
+sub FIRSTKEY {
+  my($self) = @_;
+  my($name,$eqs,$val);
+
+  if (!$DoCache || !$Cache_set) {
+    # We should eventually replace this with a C routine which walks the
+    # CLI symbol table directly.  If I ever get 'hold of an I&DS manual . . .
+    open(P,'Show Symbol * |');
+    while (<P>) {
+      ($name,$eqs,$val) = /^\s+(\S+) (=+) (.+)/
+        or carp "VMS::CLISym: unparseable line $_";
+      $name =~ s#\*##;
+      $val =~ s/"(.*)"$/$1/ or $val =~ s/^(\S+).*/$1/;
+      if ($eqs eq '==') { $Gblsyms{$name} = $val; }
+      else              { $Locsyms{$name} = $val; }
+    }
+    close P;
+    $Cache_set = 1;
+  }
+  $self ->{IDX} = 0;
+  $self->{CACHE} = $self->{TYPE} eq 'GLOBAL' ? \%Gblsyms : \%Locsyms;
+  while (($name,$val) = each(%{$self->{CACHE}}) and !defined($name)) {
+    if ($self->{CACHE}{':ID'} eq 'GLOBAL') { return undef; }
+    $self->{CACHE} = \%Gblsyms;
+  }
+  $name;
+}
+
+sub NEXTKEY {
+  my($self) = @_;
+  my($name,$val);
+
+  while (($name,$val) = each(%{$self->{CACHE}}) and !defined($name)) {
+    if ($self->{CACHE}{':ID'} eq 'GLOBAL') { return undef; }
+    $self->{CACHE} = \%Gblsyms;
+  }
+  $name;
+}
+
+
+sub EXISTS { defined($_[0]->FETCH(@_)) ? 1 : 0 }
+
+sub CLEAR { }
+
+
+bootstrap VMS::DCLsym;
+
+1;
+
+__END__
+
+=head1 NAME
+
+VMS::DCLsym - Perl extension to manipulate DCL symbols
+
+=head1 SYNOPSIS
+
+  tie %allsyms, VMS::DCLsym;
+  tie %cgisyms, VMS::DCLsym, 'GLOBAL';
+
+
+  $handle = new VMS::DCLsyms;
+  $value = $handle->getsym($name);
+  $handle->setsym($name,$value,'GLOBAL') or die "Can't create symbol: $!\n";
+  $handle->delsym($name,'LOCAL') or die "Can't delete symbol: $!\n";
+  $handle->clearcache();
+
+=head1 DESCRIPTION
+
+The VMS::DCLsym extension provides access to DCL symbols using a
+tied hash interface.  This allows Perl scripts to manipulate symbols in
+a manner similar to the way in which logical names are manipulated via
+the built-in C<%ENV> hash.  Alternatively, one can call methods in this
+package directly to read, create, and delete symbols.
+
+=head2 Tied hash interface
+
+This interface lets you treat the DCL symbol table as a Perl associative array,
+in which the key of each element is the symbol name, and the value of the
+element is that symbol's value.  Case is not significant in the key string, as
+DCL converts symbol names to uppercase, but it is significant in the value
+string.  All of the usual operations on associative arrays are supported. 
+Reading an element retrieves the current value of the symbol, assigning to it
+defines a new symbol (or overwrites the old value of an existing symbol), and
+deleting an element deletes the corresponding symbol.  Setting an element to
+C<undef>, or C<undef>ing it directly, sets the corresponding symbol to the null
+string. You may also read the special keys ':GLOBAL' and ':LOCAL' to find out
+whether a default symbol table has been specified for this hash (see C<table>
+below), or set either or these keys to specify a default symbol table.
+
+When you call the C<tie> function to bind an associative array to this package,
+you may specify as an optional argument the symbol table in which you wish to
+create and delete symbols.  If the argument is the string 'GLOBAL', then the
+global symbol table is used; any other string causes the local symbol table to
+be used.  Note that this argument does not affect attempts to read symbols; if
+a symbol with the specified name exists in the local symbol table, it is always
+returned in preference to a symbol by the same name in the global symbol table.
+
+=head2 Object interface
+
+Although it's less convenient in some ways than the tied hash interface, you
+can also call methods directly to manipulate individual symbols.  In some
+cases, this allows you finer control than using a tied hash aggregate.  The
+following methods are supported:
+
+=item new
+
+This creates a C<VMS::DCLsym> object which can be used as a handle for later
+method calls.  The single optional argument specifies the symbol table used
+by default in future method calls, in the same way as the optional argument to
+C<tie> described above.
+
+=item getsym
+
+If called in a scalar context, C<getsym> returns the value of the symbol whose
+name is given as the argument to the call, or C<undef> if no such symbol
+exists.  Symbols in the local symbol table are always used in preference to
+symbols in the global symbol table.  If called in an array context, C<getsym>
+returns a two-element list, whose first element is the value of the symbol, and
+whose second element is the string 'GLOBAL' or 'LOCAL', indicating the table
+from which the symbol's value was read.
+
+=item setsym
+
+The first two arguments taken by this method are the name of the symbol and the
+value which should be assigned to it.  The optional third argument is a string
+specifying the symbol table to be used; 'GLOBAL' specifies the global symbol
+table, and any other string specifies the local symbol table.  If this argument
+is omitted, the default symbol table for the object is used.  C<setsym> returns
+TRUE if successful, and FALSE otherwise.
+
+=item delsym
+
+This method deletes the symbol whose name is given as the first argument.  The
+optional second argument specifies the symbol table, as described above under
+C<setsym>.  It returns TRUE if the symbol was successfully deleted, and FALSE
+if it was not.
+
+=item clearcache
+
+Because of the overhead associated with obtaining the list of defined symbols
+for the tied hash iterator, it is only done once, and the list is reused for
+subsequent iterations.  Changes to symbols made through this package are
+recorded, but in the rare event that someone changes the process' symbol table
+from outside (as is possible using some software from the net), the iterator
+will be out of sync with the symbol table.  If you expect this to happen, you
+can reset the cache by calling this method.  In addition, if you pass a FALSE
+value as the first argument, caching will be disabled.  It can be reenabled
+later by calling C<clearcache> again with a TRUE value as the first argument.
+It returns TRUE or FALSE to indicate whether caching was previously enabled or
+disabled, respectively.
+
+This method is a stopgap until we can incorporate code into this extension to
+traverse the process' symbol table directly, so it may disappear in a future
+version of this package.
+
+=head1 AUTHOR
+
+Charles Bailey  bailey@genetics.upenn.edu
+
+=head1 VERSION
+
+1.01  08-Dec-1996
+
+=head1 BUGS
+
+The list of symbols for the iterator is assembled by spawning off a
+subprocess, which can be slow.  Ideally, we should just traverse the
+process' symbol table directly from C.
+
diff --git a/vms/ext/DCLsym/DCLsym.xs b/vms/ext/DCLsym/DCLsym.xs
new file mode 100644 (file)
index 0000000..3918eb1
--- /dev/null
@@ -0,0 +1,151 @@
+/* VMS::DCLsym - manipulate DCL symbols
+ *
+ * Version:  1.0
+ * Author:   Charles Bailey  bailey@genetics.upenn.edu
+ * Revised:  17-Aug-1995
+ *
+ *
+ * Revision History:
+ * 
+ * 1.0  17-Aug-1995  Charles Bailey  bailey@genetics.upenn.edu
+ *      original production version
+ */
+
+#include <descrip.h>
+#include <lib$routines.h>
+#include <libclidef.h>
+#include <libdef.h>
+#include <ssdef.h>
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+MODULE = VMS::DCLsym  PACKAGE = VMS::DCLsym
+
+void
+_getsym(name)
+  SV * name
+  PPCODE:
+  {
+    struct dsc$descriptor_s namdsc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0},
+                            valdsc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_D,0};
+    STRLEN namlen;
+    int tbltype;
+    unsigned long int retsts;
+    SETERRNO(0,SS$_NORMAL);
+    if (!name) {
+      PUSHs(sv_newmortal());
+      SETERRNO(EINVAL,LIB$_INVARG);
+      return;
+    }
+    namdsc.dsc$a_pointer = SvPV(name,namlen);
+    namdsc.dsc$w_length = (unsigned short int) namlen;
+    retsts = lib$get_symbol(&namdsc,&valdsc,0,&tbltype);
+    if (retsts & 1) {
+      PUSHs(sv_2mortal(newSVpv(valdsc.dsc$w_length ? 
+                               valdsc.dsc$a_pointer : "",valdsc.dsc$w_length)));
+      if (GIMME) {
+        EXTEND(sp,2);  /* just in case we're at the end of the stack */
+        if (tbltype == LIB$K_CLI_LOCAL_SYM)
+          PUSHs(sv_2mortal(newSVpv("LOCAL",5)));
+        else
+          PUSHs(sv_2mortal(newSVpv("GLOBAL",6)));
+      }
+      _ckvmssts(lib$sfree1_dd(&valdsc));
+    }
+    else {
+      ST(0) = &sv_undef;  /* error - we're returning undef, if anything */
+      switch (retsts) {
+        case LIB$_NOSUCHSYM:
+          break;   /* nobody home */;
+        case LIB$_INVSYMNAM:   /* user errors; set errno return undef */
+        case LIB$_INSCLIMEM:
+        case LIB$_NOCLI:
+          set_errno(EVMSERR);
+          set_vaxc_errno(retsts);
+          break;
+        default:  /* bail out */
+          { _ckvmssts(retsts); }
+      }
+    }
+  }
+
+
+void
+_setsym(name,val,typestr="LOCAL")
+  SV * name
+  SV * val
+  char *       typestr
+  CODE:
+  {
+    struct dsc$descriptor_s namdsc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0},
+                            valdsc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
+    STRLEN slen;
+    int type;
+    unsigned long int retsts;
+    SETERRNO(0,SS$_NORMAL);
+    if (!name || !val) {
+      SETERRNO(EINVAL,LIB$_INVARG);
+      XSRETURN_UNDEF;
+    }
+    namdsc.dsc$a_pointer = SvPV(name,slen);
+    namdsc.dsc$w_length = (unsigned short int) slen;
+    valdsc.dsc$a_pointer = SvPV(val,slen);
+    valdsc.dsc$w_length = (unsigned short int) slen;
+    type = strNE(typestr,"GLOBAL") ?
+              LIB$K_CLI_LOCAL_SYM : LIB$K_CLI_GLOBAL_SYM;
+    retsts = lib$set_symbol(&namdsc,&valdsc,&type);
+    if (retsts & 1) { XSRETURN_YES; }
+    else {
+      switch (retsts) {
+        case LIB$_AMBSYMDEF:  /* user errors; set errno and return */
+        case LIB$_INSCLIMEM:
+        case LIB$_INVSYMNAM:
+        case LIB$_NOCLI:
+          set_errno(EVMSERR);
+          set_vaxc_errno(retsts);
+          XSRETURN_NO;
+          break;  /* NOTREACHED */
+        default:  /* bail out */
+          { _ckvmssts(retsts); }
+      }
+    }
+  }
+
+
+void
+_delsym(name,typestr="LOCAL")
+  SV * name
+  char *       typestr
+  CODE:
+  {
+    struct dsc$descriptor_s namdsc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
+    STRLEN slen;
+    int type;
+    unsigned long int retsts;
+    SETERRNO(0,SS$_NORMAL);
+    if (!name || !typestr) {
+      SETERRNO(EINVAL,LIB$_INVARG);
+      XSRETURN_UNDEF;
+    }
+    namdsc.dsc$a_pointer = SvPV(name,slen);
+    namdsc.dsc$w_length = (unsigned short int) slen;
+    type = strNE(typestr,"GLOBAL") ?
+              LIB$K_CLI_LOCAL_SYM : LIB$K_CLI_GLOBAL_SYM;
+    retsts = lib$delete_symbol(&namdsc,&type);
+    if (retsts & 1) { XSRETURN_YES; }
+    else {
+      switch (retsts) {
+        case LIB$_INVSYMNAM:  /* user errors; set errno and return */
+        case LIB$_NOCLI:
+        case LIB$_NOSUCHSYM:
+          set_errno(EVMSERR);
+          set_vaxc_errno(retsts);
+          XSRETURN_NO;
+          break;  /* NOTREACHED */
+        default:  /* bail out */
+          { _ckvmssts(retsts); }
+      }
+    }
+  }
+
diff --git a/vms/ext/DCLsym/Makefile.PL b/vms/ext/DCLsym/Makefile.PL
new file mode 100644 (file)
index 0000000..8e6f5bc
--- /dev/null
@@ -0,0 +1,3 @@
+use ExtUtils::MakeMaker;
+
+WriteMakefile( 'VERSION_FROM' => 'DCLsym.pm' );
diff --git a/vms/ext/DCLsym/test.pl b/vms/ext/DCLsym/test.pl
new file mode 100644 (file)
index 0000000..57f2afb
--- /dev/null
@@ -0,0 +1,41 @@
+print "1..15\n";
+
+require VMS::DCLsym or die "failed 1\n";
+print "ok 1\n";
+
+tie %syms, VMS::DCLsym or die "failed 2\n";
+print "ok 2\n";
+
+$name = 'FOO_'.time();
+$syms{$name} = 'Perl_test';
+print +($! ? "(\$! = $!) not " : ''),"ok 3\n";
+
+print +($syms{$name} eq 'Perl_test' ? '' : 'not '),"ok 4\n";
+
+($val) = `Show Symbol $name` =~ /(\w+)"$/;
+print +($val eq 'Perl_test' ? '' : 'not '),"ok 5\n";
+
+while (($sym,$val) = each %syms) {
+  last if $sym eq $name && $val eq 'Perl_test';
+}
+print +($sym ? '' : 'not '),"ok 6\n";
+
+delete $syms{$name};
+print +($! ? "(\$! = $!) not " : ''),"ok 7\n";
+
+print +(defined($syms{$name}) ? 'not ' : ''),"ok 8\n";
+undef %syms;
+
+$obj = new VMS::DCLsym 'GLOBAL';
+print +($obj ? '' : 'not '),"ok 9\n";
+
+print +($obj->clearcache(0) ? '' : 'not '),"ok 10\n";
+print +($obj->clearcache(1) ? 'not ' : ''),"ok 11\n";
+
+print +($obj->setsym($name,'Another_test') ? '' : 'not '),"ok 12\n";
+
+($val,$tab) = $obj->getsym($name);
+print +($val eq 'Another_test' && $tab eq 'GLOBAL' ? '' : 'not '),"ok 13\n";
+
+print +($obj->delsym($name,'LOCAL') ? 'not ' : ''),"ok 14\n";
+print +($obj->delsym($name,'GLOBAL') ? '' : 'not '),"ok 15\n";
index af71f0b..ad16af3 100644 (file)
@@ -1,8 +1,8 @@
 #   VMS::Stdio - VMS extensions to Perl's stdio calls
 #
 #   Author:  Charles Bailey  bailey@genetics.upenn.edu
-#   Version: 2.0
-#   Revised: 28-Feb-1996
+#   Version: 2.01
+#   Revised: 10-Dec-1996
 
 package VMS::Stdio;
 
@@ -12,7 +12,7 @@ use Carp '&croak';
 use DynaLoader ();
 use Exporter ();
  
-$VERSION = '2.0';
+$VERSION = '2.01';
 @ISA = qw( Exporter DynaLoader IO::File );
 @EXPORT = qw( &O_APPEND &O_CREAT &O_EXCL  &O_NDELAY &O_NOWAIT
               &O_RDONLY &O_RDWR  &O_TRUNC &O_WRONLY );
@@ -32,15 +32,14 @@ sub AUTOLOAD {
     if ($constname =~ /^O_/) {
       my($val) = constant($constname);
       defined $val or croak("Unknown VMS::Stdio constant $constname");
+      *$AUTOLOAD = sub { val; }
     }
     else { # We don't know about it; hand off to IO::File
       require IO::File;
-      my($obj) = shift(@_);
 
-      my($val) = eval "\$obj->IO::File::$constname(@_)";
-      croak "Error autoloading $constname: $@" if $@;
+      *$AUTOLOAD = eval "sub { shift->IO::File::$constname(\@_) }";
+      croak "Error autoloading IO::File::$constname: $@" if $@;
     }
-    *$AUTOLOAD = sub { $val };
     goto &$AUTOLOAD;
 }
 
@@ -189,9 +188,9 @@ reason, it is unable to generate a name, it returns C<undef>.
 =item vmsopen
 
 The C<vmsopen> function enables you to specify optional RMS arguments
-to the VMS CRTL when opening a file.  It is similar to the built-in
+to the VMS CRTL when opening a file.  Its operation is similar to the built-in
 Perl C<open> function (see L<perlfunc> for a complete description),
-but will only open normal files; it cannot open pipes or duplicate
+but it will only open normal files; it cannot open pipes or duplicate
 existing I/O handles.  Up to 8 optional arguments may follow the
 file name.  These arguments should be strings which specify
 optional file characteristics as allowed by the CRTL. (See the
@@ -199,7 +198,7 @@ CRTL reference manual description of creat() and fopen() for details.)
 If successful, C<vmsopen> returns a VMS::Stdio file handle; if an
 error occurs, it returns C<undef>.
 
-You can use the file handle returned by C<vmsfopen> just as you
+You can use the file handle returned by C<vmsopen> just as you
 would any other Perl file handle.  The class VMS::Stdio ISA
 IO::File, so you can call IO::File methods using the handle
 returned by C<vmsopen>.  However, C<use>ing VMS::Stdio does not
@@ -232,6 +231,6 @@ task by calling the CRTL routine fwait().
 
 =head1 REVISION
 
-This document was last revised on 28-Jan-1996, for Perl 5.002.
+This document was last revised on 10-Dec-1996, for Perl 5.004.
 
 =cut
index a1ec91f..200268c 100644 (file)
@@ -100,7 +100,7 @@ newFH(FILE *fp, char type) {
     gv_init(gv,stash,"__FH__",6,0);
     io = GvIOp(gv) = newIO();
     IoIFP(io) = fp;
-    if (type != '>') IoOFP(io) = fp;
+    if (type != '<') IoOFP(io) = fp;
     IoTYPE(io) = type;
     rv = newRV((SV *)gv);
     SvREFCNT_dec(gv);
@@ -225,7 +225,7 @@ vmsopen(spec,...)
                break;
            }
            if (fp != Nullfp) {
-             SV *fh = newFH(fp,(mode[1] ? '+' : (mode[0] == 'r' ? '<' : '>')));
+             SV *fh = newFH(fp,(mode[1] ? '+' : (mode[0] == 'r' ? '<' : (mode[0] == 'a' ? 'a' : '>'))));
              ST(0) = (fh ? sv_2mortal(fh) : &sv_undef);
            }
            else { ST(0) = &sv_undef; }
index 12e508a..0b50d63 100644 (file)
@@ -1,8 +1,8 @@
-# Tests for VMS::Stdio v2.0
+# Tests for VMS::Stdio v2.01
 use VMS::Stdio;
 import VMS::Stdio qw(&flush &getname &rewind &sync);
 
-print "1..13\n";
+print "1..14\n";
 print +(defined(&getname) ? '' : 'not '), "ok 1\n";
 
 $name = "test$$";
@@ -16,26 +16,29 @@ print +(sync($fh) ? '' : 'not '),"ok 4\n";
 $time = (stat("$name.tmp"))[9];
 print +($time ? '' : 'not '), "ok 5\n";
 
-print 'not ' unless print $fh scalar(localtime($time)),"\n";
+$fh->autoflush;  # Can we autoload autoflush from IO::File?  Do or die.
 print "ok 6\n";
 
-print +(rewind($fh) ? '' : 'not '),"ok 7\n";
+print 'not ' unless print $fh scalar(localtime($time)),"\n";
+print "ok 7\n";
+
+print +(rewind($fh) ? '' : 'not '),"ok 8\n";
 
 chop($line = <$fh>);
-print +($line eq localtime($time) ? '' : 'not '), "ok 8\n";
+print +($line eq localtime($time) ? '' : 'not '), "ok 9\n";
 
 ($gotname) = (getname($fh) =~/\](.*);/);
-print +($gotname eq "\U$name.tmp" ? '' : 'not '), "ok 9\n";
+print +($gotname eq "\U$name.tmp" ? '' : 'not '), "ok 10\n";
 
 $sfh = VMS::Stdio::vmssysopen($name, O_RDONLY, 0,
                               'ctx=rec', 'shr=put', 'dna=.tmp');
-print +($sfh ? '' : 'not ($!) '), "ok 10\n";
+print +($sfh ? '' : 'not ($!) '), "ok 11\n";
 
 close($fh);
 sysread($sfh,$line,24);
-print +($line eq localtime($time) ? '' : 'not '), "ok 11\n";
+print +($line eq localtime($time) ? '' : 'not '), "ok 12\n";
 
 undef $sfh;
-print +(stat("$name.tmp") ? 'not ' : ''),"ok 12\n";
+print +(stat("$name.tmp") ? 'not ' : ''),"ok 13\n";
 
-print +(&VMS::Stdio::tmpnam ? '' : 'not '),"ok 13\n";
+print +(&VMS::Stdio::tmpnam ? '' : 'not '),"ok 14\n";
index 70013ae..53ee6a8 100644 (file)
@@ -9,6 +9,21 @@ $loop:
 $ x=f$element(element,p2,p3)
 $ if x .eqs. p2 then goto out
 $ y=f$edit(x,"COLLAPSE")  ! lose spaces
+$! Expand potential name-only args so we find shareable images
+$! either via a logical name or in the default location
+$ if y .nes. "" .and. -
+     f$locate("/SHARE",f$edit(y,"UPCASE")) .ne. f$length(y)
+$ then
+$   name = f$element(0,"/",y)
+$   tail = f$extract(f$length(name),1024,y)
+$   name = f$parse(name,"sys$share:.exe;")   ! Look where image activator will
+$   name = f$search(name)                    ! Does it really exist?
+$   if name .nes. ""
+$   then
+$     name = name - f$parse(name,,,"version")  ! Insist on current version
+$     y = name + tail
+$   endif
+$ endif
 $ if y .nes. "" then write file y
 $ element=element+1
 $ goto loop
index b1cb69c..28b84e4 100644 (file)
@@ -13,1105 +13,1055 @@ dep()
     deprecate("\"do\" to call subroutines");
 }
 
+#line 16 "perly.c"
 #define YYERRCODE 256
 dEXT short yylhs[] = {                                        -1,
-   31,    0,    5,    3,    6,    6,    6,    7,    7,    7,
-    7,   21,   21,   21,   21,   21,   21,   11,   11,   11,
-    9,    9,    9,    9,   30,   30,    8,    8,    8,    8,
-    8,    8,    8,    8,   10,   10,   25,   25,   29,   29,
-    1,    1,    1,    1,    2,    2,   32,   32,   28,   28,
-    4,   33,   33,   34,   13,   13,   13,   12,   12,   12,
-   26,   26,   26,   26,   26,   26,   26,   26,   27,   27,
-   14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
-   14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
-   14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
-   14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
-   14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
-   14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
-   14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
-   14,   14,   14,   14,   22,   22,   23,   23,   23,   20,
-   15,   16,   17,   18,   19,   24,   24,   24,   24,
+   40,    0,    7,    5,    8,    6,    9,    9,    9,   10,
+   10,   10,   10,   22,   22,   22,   22,   22,   22,   13,
+   13,   13,   12,   12,   12,   12,   37,   37,   11,   11,
+   11,   11,   11,   11,   11,   11,   11,   24,   24,   25,
+   25,   26,   27,   28,   29,   30,   39,   39,    1,    1,
+    1,    1,    3,    3,   41,   41,   36,   36,    4,   42,
+   42,   43,   14,   14,   14,   23,   23,   23,   34,   34,
+   34,   34,   34,   34,   34,   34,   35,   35,   15,   15,
+   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
+   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
+   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
+   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
+   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
+   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
+   15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
+   15,   15,   31,   31,   32,   32,   32,    2,    2,   38,
+   21,   16,   17,   18,   19,   20,   33,   33,   33,   33,
 };
 dEXT short yylen[] = {                                         2,
-    0,    2,    4,    0,    0,    2,    2,    2,    1,    2,
-    3,    1,    1,    3,    3,    3,    3,    0,    2,    6,
-    6,    6,    4,    4,    0,    2,    7,    7,    5,    5,
-    8,    7,   10,    3,    0,    1,    0,    1,    0,    1,
-    1,    1,    1,    1,    4,    3,    5,    5,    0,    1,
-    0,    3,    2,    6,    3,    3,    1,    2,    3,    1,
-    3,    5,    6,    3,    5,    2,    4,    4,    1,    1,
+    0,    2,    4,    0,    4,    0,    0,    2,    2,    2,
+    1,    2,    3,    1,    1,    3,    3,    3,    3,    0,
+    2,    6,    7,    7,    4,    4,    0,    2,    8,    8,
+    5,    5,   10,    9,    8,   11,    3,    0,    1,    0,
+    1,    1,    1,    1,    1,    1,    0,    1,    1,    1,
+    1,    1,    4,    3,    5,    5,    0,    1,    0,    3,
+    2,    6,    3,    3,    1,    2,    3,    1,    3,    5,
+    6,    3,    5,    2,    4,    4,    1,    1,    3,    3,
     3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
-    3,    3,    5,    3,    2,    2,    2,    2,    2,    2,
-    2,    2,    2,    2,    3,    2,    3,    2,    4,    3,
-    4,    1,    5,    1,    4,    5,    4,    1,    1,    1,
-    5,    6,    5,    6,    5,    4,    5,    1,    1,    3,
-    4,    3,    2,    2,    4,    5,    4,    5,    1,    2,
-    2,    1,    2,    2,    2,    1,    3,    1,    3,    4,
-    4,    6,    1,    1,    0,    1,    0,    1,    2,    2,
-    2,    2,    2,    2,    2,    1,    1,    1,    1,
+    5,    3,    2,    2,    2,    2,    2,    2,    2,    2,
+    2,    2,    3,    2,    3,    2,    4,    3,    4,    1,
+    5,    1,    4,    5,    4,    1,    1,    1,    5,    6,
+    5,    6,    5,    4,    5,    1,    1,    3,    4,    3,
+    2,    2,    4,    5,    4,    5,    1,    2,    2,    1,
+    2,    2,    2,    1,    3,    1,    3,    4,    4,    6,
+    1,    1,    0,    1,    0,    1,    2,    1,    1,    1,
+    2,    2,    2,    2,    2,    2,    1,    1,    1,    1,
 };
 dEXT short yydefred[] = {                                      1,
-    0,    5,    0,   40,   51,   51,    0,   51,    6,   41,
-    7,    9,    0,   42,   43,   44,    0,    0,    0,   53,
-    0,   12,    4,  143,    0,    0,  118,    0,  138,    0,
-   51,   51,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    7,    0,   48,   59,   59,    0,   59,    8,   49,
+    9,   11,    0,   50,   51,   52,    0,    0,    0,   61,
+    0,   14,    4,  151,    0,    0,  126,    0,  146,    0,
+   59,   59,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,  158,  159,    0,
+    0,    0,    0,    0,    0,    0,    0,   12,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,   10,    0,    0,
+    0,    0,  116,  118,    0,    0,    0,    0,  152,    0,
+   54,    0,   60,    0,    7,  167,  170,  169,  168,    0,
+    0,    0,    0,    0,    0,    4,    0,    4,    0,    4,
+    0,    4,    0,    4,    4,    0,    0,    0,    0,    0,
+  141,    0,    0,    0,    0,   74,    0,  165,    0,  132,
+    0,    0,    0,    0,    0,  161,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,  106,    0,  162,  163,
+  164,  166,    0,    0,   37,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,   10,    0,    0,    0,
-    0,    0,    0,    0,    0,    8,    0,    0,    0,    0,
-    0,  108,  110,    0,    0,    0,  144,    0,   46,    0,
-   52,    0,    5,  156,  159,  158,  157,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,  154,    0,  124,
-    0,    0,    0,    0,    0,    0,  150,    0,    0,    0,
-    0,   66,    0,  133,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,   98,    0,  151,  152,  153,  155,
-    0,   34,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,   90,   91,    0,    0,    0,    0,
-    0,    0,    0,    0,   11,   45,   50,    0,    0,    0,
-   64,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,   36,    0,  137,  139,
-    0,    0,    0,    0,    0,    0,  100,    0,  122,    0,
-    0,    0,   97,   26,    0,    0,    0,    0,    0,    0,
-   55,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,   69,    0,   70,
-    0,    0,    0,    0,    0,    0,    0,  120,    0,   48,
-   47,    0,    3,    0,  141,    0,   68,  101,    0,   29,
-    0,   30,    0,    0,    0,   23,    0,   24,    0,    0,
-    0,  140,  149,   67,    0,  125,    0,  127,    0,   99,
-    0,    0,    0,    0,    0,    0,    0,  107,    0,  105,
-    0,  116,    0,  121,   54,   65,    0,    0,    0,    0,
-   19,    0,    0,    0,    0,    0,   62,  126,  128,  115,
-    0,  113,    0,    0,  106,    0,  111,  117,  103,  142,
-   27,   28,   21,    0,   22,    0,   32,    0,  114,  112,
-   63,    0,    0,   31,    0,    0,   20,   33,
+    0,    0,    0,    0,    0,    0,   98,   99,    0,    0,
+    0,    0,    0,    0,    0,    0,   13,    0,   53,   58,
+    0,    0,    0,   72,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    4,  145,
+  147,    0,    0,    0,    0,    0,    0,    0,  108,    0,
+  130,    0,    0,  105,   28,    0,    0,   19,    0,    0,
+    0,   63,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,   77,    0,
+   78,    0,    0,    0,    0,    0,    0,    0,  128,    0,
+    0,   56,   55,    0,    3,    0,  149,    0,   76,  109,
+    0,   45,    0,   31,   46,    0,   32,    0,    0,    0,
+    0,   25,    0,   26,  160,    0,    0,   39,   44,    0,
+    0,    0,  148,  157,   75,    0,  133,    0,  135,    0,
+  107,    0,    0,    0,    0,    0,    0,    0,  115,    0,
+  113,    0,  124,    0,  129,   62,   73,    0,    0,    0,
+    0,    6,   21,    0,    0,    0,    0,    0,    0,   70,
+  134,  136,  123,    0,  121,    0,    0,  114,    0,  119,
+  125,  111,  150,    0,    0,    0,    7,    0,    0,    0,
+    0,    0,    0,  122,  120,   71,   29,   30,   23,    0,
+    0,   24,    0,   35,    0,    0,    5,    0,    0,    0,
+   34,   22,   33,    0,   36,
 };
 dEXT short yydgoto[] = {                                       1,
-    9,   10,   83,   17,   86,    3,   11,   12,   66,  195,
-  266,   67,  202,   69,   70,   71,   72,   73,   74,   75,
-  197,  122,  203,   88,  187,   77,  241,  178,   13,  142,
-    2,   14,   15,   16,
+    9,   66,   10,   17,   85,  337,   88,  313,    3,   11,
+   12,   68,  272,  268,   70,   71,   72,   73,   74,   75,
+   76,  278,   78,  279,  262,  265,  269,  281,  263,  266,
+  116,  204,   90,   79,  242,  181,  145,  276,   13,    2,
+   14,   15,   16,
 };
 dEXT short yysindex[] = {                                      0,
-    0,    0,  303,    0,    0,    0,  -53,    0,    0,    0,
-    0,    0,  607,    0,    0,    0, -111, -242,  -32,    0,
- -216,    0,    0,    0,  149,  149,    0,    8,    0, 2109,
-    0,    0,  -15,   -8,    4,    6,   32, 2109,   13,   20,
-   57,  149,  994, 2109, 1057, -206,  149, 2109,  938, 1291,
- 2109, 2109, 2109, 2109, 2109, 1347,    0, 2109, 2109, 1403,
-  149,  149,  149,  149, -203,    0,   68,  664,  491,  -67,
-  -52,    0,    0,  -21,   73,   65,    0,    7,    0, -135,
-    0, -126,    0,    0,    0,    0,    0, 2109,   92, 2109,
-  491,    7, -135, 2109,    7, 2109,    7, 2109,    7, 2109,
-    7, 1466,  101,  491,  112, 1700,  938,    0,  102,    0,
- 1228,  -22, 1228,   39,  -58, 2109,    0,   68,    0,   68,
-  -67,    0, 2109,    0, 1228,  472,  472,  472,  -88,  -88,
-   78,  -10,  472,  472,    0,  -85,    0,    0,    0,    0,
-    7,    0, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109,
- 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109,
- 2109, 2109, 2109, 2109,    0,    0,  -29, 2109, 2109, 2109,
- 2109, 2109, 2109, 1756,    0,    0,    0,  -46, 2109,  391,
-    0, 2109,  -25, 2109,    7, -214,  129, -203,   -5, -203,
-    1, -167,    9, -167,  117,   52,    0, 2109,    0,    0,
-   23,   60,  132, 2109, 1812, 1875,    0,   53,    0,   68,
- 2109,   86,    0,    0,  491, -214, -214, -214, -214, -147,
-    0,  -54,  382, 1228, 1090,  771,  115,  491, 2942, 1523,
-  314, 1554,  392,  677,  472,  472, 2109,    0, 2109,    0,
-  141,   89,  -42,   99,   46,  114,   64,    0,   26,    0,
-    0,  124,    0,  143,    0, 2109,    0,    0,    7,    0,
-    7,    0,    7,    7,  146,    0,    7,    0, 2109,    7,
-   35,    0,    0,    0,   37,    0,   49,    0,   55,    0,
-  130, 2109,   63, 2109,   67,  166, 2109,    0,   66,    0,
-   71,    0,   74,    0,    0,    0, 1170, -203, -203, -167,
-    0, 2109, -167,  131, -203,    7,    0,    0,    0,    0,
-  185,    0, 1119,   76,    0,  161,    0,    0,    0,    0,
-    0,    0,    0,   58,    0, 1466,    0, -203,    0,    0,
-    0,    7,  162,    0, -167,    7,    0,    0,
+    0,    0, -178,    0,    0,    0,  -49,    0,    0,    0,
+    0,    0,  616,    0,    0,    0, -108, -233,    3,    0,
+ -230,    0,    0,    0,  -24,  -24,    0,   28,    0, 1899,
+    0,    0,  -17,  -12,  -11,  -10,  -35, 1899,   39,   54,
+   60,  992,  936,  -24, 1055, 1319, -217,    0,    0,  -24,
+ 1899, 1899, 1899, 1899, 1899, 1899, 1375,    0, 1899, 1899,
+ 1431,  -24,  -24,  -24,  -24, 1899, -161,    0,  277, 3829,
+  -69,  -42,    0,    0,   -4,   88,   89,   97,    0,   24,
+    0, -107,    0, -105,    0,    0,    0,    0,    0, 1899,
+  114, 1899,  328,   24, -107,    0,   24,    0,   24,    0,
+   24,    0,   24,    0,    0,  115, 3829,  133, 1490,  936,
+    0,  328,    0,  -69,   97,    0, 1899,    0,  137,    0,
+  328,  -19,   56,   19, 1899,    0,   97,   98,   98,   98,
+  -82,  -82,   93,  -21,   98,   98,    0,  -87,    0,    0,
+    0,    0,  328,   24,    0, 1899, 1899, 1899, 1899, 1899,
+ 1899, 1899, 1899, 1899, 1899, 1899, 1899, 1899, 1899, 1899,
+ 1899, 1899, 1899, 1899, 1899, 1899,    0,    0,  -32, 1899,
+ 1899, 1899, 1899, 1899, 1899, 1665,    0, 1899,    0,    0,
+   -8, 1899,  357,    0, 1899,   82, 1899,   24, 1899, -161,
+ 1899, -161, 1899, -234, 1899, -234,  144, 1724,    0,    0,
+    0,    4,   11,  138, 1899,   97, 1780, 1836,    0,   61,
+    0, 1899,   96,    0,    0, -176, -176,    0, -176, -176,
+  -95,    0,   21, 1092,  328,  373,  434,   92, 3829, 1204,
+ 3238, 3721, 2430,  815,  419,   98,   98, 1899,    0, 1899,
+    0,  173,  -80,   55,  -68,   57,  -54,   68,    0,    6,
+ 3829,    0,    0,  157,    0,  178,    0, 1899,    0,    0,
+ -176,    0,  181,    0,    0,  183,    0, -176,  190,  112,
+  209,    0,  231,    0,    0,  210,  277,    0,    0,  237,
+  224, 1899,    0,    0,    0,    9,    0,   15,    0,   17,
+    0,  105, 1899,  163, 1899,   81,  119, 1899,    0,  168,
+    0,  175,    0,  185,    0,    0,    0, 1146,  112,  112,
+  112,    0,    0, 1899,  112, 1899,  112, 1899,  279,    0,
+    0,    0,    0,  143,    0, 3863,  202,    0,  300,    0,
+    0,    0,    0, -161, -161, -234,    0,  321, -234,  326,
+ -161,  309,  112,    0,    0,    0,    0,    0,    0,  398,
+  112,    0,  112,    0, 1724, -161,    0, -234, -161,  336,
+    0,    0,    0,  112,    0,
 };
 dEXT short yyrindex[] = {                                      0,
-    0,    0,  269,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,  220,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0, 2241, 1964,    0,
-    0,    0,    0,    0,    0,    0,    0,    0, 2857, 2901,
+    0,    0,    0,    0,    0,    0,    0, 2159, 1989,    0,
+    0, 2799, 2867,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,  107,    0,  360,   -1,   62, 3027,
- 3078,    0,    0, 2286, 2020,    0,    0,    0,    0,  -12,
-    0,    0,    0,    0,    0,    0,    0, 2415,    0,    0,
- 1251,    0,   82,  173,    0,    0,    0,    0,    0,    0,
-    0,  157,    0, 1661,    0,    0,  178,    0, 2150,    0,
- 3927, 3027, 3958,    0,    0, 2415,    0, 2537,  454, 2581,
-  548,    0,    0,    0, 3989, 3384, 3425, 3461, 3122, 3163,
- 2636,    0, 3497, 3533,    0,    0,    0,    0,    0,    0,
-    0,    0, 2680,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,   65,    0,  -25,  193,
+ 2910, 2954,    0,    0, 2225, 2048,    0,  333,    0,    0,
+    0,    2,    0,    0,    0,    0,    0,    0,    0, 2284,
+    0,    0, 3575,    0,  257,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0, 3017,    0,    0,  348,
+    0, 3642,  496,  557, 2395,    0,    0,    0, 2111,    0,
+ 3695, 2910,    0,    0, 2284,    0, 2520, 3065, 3103, 3190,
+  659, 2997, 2563,    0, 3301, 3354,    0,    0,    0,    0,
+    0,    0, 3741,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,  163,  882,
-    0,  178,    0, 2415,    0,    2,    0,  107,    0,  107,
-    0,  175,    0,  175,    0,  165,    0,    0,    0,    0,
-    0,  180,    0,    0,    0,    0,    0,    0,    0, 2723,
-    0, 2985,    0,    0, 2785,   11,   14,   33,   59,  833,
-    0,    0,  -30, 4020, 4036, 3817, 3850, 3275,    0, 1611,
- 4179, 4114, 4098, 3894, 3569, 3646,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0, 2631,    0,    0,
+    0,  331,  880,    0,  348,    0, 2284,    0,  352,   65,
+    0,   65,    0,  164,    0,  164,    0,  338,    0,    0,
+    0,    0,  358,    0,    0, 2674,    0,    0,    0,    0,
+    0,    0, 2718,    0,    0,  -22,   36,    0,   91,  110,
+  -33,    0,    0, 2573, 1267, 1531, 3476, 3521, 3675,    0,
+  -27, 3826, 3794, 1587,   -6, 3392, 3440,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+ 3787,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+  134,    0,    0,    0,    0,    0,    0,  359,    0,    0,
+    0,    0,    0,    0,    0,    0,  155,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,  168,    0,
+    0,    0,    0,    0,    0,    0,    0,  348,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,  178,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,  107,  107,  175,
-    0,    0,  175,    0,  107,    0,    0,    0,    0,    0,
-    0,    0, 2462,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,  190,    0,  107,    0,    0,
-    0,    0,    0,    0,  175,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,  349,    0,    0,
+    0,    0,    0,    0,    0, 1953,    0,    0,    0,    0,
+    0,    0,    0,   65,   65,  164,    0,    0,  164,    0,
+   65,    0,    0,    0,    0,    0,    0,    0,    0,  880,
+    0,    0,    0,    0,  368,   65,    0,  164,   65,    0,
+    0,    0,    0,    0,    0,
 };
 dEXT short yygindex[] = {                                      0,
-    0,    0,    0,  148,  -13,  106,    0,    0,    0,  -91,
- -184,  452,  -11, 4373,  886,    0,    0,    0,    0,    0,
-  234,  -62, -173,  460,  -20,    0,    0,  174,    0, -131,
-    0,    0,    0,    0,
+    0,    0,    0,  136,  -29,    0, 4145,  680,  -78,    0,
+    0,    0, -193,  -13, 3266,  519,    0,    0,    0,    0,
+    0,  400,  885,    0,    0,  267, -196,   63,  124,  250,
+  -16, -167,   20,    0,    0,  320,  356,    0,    0,    0,
+    0,    0,    0,
 };
-#define YYTABLESIZE 4657
-dEXT short yytable[] = {                                      65,
-  208,   68,  168,   79,  283,   20,   61,  213,  254,  268,
-   80,   23,  250,   80,   80,  255,  289,  206,  256,   95,
-   97,   99,  101,  170,   94,  181,   81,   80,   80,  110,
-  212,   96,   80,  115,  150,  261,  124,  157,  172,   13,
-   82,  263,   38,   98,  132,  100,   49,   90,  136,  267,
-  116,   16,  105,  209,   17,  169,  260,   13,  262,  106,
-   38,  239,   80,  272,  176,  168,  294,   61,  170,   16,
-  171,  102,   17,   14,  141,  306,   23,  307,  184,  148,
-  149,  188,  186,  190,  189,  192,  191,  194,  193,  308,
-  196,   14,  270,  237,  201,  309,  107,  150,  332,   15,
-  169,  173,   60,  273,  291,   60,   25,   23,  264,  265,
-   49,  143,  174,  316,   23,  323,  252,   15,  325,   60,
-   60,  257,  293,  175,  177,  314,   23,  214,   23,   23,
-  179,  182,  216,  217,  218,  219,  220,  221,  222,   25,
-  198,  205,   25,   25,   25,   78,   25,  149,   25,   25,
-  337,   25,  199,   18,   60,   21,  242,  243,  244,  245,
-  246,  247,  249,  207,  251,   25,  321,  322,  211,  259,
-   25,  258,  274,  327,   18,  269,  282,  280,   92,   93,
-  287,  288,  295,  296,   61,  302,  271,  312,  180,  326,
-  317,  290,  275,  277,  279,  318,  334,   25,  319,  281,
-  330,  331,  336,   19,   49,  168,  292,   18,  148,  149,
-   18,   18,   18,   37,   18,   35,   18,   18,  147,   18,
-  148,  145,  310,   13,  167,  285,   37,  286,  238,   25,
-   35,   25,   25,   18,  333,  148,  149,  150,   18,  148,
-  149,   80,   80,   80,   80,  298,   76,  299,  304,  300,
-  301,  148,  149,  303,    0,  151,  305,  186,  315,  152,
-  153,  154,  155,   80,   80,   18,  185,   80,    2,    0,
-  311,   23,  156,  158,  159,  160,  161,  329,  162,  163,
-    0,    0,  164,  148,  149,  165,  166,  167,  148,  149,
-  324,    0,  328,    0,  148,  149,    0,   18,    0,   18,
-   18,   39,  148,  149,   39,   39,   39,    0,   39,    0,
-   39,   39,    0,   39,   68,    0,  148,  149,  335,  148,
-  149,    0,  338,  144,  145,  146,  147,   39,  148,  149,
-  148,  149,   39,   60,   60,   60,   60,    0,    0,  148,
-  149,    0,  148,  149,    0,  148,  149,    0,  148,  149,
-    0,  148,  149,  148,  149,   60,   60,  148,  149,   39,
-  148,  149,   25,   25,   25,   25,   25,   25,    0,   25,
-   25,   25,   25,   25,   25,   25,   25,   25,   25,   25,
-   25,   25,  148,  149,    0,   25,   25,    0,   25,   25,
-   25,   39,  148,  149,   39,   25,   25,   25,   25,   25,
-   57,  154,   25,   25,  168,   84,    0,  148,  149,   25,
-   85,    0,    0,   25,    0,   25,   25,    0,   57,  163,
-    0,    0,  164,  148,  149,  165,  166,  167,    0,    0,
-   18,   18,   18,   18,   18,   18,  150,   18,   18,   18,
-   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
-    0,    0,   57,   18,   18,    0,   18,   18,   18,  148,
-  149,    0,    0,   18,   18,   18,   18,   18,    0,    0,
-   18,   18,  168,    0,    0,    0,    0,   18,  148,  149,
-    0,   18,  168,   18,   18,   89,  156,    0,    0,  156,
-  156,  156,    0,  156,  143,  156,  156,  143,  156,  118,
-  120,  108,    0,    0,  150,    0,  117,    0,  123,    0,
-    0,  143,  143,    0,  150,  253,  143,  156,    0,    0,
-  137,  138,  139,  140,   39,   39,   39,   39,   39,   39,
-    0,   39,   39,   39,    0,    0,    0,   39,    0,  120,
-   39,   39,   39,   39,  143,    0,  143,   39,   39,    0,
-   39,   39,   39,  157,    0,    0,    0,   39,   39,   39,
-   39,   39,  168,    0,   39,   39,  204,  120,    4,    5,
-    6,   39,    7,    8,  210,   39,  143,   39,   39,  156,
-  157,  168,    0,  157,  157,  157,    0,  157,  102,  157,
-  157,  102,  157,    0,  150,    0,    0,    0,  152,  153,
-  154,  155,    0,    0,    0,  102,  102,    0,    0,    0,
-  102,  157,    0,  150,  160,  161,    0,  162,  163,    0,
-    0,  164,    0,    0,  165,  166,  167,    0,    0,    0,
-  120,   57,   57,   57,   57,  120,    0,    0,    0,   51,
-  102,    0,   61,   63,   47,    0,   56,    0,   64,   59,
-    0,   58,    0,   57,   57,    0,    4,    5,    6,    0,
-    7,    8,    0,    0,    0,   57,  152,  153,  154,  155,
-   62,    0,    0,  157,    0,    0,  152,  153,  154,  155,
-  158,  159,  160,  161,    0,  162,  163,    0,    0,  164,
-    0,    0,  165,  166,  167,  162,  163,   60,    0,  164,
-    0,    0,  165,  166,  167,    0,    0,    0,    0,    0,
-  156,  156,  156,  156,  156,    0,  156,  156,  156,    0,
-    0,    0,  156,    0,    0,  143,  143,  143,  143,   23,
-    0,    0,   52,  156,  143,  156,  156,  156,  143,  143,
-  143,  143,  156,  156,  156,  156,  156,  143,  143,  156,
-  156,  143,  143,  143,  143,  143,  156,  143,  143,    0,
-  156,  143,  156,  156,  143,  143,  143,  168,    0,    0,
-    0,  151,    0,    0,    0,  152,  153,  154,  155,  164,
-    0,    0,  165,  166,  167,    0,    0,    0,  156,  158,
-  159,  160,  161,    0,  162,  163,    0,    0,  164,  150,
-    0,  165,  166,  167,  157,  157,  157,  157,  157,    0,
-  157,  157,  157,    0,    0,    0,  157,    0,    0,  102,
-  102,  102,  102,    0,    0,    0,    0,  157,  102,  157,
-  157,  157,  102,  102,  102,  102,  157,  157,  157,  157,
-  157,  102,  102,  157,  157,  102,  102,  102,  102,  102,
-  157,  102,  102,    0,  157,  102,  157,  157,  102,  102,
-  102,  168,   22,   24,   25,   26,   27,   28,    0,   29,
-   30,   31,    0,   56,    0,   32,   56,    0,   33,   34,
-   35,   36,    0,    0,    0,   37,   38,    0,   39,   40,
-   41,   56,    0,  150,    0,   42,   43,   44,   45,   46,
-    0,    0,   48,   49,    0,    0,    0,    0,    0,   50,
-   87,   87,    0,   53,   39,   54,   55,   39,   39,   39,
-    0,   39,  103,   39,   39,   56,   39,   87,  112,    0,
-    0,    0,   87,    0,  121,  144,  145,  146,  147,    0,
-   39,    0,    0,    0,    0,   39,   87,   87,   87,   87,
-    0,    0,    0,    0,    0,    0,    0,  148,  149,    0,
-    0,    0,    0,  154,  155,    0,    0,    0,    0,    0,
-   51,    0,   39,   61,   63,   47,    0,   56,    0,   64,
-   59,  163,   58,    0,  164,    0,    0,  165,  166,  167,
-    0,    0,  121,    0,    0,    0,    0,    0,    0,    0,
-    0,   62,    0,    0,   39,    0,    0,   39,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,   51,    0,   60,   61,
-   63,   47,    0,   56,    0,   64,   59,    0,   58,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,  240,    0,    0,    0,    0,   62,    0,    0,
-   23,    0,    0,   52,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,  163,    0,    0,  164,    0,
-    0,  165,  166,  167,   60,    0,    0,    0,    0,   51,
-    0,    0,   61,   63,   47,    0,   56,    0,   64,   59,
-    0,   58,    0,    0,   56,   56,   56,   56,    0,    0,
-    0,    0,    0,    0,    0,  114,   23,    0,    0,   52,
-   62,    0,    0,    0,    0,    0,   56,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,   39,   39,   39,
-   39,   39,   39,    0,   39,   39,   39,   60,    0,    0,
-   39,    0,    0,   39,   39,   39,   39,    0,    0,    0,
-   39,   39,    0,   39,   39,   39,    0,    0,    0,    0,
-   39,   39,   39,   39,   39,    0,    0,   39,   39,    0,
-  168,  157,   52,    0,   39,    0,    0,    0,   39,    0,
-   39,   39,    0,    0,  119,   25,   26,   27,   28,   85,
-   29,   30,   31,    0,    0,    0,   32,    0,    0,  168,
-  320,    0,  150,    0,    0,    0,    0,   38,    0,   39,
-   40,   41,    0,    0,    0,    0,   42,   43,   44,   45,
-   46,    0,  157,   48,   49,    0,    0,    0,    0,    0,
-   50,  150,    0,    0,   53,    0,   54,   55,    0,    0,
-  109,   25,   26,   27,   28,    0,   29,   30,   31,    0,
-  168,    0,   32,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,   38,    0,   39,   40,   41,    0,    0,
-    0,    0,   42,   43,   44,   45,   46,    0,    0,   48,
-   49,  135,  150,    0,  135,    0,   50,    0,    0,    0,
-   53,    0,   54,   55,    0,    0,    0,    0,  135,  135,
-    0,    0,    0,   24,   25,   26,   27,   28,  168,   29,
-   30,   31,    0,   51,    0,   32,   61,   63,   47,    0,
-   56,    0,   64,   59,    0,   58,   38,    0,   39,   40,
-   41,    0,    0,  135,    0,   42,   43,   44,   45,   46,
-  150,    0,   48,   49,   62,    0,    0,    0,    0,   50,
-    0,    0,    0,   53,    0,   54,   55,    0,    0,    0,
-    0,    0,    0,    0,  152,    0,  154,  155,    0,   51,
-    0,   60,   61,   63,   47,    0,   56,  131,   64,   59,
-    0,   58,    0,  162,  163,    0,    0,  164,    0,  151,
-  165,  166,  167,  152,  153,  154,  155,    0,    0,    0,
-   62,    0,    0,   23,    0,    0,   52,  158,  159,  160,
-  161,    0,  162,  163,    0,    0,  164,    0,    0,  165,
-  166,  167,    0,    0,    0,   51,    0,   60,   61,   63,
-   47,    0,   56,    0,   64,   59,    0,   58,    0,    0,
-  151,    0,    0,    0,  152,  153,  154,  155,    0,    0,
-    0,    0,    0,    0,    0,    0,   62,  156,  158,  159,
-  160,  161,   52,  162,  163,    0,    0,  164,    0,    0,
-  165,  166,  167,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,   60,    0,  135,    0,    0,   51,    0,
-    0,   61,   63,   47,    0,   56,    0,   64,   59,    0,
-   58,    0,    0,    0,  154,  155,    0,    0,    0,    0,
-    0,    0,  135,  135,  135,  135,    0,    0,   52,   62,
-    0,  162,  163,    0,    0,  164,    0,    0,  165,  166,
-  167,    0,    0,    0,  135,  135,    0,   24,   25,   26,
-   27,   28,    0,   29,   30,   31,   60,    0,    0,   32,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-   38,    0,   39,   40,   41,    0,    0,    0,    0,   42,
-   43,   44,   45,   46,    0,    0,   48,   49,    0,    0,
-    0,   52,    0,   50,    0,    0,    0,   53,    0,   54,
-   55,    0,    0,   24,   25,   26,   27,   28,    0,   29,
-   30,   31,    0,  168,    0,   32,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,   38,    0,   39,   40,
-   41,    0,    0,    0,    0,   42,   43,   44,   45,   46,
-    0,    0,   48,   49,  168,  150,    0,    0,    0,   50,
-    0,   82,    0,   53,   82,   54,   55,    0,    0,   24,
-   25,   26,   27,   28,    0,   29,   30,   31,   82,   82,
-    0,   32,    0,   82,    0,    0,  150,    0,    0,    0,
-    0,    0,   38,    0,   39,   40,   41,    0,    0,    0,
-    0,   42,   43,   44,   45,   46,    0,    0,   48,   49,
-    0,  130,    0,   82,  130,   50,    0,    0,    0,   53,
-    0,   54,   55,    0,    0,    0,    0,    0,  130,  130,
-    0,   22,   24,   25,   26,   27,   28,    0,   29,   30,
-   31,    0,   51,    0,   32,   61,   63,   47,    0,   56,
-  200,   64,   59,    0,   58,   38,    0,   39,   40,   41,
-    0,    0,    0,  130,   42,   43,   44,   45,   46,    0,
-    0,   48,   49,   62,    0,    0,    0,    0,   50,    0,
-    0,    0,   53,    0,   54,   55,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,   51,    0,
-   60,   61,   63,   47,    0,   56,  248,   64,   59,    0,
-   58,    0,    0,    0,    0,    0,    0,  152,  153,  154,
-  155,    0,    0,    0,    0,    0,    0,    0,    0,   62,
-    0,    0,  159,  160,  161,   52,  162,  163,    0,    0,
-  164,    0,    0,  165,  166,  167,    0,    0,  152,  153,
-  154,  155,    0,    0,   51,    0,   60,   61,   63,   47,
-    0,   56,  276,   64,   59,  161,   58,  162,  163,    0,
-    0,  164,    0,    0,  165,  166,  167,    0,    0,    0,
-    0,    0,    0,    0,    0,   62,    0,    0,    0,    0,
-    0,   52,   82,   82,   82,   82,    0,    0,    0,    0,
-    0,   82,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,   60,    0,   82,   82,    0,   51,   82,   82,
-   61,   63,   47,    0,   56,  278,   64,   59,    0,   58,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,  130,  130,  130,  130,    0,   52,   62,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,  130,  130,   24,   25,   26,   27,
-   28,    0,   29,   30,   31,   60,    0,    0,   32,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,   38,
-    0,   39,   40,   41,    0,    0,    0,    0,   42,   43,
-   44,   45,   46,    0,    0,   48,   49,    0,    0,    0,
-   52,    0,   50,    0,  136,    0,   53,  136,   54,   55,
-    0,    0,   24,   25,   26,   27,   28,    0,   29,   30,
-   31,  136,  136,    0,   32,    0,  136,    0,    0,    0,
-    0,    0,    0,    0,    0,   38,    0,   39,   40,   41,
-    0,    0,    0,    0,   42,   43,   44,   45,   46,    0,
-    0,   48,   49,    0,  136,    0,  136,    0,   50,    0,
-  119,    0,   53,  119,   54,   55,    0,    0,   24,   25,
-   26,   27,   28,    0,   29,   30,   31,  119,  119,    0,
-   32,    0,  119,    0,    0,    0,  136,    0,    0,    0,
-    0,   38,    0,   39,   40,   41,    0,    0,    0,    0,
-   42,   43,   44,   45,   46,    0,    0,   48,   49,    0,
-  119,    0,  119,    0,   50,    0,    0,    0,   53,    0,
-   54,   55,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,   24,   25,   26,   27,   28,    0,   29,   30,   31,
-    0,   51,  119,   32,   61,   63,   47,    0,   56,    0,
-   64,   59,    0,   58,   38,    0,   39,   40,   41,    0,
-    0,    0,    0,   42,   43,   44,   45,   46,    0,    0,
-   48,   49,   62,    0,    0,    0,    0,   50,    0,    0,
-    0,   53,    0,   54,   55,    0,    0,    0,    0,    0,
-  143,    0,    0,  143,    0,    0,    0,    0,    0,   60,
-    0,    0,    0,    0,    0,    0,    0,  143,  143,    0,
-    0,    0,  143,    0,    0,    0,    0,    0,    0,    0,
+#define YYTABLESIZE 4333
+dEXT short yytable[] = {                                      69,
+   62,  280,  274,   62,  105,  214,  183,   64,  170,   20,
+   64,   62,  299,   90,   23,   15,   90,  256,   18,  213,
+  208,  172,   96,   82,  301,   64,   84,   98,  100,  102,
+   90,   90,  124,   15,   83,   90,   18,   83,  303,  125,
+  152,  270,  271,  134,  283,   91,  305,  138,  174,  320,
+  252,   83,   83,  171,  284,  321,   83,  322,  240,   64,
+   57,   83,  117,  118,   27,   90,  189,   92,  191,  126,
+  193,  172,  195,  184,  197,  198,   42,  210,  108,  294,
+  173,  139,  140,  141,  142,  319,   83,    4,    5,    6,
+  238,    7,    8,  109,   42,  202,  203,   27,   23,  110,
+   27,   27,   27,  171,   27,   23,   27,   27,  211,   27,
+   23,   23,   23,  300,   23,  302,  144,  338,  175,  340,
+  150,  151,  257,   27,   57,  258,  304,  176,   27,  205,
+  329,   16,  216,  217,  219,  220,  221,  222,  223,  327,
+  178,   18,  349,   21,  159,  352,   23,  177,   80,   16,
+   17,  182,  180,  185,  199,   27,  243,  244,  245,  246,
+  247,  248,  250,   20,  362,  254,   94,   95,   17,  282,
+  259,  203,  170,  200,   41,  261,  207,  217,  285,   62,
+  209,  217,  170,  212,  277,  291,  293,   27,  170,   27,
+   27,  286,   41,  288,  290,   43,   20,  323,  292,   20,
+   20,   20,  151,   20,  152,   20,   20,   19,   20,  150,
+  151,  328,  298,   15,  152,  306,  150,  151,  307,    2,
+  152,  309,   20,  310,  296,  239,  297,   20,  150,  151,
+  311,  169,   86,   68,  312,  344,   68,   87,   64,   64,
+   64,   64,  150,  151,   90,   90,   90,   90,  314,  316,
+   68,   68,   47,   90,   20,   47,   47,   47,  350,   47,
+  104,   47,   47,   64,   47,   83,   83,   83,   83,   90,
+   90,  315,   90,   90,   83,  150,  151,  317,   47,  324,
+   83,   83,  318,   47,  203,   68,   20,  325,   20,   20,
+   83,   83,  330,   83,   83,   83,   83,   83,   83,  331,
+  150,  151,  150,  151,  261,  150,  151,  150,  151,  332,
+   47,  150,  151,  150,  151,  150,  151,  150,  151,  343,
+   27,   27,   27,   27,   27,   27,  345,   27,   27,   27,
+   27,   27,   27,   27,   27,   27,   27,   27,   27,   27,
+  346,   69,   47,   27,   27,   47,   27,   27,   27,   27,
+   27,  150,  151,  150,  151,   27,   27,   27,   27,   27,
+   27,  351,  153,   27,  150,  151,  353,  355,  154,  155,
+  156,  157,   27,   65,   27,   27,  364,  150,  151,   57,
+  156,  158,  160,  161,  162,  163,  164,  165,  155,  153,
+  166,   65,   40,  167,  168,  169,   38,  165,  156,   43,
+  166,  150,  151,  167,  168,  169,  166,   40,   38,  167,
+  168,  169,   77,  218,  188,  150,  151,  360,  170,   20,
+   20,   20,   20,   20,   20,   65,   20,   20,   20,   20,
+   20,   20,   20,   20,   20,   20,   20,   20,   20,  150,
+  151,  342,   20,   20,  273,   20,   20,   20,   20,   20,
+  152,    0,    0,    0,   20,   20,   20,   20,   20,   20,
+    0,    0,   20,  170,   68,   68,   68,   68,    0,    0,
+    0,   20,    0,   20,   20,   47,   47,   47,   47,   47,
+   47,  255,   47,   47,   47,    0,    0,    0,   47,   68,
+   68,   47,   47,   47,   47,  152,    0,    0,   47,   47,
+    0,   47,   47,   47,   47,   47,    0,    0,    0,  170,
+   47,   47,   47,   47,   47,   47,    0,    0,   47,    0,
+    0,    0,  357,    0,  170,    0,    0,   47,  167,   47,
+   47,  167,  167,  167,    0,  167,  151,  167,  167,  151,
+  167,  152,    0,   89,   89,  264,    0,  267,  146,  147,
+  148,  149,    0,  151,  151,  106,  152,    0,  151,  167,
+    0,  114,   89,  122,    0,    0,    0,    0,   89,    0,
+    0,    0,    0,  150,  151,    0,    0,    0,    0,    0,
+   89,   89,   89,   89,    0,    0,  151,    0,  151,  168,
+    0,    0,  168,  168,  168,    0,  168,  110,  168,  168,
+  110,  168,    0,    0,   65,   65,   65,   65,    0,    0,
+    0,    0,    0,    0,  110,  110,  156,  157,  151,  110,
+  168,  167,    4,    5,    6,    0,    7,    8,  114,   65,
+   65,    0,  164,  165,    0,    0,  166,    0,    0,  167,
+  168,  169,    0,    0,    0,    0,    0,    0,   52,  110,
+    0,   62,   64,   50,    0,   57,    0,   65,   60,  154,
+   59,  156,  157,    4,    5,    6,    0,    7,    8,    0,
+    0,    0,    0,    0,   58,    0,    0,  164,  165,   63,
+    0,  166,  168,    0,  167,  168,  169,  241,    0,  347,
+  348,    0,    0,    0,    0,    0,  354,    0,    0,  100,
+    0,    0,  100,    0,    0,    0,   61,  156,  157,    0,
+    0,  361,    0,    0,  363,  275,  100,  100,    0,    0,
+    0,  100,    0,    0,  165,    0,    0,  166,    0,    0,
+  167,  168,  169,    0,    0,    0,    0,    0,   23,  165,
+    0,   53,  166,    0,    0,  167,  168,  169,    0,    0,
+    0,  100,  167,  167,  167,  167,  167,    0,  167,  167,
+  167,    0,    0,    0,  167,    0,    0,  151,  151,  151,
+  151,    0,    0,    0,    0,  167,  151,  167,  167,  167,
+  167,  167,  151,  151,  151,  151,  167,  167,  167,  167,
+  167,  167,  151,  151,  167,  151,  151,  151,  151,  151,
+  151,  151,    0,  167,  151,  167,  167,  151,  151,  151,
+    0,    0,    0,  168,  168,  168,  168,  168,    0,  168,
+  168,  168,    0,    0,    0,  168,    0,    0,  110,  110,
+  110,  110,    0,    0,    0,    0,  168,  110,  168,  168,
+  168,  168,  168,  110,  110,  110,  110,  168,  168,  168,
+  168,  168,  168,  110,  110,  168,  110,  110,  110,  110,
+  110,  110,  110,    0,  168,  110,  168,  168,  110,  110,
+  110,   22,   24,   25,   26,   27,   28,    0,   29,   30,
+   31,    0,    0,    0,   32,    0,    0,   33,   34,   35,
+   36,    0,    0,    0,   37,   38,    0,   39,   40,   41,
+   42,   43,    0,    0,    0,  170,   44,   45,   46,   47,
+   48,   49,   47,    0,   51,   47,   47,   47,    0,   47,
+    0,   47,   47,   54,   47,   55,   56,  115,    0,    0,
+  100,  100,  100,  100,    0,  127,    0,  152,   47,  100,
+    0,    0,    0,   47,    0,  100,  100,  100,  100,    0,
+    0,    0,    0,    0,    0,  100,  100,    0,  100,  100,
+  100,  100,  100,  100,  100,    0,    0,  100,   52,    0,
+   47,   62,   64,   50,  115,   57,    0,   65,   60,    0,
+   59,    0,    0,    0,    0,    0,    0,    0,  334,  335,
+  336,    0,    0,    0,  339,    0,  341,    0,    0,   63,
+    0,  206,   47,    0,    0,   47,    0,    0,    0,  115,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,   52,  136,  136,  136,  136,    0,
-  143,    0,  143,    0,  136,    0,    0,    0,  136,  136,
-  136,  136,    0,    0,    0,    0,    0,  136,  136,    0,
-    0,  136,  136,  136,  136,  136,    0,  136,  136,    0,
-    0,  136,  143,    0,  136,  136,  136,    0,    0,    0,
-    0,  129,    0,    0,  129,    0,    0,    0,    0,    0,
-    0,  119,  119,  119,  119,    0,    0,    0,  129,  129,
-  119,    0,    0,  129,  119,  119,  119,  119,    0,    0,
-    0,    0,    0,  119,  119,    0,    0,  119,  119,  119,
-  119,  119,    0,  119,  119,    0,  104,  119,    0,  104,
-  119,  119,  119,  129,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,  104,  104,    0,    0,    0,  104,    0,
+    0,    0,  356,    0,   52,    0,   61,   62,   64,   50,
+  358,   57,  359,   65,   60,    0,   59,    0,    0,    0,
+    0,    0,    0,  365,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,   63,    0,    0,   23,    0,
+    0,   53,    0,    0,    0,    0,  115,    0,    0,    0,
+    0,  115,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,   61,    0,    0,    0,    0,   52,    0,    0,
+   62,   64,   50,    0,   57,    0,   65,   60,    0,   59,
+    0,  154,  155,  156,  157,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,   23,    0,    0,   53,   63,  164,
+  165,    0,    0,  166,    0,    0,  167,  168,  169,    0,
+    0,    0,    0,    0,    0,   47,   47,   47,   47,   47,
+   47,    0,   47,   47,   47,   61,    0,    0,   47,    0,
+    0,   47,   47,   47,   47,    0,    0,    0,   47,   47,
+    0,   47,   47,   47,   47,   47,    0,    0,    0,    0,
+   47,   47,   47,   47,   47,   47,    0,   23,   47,    0,
+   53,    0,  170,    0,    0,    0,  333,   47,    0,   47,
+   47,    0,  113,   25,   26,   27,   28,   87,   29,   30,
+   31,    0,    0,    0,   32,    0,    0,    0,  159,    0,
+    0,    0,    0,    0,  152,   38,    0,   39,   40,   41,
+   42,   43,    0,    0,    0,    0,   44,   45,   46,   47,
+   48,   49,    0,    0,   51,    0,  170,    0,    0,    0,
+    0,    0,    0,   54,    0,   55,   56,    0,   24,   25,
+   26,   27,   28,    0,   29,   30,   31,    0,    0,    0,
+   32,  295,    0,    0,    0,    0,  159,    0,  152,    0,
+    0,   38,    0,   39,   40,   41,   42,   43,    0,    0,
+    0,    0,   44,   45,   46,   47,   48,   49,    0,    0,
+   51,    0,    0,    0,  170,    0,    0,    0,    0,   54,
+    0,   55,   56,    0,    0,    0,    0,   84,    0,    0,
+   84,  119,   25,   26,   27,   28,    0,   29,   30,   31,
+    0,    0,    0,   32,   84,   84,  152,    0,    0,   84,
+    0,    0,    0,    0,   38,    0,   39,   40,   41,   42,
+   43,    0,    0,    0,    0,   44,   45,   46,   47,   48,
+   49,   52,    0,   51,   62,   64,   50,    0,   57,   84,
+   65,   60,   54,   59,   55,   56,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,  123,  154,  155,
+  156,  157,   63,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,  160,  161,  162,  163,  164,  165,    0,    0,
+  166,    0,    0,  167,  168,  169,    0,   52,    0,   61,
+   62,   64,   50,    0,   57,  133,   65,   60,    0,   59,
+    0,    0,    0,    0,    0,    0,  153,    0,    0,    0,
+    0,    0,  154,  155,  156,  157,    0,    0,   63,    0,
+    0,    0,    0,    0,   53,  158,  160,  161,  162,  163,
+  164,  165,    0,    0,  166,    0,    0,  167,  168,  169,
+    0,    0,    0,   52,    0,   61,   62,   64,   50,    0,
+   57,    0,   65,   60,    0,   59,    0,    0,    0,    0,
+    0,    0,    0,    0,  153,    0,    0,    0,    0,    0,
+  154,  155,  156,  157,   63,    0,    0,    0,    0,    0,
+   53,    0,    0,  158,  160,  161,  162,  163,  164,  165,
+    0,    0,  166,    0,    0,  167,  168,  169,    0,    0,
+    0,   61,   52,  137,    0,   62,   64,   50,    0,   57,
+  201,   65,   60,    0,   59,    0,    0,    0,   84,   84,
+   84,   84,    0,    0,    0,    0,    0,   84,    0,    0,
+    0,    0,    0,   63,   84,    0,   53,    0,    0,    0,
+    0,    0,    0,   84,   84,    0,   84,   84,   84,   84,
+   84,   85,    0,    0,   85,   24,   25,   26,   27,   28,
+   61,   29,   30,   31,    0,    0,    0,   32,   85,   85,
+    0,    0,    0,   85,    0,    0,    0,    0,   38,    0,
+   39,   40,   41,   42,   43,    0,    0,    0,    0,   44,
+   45,   46,   47,   48,   49,   53,    0,   51,    0,    0,
+    0,    0,    0,   85,    0,    0,   54,   86,   55,   56,
+   86,   24,   25,   26,   27,   28,    0,   29,   30,   31,
+    0,    0,    0,   32,   86,   86,    0,    0,    0,   86,
+    0,    0,    0,    0,   38,    0,   39,   40,   41,   42,
+   43,    0,    0,    0,    0,   44,   45,   46,   47,   48,
+   49,    0,    0,   51,    0,    0,    0,    0,    0,   86,
+    0,    0,   54,    0,   55,   56,    0,   24,   25,   26,
+   27,   28,    0,   29,   30,   31,    0,   52,    0,   32,
+   62,   64,   50,    0,   57,  249,   65,   60,    0,   59,
+   38,    0,   39,   40,   41,   42,   43,    0,    0,    0,
+    0,   44,   45,   46,   47,   48,   49,    0,   63,   51,
+    0,    0,    0,    0,    0,    0,    0,    0,   54,    0,
+   55,   56,    0,    0,    0,    0,   24,   25,   26,   27,
+   28,    0,   29,   30,   31,   61,   52,    0,   32,   62,
+   64,   50,    0,   57,    0,   65,   60,    0,   59,   38,
+    0,   39,   40,   41,   42,   43,    0,    0,    0,    0,
+   44,   45,   46,   47,   48,   49,    0,   63,   51,    0,
+   53,    0,    0,    0,    0,    0,    0,   54,    0,   55,
+   56,    0,   85,   85,   85,   85,    0,    0,    0,    0,
+    0,   85,   52,    0,   61,   62,   64,   50,    0,   57,
+  287,   65,   60,    0,   59,    0,    0,   85,   85,    0,
+   85,   85,   85,   85,   85,    0,    0,    0,    0,    0,
+    0,    0,    0,   63,    0,    0,    0,    0,    0,   53,
+    0,    0,    0,    0,    0,    0,    0,    0,   86,   86,
+   86,   86,    0,    0,    0,    0,    0,   86,   52,    0,
+   61,   62,   64,   50,    0,   57,  289,   65,   60,    0,
+   59,    0,    0,   86,   86,    0,   86,   86,   86,   86,
+   86,    0,    0,    0,    0,    0,    0,    0,    0,   63,
+    0,    0,    0,    0,    0,   53,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,  129,    0,   24,   25,   26,   27,   28,
-    0,   29,   30,   31,    0,    0,  104,   32,  104,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,   38,    0,
-   39,   40,   41,    0,    0,    0,    0,   42,   43,   44,
-   45,   46,    0,    0,   48,   49,    0,    0,    0,    0,
-    0,   50,    0,    0,    0,   53,    0,   54,   55,    0,
-    0,  143,  143,  143,  143,    0,    0,    0,    0,    0,
-  143,    0,    0,    0,  143,  143,  143,  143,    0,    0,
-    0,    0,    0,  143,  143,    0,    0,  143,  143,  143,
-  143,  143,    0,  143,  143,  145,    0,  143,  145,    0,
-  143,  143,  143,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,  145,  145,    0,    0,    0,  145,    0,    0,
+    0,   24,   25,   26,   27,   28,   61,   29,   30,   31,
+    0,   52,    0,   32,   62,   64,   50,    0,   57,    0,
+   65,   60,    0,   59,   38,    0,   39,   40,   41,   42,
+   43,    0,    0,    0,    0,   44,   45,   46,   47,   48,
+   49,   53,   63,   51,    0,    0,    0,    0,    0,    0,
+    0,    0,   54,    0,   55,   56,    0,    0,    0,   22,
+   24,   25,   26,   27,   28,    0,   29,   30,   31,   61,
+    0,    0,   32,   91,    0,    0,   91,    0,    0,    0,
+    0,    0,    0,   38,    0,   39,   40,   41,   42,   43,
+   91,   91,    0,    0,   44,   45,   46,   47,   48,   49,
+    0,    0,   51,    0,   53,    0,    0,    0,    0,  144,
+    0,   54,  144,   55,   56,    0,   24,   25,   26,   27,
+   28,    0,   29,   30,   31,   91,  144,  144,   32,    0,
+    0,  144,    0,    0,    0,    0,    0,    0,    0,   38,
+    0,   39,   40,   41,   42,   43,    0,    0,    0,    0,
+   44,   45,   46,   47,   48,   49,    0,    0,   51,  144,
+    0,  144,    0,    0,    0,    0,    0,   54,  127,   55,
+   56,  127,   24,   25,   26,   27,   28,    0,   29,   30,
+   31,    0,    0,    0,   32,  127,  127,    0,    0,    0,
+  127,  144,    0,    0,    0,   38,    0,   39,   40,   41,
+   42,   43,    0,    0,    0,    0,   44,   45,   46,   47,
+   48,   49,    0,    0,   51,    0,    0,    0,  127,    0,
+  127,    0,    0,   54,    0,   55,   56,    0,    0,    0,
+    0,  151,    0,    0,  151,   24,   25,   26,   27,   28,
+    0,   29,   30,   31,    0,    0,    0,   32,  151,  151,
+  127,    0,    0,  151,    0,    0,    0,    0,   38,    0,
+   39,   40,   41,   42,   43,    0,    0,    0,    0,   44,
+   45,   46,   47,   48,   49,    0,    0,   51,    0,  137,
+    0,  151,  137,  151,    0,    0,   54,    0,   55,   56,
+    0,    0,    0,    0,    0,    0,  137,  137,    0,    0,
+    0,  137,    0,    0,   91,   91,   91,   91,    0,    0,
+    0,    0,    0,  151,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,   91,
+   91,  137,   91,    0,    0,    0,    0,    0,    0,    0,
+  144,  144,  144,  144,    0,  112,    0,    0,  112,  144,
+    0,    0,    0,    0,    0,  144,  144,  144,  144,    0,
+    0,  137,  112,  112,    0,  144,  144,  112,  144,  144,
+  144,  144,  144,  144,  144,    0,    0,  144,    0,    0,
+  144,  144,  144,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,  112,    0,  112,    0,  127,
+  127,  127,  127,    0,  153,    0,    0,  153,  127,    0,
+    0,    0,    0,    0,  127,  127,  127,  127,    0,    0,
+    0,  153,  153,    0,  127,  127,  153,  127,  127,  127,
+  127,  127,  127,  127,    0,    0,  127,    0,    0,  127,
+  127,  127,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,  153,    0,    0,    0,
+    0,    0,  151,  151,  151,  151,    0,    0,    0,    0,
+    0,  151,    0,    0,    0,    0,    0,  151,  151,  151,
+  151,    0,    0,    0,    0,    0,  153,  151,  151,    0,
+  151,  151,  151,  151,  151,  151,  151,    0,    0,  151,
+    0,    0,  151,  151,  151,    0,    0,    0,    0,    0,
+  137,  137,  137,  137,    0,  154,    0,    0,    0,  137,
+    0,    0,    0,    0,    0,  137,  137,  137,  137,    0,
+    0,    0,  154,  154,    0,  137,  137,  154,  137,  137,
+  137,  137,  137,  137,  137,    0,    0,  137,    0,    0,
+  137,  137,  137,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,  154,    0,  154,    0,    0,
+    0,    0,    0,    0,    0,    0,  112,  112,  112,  112,
+    0,    0,    0,    0,    0,  112,    0,    0,    0,    0,
+    0,  112,  112,  112,  112,    0,    0,  154,    0,    0,
+  170,  112,  112,    0,  112,  112,  112,  112,  112,  112,
+  112,    0,    0,  112,    0,    0,  112,  112,  112,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,  152,    0,    0,  153,  153,  153,  153,    0,
+  139,    0,    0,    0,  153,    0,    0,    0,    0,    0,
+  153,  153,  153,  153,    0,    0,    0,  139,  139,    0,
+  153,  153,  139,  153,  153,  153,  153,  153,  153,  153,
+    0,    0,  153,    0,    0,  153,  153,  153,    0,    0,
+    0,    0,    0,  104,    0,    0,  104,    0,    0,    0,
+  139,    0,  139,   88,    0,    0,   88,    0,    0,    0,
+  104,  104,    0,    0,    0,  104,    0,    0,    0,    0,
+   88,   88,    0,    0,    0,   88,    0,    0,    0,    0,
+    0,    0,  139,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,  104,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,   88,  154,  154,  154,  154,
+    0,   66,    0,    0,   66,  154,    0,    0,    0,    0,
+    0,  154,  154,  154,  154,  104,    0,    0,   66,   66,
+    0,  154,  154,   66,  154,  154,  154,  154,  154,  154,
+  154,    0,    0,  154,    0,    0,  154,  154,  154,    0,
+    0,    0,    0,    0,   69,    0,  154,  155,  156,  157,
+    0,    0,    0,   66,    0,    0,    0,    0,    0,    0,
+    0,   69,   69,  163,  164,  165,   69,    0,  166,    0,
+    0,  167,  168,  169,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,   66,    0,    0,    0,    0,  103,    0,
+    0,  103,    0,    0,   69,    0,   69,    0,    0,    0,
+    0,    0,    0,    0,    0,  103,  103,    0,    0,    0,
+  103,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,  139,  139,  139,  139,    0,   69,    0,    0,    0,
+  139,    0,    0,    0,    0,    0,  139,  139,  139,  139,
+  103,    0,    0,    0,    0,    0,  139,  139,    0,  139,
+  139,  139,  139,  139,  139,  139,    0,    0,  139,    0,
+    0,  139,  139,  139,  104,  104,  104,  104,    0,  140,
+  103,    0,  140,  104,   88,   88,   88,   88,    0,  104,
+  104,  104,  104,    0,    0,    0,  140,  140,    0,  104,
+  104,  140,  104,  104,  104,  104,  104,  104,  104,   88,
+   88,  104,   88,    0,  104,  104,  104,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,   83,    0,    0,   83,    0,  145,    0,    0,
-    0,    0,  129,  129,  129,  129,    0,    0,    0,   83,
-   83,  129,    0,    0,    0,  129,  129,  129,  129,    0,
-    0,    0,    0,    0,  129,  129,    0,  145,  129,  129,
-  129,  129,  129,    0,  129,  129,    0,    0,  129,    0,
-    0,  129,  129,  129,   83,    0,    0,  104,  104,  104,
-  104,    0,    0,    0,    0,    0,  104,    0,    0,    0,
-  104,  104,  104,  104,    0,    0,    0,  131,    0,  104,
-  104,    0,    0,  104,  104,  104,  104,  104,    0,  104,
-  104,    0,    0,  104,  131,  131,  104,  104,  104,  131,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,  146,    0,    0,    0,    0,    0,  131,    0,  131,
-    0,    0,    0,    0,    0,    0,    0,    0,  146,  146,
-    0,    0,    0,  146,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,  131,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,  146,    0,  146,    0,    0,   96,    0,    0,   96,
-    0,    0,    0,    0,    0,    0,  145,  145,  145,  145,
-    0,    0,    0,   96,   96,  145,    0,    0,   96,  145,
-  145,  145,  145,  146,    0,    0,    0,    0,  145,  145,
-    0,    0,  145,  145,  145,  145,  145,    0,  145,  145,
-   58,    0,  145,   58,    0,  145,  145,  145,   96,    0,
-    0,    0,    0,   83,   83,   83,   83,   58,   58,    0,
-    0,    0,   58,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,   83,   83,    0,   96,   83,
-    0,    0,    0,   61,    0,    0,    0,    0,    0,    0,
-    0,    0,   58,    0,    0,    0,    0,    0,    0,    0,
-   61,   61,    0,    0,    0,   61,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,   58,    0,    0,    0,    0,    0,  131,  131,
-  131,  131,    0,   61,    0,   61,    0,  131,    0,    0,
-    0,  131,  131,  131,  131,   59,    0,    0,   59,    0,
-  131,  131,    0,    0,  131,  131,  131,  131,  131,    0,
-  131,  131,   59,   59,  131,   61,    0,  131,  131,  131,
-    0,    0,  146,  146,  146,  146,    0,    0,    0,    0,
-    0,  146,    0,    0,    0,  146,  146,  146,  146,    0,
-    0,    0,    0,    0,  146,  146,    0,   59,  146,  146,
-  146,  146,  146,    0,  146,  146,    0,    0,  146,    0,
-    0,  146,  146,  146,    0,    0,    0,  145,    0,    0,
-  145,    0,    0,    0,    0,    0,    0,   96,   96,   96,
-   96,    0,    0,    0,  145,  145,   96,    0,    0,  145,
-   96,   96,   96,   96,    0,    0,    0,    0,    0,   96,
-   96,    0,    0,   96,   96,   96,   96,   96,    0,   96,
-   96,  132,    0,   96,  132,    0,   96,   96,   96,  145,
-    0,   58,   58,   58,   58,    0,    0,    0,  132,  132,
-   58,    0,    0,  132,   58,   58,   58,   58,    0,    0,
-    0,    0,    0,   58,   58,    0,    0,   58,   58,   58,
-   58,   58,    0,   58,   58,    0,    0,   58,    0,    0,
-   58,   58,   58,  132,   61,   61,   61,   61,    0,  284,
-    0,    0,    0,   61,  157,    0,    0,   61,   61,   61,
-   61,    0,    0,    0,    0,    0,   61,   61,    0,    0,
-   61,   61,   61,   61,   61,   95,   61,   61,   95,    0,
-   61,    0,  168,   61,   61,   61,    0,    0,    0,    0,
+    0,  140,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,   66,   66,   66,   66,    0,  153,    0,    0,
+  153,   66,    0,    0,    0,    0,    0,   66,   66,   66,
+   66,    0,    0,    0,  153,  153,    0,   66,   66,  153,
+   66,   66,   66,   66,   66,   66,   66,    0,    0,   66,
+    0,    0,   66,   66,   66,   69,   69,   69,   69,    0,
+  110,    0,    0,  110,   69,    0,    0,    0,    0,  153,
+   69,   69,   69,   69,    0,    0,    0,  110,  110,    0,
+   69,   69,  110,   69,   69,   69,   69,   69,   69,   69,
+    0,    0,   69,    0,    0,   69,   69,   69,    0,  103,
+  103,  103,  103,    0,  117,    0,    0,  117,  103,    0,
+    0,    0,  110,    0,  103,  103,  103,  103,    0,    0,
+    0,  117,  117,    0,  103,  103,  117,  103,  103,  103,
+  103,  103,  103,  103,    0,    0,  103,    0,    0,  103,
+  103,  103,    0,    0,    0,    0,    0,  101,    0,    0,
+  101,    0,    0,    0,    0,    0,  117,    0,    0,    0,
+    0,    0,    0,    0,  101,  101,    0,  138,    0,  101,
+  138,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+  140,  140,  140,  140,  138,  138,    0,    0,    0,  140,
+    0,    0,    0,    0,    0,  140,  140,  140,  140,  101,
+    0,    0,    0,    0,    0,  140,  140,    0,  140,  140,
+  140,  140,  140,  140,  140,   95,    0,  140,   95,  138,
+  140,  140,  140,    0,    0,    0,    0,    0,    0,    0,
     0,    0,   95,   95,    0,    0,    0,   95,    0,    0,
-    0,    0,    0,    0,    0,    0,   59,   59,   59,   59,
-    0,    0,    0,    0,  150,    0,    0,  102,    0,    0,
-  102,    0,    0,    0,    0,    0,    0,   95,   59,   59,
-    0,    0,    0,    0,  102,  102,    0,    0,    0,  102,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,   95,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,  109,  102,
-    0,  109,    0,    0,    0,    0,    0,    0,  145,  145,
-  145,  145,    0,    0,    0,  109,  109,  145,    0,    0,
-  109,  145,  145,  145,  145,    0,    0,    0,    0,    0,
-  145,  145,    0,    0,  145,  145,  145,  145,  145,    0,
-  145,  145,   92,    0,  145,   92,    0,  145,  145,  145,
-  109,    0,  132,  132,  132,  132,    0,    0,    0,   92,
-   92,  132,    0,    0,   92,  132,  132,  132,  132,    0,
-    0,    0,    0,    0,  132,  132,    0,    0,  132,  132,
-  132,  132,  132,   93,  132,  132,   93,    0,  132,    0,
-    0,  132,  132,  132,   92,    0,    0,    0,    0,    0,
-   93,   93,  151,    0,    0,   93,  152,  153,  154,  155,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,  156,
-  158,  159,  160,  161,    0,  162,  163,    0,    0,  164,
-    0,    0,  165,  166,  167,   93,   95,   95,   95,   95,
-    0,    0,    0,    0,    0,   95,    0,    0,    0,   95,
-   95,   95,   95,    0,    0,    0,    0,    0,   95,   95,
-    0,    0,   95,   95,   95,   95,   95,    0,   95,   95,
-    0,    0,   95,    0,    0,   95,   95,   95,  102,  102,
-  102,  102,    0,    0,    0,    0,    0,  102,    0,    0,
-    0,  102,  102,  102,  102,   71,    0,    0,   71,    0,
-  102,  102,    0,    0,  102,  102,  102,  102,  102,    0,
-  102,  102,   71,   71,  102,    0,    0,  102,  102,  102,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,  109,
-  109,  109,  109,    0,    0,    0,    0,    0,  109,    0,
-    0,    0,  109,  109,  109,  109,    0,   71,    0,    0,
-    0,  109,  109,    0,    0,  109,  109,  109,  109,  109,
-    0,  109,  109,    0,    0,  109,    0,    0,  109,  109,
-  109,    0,    0,   92,   92,   92,   92,    0,    0,    0,
-    0,    0,   92,    0,    0,    0,   92,   92,   92,   92,
-    0,    0,    0,    0,    0,   92,   92,    0,    0,   92,
-   92,   92,   92,   92,   87,   92,   92,   87,    0,   92,
-    0,    0,    0,    0,   93,   93,   93,   93,    0,    0,
-    0,   87,   87,   93,    0,    0,   87,   93,   93,   93,
-   93,    0,    0,    0,    0,    0,   93,   93,    0,    0,
-   93,   93,   93,   93,   93,   88,   93,   93,   88,    0,
-   93,    0,    0,    0,    0,    0,   87,    0,    0,    0,
-    0,    0,   88,   88,    0,    0,    0,   88,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,   89,    0,    0,   89,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,   88,   89,   89,
-    0,    0,    0,   89,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,   85,    0,    0,
-   85,    0,    0,    0,    0,    0,   71,   71,   71,   71,
-    0,    0,    0,   89,   85,   85,    0,    0,    0,   85,
-    0,    0,    0,    0,    0,    0,    0,    0,   71,   71,
-    0,    0,    0,   86,    0,    0,   86,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,   85,
-   86,   86,    0,    0,    0,   86,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,   84,
-    0,    0,   84,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,   86,   84,   84,    0,    0,
-    0,   84,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,   87,   87,   87,   87,    0,
-    0,   84,    0,    0,   87,    0,    0,    0,   87,   87,
-   87,   87,    0,    0,    0,    0,    0,   87,   87,    0,
-    0,   87,   87,   87,   87,   87,   72,   87,   87,   72,
-    0,    0,    0,    0,    0,    0,   88,   88,   88,   88,
-    0,    0,    0,   72,   72,   88,    0,    0,   72,   88,
-   88,   88,   88,    0,    0,    0,    0,    0,   88,   88,
-    0,    0,   88,   88,   88,   88,   88,    0,   88,   88,
-    0,    0,   89,   89,   89,   89,    0,    0,   72,    0,
-    0,   89,    0,    0,    0,   89,   89,   89,   89,    0,
-    0,    0,    0,    0,   89,   89,    0,    0,   89,   89,
-   89,   89,   89,    0,   89,   89,    0,    0,   85,   85,
-   85,   85,    0,    0,    0,    0,    0,   85,    0,    0,
-    0,   85,   85,   85,   85,    0,    0,    0,    0,    0,
-   85,   85,    0,    0,   85,   85,   85,   85,   85,    0,
-   85,   85,    0,    0,   86,   86,   86,   86,    0,    0,
-    0,    0,    0,   86,    0,    0,    0,   86,   86,   86,
-   86,    0,    0,    0,    0,    0,   86,   86,    0,    0,
-   86,   86,   86,   86,   86,    0,   86,   86,    0,    0,
-   84,   84,   84,   84,    0,    0,    0,    0,    0,   84,
-    0,    0,    0,   84,   84,   84,   84,   73,    0,    0,
-   73,    0,   84,   84,    0,    0,   84,   84,   84,   84,
-   84,    0,   84,   84,   73,   73,    0,    0,    0,   73,
+    0,    0,    0,    0,    0,    0,    0,    0,  153,  153,
+  153,  153,    0,   96,    0,    0,   96,  153,    0,    0,
+    0,    0,    0,  153,  153,  153,  153,   95,    0,    0,
+   96,   96,    0,  153,  153,   96,  153,  153,  153,  153,
+  153,  153,  153,    0,    0,  153,    0,    0,  153,  153,
+  153,  110,  110,  110,  110,    0,    0,    0,    0,    0,
+  110,    0,    0,    0,    0,   96,  110,  110,  110,  110,
+    0,    0,    0,    0,    0,    0,  110,  110,    0,  110,
+  110,  110,  110,  110,  110,  110,    0,    0,  110,    0,
+    0,  110,  110,  110,    0,  117,  117,  117,  117,    0,
+   97,    0,    0,   97,  117,    0,    0,    0,    0,    0,
+  117,  117,  117,  117,    0,    0,    0,   97,   97,    0,
+  117,  117,   97,  117,  117,  117,  117,  117,  117,  117,
+    0,    0,  117,    0,    0,  117,  117,  117,  101,  101,
+  101,  101,    0,    0,    0,    0,    0,  101,    0,    0,
+    0,    0,   97,  101,  101,  101,  101,    0,  138,  138,
+  138,  138,    0,  101,  101,   93,  101,  101,  101,  101,
+  101,  101,  101,  107,    0,  101,    0,  112,    0,    0,
+  121,    0,    0,  138,  138,    0,    0,  128,  129,  130,
+  131,  132,    0,    0,  135,  136,    0,    0,  170,    0,
+    0,  143,    0,    0,    0,    0,   95,   95,   95,   95,
+    0,   93,    0,    0,   93,   95,    0,    0,    0,    0,
+    0,   95,   95,   95,   95,    0,    0,  186,   93,   93,
+  152,   95,   95,   93,   95,   95,   95,   95,   95,   95,
+   95,    0,    0,    0,   96,   96,   96,   96,    0,    0,
+    0,    0,    0,   96,    0,    0,    0,    0,    0,   96,
+   96,   96,   96,   93,   94,    0,    0,   94,    0,   96,
+   96,    0,   96,   96,   96,   96,   96,   96,   96,    0,
+    0,   94,   94,    0,    0,    0,   94,    0,  224,  225,
+  226,  227,  228,  229,  230,  231,  232,  233,  234,  235,
+  236,  237,   92,    0,    0,   92,    0,    0,    0,    0,
+    0,    0,    0,  251,    0,    0,   94,    0,    0,   92,
+   92,    0,    0,    0,   92,    0,    0,    0,    0,    0,
+    0,   97,   97,   97,   97,    0,    0,    0,    0,    0,
+   97,    0,    0,    0,    0,    0,   97,   97,   97,   97,
+   80,    0,    0,   80,   92,    0,   97,   97,    0,   97,
+   97,   97,   97,   97,   97,   97,    0,   80,   80,    0,
+    0,    0,   80,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,   81,    0,    0,   81,
+    0,    0,    0,  308,  154,  155,  156,  157,    0,    0,
+    0,    0,   80,   81,   81,    0,    0,    0,   81,  161,
+  162,  163,  164,  165,    0,    0,  166,    0,    0,  167,
+  168,  169,    0,    0,    0,    0,    0,    0,    0,    0,
+  326,   82,    0,    0,   82,    0,    0,    0,   81,    0,
+    0,    0,   93,   93,   93,   93,    0,    0,   82,   82,
+    0,   93,    0,   82,    0,    0,    0,   93,   93,   93,
+   93,    0,    0,    0,    0,    0,    0,   93,   93,    0,
+   93,   93,   93,   93,   93,   93,   93,    0,    0,    0,
+    0,    0,    0,   82,    0,  143,    0,    0,  143,    0,
+    0,    0,    0,    0,    0,   94,   94,   94,   94,    0,
+    0,    0,  143,  143,   94,    0,    0,  143,    0,    0,
+   94,   94,   94,   94,    0,    0,    0,    0,    0,    0,
+   94,   94,    0,   94,   94,   94,   94,   94,   94,   94,
+    0,    0,    0,   92,   92,   92,   92,  143,    0,    0,
+    0,    0,   92,    0,    0,    0,    0,    0,   92,   92,
+   92,   92,  142,    0,    0,  142,    0,    0,   92,   92,
+    0,   92,   92,   92,   92,   92,   92,   92,    0,  142,
+  142,    0,    0,    0,  142,    0,    0,    0,    0,    0,
+    0,   80,   80,   80,   80,   79,    0,    0,   79,    0,
+   80,    0,    0,    0,    0,    0,   80,   80,   80,   80,
+    0,    0,   79,   79,  142,  131,   80,   80,  131,   80,
+   80,   80,   80,   80,   80,   80,    0,   81,   81,   81,
+   81,    0,  131,  131,    0,    0,   81,  131,    0,    0,
+    0,    0,   81,   81,   81,   81,    0,   79,    0,    0,
+    0,    0,   81,   81,    0,   81,   81,   81,   81,   81,
+   81,  102,    0,    0,  102,    0,    0,  131,    0,    0,
+    0,    0,   82,   82,   82,   82,    0,    0,  102,  102,
+    0,   82,    0,  102,    0,    0,    0,   82,   82,    0,
+   82,  170,    0,    0,    0,    0,    0,   82,   82,    0,
+   82,   82,   82,   82,   82,   82,    0,   67,    0,    0,
+   67,    0,    0,  102,   87,    0,    0,   87,    0,    0,
+    0,    0,    0,  152,   67,   67,  143,  143,  143,  143,
+    0,   87,   87,    0,    0,  143,   87,    0,    0,    0,
+    0,  143,  143,    0,    0,    0,   89,    0,    0,   89,
+    0,  143,  143,    0,  143,  143,  143,  143,  143,   67,
+    0,    0,    0,   89,   89,    0,   87,    0,   89,    0,
+    0,  159,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-   74,    0,    0,   74,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,   74,   74,   73,
-    0,    0,   74,    0,    0,    0,    0,   72,   72,   72,
-   72,    0,    0,    0,    0,    0,   72,    0,    0,    0,
-   72,   72,   72,   72,   75,    0,    0,   75,    0,   72,
-   72,    0,   74,   72,   72,   72,   72,   72,    0,   72,
-   72,   75,   75,    0,    0,    0,   75,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,  123,    0,    0,
-  123,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,  123,  123,   75,    0,    0,  123,
-    0,    0,    0,    0,    0,    0,    0,    0,   94,    0,
-    0,   94,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,   94,   94,    0,    0,  123,
-   94,    0,    0,    0,    0,    0,    0,    0,    0,  134,
-    0,    0,  134,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,  134,  134,    0,    0,
-   94,  134,    0,    0,    0,    0,    0,    0,    0,    0,
-   76,    0,    0,   76,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,   77,   76,   76,   77,
-    0,  134,   76,    0,    0,    0,    0,    0,   73,   73,
-   73,   73,    0,   77,   77,    0,    0,   73,   77,    0,
-    0,   73,   73,   73,   73,    0,    0,    0,    0,    0,
-   73,   73,   76,    0,   73,   73,   73,   73,   73,    0,
-   73,   74,   74,   74,   74,    0,    0,    0,   77,    0,
-   74,    0,    0,    0,   74,   74,    0,   74,   78,    0,
-    0,   78,    0,   74,   74,    0,    0,   74,   74,   74,
-   74,   74,    0,   74,   79,   78,   78,   79,    0,    0,
-   78,    0,    0,    0,    0,   75,   75,   75,   75,    0,
-    0,   79,   79,    0,   75,    0,   79,    0,   75,   75,
-    0,    0,    0,    0,    0,    0,    0,   75,   75,    0,
-   78,   75,   75,   75,   75,   75,    0,   75,  123,  123,
-  123,  123,    0,    0,    0,    0,   79,  123,    0,    0,
-    0,  123,  123,    0,    0,    0,    0,    0,    0,   81,
-  123,  123,   81,    0,  123,  123,  123,  123,  123,   94,
-   94,   94,   94,    0,    0,    0,   81,   81,   94,    0,
-    0,   81,   94,   94,    0,    0,    0,    0,    0,    0,
-    0,   94,   94,    0,    0,   94,   94,   94,   94,   94,
-  134,  134,  134,  134,    0,    0,    0,    0,    0,  134,
-    0,   81,    0,  134,  134,    0,    0,    0,    0,    0,
-    0,    0,  134,  134,    0,    0,  134,  134,  134,  134,
-  134,   76,   76,   76,   76,    0,    0,    0,    0,    0,
-   76,    0,    0,    0,    0,   76,    0,   77,   77,   77,
-   77,    0,    0,   76,   76,    0,   77,   76,   76,   76,
-   76,   76,    0,    0,    0,    0,    0,    0,    0,   77,
-   77,    0,    0,   77,   77,   77,   77,   77,    0,    0,
+    0,    0,    0,  142,  142,  142,  142,    0,   89,  170,
+    0,    0,  142,    0,    0,  159,    0,    0,  142,  142,
+    0,    0,    0,    0,    0,    0,    0,    0,  142,  142,
+    0,  142,  142,  142,  142,  142,   79,   79,   79,   79,
+    0,  152,    0,  170,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,  131,  131,  131,  131,
+    0,   79,   79,    0,    0,  131,    0,    0,    0,    0,
+    0,  131,  131,    0,    0,  152,    0,    0,    0,    0,
+    0,  131,  131,    0,  131,  131,  131,  131,  131,    0,
+    0,    0,    0,    0,    0,    0,    0,  154,  155,  156,
+  157,    0,  102,  102,  102,  102,    0,    0,    0,    0,
+    0,  102,    0,  162,  163,  164,  165,  102,  102,  166,
+    0,    0,  167,  168,  169,    0,    0,  102,  102,    0,
+  102,  102,  102,  102,  102,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,   67,   67,
+   67,   67,    0,    0,    0,   87,   87,   87,   87,    0,
+    0,    0,    0,    0,   87,    0,    0,    0,    0,    0,
+    0,    0,    0,   67,   67,    0,    0,    0,    0,    0,
+   87,   87,    0,   87,   87,   87,   87,   89,   89,   89,
+   89,    0,    0,    0,    0,    0,   89,    0,    0,  153,
+    0,    0,    0,    0,    0,  154,  155,  156,  157,    0,
+    0,    0,   89,   89,    0,   89,   89,   89,  158,  160,
+  161,  162,  163,  164,  165,    0,    0,  166,    0,    0,
+  167,  168,  169,  153,    0,    0,    0,    0,    0,  154,
+  155,  156,  157,    0,    0,    0,    0,   67,    0,    0,
+    0,   81,    0,  160,  161,  162,  163,  164,  165,    0,
+    0,  166,    0,    0,  167,  168,  169,   97,   99,  101,
+  103,    0,    0,    0,    0,    0,  111,    0,    0,  120,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,   78,
-   78,   78,   78,    0,    0,    0,    0,    0,   78,    0,
-    0,    0,    0,    0,    0,   79,   79,   79,   79,    0,
-    0,   78,   78,    0,   79,   78,   78,   78,   78,   78,
-    0,    0,   91,    0,    0,    0,    0,   79,   79,    0,
-  104,   79,   79,   79,   79,  111,  113,    0,    0,    0,
-    0,    0,  125,  126,  127,  128,  129,  130,    0,    0,
-  133,  134,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-   81,   81,   81,   81,    0,    0,    0,    0,    0,   81,
-    0,    0,  183,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,   81,   81,    0,    0,   81,   81,   81,    0,
+    0,    0,    0,    0,  179,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,  187,    0,
+    0,  190,    0,  192,    0,  194,    0,  196,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,  215,    0,    0,    0,    0,
-    0,    0,    0,  223,  224,  225,  226,  227,  228,  229,
-  230,  231,  232,  233,  234,  235,  236,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,  215,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,  297,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,  313,
+    0,    0,    0,    0,    0,  253,    0,    0,    0,    0,
+    0,    0,  260,
 };
 dEXT short yycheck[] = {                                      13,
-   59,   13,   91,   17,   59,   59,   36,   93,  182,  194,
-   41,  123,   59,   44,  257,   41,   59,   40,   44,   33,
-   34,   35,   36,   91,   40,   88,   59,   58,   59,   43,
-   41,   40,   63,   45,  123,   41,   50,   63,   91,   41,
-  257,   41,   41,   40,   56,   40,   59,   40,   60,   41,
-  257,   41,   40,  116,   41,  123,  188,   59,  190,   40,
-   59,   91,   93,   41,   78,   91,   41,   36,   91,   59,
-  123,   40,   59,   41,  278,   41,  123,   41,   92,  294,
-  295,   95,   94,   97,   96,   99,   98,  101,  100,   41,
-  102,   59,   41,  123,  106,   41,   40,  123,   41,   41,
-  123,  123,   41,   44,   59,   44,    0,  123,  276,  277,
-  123,   44,   40,  287,  123,  300,  179,   59,  303,   58,
-   59,  184,   59,   59,  260,   59,  123,  141,  123,  123,
-  257,   40,  144,  145,  146,  147,  148,  149,  150,   33,
-   40,   40,   36,   37,   38,  257,   40,  295,   42,   43,
-  335,   45,   41,    6,   93,    8,  168,  169,  170,  171,
-  172,  173,  174,  125,  178,   59,  298,  299,   91,   41,
-   64,  185,   41,  305,    0,   59,   91,  125,   31,   32,
-   40,   93,   59,   41,   36,   40,  198,  125,   83,   59,
-  125,   93,  204,  205,  206,  125,  328,   91,  125,  211,
-  125,   41,   41,  257,  123,   91,   93,   33,  294,  295,
-   36,   37,   38,   41,   40,   59,   42,   43,   41,   45,
-   41,   59,   93,   59,  313,  237,   59,  239,  258,  123,
-   41,  125,  126,   59,  326,  294,  295,  123,   64,  294,
-  295,  272,  273,  274,  275,  259,   13,  261,  269,  263,
-  264,  294,  295,  267,   -1,  281,  270,  269,   93,  285,
-  286,  287,  288,  294,  295,   91,   93,  298,    0,   -1,
-  282,  123,  298,  299,  300,  301,  302,   93,  304,  305,
-   -1,   -1,  308,  294,  295,  311,  312,  313,  294,  295,
-  302,   -1,  306,   -1,  294,  295,   -1,  123,   -1,  125,
-  126,   33,  294,  295,   36,   37,   38,   -1,   40,   -1,
-   42,   43,   -1,   45,  326,   -1,  294,  295,  332,  294,
-  295,   -1,  336,  272,  273,  274,  275,   59,  294,  295,
-  294,  295,   64,  272,  273,  274,  275,   -1,   -1,  294,
-  295,   -1,  294,  295,   -1,  294,  295,   -1,  294,  295,
-   -1,  294,  295,  294,  295,  294,  295,  294,  295,   91,
-  294,  295,  256,  257,  258,  259,  260,  261,   -1,  263,
-  264,  265,  266,  267,  268,  269,  270,  271,  272,  273,
-  274,  275,  294,  295,   -1,  279,  280,   -1,  282,  283,
-  284,  123,  294,  295,  126,  289,  290,  291,  292,  293,
-   41,  287,  296,  297,   91,  257,   -1,  294,  295,  303,
-  262,   -1,   -1,  307,   -1,  309,  310,   -1,   59,  305,
-   -1,   -1,  308,  294,  295,  311,  312,  313,   -1,   -1,
-  256,  257,  258,  259,  260,  261,  123,  263,  264,  265,
+   36,  198,  196,   36,   40,   93,   85,   41,   91,   59,
+   44,   36,   93,   41,  123,   41,   44,  185,   41,   41,
+   40,   91,   40,  257,   93,   59,  257,   40,   40,   40,
+   58,   59,   46,   59,   41,   63,   59,   44,   93,  257,
+  123,  276,  277,   57,   41,   26,   41,   61,   91,   41,
+   59,   58,   59,  123,   44,   41,   63,   41,   91,   93,
+   59,   59,   43,   44,    0,   93,   96,   40,   98,   50,
+  100,   91,  102,   90,  104,  105,   41,   59,   40,   59,
+  123,   62,   63,   64,   65,  282,   93,  266,  267,  268,
+  123,  270,  271,   40,   59,  109,  110,   33,  123,   40,
+   36,   37,   38,  123,   40,  123,   42,   43,  125,   45,
+  123,  123,  123,   59,  123,   59,  278,  314,  123,  316,
+  297,  298,   41,   59,  123,   44,   59,   40,   64,  110,
+  298,   41,  146,  147,  148,  149,  150,  151,  152,   59,
+   44,    6,  336,    8,   63,  339,  123,   59,  257,   59,
+   41,  257,  260,   40,   40,   91,  170,  171,  172,  173,
+  174,  175,  176,    0,  358,  182,   31,   32,   59,  199,
+  187,  185,   91,   41,   41,  189,   40,  191,   41,   36,
+  125,  195,   91,   91,  198,  125,   91,  123,   91,  125,
+  126,  205,   59,  207,  208,   41,   33,   93,  212,   36,
+   37,   38,  298,   40,  123,   42,   43,  257,   45,  297,
+  298,   93,   40,   59,  123,   59,  297,  298,   41,    0,
+  123,   41,   59,   41,  238,  258,  240,   64,  297,  298,
+   41,  314,  257,   41,  123,   93,   44,  262,  272,  273,
+  274,  275,  297,  298,  272,  273,  274,  275,   40,   40,
+   58,   59,   33,  281,   91,   36,   37,   38,  337,   40,
+  296,   42,   43,  297,   45,  272,  273,  274,  275,  297,
+  298,   41,  300,  301,  281,  297,  298,   41,   59,  293,
+  287,  288,   59,   64,  298,   93,  123,  125,  125,  126,
+  297,  298,  125,  300,  301,  302,  303,  304,  305,  125,
+  297,  298,  297,  298,  318,  297,  298,  297,  298,  125,
+   91,  297,  298,  297,  298,  297,  298,  297,  298,   41,
+  256,  257,  258,  259,  260,  261,  125,  263,  264,  265,
   266,  267,  268,  269,  270,  271,  272,  273,  274,  275,
-   -1,   -1,   93,  279,  280,   -1,  282,  283,  284,  294,
-  295,   -1,   -1,  289,  290,  291,  292,  293,   -1,   -1,
-  296,  297,   91,   -1,   -1,   -1,   -1,  303,  294,  295,
-   -1,  307,   91,  309,  310,   26,   33,   -1,   -1,   36,
-   37,   38,   -1,   40,   41,   42,   43,   44,   45,   48,
-   49,   42,   -1,   -1,  123,   -1,   47,   -1,   49,   -1,
-   -1,   58,   59,   -1,  123,  125,   63,   64,   -1,   -1,
-   61,   62,   63,   64,  256,  257,  258,  259,  260,  261,
-   -1,  263,  264,  265,   -1,   -1,   -1,  269,   -1,   88,
-  272,  273,  274,  275,   91,   -1,   93,  279,  280,   -1,
-  282,  283,  284,   63,   -1,   -1,   -1,  289,  290,  291,
-  292,  293,   91,   -1,  296,  297,  107,  116,  266,  267,
-  268,  303,  270,  271,  123,  307,  123,  309,  310,  126,
-   33,   91,   -1,   36,   37,   38,   -1,   40,   41,   42,
-   43,   44,   45,   -1,  123,   -1,   -1,   -1,  285,  286,
-  287,  288,   -1,   -1,   -1,   58,   59,   -1,   -1,   -1,
-   63,   64,   -1,  123,  301,  302,   -1,  304,  305,   -1,
-   -1,  308,   -1,   -1,  311,  312,  313,   -1,   -1,   -1,
-  179,  272,  273,  274,  275,  184,   -1,   -1,   -1,   33,
-   93,   -1,   36,   37,   38,   -1,   40,   -1,   42,   43,
-   -1,   45,   -1,  294,  295,   -1,  266,  267,  268,   -1,
-  270,  271,   -1,   -1,   -1,   59,  285,  286,  287,  288,
-   64,   -1,   -1,  126,   -1,   -1,  285,  286,  287,  288,
-  299,  300,  301,  302,   -1,  304,  305,   -1,   -1,  308,
-   -1,   -1,  311,  312,  313,  304,  305,   91,   -1,  308,
-   -1,   -1,  311,  312,  313,   -1,   -1,   -1,   -1,   -1,
-  257,  258,  259,  260,  261,   -1,  263,  264,  265,   -1,
-   -1,   -1,  269,   -1,   -1,  272,  273,  274,  275,  123,
-   -1,   -1,  126,  280,  281,  282,  283,  284,  285,  286,
-  287,  288,  289,  290,  291,  292,  293,  294,  295,  296,
-  297,  298,  299,  300,  301,  302,  303,  304,  305,   -1,
-  307,  308,  309,  310,  311,  312,  313,   91,   -1,   -1,
-   -1,  281,   -1,   -1,   -1,  285,  286,  287,  288,  308,
-   -1,   -1,  311,  312,  313,   -1,   -1,   -1,  298,  299,
-  300,  301,  302,   -1,  304,  305,   -1,   -1,  308,  123,
-   -1,  311,  312,  313,  257,  258,  259,  260,  261,   -1,
-  263,  264,  265,   -1,   -1,   -1,  269,   -1,   -1,  272,
-  273,  274,  275,   -1,   -1,   -1,   -1,  280,  281,  282,
-  283,  284,  285,  286,  287,  288,  289,  290,  291,  292,
-  293,  294,  295,  296,  297,  298,  299,  300,  301,  302,
-  303,  304,  305,   -1,  307,  308,  309,  310,  311,  312,
-  313,   91,  256,  257,  258,  259,  260,  261,   -1,  263,
-  264,  265,   -1,   41,   -1,  269,   44,   -1,  272,  273,
-  274,  275,   -1,   -1,   -1,  279,  280,   -1,  282,  283,
-  284,   59,   -1,  123,   -1,  289,  290,  291,  292,  293,
-   -1,   -1,  296,  297,   -1,   -1,   -1,   -1,   -1,  303,
-   25,   26,   -1,  307,   33,  309,  310,   36,   37,   38,
-   -1,   40,   37,   42,   43,   93,   45,   42,   43,   -1,
-   -1,   -1,   47,   -1,   49,  272,  273,  274,  275,   -1,
-   59,   -1,   -1,   -1,   -1,   64,   61,   62,   63,   64,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,  294,  295,   -1,
-   -1,   -1,   -1,  287,  288,   -1,   -1,   -1,   -1,   -1,
-   33,   -1,   91,   36,   37,   38,   -1,   40,   -1,   42,
-   43,  305,   45,   -1,  308,   -1,   -1,  311,  312,  313,
-   -1,   -1,  107,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   64,   -1,   -1,  123,   -1,   -1,  126,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   33,   -1,   91,   36,
-   37,   38,   -1,   40,   -1,   42,   43,   -1,   45,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,  167,   -1,   -1,   -1,   -1,   64,   -1,   -1,
-  123,   -1,   -1,  126,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,  305,   -1,   -1,  308,   -1,
-   -1,  311,  312,  313,   91,   -1,   -1,   -1,   -1,   33,
-   -1,   -1,   36,   37,   38,   -1,   40,   -1,   42,   43,
-   -1,   45,   -1,   -1,  272,  273,  274,  275,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   59,  123,   -1,   -1,  126,
-   64,   -1,   -1,   -1,   -1,   -1,  294,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,  256,  257,  258,
-  259,  260,  261,   -1,  263,  264,  265,   91,   -1,   -1,
-  269,   -1,   -1,  272,  273,  274,  275,   -1,   -1,   -1,
-  279,  280,   -1,  282,  283,  284,   -1,   -1,   -1,   -1,
-  289,  290,  291,  292,  293,   -1,   -1,  296,  297,   -1,
-   91,   63,  126,   -1,  303,   -1,   -1,   -1,  307,   -1,
-  309,  310,   -1,   -1,  257,  258,  259,  260,  261,  262,
-  263,  264,  265,   -1,   -1,   -1,  269,   -1,   -1,   91,
-   41,   -1,  123,   -1,   -1,   -1,   -1,  280,   -1,  282,
-  283,  284,   -1,   -1,   -1,   -1,  289,  290,  291,  292,
-  293,   -1,   63,  296,  297,   -1,   -1,   -1,   -1,   -1,
-  303,  123,   -1,   -1,  307,   -1,  309,  310,   -1,   -1,
-  257,  258,  259,  260,  261,   -1,  263,  264,  265,   -1,
-   91,   -1,  269,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,  280,   -1,  282,  283,  284,   -1,   -1,
-   -1,   -1,  289,  290,  291,  292,  293,   -1,   -1,  296,
-  297,   41,  123,   -1,   44,   -1,  303,   -1,   -1,   -1,
-  307,   -1,  309,  310,   -1,   -1,   -1,   -1,   58,   59,
-   -1,   -1,   -1,  257,  258,  259,  260,  261,   91,  263,
-  264,  265,   -1,   33,   -1,  269,   36,   37,   38,   -1,
-   40,   -1,   42,   43,   -1,   45,  280,   -1,  282,  283,
-  284,   -1,   -1,   93,   -1,  289,  290,  291,  292,  293,
-  123,   -1,  296,  297,   64,   -1,   -1,   -1,   -1,  303,
-   -1,   -1,   -1,  307,   -1,  309,  310,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,  285,   -1,  287,  288,   -1,   33,
-   -1,   91,   36,   37,   38,   -1,   40,   41,   42,   43,
-   -1,   45,   -1,  304,  305,   -1,   -1,  308,   -1,  281,
-  311,  312,  313,  285,  286,  287,  288,   -1,   -1,   -1,
-   64,   -1,   -1,  123,   -1,   -1,  126,  299,  300,  301,
-  302,   -1,  304,  305,   -1,   -1,  308,   -1,   -1,  311,
-  312,  313,   -1,   -1,   -1,   33,   -1,   91,   36,   37,
-   38,   -1,   40,   -1,   42,   43,   -1,   45,   -1,   -1,
-  281,   -1,   -1,   -1,  285,  286,  287,  288,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   64,  298,  299,  300,
-  301,  302,  126,  304,  305,   -1,   -1,  308,   -1,   -1,
-  311,  312,  313,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   91,   -1,   93,   -1,   -1,   33,   -1,
-   -1,   36,   37,   38,   -1,   40,   -1,   42,   43,   -1,
-   45,   -1,   -1,   -1,  287,  288,   -1,   -1,   -1,   -1,
-   -1,   -1,  272,  273,  274,  275,   -1,   -1,  126,   64,
-   -1,  304,  305,   -1,   -1,  308,   -1,   -1,  311,  312,
-  313,   -1,   -1,   -1,  294,  295,   -1,  257,  258,  259,
-  260,  261,   -1,  263,  264,  265,   91,   -1,   -1,  269,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-  280,   -1,  282,  283,  284,   -1,   -1,   -1,   -1,  289,
-  290,  291,  292,  293,   -1,   -1,  296,  297,   -1,   -1,
-   -1,  126,   -1,  303,   -1,   -1,   -1,  307,   -1,  309,
-  310,   -1,   -1,  257,  258,  259,  260,  261,   -1,  263,
-  264,  265,   -1,   91,   -1,  269,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,  280,   -1,  282,  283,
-  284,   -1,   -1,   -1,   -1,  289,  290,  291,  292,  293,
-   -1,   -1,  296,  297,   91,  123,   -1,   -1,   -1,  303,
-   -1,   41,   -1,  307,   44,  309,  310,   -1,   -1,  257,
-  258,  259,  260,  261,   -1,  263,  264,  265,   58,   59,
-   -1,  269,   -1,   63,   -1,   -1,  123,   -1,   -1,   -1,
-   -1,   -1,  280,   -1,  282,  283,  284,   -1,   -1,   -1,
-   -1,  289,  290,  291,  292,  293,   -1,   -1,  296,  297,
-   -1,   41,   -1,   93,   44,  303,   -1,   -1,   -1,  307,
-   -1,  309,  310,   -1,   -1,   -1,   -1,   -1,   58,   59,
-   -1,  256,  257,  258,  259,  260,  261,   -1,  263,  264,
-  265,   -1,   33,   -1,  269,   36,   37,   38,   -1,   40,
-   41,   42,   43,   -1,   45,  280,   -1,  282,  283,  284,
-   -1,   -1,   -1,   93,  289,  290,  291,  292,  293,   -1,
-   -1,  296,  297,   64,   -1,   -1,   -1,   -1,  303,   -1,
-   -1,   -1,  307,   -1,  309,  310,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   33,   -1,
-   91,   36,   37,   38,   -1,   40,   41,   42,   43,   -1,
-   45,   -1,   -1,   -1,   -1,   -1,   -1,  285,  286,  287,
-  288,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   64,
-   -1,   -1,  300,  301,  302,  126,  304,  305,   -1,   -1,
-  308,   -1,   -1,  311,  312,  313,   -1,   -1,  285,  286,
-  287,  288,   -1,   -1,   33,   -1,   91,   36,   37,   38,
-   -1,   40,   41,   42,   43,  302,   45,  304,  305,   -1,
-   -1,  308,   -1,   -1,  311,  312,  313,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   64,   -1,   -1,   -1,   -1,
-   -1,  126,  272,  273,  274,  275,   -1,   -1,   -1,   -1,
-   -1,  281,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   91,   -1,  294,  295,   -1,   33,  298,  299,
-   36,   37,   38,   -1,   40,   41,   42,   43,   -1,   45,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,  272,  273,  274,  275,   -1,  126,   64,   -1,
+   41,  355,  123,  279,  280,  126,  282,  283,  284,  285,
+  286,  297,  298,  297,  298,  291,  292,  293,  294,  295,
+  296,   41,  281,  299,  297,  298,   41,   59,  287,  288,
+  289,  290,  308,   41,  310,  311,   41,  297,  298,  123,
+  289,  300,  301,  302,  303,  304,  305,  306,   41,   59,
+  309,   59,   41,  312,  313,  314,   59,  306,   41,   41,
+  309,  297,  298,  312,  313,  314,  309,   59,   41,  312,
+  313,  314,   13,  147,   95,  297,  298,  355,   91,  256,
+  257,  258,  259,  260,  261,   93,  263,  264,  265,  266,
+  267,  268,  269,  270,  271,  272,  273,  274,  275,  297,
+  298,  318,  279,  280,  195,  282,  283,  284,  285,  286,
+  123,   -1,   -1,   -1,  291,  292,  293,  294,  295,  296,
+   -1,   -1,  299,   91,  272,  273,  274,  275,   -1,   -1,
+   -1,  308,   -1,  310,  311,  256,  257,  258,  259,  260,
+  261,  125,  263,  264,  265,   -1,   -1,   -1,  269,  297,
+  298,  272,  273,  274,  275,  123,   -1,   -1,  279,  280,
+   -1,  282,  283,  284,  285,  286,   -1,   -1,   -1,   91,
+  291,  292,  293,  294,  295,  296,   -1,   -1,  299,   -1,
+   -1,   -1,  125,   -1,   91,   -1,   -1,  308,   33,  310,
+  311,   36,   37,   38,   -1,   40,   41,   42,   43,   44,
+   45,  123,   -1,   25,   26,  190,   -1,  192,  272,  273,
+  274,  275,   -1,   58,   59,   37,  123,   -1,   63,   64,
+   -1,   43,   44,   45,   -1,   -1,   -1,   -1,   50,   -1,
+   -1,   -1,   -1,  297,  298,   -1,   -1,   -1,   -1,   -1,
+   62,   63,   64,   65,   -1,   -1,   91,   -1,   93,   33,
+   -1,   -1,   36,   37,   38,   -1,   40,   41,   42,   43,
+   44,   45,   -1,   -1,  272,  273,  274,  275,   -1,   -1,
+   -1,   -1,   -1,   -1,   58,   59,  289,  290,  123,   63,
+   64,  126,  266,  267,  268,   -1,  270,  271,  110,  297,
+  298,   -1,  305,  306,   -1,   -1,  309,   -1,   -1,  312,
+  313,  314,   -1,   -1,   -1,   -1,   -1,   -1,   33,   93,
+   -1,   36,   37,   38,   -1,   40,   -1,   42,   43,  287,
+   45,  289,  290,  266,  267,  268,   -1,  270,  271,   -1,
+   -1,   -1,   -1,   -1,   59,   -1,   -1,  305,  306,   64,
+   -1,  309,  126,   -1,  312,  313,  314,  169,   -1,  334,
+  335,   -1,   -1,   -1,   -1,   -1,  341,   -1,   -1,   41,
+   -1,   -1,   44,   -1,   -1,   -1,   91,  289,  290,   -1,
+   -1,  356,   -1,   -1,  359,  197,   58,   59,   -1,   -1,
+   -1,   63,   -1,   -1,  306,   -1,   -1,  309,   -1,   -1,
+  312,  313,  314,   -1,   -1,   -1,   -1,   -1,  123,  306,
+   -1,  126,  309,   -1,   -1,  312,  313,  314,   -1,   -1,
+   -1,   93,  257,  258,  259,  260,  261,   -1,  263,  264,
+  265,   -1,   -1,   -1,  269,   -1,   -1,  272,  273,  274,
+  275,   -1,   -1,   -1,   -1,  280,  281,  282,  283,  284,
+  285,  286,  287,  288,  289,  290,  291,  292,  293,  294,
+  295,  296,  297,  298,  299,  300,  301,  302,  303,  304,
+  305,  306,   -1,  308,  309,  310,  311,  312,  313,  314,
+   -1,   -1,   -1,  257,  258,  259,  260,  261,   -1,  263,
+  264,  265,   -1,   -1,   -1,  269,   -1,   -1,  272,  273,
+  274,  275,   -1,   -1,   -1,   -1,  280,  281,  282,  283,
+  284,  285,  286,  287,  288,  289,  290,  291,  292,  293,
+  294,  295,  296,  297,  298,  299,  300,  301,  302,  303,
+  304,  305,  306,   -1,  308,  309,  310,  311,  312,  313,
+  314,  256,  257,  258,  259,  260,  261,   -1,  263,  264,
+  265,   -1,   -1,   -1,  269,   -1,   -1,  272,  273,  274,
+  275,   -1,   -1,   -1,  279,  280,   -1,  282,  283,  284,
+  285,  286,   -1,   -1,   -1,   91,  291,  292,  293,  294,
+  295,  296,   33,   -1,  299,   36,   37,   38,   -1,   40,
+   -1,   42,   43,  308,   45,  310,  311,   43,   -1,   -1,
+  272,  273,  274,  275,   -1,   51,   -1,  123,   59,  281,
+   -1,   -1,   -1,   64,   -1,  287,  288,  289,  290,   -1,
+   -1,   -1,   -1,   -1,   -1,  297,  298,   -1,  300,  301,
+  302,  303,  304,  305,  306,   -1,   -1,  309,   33,   -1,
+   91,   36,   37,   38,   90,   40,   -1,   42,   43,   -1,
+   45,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  309,  310,
+  311,   -1,   -1,   -1,  315,   -1,  317,   -1,   -1,   64,
+   -1,  117,  123,   -1,   -1,  126,   -1,   -1,   -1,  125,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,  294,  295,  257,  258,  259,  260,
+   -1,   -1,  343,   -1,   33,   -1,   91,   36,   37,   38,
+  351,   40,  353,   42,   43,   -1,   45,   -1,   -1,   -1,
+   -1,   -1,   -1,  364,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   64,   -1,   -1,  123,   -1,
+   -1,  126,   -1,   -1,   -1,   -1,  182,   -1,   -1,   -1,
+   -1,  187,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   91,   -1,   -1,   -1,   -1,   33,   -1,   -1,
+   36,   37,   38,   -1,   40,   -1,   42,   43,   -1,   45,
+   -1,  287,  288,  289,  290,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  123,   -1,   -1,  126,   64,  305,
+  306,   -1,   -1,  309,   -1,   -1,  312,  313,  314,   -1,
+   -1,   -1,   -1,   -1,   -1,  256,  257,  258,  259,  260,
   261,   -1,  263,  264,  265,   91,   -1,   -1,  269,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  280,
-   -1,  282,  283,  284,   -1,   -1,   -1,   -1,  289,  290,
-  291,  292,  293,   -1,   -1,  296,  297,   -1,   -1,   -1,
-  126,   -1,  303,   -1,   41,   -1,  307,   44,  309,  310,
-   -1,   -1,  257,  258,  259,  260,  261,   -1,  263,  264,
-  265,   58,   59,   -1,  269,   -1,   63,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,  280,   -1,  282,  283,  284,
-   -1,   -1,   -1,   -1,  289,  290,  291,  292,  293,   -1,
-   -1,  296,  297,   -1,   91,   -1,   93,   -1,  303,   -1,
-   41,   -1,  307,   44,  309,  310,   -1,   -1,  257,  258,
-  259,  260,  261,   -1,  263,  264,  265,   58,   59,   -1,
-  269,   -1,   63,   -1,   -1,   -1,  123,   -1,   -1,   -1,
-   -1,  280,   -1,  282,  283,  284,   -1,   -1,   -1,   -1,
-  289,  290,  291,  292,  293,   -1,   -1,  296,  297,   -1,
-   91,   -1,   93,   -1,  303,   -1,   -1,   -1,  307,   -1,
-  309,  310,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,  257,  258,  259,  260,  261,   -1,  263,  264,  265,
-   -1,   33,  123,  269,   36,   37,   38,   -1,   40,   -1,
-   42,   43,   -1,   45,  280,   -1,  282,  283,  284,   -1,
-   -1,   -1,   -1,  289,  290,  291,  292,  293,   -1,   -1,
-  296,  297,   64,   -1,   -1,   -1,   -1,  303,   -1,   -1,
-   -1,  307,   -1,  309,  310,   -1,   -1,   -1,   -1,   -1,
-   41,   -1,   -1,   44,   -1,   -1,   -1,   -1,   -1,   91,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   58,   59,   -1,
-   -1,   -1,   63,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,  126,  272,  273,  274,  275,   -1,
-   91,   -1,   93,   -1,  281,   -1,   -1,   -1,  285,  286,
-  287,  288,   -1,   -1,   -1,   -1,   -1,  294,  295,   -1,
-   -1,  298,  299,  300,  301,  302,   -1,  304,  305,   -1,
-   -1,  308,  123,   -1,  311,  312,  313,   -1,   -1,   -1,
-   -1,   41,   -1,   -1,   44,   -1,   -1,   -1,   -1,   -1,
-   -1,  272,  273,  274,  275,   -1,   -1,   -1,   58,   59,
-  281,   -1,   -1,   63,  285,  286,  287,  288,   -1,   -1,
-   -1,   -1,   -1,  294,  295,   -1,   -1,  298,  299,  300,
-  301,  302,   -1,  304,  305,   -1,   41,  308,   -1,   44,
-  311,  312,  313,   93,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   58,   59,   -1,   -1,   -1,   63,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,  123,   -1,  257,  258,  259,  260,  261,
-   -1,  263,  264,  265,   -1,   -1,   91,  269,   93,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  280,   -1,
-  282,  283,  284,   -1,   -1,   -1,   -1,  289,  290,  291,
-  292,  293,   -1,   -1,  296,  297,   -1,   -1,   -1,   -1,
-   -1,  303,   -1,   -1,   -1,  307,   -1,  309,  310,   -1,
-   -1,  272,  273,  274,  275,   -1,   -1,   -1,   -1,   -1,
-  281,   -1,   -1,   -1,  285,  286,  287,  288,   -1,   -1,
-   -1,   -1,   -1,  294,  295,   -1,   -1,  298,  299,  300,
-  301,  302,   -1,  304,  305,   41,   -1,  308,   44,   -1,
-  311,  312,  313,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   58,   59,   -1,   -1,   -1,   63,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   41,   -1,   -1,   44,   -1,   93,   -1,   -1,
-   -1,   -1,  272,  273,  274,  275,   -1,   -1,   -1,   58,
-   59,  281,   -1,   -1,   -1,  285,  286,  287,  288,   -1,
-   -1,   -1,   -1,   -1,  294,  295,   -1,  123,  298,  299,
-  300,  301,  302,   -1,  304,  305,   -1,   -1,  308,   -1,
-   -1,  311,  312,  313,   93,   -1,   -1,  272,  273,  274,
-  275,   -1,   -1,   -1,   -1,   -1,  281,   -1,   -1,   -1,
-  285,  286,  287,  288,   -1,   -1,   -1,   41,   -1,  294,
-  295,   -1,   -1,  298,  299,  300,  301,  302,   -1,  304,
-  305,   -1,   -1,  308,   58,   59,  311,  312,  313,   63,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   41,   -1,   -1,   -1,   -1,   -1,   91,   -1,   93,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   58,   59,
-   -1,   -1,   -1,   63,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  123,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   91,   -1,   93,   -1,   -1,   41,   -1,   -1,   44,
-   -1,   -1,   -1,   -1,   -1,   -1,  272,  273,  274,  275,
-   -1,   -1,   -1,   58,   59,  281,   -1,   -1,   63,  285,
-  286,  287,  288,  123,   -1,   -1,   -1,   -1,  294,  295,
-   -1,   -1,  298,  299,  300,  301,  302,   -1,  304,  305,
-   41,   -1,  308,   44,   -1,  311,  312,  313,   93,   -1,
-   -1,   -1,   -1,  272,  273,  274,  275,   58,   59,   -1,
-   -1,   -1,   63,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,  294,  295,   -1,  123,  298,
-   -1,   -1,   -1,   41,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   93,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   58,   59,   -1,   -1,   -1,   63,   -1,   -1,   -1,   -1,
+   -1,  272,  273,  274,  275,   -1,   -1,   -1,  279,  280,
+   -1,  282,  283,  284,  285,  286,   -1,   -1,   -1,   -1,
+  291,  292,  293,  294,  295,  296,   -1,  123,  299,   -1,
+  126,   -1,   91,   -1,   -1,   -1,   41,  308,   -1,  310,
+  311,   -1,  257,  258,  259,  260,  261,  262,  263,  264,
+  265,   -1,   -1,   -1,  269,   -1,   -1,   -1,   63,   -1,
+   -1,   -1,   -1,   -1,  123,  280,   -1,  282,  283,  284,
+  285,  286,   -1,   -1,   -1,   -1,  291,  292,  293,  294,
+  295,  296,   -1,   -1,  299,   -1,   91,   -1,   -1,   -1,
+   -1,   -1,   -1,  308,   -1,  310,  311,   -1,  257,  258,
+  259,  260,  261,   -1,  263,  264,  265,   -1,   -1,   -1,
+  269,   58,   -1,   -1,   -1,   -1,   63,   -1,  123,   -1,
+   -1,  280,   -1,  282,  283,  284,  285,  286,   -1,   -1,
+   -1,   -1,  291,  292,  293,  294,  295,  296,   -1,   -1,
+  299,   -1,   -1,   -1,   91,   -1,   -1,   -1,   -1,  308,
+   -1,  310,  311,   -1,   -1,   -1,   -1,   41,   -1,   -1,
+   44,  257,  258,  259,  260,  261,   -1,  263,  264,  265,
+   -1,   -1,   -1,  269,   58,   59,  123,   -1,   -1,   63,
+   -1,   -1,   -1,   -1,  280,   -1,  282,  283,  284,  285,
+  286,   -1,   -1,   -1,   -1,  291,  292,  293,  294,  295,
+  296,   33,   -1,  299,   36,   37,   38,   -1,   40,   93,
+   42,   43,  308,   45,  310,  311,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   59,  287,  288,
+  289,  290,   64,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  301,  302,  303,  304,  305,  306,   -1,   -1,
+  309,   -1,   -1,  312,  313,  314,   -1,   33,   -1,   91,
+   36,   37,   38,   -1,   40,   41,   42,   43,   -1,   45,
+   -1,   -1,   -1,   -1,   -1,   -1,  281,   -1,   -1,   -1,
+   -1,   -1,  287,  288,  289,  290,   -1,   -1,   64,   -1,
+   -1,   -1,   -1,   -1,  126,  300,  301,  302,  303,  304,
+  305,  306,   -1,   -1,  309,   -1,   -1,  312,  313,  314,
+   -1,   -1,   -1,   33,   -1,   91,   36,   37,   38,   -1,
+   40,   -1,   42,   43,   -1,   45,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  281,   -1,   -1,   -1,   -1,   -1,
+  287,  288,  289,  290,   64,   -1,   -1,   -1,   -1,   -1,
+  126,   -1,   -1,  300,  301,  302,  303,  304,  305,  306,
+   -1,   -1,  309,   -1,   -1,  312,  313,  314,   -1,   -1,
+   -1,   91,   33,   93,   -1,   36,   37,   38,   -1,   40,
+   41,   42,   43,   -1,   45,   -1,   -1,   -1,  272,  273,
+  274,  275,   -1,   -1,   -1,   -1,   -1,  281,   -1,   -1,
+   -1,   -1,   -1,   64,  288,   -1,  126,   -1,   -1,   -1,
+   -1,   -1,   -1,  297,  298,   -1,  300,  301,  302,  303,
+  304,   41,   -1,   -1,   44,  257,  258,  259,  260,  261,
+   91,  263,  264,  265,   -1,   -1,   -1,  269,   58,   59,
+   -1,   -1,   -1,   63,   -1,   -1,   -1,   -1,  280,   -1,
+  282,  283,  284,  285,  286,   -1,   -1,   -1,   -1,  291,
+  292,  293,  294,  295,  296,  126,   -1,  299,   -1,   -1,
+   -1,   -1,   -1,   93,   -1,   -1,  308,   41,  310,  311,
+   44,  257,  258,  259,  260,  261,   -1,  263,  264,  265,
+   -1,   -1,   -1,  269,   58,   59,   -1,   -1,   -1,   63,
+   -1,   -1,   -1,   -1,  280,   -1,  282,  283,  284,  285,
+  286,   -1,   -1,   -1,   -1,  291,  292,  293,  294,  295,
+  296,   -1,   -1,  299,   -1,   -1,   -1,   -1,   -1,   93,
+   -1,   -1,  308,   -1,  310,  311,   -1,  257,  258,  259,
+  260,  261,   -1,  263,  264,  265,   -1,   33,   -1,  269,
+   36,   37,   38,   -1,   40,   41,   42,   43,   -1,   45,
+  280,   -1,  282,  283,  284,  285,  286,   -1,   -1,   -1,
+   -1,  291,  292,  293,  294,  295,  296,   -1,   64,  299,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  308,   -1,
+  310,  311,   -1,   -1,   -1,   -1,  257,  258,  259,  260,
+  261,   -1,  263,  264,  265,   91,   33,   -1,  269,   36,
+   37,   38,   -1,   40,   -1,   42,   43,   -1,   45,  280,
+   -1,  282,  283,  284,  285,  286,   -1,   -1,   -1,   -1,
+  291,  292,  293,  294,  295,  296,   -1,   64,  299,   -1,
+  126,   -1,   -1,   -1,   -1,   -1,   -1,  308,   -1,  310,
+  311,   -1,  272,  273,  274,  275,   -1,   -1,   -1,   -1,
+   -1,  281,   33,   -1,   91,   36,   37,   38,   -1,   40,
+   41,   42,   43,   -1,   45,   -1,   -1,  297,  298,   -1,
+  300,  301,  302,  303,  304,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   64,   -1,   -1,   -1,   -1,   -1,  126,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  272,  273,
+  274,  275,   -1,   -1,   -1,   -1,   -1,  281,   33,   -1,
+   91,   36,   37,   38,   -1,   40,   41,   42,   43,   -1,
+   45,   -1,   -1,  297,  298,   -1,  300,  301,  302,  303,
+  304,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   64,
+   -1,   -1,   -1,   -1,   -1,  126,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,  123,   -1,   -1,   -1,   -1,   -1,  272,  273,
-  274,  275,   -1,   91,   -1,   93,   -1,  281,   -1,   -1,
-   -1,  285,  286,  287,  288,   41,   -1,   -1,   44,   -1,
-  294,  295,   -1,   -1,  298,  299,  300,  301,  302,   -1,
-  304,  305,   58,   59,  308,  123,   -1,  311,  312,  313,
+   -1,  257,  258,  259,  260,  261,   91,  263,  264,  265,
+   -1,   33,   -1,  269,   36,   37,   38,   -1,   40,   -1,
+   42,   43,   -1,   45,  280,   -1,  282,  283,  284,  285,
+  286,   -1,   -1,   -1,   -1,  291,  292,  293,  294,  295,
+  296,  126,   64,  299,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  308,   -1,  310,  311,   -1,   -1,   -1,  256,
+  257,  258,  259,  260,  261,   -1,  263,  264,  265,   91,
+   -1,   -1,  269,   41,   -1,   -1,   44,   -1,   -1,   -1,
+   -1,   -1,   -1,  280,   -1,  282,  283,  284,  285,  286,
+   58,   59,   -1,   -1,  291,  292,  293,  294,  295,  296,
+   -1,   -1,  299,   -1,  126,   -1,   -1,   -1,   -1,   41,
+   -1,  308,   44,  310,  311,   -1,  257,  258,  259,  260,
+  261,   -1,  263,  264,  265,   93,   58,   59,  269,   -1,
+   -1,   63,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  280,
+   -1,  282,  283,  284,  285,  286,   -1,   -1,   -1,   -1,
+  291,  292,  293,  294,  295,  296,   -1,   -1,  299,   91,
+   -1,   93,   -1,   -1,   -1,   -1,   -1,  308,   41,  310,
+  311,   44,  257,  258,  259,  260,  261,   -1,  263,  264,
+  265,   -1,   -1,   -1,  269,   58,   59,   -1,   -1,   -1,
+   63,  123,   -1,   -1,   -1,  280,   -1,  282,  283,  284,
+  285,  286,   -1,   -1,   -1,   -1,  291,  292,  293,  294,
+  295,  296,   -1,   -1,  299,   -1,   -1,   -1,   91,   -1,
+   93,   -1,   -1,  308,   -1,  310,  311,   -1,   -1,   -1,
+   -1,   41,   -1,   -1,   44,  257,  258,  259,  260,  261,
+   -1,  263,  264,  265,   -1,   -1,   -1,  269,   58,   59,
+  123,   -1,   -1,   63,   -1,   -1,   -1,   -1,  280,   -1,
+  282,  283,  284,  285,  286,   -1,   -1,   -1,   -1,  291,
+  292,  293,  294,  295,  296,   -1,   -1,  299,   -1,   41,
+   -1,   91,   44,   93,   -1,   -1,  308,   -1,  310,  311,
+   -1,   -1,   -1,   -1,   -1,   -1,   58,   59,   -1,   -1,
+   -1,   63,   -1,   -1,  272,  273,  274,  275,   -1,   -1,
+   -1,   -1,   -1,  123,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  297,
+  298,   93,  300,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  272,  273,  274,  275,   -1,   41,   -1,   -1,   44,  281,
+   -1,   -1,   -1,   -1,   -1,  287,  288,  289,  290,   -1,
+   -1,  123,   58,   59,   -1,  297,  298,   63,  300,  301,
+  302,  303,  304,  305,  306,   -1,   -1,  309,   -1,   -1,
+  312,  313,  314,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   91,   -1,   93,   -1,  272,
+  273,  274,  275,   -1,   41,   -1,   -1,   44,  281,   -1,
+   -1,   -1,   -1,   -1,  287,  288,  289,  290,   -1,   -1,
+   -1,   58,   59,   -1,  297,  298,   63,  300,  301,  302,
+  303,  304,  305,  306,   -1,   -1,  309,   -1,   -1,  312,
+  313,  314,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   93,   -1,   -1,   -1,
    -1,   -1,  272,  273,  274,  275,   -1,   -1,   -1,   -1,
-   -1,  281,   -1,   -1,   -1,  285,  286,  287,  288,   -1,
-   -1,   -1,   -1,   -1,  294,  295,   -1,   93,  298,  299,
-  300,  301,  302,   -1,  304,  305,   -1,   -1,  308,   -1,
-   -1,  311,  312,  313,   -1,   -1,   -1,   41,   -1,   -1,
-   44,   -1,   -1,   -1,   -1,   -1,   -1,  272,  273,  274,
-  275,   -1,   -1,   -1,   58,   59,  281,   -1,   -1,   63,
-  285,  286,  287,  288,   -1,   -1,   -1,   -1,   -1,  294,
-  295,   -1,   -1,  298,  299,  300,  301,  302,   -1,  304,
-  305,   41,   -1,  308,   44,   -1,  311,  312,  313,   93,
-   -1,  272,  273,  274,  275,   -1,   -1,   -1,   58,   59,
-  281,   -1,   -1,   63,  285,  286,  287,  288,   -1,   -1,
-   -1,   -1,   -1,  294,  295,   -1,   -1,  298,  299,  300,
-  301,  302,   -1,  304,  305,   -1,   -1,  308,   -1,   -1,
-  311,  312,  313,   93,  272,  273,  274,  275,   -1,   58,
-   -1,   -1,   -1,  281,   63,   -1,   -1,  285,  286,  287,
-  288,   -1,   -1,   -1,   -1,   -1,  294,  295,   -1,   -1,
-  298,  299,  300,  301,  302,   41,  304,  305,   44,   -1,
-  308,   -1,   91,  311,  312,  313,   -1,   -1,   -1,   -1,
-   -1,   -1,   58,   59,   -1,   -1,   -1,   63,   -1,   -1,
+   -1,  281,   -1,   -1,   -1,   -1,   -1,  287,  288,  289,
+  290,   -1,   -1,   -1,   -1,   -1,  123,  297,  298,   -1,
+  300,  301,  302,  303,  304,  305,  306,   -1,   -1,  309,
+   -1,   -1,  312,  313,  314,   -1,   -1,   -1,   -1,   -1,
+  272,  273,  274,  275,   -1,   41,   -1,   -1,   -1,  281,
+   -1,   -1,   -1,   -1,   -1,  287,  288,  289,  290,   -1,
+   -1,   -1,   58,   59,   -1,  297,  298,   63,  300,  301,
+  302,  303,  304,  305,  306,   -1,   -1,  309,   -1,   -1,
+  312,  313,  314,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   91,   -1,   93,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,  272,  273,  274,  275,
-   -1,   -1,   -1,   -1,  123,   -1,   -1,   41,   -1,   -1,
-   44,   -1,   -1,   -1,   -1,   -1,   -1,   93,  294,  295,
-   -1,   -1,   -1,   -1,   58,   59,   -1,   -1,   -1,   63,
+   -1,   -1,   -1,   -1,   -1,  281,   -1,   -1,   -1,   -1,
+   -1,  287,  288,  289,  290,   -1,   -1,  123,   -1,   -1,
+   91,  297,  298,   -1,  300,  301,  302,  303,  304,  305,
+  306,   -1,   -1,  309,   -1,   -1,  312,  313,  314,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,  123,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   41,   93,
-   -1,   44,   -1,   -1,   -1,   -1,   -1,   -1,  272,  273,
-  274,  275,   -1,   -1,   -1,   58,   59,  281,   -1,   -1,
-   63,  285,  286,  287,  288,   -1,   -1,   -1,   -1,   -1,
-  294,  295,   -1,   -1,  298,  299,  300,  301,  302,   -1,
-  304,  305,   41,   -1,  308,   44,   -1,  311,  312,  313,
-   93,   -1,  272,  273,  274,  275,   -1,   -1,   -1,   58,
-   59,  281,   -1,   -1,   63,  285,  286,  287,  288,   -1,
-   -1,   -1,   -1,   -1,  294,  295,   -1,   -1,  298,  299,
-  300,  301,  302,   41,  304,  305,   44,   -1,  308,   -1,
-   -1,  311,  312,  313,   93,   -1,   -1,   -1,   -1,   -1,
-   58,   59,  281,   -1,   -1,   63,  285,  286,  287,  288,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  298,
-  299,  300,  301,  302,   -1,  304,  305,   -1,   -1,  308,
-   -1,   -1,  311,  312,  313,   93,  272,  273,  274,  275,
-   -1,   -1,   -1,   -1,   -1,  281,   -1,   -1,   -1,  285,
-  286,  287,  288,   -1,   -1,   -1,   -1,   -1,  294,  295,
-   -1,   -1,  298,  299,  300,  301,  302,   -1,  304,  305,
-   -1,   -1,  308,   -1,   -1,  311,  312,  313,  272,  273,
-  274,  275,   -1,   -1,   -1,   -1,   -1,  281,   -1,   -1,
-   -1,  285,  286,  287,  288,   41,   -1,   -1,   44,   -1,
-  294,  295,   -1,   -1,  298,  299,  300,  301,  302,   -1,
-  304,  305,   58,   59,  308,   -1,   -1,  311,  312,  313,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  272,
-  273,  274,  275,   -1,   -1,   -1,   -1,   -1,  281,   -1,
-   -1,   -1,  285,  286,  287,  288,   -1,   93,   -1,   -1,
-   -1,  294,  295,   -1,   -1,  298,  299,  300,  301,  302,
-   -1,  304,  305,   -1,   -1,  308,   -1,   -1,  311,  312,
-  313,   -1,   -1,  272,  273,  274,  275,   -1,   -1,   -1,
-   -1,   -1,  281,   -1,   -1,   -1,  285,  286,  287,  288,
-   -1,   -1,   -1,   -1,   -1,  294,  295,   -1,   -1,  298,
-  299,  300,  301,  302,   41,  304,  305,   44,   -1,  308,
-   -1,   -1,   -1,   -1,  272,  273,  274,  275,   -1,   -1,
-   -1,   58,   59,  281,   -1,   -1,   63,  285,  286,  287,
-  288,   -1,   -1,   -1,   -1,   -1,  294,  295,   -1,   -1,
-  298,  299,  300,  301,  302,   41,  304,  305,   44,   -1,
-  308,   -1,   -1,   -1,   -1,   -1,   93,   -1,   -1,   -1,
-   -1,   -1,   58,   59,   -1,   -1,   -1,   63,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   41,   -1,   -1,   44,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   93,   58,   59,
-   -1,   -1,   -1,   63,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   41,   -1,   -1,
-   44,   -1,   -1,   -1,   -1,   -1,  272,  273,  274,  275,
-   -1,   -1,   -1,   93,   58,   59,   -1,   -1,   -1,   63,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  294,  295,
+   -1,   -1,  123,   -1,   -1,  272,  273,  274,  275,   -1,
+   41,   -1,   -1,   -1,  281,   -1,   -1,   -1,   -1,   -1,
+  287,  288,  289,  290,   -1,   -1,   -1,   58,   59,   -1,
+  297,  298,   63,  300,  301,  302,  303,  304,  305,  306,
+   -1,   -1,  309,   -1,   -1,  312,  313,  314,   -1,   -1,
    -1,   -1,   -1,   41,   -1,   -1,   44,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   93,
+   91,   -1,   93,   41,   -1,   -1,   44,   -1,   -1,   -1,
    58,   59,   -1,   -1,   -1,   63,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   41,
-   -1,   -1,   44,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   93,   58,   59,   -1,   -1,
-   -1,   63,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,  272,  273,  274,  275,   -1,
-   -1,   93,   -1,   -1,  281,   -1,   -1,   -1,  285,  286,
-  287,  288,   -1,   -1,   -1,   -1,   -1,  294,  295,   -1,
-   -1,  298,  299,  300,  301,  302,   41,  304,  305,   44,
-   -1,   -1,   -1,   -1,   -1,   -1,  272,  273,  274,  275,
-   -1,   -1,   -1,   58,   59,  281,   -1,   -1,   63,  285,
-  286,  287,  288,   -1,   -1,   -1,   -1,   -1,  294,  295,
-   -1,   -1,  298,  299,  300,  301,  302,   -1,  304,  305,
-   -1,   -1,  272,  273,  274,  275,   -1,   -1,   93,   -1,
-   -1,  281,   -1,   -1,   -1,  285,  286,  287,  288,   -1,
-   -1,   -1,   -1,   -1,  294,  295,   -1,   -1,  298,  299,
-  300,  301,  302,   -1,  304,  305,   -1,   -1,  272,  273,
-  274,  275,   -1,   -1,   -1,   -1,   -1,  281,   -1,   -1,
-   -1,  285,  286,  287,  288,   -1,   -1,   -1,   -1,   -1,
-  294,  295,   -1,   -1,  298,  299,  300,  301,  302,   -1,
-  304,  305,   -1,   -1,  272,  273,  274,  275,   -1,   -1,
-   -1,   -1,   -1,  281,   -1,   -1,   -1,  285,  286,  287,
-  288,   -1,   -1,   -1,   -1,   -1,  294,  295,   -1,   -1,
-  298,  299,  300,  301,  302,   -1,  304,  305,   -1,   -1,
-  272,  273,  274,  275,   -1,   -1,   -1,   -1,   -1,  281,
-   -1,   -1,   -1,  285,  286,  287,  288,   41,   -1,   -1,
-   44,   -1,  294,  295,   -1,   -1,  298,  299,  300,  301,
-  302,   -1,  304,  305,   58,   59,   -1,   -1,   -1,   63,
+   58,   59,   -1,   -1,   -1,   63,   -1,   -1,   -1,   -1,
+   -1,   -1,  123,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   93,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   93,  272,  273,  274,  275,
+   -1,   41,   -1,   -1,   44,  281,   -1,   -1,   -1,   -1,
+   -1,  287,  288,  289,  290,  123,   -1,   -1,   58,   59,
+   -1,  297,  298,   63,  300,  301,  302,  303,  304,  305,
+  306,   -1,   -1,  309,   -1,   -1,  312,  313,  314,   -1,
+   -1,   -1,   -1,   -1,   41,   -1,  287,  288,  289,  290,
+   -1,   -1,   -1,   93,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   58,   59,  304,  305,  306,   63,   -1,  309,   -1,
+   -1,  312,  313,  314,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  123,   -1,   -1,   -1,   -1,   41,   -1,
+   -1,   44,   -1,   -1,   91,   -1,   93,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   58,   59,   -1,   -1,   -1,
+   63,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  272,  273,  274,  275,   -1,  123,   -1,   -1,   -1,
+  281,   -1,   -1,   -1,   -1,   -1,  287,  288,  289,  290,
+   93,   -1,   -1,   -1,   -1,   -1,  297,  298,   -1,  300,
+  301,  302,  303,  304,  305,  306,   -1,   -1,  309,   -1,
+   -1,  312,  313,  314,  272,  273,  274,  275,   -1,   41,
+  123,   -1,   44,  281,  272,  273,  274,  275,   -1,  287,
+  288,  289,  290,   -1,   -1,   -1,   58,   59,   -1,  297,
+  298,   63,  300,  301,  302,  303,  304,  305,  306,  297,
+  298,  309,  300,   -1,  312,  313,  314,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   41,   -1,   -1,   44,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   58,   59,   93,
-   -1,   -1,   63,   -1,   -1,   -1,   -1,  272,  273,  274,
-  275,   -1,   -1,   -1,   -1,   -1,  281,   -1,   -1,   -1,
-  285,  286,  287,  288,   41,   -1,   -1,   44,   -1,  294,
-  295,   -1,   93,  298,  299,  300,  301,  302,   -1,  304,
-  305,   58,   59,   -1,   -1,   -1,   63,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   41,   -1,   -1,
+   -1,   93,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  272,  273,  274,  275,   -1,   41,   -1,   -1,
+   44,  281,   -1,   -1,   -1,   -1,   -1,  287,  288,  289,
+  290,   -1,   -1,   -1,   58,   59,   -1,  297,  298,   63,
+  300,  301,  302,  303,  304,  305,  306,   -1,   -1,  309,
+   -1,   -1,  312,  313,  314,  272,  273,  274,  275,   -1,
+   41,   -1,   -1,   44,  281,   -1,   -1,   -1,   -1,   93,
+  287,  288,  289,  290,   -1,   -1,   -1,   58,   59,   -1,
+  297,  298,   63,  300,  301,  302,  303,  304,  305,  306,
+   -1,   -1,  309,   -1,   -1,  312,  313,  314,   -1,  272,
+  273,  274,  275,   -1,   41,   -1,   -1,   44,  281,   -1,
+   -1,   -1,   93,   -1,  287,  288,  289,  290,   -1,   -1,
+   -1,   58,   59,   -1,  297,  298,   63,  300,  301,  302,
+  303,  304,  305,  306,   -1,   -1,  309,   -1,   -1,  312,
+  313,  314,   -1,   -1,   -1,   -1,   -1,   41,   -1,   -1,
+   44,   -1,   -1,   -1,   -1,   -1,   93,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   58,   59,   -1,   41,   -1,   63,
    44,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   58,   59,   93,   -1,   -1,   63,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   41,   -1,
-   -1,   44,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   58,   59,   -1,   -1,   93,
-   63,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   41,
-   -1,   -1,   44,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   58,   59,   -1,   -1,
-   93,   63,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   41,   -1,   -1,   44,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   41,   58,   59,   44,
-   -1,   93,   63,   -1,   -1,   -1,   -1,   -1,  272,  273,
-  274,  275,   -1,   58,   59,   -1,   -1,  281,   63,   -1,
-   -1,  285,  286,  287,  288,   -1,   -1,   -1,   -1,   -1,
-  294,  295,   93,   -1,  298,  299,  300,  301,  302,   -1,
-  304,  272,  273,  274,  275,   -1,   -1,   -1,   93,   -1,
-  281,   -1,   -1,   -1,  285,  286,   -1,  288,   41,   -1,
-   -1,   44,   -1,  294,  295,   -1,   -1,  298,  299,  300,
-  301,  302,   -1,  304,   41,   58,   59,   44,   -1,   -1,
-   63,   -1,   -1,   -1,   -1,  272,  273,  274,  275,   -1,
-   -1,   58,   59,   -1,  281,   -1,   63,   -1,  285,  286,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,  294,  295,   -1,
-   93,  298,  299,  300,  301,  302,   -1,  304,  272,  273,
-  274,  275,   -1,   -1,   -1,   -1,   93,  281,   -1,   -1,
-   -1,  285,  286,   -1,   -1,   -1,   -1,   -1,   -1,   41,
-  294,  295,   44,   -1,  298,  299,  300,  301,  302,  272,
-  273,  274,  275,   -1,   -1,   -1,   58,   59,  281,   -1,
-   -1,   63,  285,  286,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,  294,  295,   -1,   -1,  298,  299,  300,  301,  302,
-  272,  273,  274,  275,   -1,   -1,   -1,   -1,   -1,  281,
-   -1,   93,   -1,  285,  286,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,  294,  295,   -1,   -1,  298,  299,  300,  301,
-  302,  272,  273,  274,  275,   -1,   -1,   -1,   -1,   -1,
-  281,   -1,   -1,   -1,   -1,  286,   -1,  272,  273,  274,
-  275,   -1,   -1,  294,  295,   -1,  281,  298,  299,  300,
-  301,  302,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  294,
-  295,   -1,   -1,  298,  299,  300,  301,  302,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  272,
-  273,  274,  275,   -1,   -1,   -1,   -1,   -1,  281,   -1,
+  272,  273,  274,  275,   58,   59,   -1,   -1,   -1,  281,
+   -1,   -1,   -1,   -1,   -1,  287,  288,  289,  290,   93,
+   -1,   -1,   -1,   -1,   -1,  297,  298,   -1,  300,  301,
+  302,  303,  304,  305,  306,   41,   -1,  309,   44,   93,
+  312,  313,  314,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   58,   59,   -1,   -1,   -1,   63,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  272,  273,
+  274,  275,   -1,   41,   -1,   -1,   44,  281,   -1,   -1,
+   -1,   -1,   -1,  287,  288,  289,  290,   93,   -1,   -1,
+   58,   59,   -1,  297,  298,   63,  300,  301,  302,  303,
+  304,  305,  306,   -1,   -1,  309,   -1,   -1,  312,  313,
+  314,  272,  273,  274,  275,   -1,   -1,   -1,   -1,   -1,
+  281,   -1,   -1,   -1,   -1,   93,  287,  288,  289,  290,
+   -1,   -1,   -1,   -1,   -1,   -1,  297,  298,   -1,  300,
+  301,  302,  303,  304,  305,  306,   -1,   -1,  309,   -1,
+   -1,  312,  313,  314,   -1,  272,  273,  274,  275,   -1,
+   41,   -1,   -1,   44,  281,   -1,   -1,   -1,   -1,   -1,
+  287,  288,  289,  290,   -1,   -1,   -1,   58,   59,   -1,
+  297,  298,   63,  300,  301,  302,  303,  304,  305,  306,
+   -1,   -1,  309,   -1,   -1,  312,  313,  314,  272,  273,
+  274,  275,   -1,   -1,   -1,   -1,   -1,  281,   -1,   -1,
+   -1,   -1,   93,  287,  288,  289,  290,   -1,  272,  273,
+  274,  275,   -1,  297,  298,   30,  300,  301,  302,  303,
+  304,  305,  306,   38,   -1,  309,   -1,   42,   -1,   -1,
+   45,   -1,   -1,  297,  298,   -1,   -1,   52,   53,   54,
+   55,   56,   -1,   -1,   59,   60,   -1,   -1,   91,   -1,
+   -1,   66,   -1,   -1,   -1,   -1,  272,  273,  274,  275,
+   -1,   41,   -1,   -1,   44,  281,   -1,   -1,   -1,   -1,
+   -1,  287,  288,  289,  290,   -1,   -1,   92,   58,   59,
+  123,  297,  298,   63,  300,  301,  302,  303,  304,  305,
+  306,   -1,   -1,   -1,  272,  273,  274,  275,   -1,   -1,
+   -1,   -1,   -1,  281,   -1,   -1,   -1,   -1,   -1,  287,
+  288,  289,  290,   93,   41,   -1,   -1,   44,   -1,  297,
+  298,   -1,  300,  301,  302,  303,  304,  305,  306,   -1,
+   -1,   58,   59,   -1,   -1,   -1,   63,   -1,  153,  154,
+  155,  156,  157,  158,  159,  160,  161,  162,  163,  164,
+  165,  166,   41,   -1,   -1,   44,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  178,   -1,   -1,   93,   -1,   -1,   58,
+   59,   -1,   -1,   -1,   63,   -1,   -1,   -1,   -1,   -1,
+   -1,  272,  273,  274,  275,   -1,   -1,   -1,   -1,   -1,
+  281,   -1,   -1,   -1,   -1,   -1,  287,  288,  289,  290,
+   41,   -1,   -1,   44,   93,   -1,  297,  298,   -1,  300,
+  301,  302,  303,  304,  305,  306,   -1,   58,   59,   -1,
+   -1,   -1,   63,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   41,   -1,   -1,   44,
+   -1,   -1,   -1,  258,  287,  288,  289,  290,   -1,   -1,
+   -1,   -1,   93,   58,   59,   -1,   -1,   -1,   63,  302,
+  303,  304,  305,  306,   -1,   -1,  309,   -1,   -1,  312,
+  313,  314,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  295,   41,   -1,   -1,   44,   -1,   -1,   -1,   93,   -1,
+   -1,   -1,  272,  273,  274,  275,   -1,   -1,   58,   59,
+   -1,  281,   -1,   63,   -1,   -1,   -1,  287,  288,  289,
+  290,   -1,   -1,   -1,   -1,   -1,   -1,  297,  298,   -1,
+  300,  301,  302,  303,  304,  305,  306,   -1,   -1,   -1,
+   -1,   -1,   -1,   93,   -1,   41,   -1,   -1,   44,   -1,
    -1,   -1,   -1,   -1,   -1,  272,  273,  274,  275,   -1,
-   -1,  294,  295,   -1,  281,  298,  299,  300,  301,  302,
-   -1,   -1,   30,   -1,   -1,   -1,   -1,  294,  295,   -1,
-   38,  298,  299,  300,  301,   43,   44,   -1,   -1,   -1,
-   -1,   -1,   50,   51,   52,   53,   54,   55,   -1,   -1,
-   58,   59,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-  272,  273,  274,  275,   -1,   -1,   -1,   -1,   -1,  281,
-   -1,   -1,   90,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,  294,  295,   -1,   -1,  298,  299,  300,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,  143,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,  151,  152,  153,  154,  155,  156,  157,
-  158,  159,  160,  161,  162,  163,  164,   -1,   -1,   -1,
+   -1,   -1,   58,   59,  281,   -1,   -1,   63,   -1,   -1,
+  287,  288,  289,  290,   -1,   -1,   -1,   -1,   -1,   -1,
+  297,  298,   -1,  300,  301,  302,  303,  304,  305,  306,
+   -1,   -1,   -1,  272,  273,  274,  275,   93,   -1,   -1,
+   -1,   -1,  281,   -1,   -1,   -1,   -1,   -1,  287,  288,
+  289,  290,   41,   -1,   -1,   44,   -1,   -1,  297,  298,
+   -1,  300,  301,  302,  303,  304,  305,  306,   -1,   58,
+   59,   -1,   -1,   -1,   63,   -1,   -1,   -1,   -1,   -1,
+   -1,  272,  273,  274,  275,   41,   -1,   -1,   44,   -1,
+  281,   -1,   -1,   -1,   -1,   -1,  287,  288,  289,  290,
+   -1,   -1,   58,   59,   93,   41,  297,  298,   44,  300,
+  301,  302,  303,  304,  305,  306,   -1,  272,  273,  274,
+  275,   -1,   58,   59,   -1,   -1,  281,   63,   -1,   -1,
+   -1,   -1,  287,  288,  289,  290,   -1,   93,   -1,   -1,
+   -1,   -1,  297,  298,   -1,  300,  301,  302,  303,  304,
+  305,   41,   -1,   -1,   44,   -1,   -1,   93,   -1,   -1,
+   -1,   -1,  272,  273,  274,  275,   -1,   -1,   58,   59,
+   -1,  281,   -1,   63,   -1,   -1,   -1,  287,  288,   -1,
+  290,   91,   -1,   -1,   -1,   -1,   -1,  297,  298,   -1,
+  300,  301,  302,  303,  304,  305,   -1,   41,   -1,   -1,
+   44,   -1,   -1,   93,   41,   -1,   -1,   44,   -1,   -1,
+   -1,   -1,   -1,  123,   58,   59,  272,  273,  274,  275,
+   -1,   58,   59,   -1,   -1,  281,   63,   -1,   -1,   -1,
+   -1,  287,  288,   -1,   -1,   -1,   41,   -1,   -1,   44,
+   -1,  297,  298,   -1,  300,  301,  302,  303,  304,   93,
+   -1,   -1,   -1,   58,   59,   -1,   93,   -1,   63,   -1,
+   -1,   63,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  272,  273,  274,  275,   -1,   93,   91,
+   -1,   -1,  281,   -1,   -1,   63,   -1,   -1,  287,  288,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  297,  298,
+   -1,  300,  301,  302,  303,  304,  272,  273,  274,  275,
+   -1,  123,   -1,   91,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  272,  273,  274,  275,
+   -1,  297,  298,   -1,   -1,  281,   -1,   -1,   -1,   -1,
+   -1,  287,  288,   -1,   -1,  123,   -1,   -1,   -1,   -1,
+   -1,  297,  298,   -1,  300,  301,  302,  303,  304,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  287,  288,  289,
+  290,   -1,  272,  273,  274,  275,   -1,   -1,   -1,   -1,
+   -1,  281,   -1,  303,  304,  305,  306,  287,  288,  309,
+   -1,   -1,  312,  313,  314,   -1,   -1,  297,  298,   -1,
+  300,  301,  302,  303,  304,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  272,  273,
+  274,  275,   -1,   -1,   -1,  272,  273,  274,  275,   -1,
+   -1,   -1,   -1,   -1,  281,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  297,  298,   -1,   -1,   -1,   -1,   -1,
+  297,  298,   -1,  300,  301,  302,  303,  272,  273,  274,
+  275,   -1,   -1,   -1,   -1,   -1,  281,   -1,   -1,  281,
+   -1,   -1,   -1,   -1,   -1,  287,  288,  289,  290,   -1,
+   -1,   -1,  297,  298,   -1,  300,  301,  302,  300,  301,
+  302,  303,  304,  305,  306,   -1,   -1,  309,   -1,   -1,
+  312,  313,  314,  281,   -1,   -1,   -1,   -1,   -1,  287,
+  288,  289,  290,   -1,   -1,   -1,   -1,   13,   -1,   -1,
+   -1,   17,   -1,  301,  302,  303,  304,  305,  306,   -1,
+   -1,  309,   -1,   -1,  312,  313,  314,   33,   34,   35,
+   36,   -1,   -1,   -1,   -1,   -1,   42,   -1,   -1,   45,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   80,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   94,   -1,
+   -1,   97,   -1,   99,   -1,  101,   -1,  103,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  144,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  256,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,  284,
+   -1,   -1,   -1,   -1,   -1,  181,   -1,   -1,   -1,   -1,
+   -1,   -1,  188,
 };
 #define YYFINAL 1
 #ifndef YYDEBUG
 #define YYDEBUG 0
 #endif
-#define YYMAXTOKEN 313
+#define YYMAXTOKEN 314
 #if YYDEBUG
 dEXT char * yyname[] = {
 "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -1124,9 +1074,9 @@ dEXT char * yyname[] = {
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"WORD","METHOD","FUNCMETH","THING",
 "PMFUNC","PRIVATEREF","FUNC0SUB","UNIOPSUB","LSTOPSUB","LABEL","FORMAT","SUB",
 "ANONSUB","PACKAGE","USE","WHILE","UNTIL","IF","UNLESS","ELSE","ELSIF",
-"CONTINUE","FOR","LOOPEX","DOTDOT","FUNC0","FUNC1","FUNC","RELOP","EQOP",
-"MULOP","ADDOP","DOLSHARP","DO","LOCAL","HASHBRACK","NOAMP","OROP","ANDOP",
-"NOTOP","LSTOP","ASSIGNOP","OROR","ANDAND","BITOROP","BITANDOP","UNIOP",
+"CONTINUE","FOR","LOOPEX","DOTDOT","FUNC0","FUNC1","FUNC","UNIOP","LSTOP",
+"RELOP","EQOP","MULOP","ADDOP","DOLSHARP","DO","HASHBRACK","NOAMP","LOCAL","MY",
+"OROP","ANDOP","NOTOP","ASSIGNOP","OROR","ANDAND","BITOROP","BITANDOP",
 "SHIFTOP","MATCHOP","UMINUS","REFGEN","POWOP","PREINC","PREDEC","POSTINC",
 "POSTDEC","ARROW",
 };
@@ -1136,6 +1086,8 @@ dEXT char * yyrule[] = {
 "prog : $$1 lineseq",
 "block : '{' remember lineseq '}'",
 "remember :",
+"mblock : '{' mremember lineseq '}'",
+"mremember :",
 "lineseq :",
 "lineseq : lineseq decl",
 "lineseq : lineseq line",
@@ -1148,28 +1100,34 @@ dEXT char * yyrule[] = {
 "sideff : expr IF expr",
 "sideff : expr UNLESS expr",
 "sideff : expr WHILE expr",
-"sideff : expr UNTIL expr",
+"sideff : expr UNTIL iexpr",
 "else :",
-"else : ELSE block",
-"else : ELSIF '(' expr ')' block else",
-"cond : IF '(' expr ')' block else",
-"cond : UNLESS '(' expr ')' block else",
+"else : ELSE mblock",
+"else : ELSIF '(' mexpr ')' mblock else",
+"cond : IF '(' remember mexpr ')' mblock else",
+"cond : UNLESS '(' remember miexpr ')' mblock else",
 "cond : IF block block else",
 "cond : UNLESS block block else",
 "cont :",
 "cont : CONTINUE block",
-"loop : label WHILE '(' texpr ')' block cont",
-"loop : label UNTIL '(' expr ')' block cont",
+"loop : label WHILE '(' remember mtexpr ')' mblock cont",
+"loop : label UNTIL '(' remember miexpr ')' mblock cont",
 "loop : label WHILE block block cont",
 "loop : label UNTIL block block cont",
-"loop : label FOR scalar '(' expr ')' block cont",
-"loop : label FOR '(' expr ')' block cont",
-"loop : label FOR '(' nexpr ';' texpr ';' nexpr ')' block",
+"loop : label FOR MY remember my_scalar '(' mexpr ')' mblock cont",
+"loop : label FOR scalar '(' remember mexpr ')' mblock cont",
+"loop : label FOR '(' remember mexpr ')' mblock cont",
+"loop : label FOR '(' remember mnexpr ';' mtexpr ';' mnexpr ')' mblock",
 "loop : label block cont",
 "nexpr :",
 "nexpr : sideff",
 "texpr :",
 "texpr : expr",
+"iexpr : expr",
+"mexpr : expr",
+"mnexpr : nexpr",
+"mtexpr : texpr",
+"miexpr : iexpr",
 "label :",
 "label : LABEL",
 "decl : format",
@@ -1225,7 +1183,7 @@ dEXT char * yyrule[] = {
 "term : term POSTDEC",
 "term : PREINC term",
 "term : PREDEC term",
-"term : LOCAL term",
+"term : local term",
 "term : '(' expr ')'",
 "term : '(' ')'",
 "term : '[' expr ']'",
@@ -1281,6 +1239,9 @@ dEXT char * yyrule[] = {
 "listexprcom :",
 "listexprcom : expr",
 "listexprcom : expr ','",
+"local : LOCAL",
+"local : MY",
+"my_scalar : scalar",
 "amper : '&' indirob",
 "scalar : '$' indirob",
 "ary : '@' indirob",
@@ -1313,9 +1274,9 @@ dEXT int yyerrflag;
 dEXT int yychar;
 dEXT YYSTYPE yyval;
 dEXT YYSTYPE yylval;
-#line 571 "perly.y"
+#line 624 "perly.y"
  /* PROGRAM */
-#line 1388 "y_tab.c"
+#line 1349 "perly.c"
 #define YYABORT goto yyabort
 #define YYACCEPT goto yyaccept
 #define YYERROR goto yyerrlab
@@ -1336,15 +1297,15 @@ yydestruct(ptr)
 void* ptr;
 {
     struct ysv* ysave = (struct ysv*)ptr;
-    if (ysave->yyss) safefree((char *)ysave->yyss);
-    if (ysave->yyvs) safefree((char *)ysave->yyvs);
+    if (ysave->yyss) Safefree(ysave->yyss);
+    if (ysave->yyvs) Safefree(ysave->yyvs);
     yydebug    = ysave->oldyydebug;
     yynerrs    = ysave->oldyynerrs;
     yyerrflag  = ysave->oldyyerrflag;
     yychar     = ysave->oldyychar;
     yyval      = ysave->oldyyval;
     yylval     = ysave->oldyylval;
-    safefree((char *)ysave);
+    Safefree(ysave);
 }
 
 int
@@ -1540,7 +1501,7 @@ yyreduce:
     switch (yyn)
     {
 case 1:
-#line 84 "perly.y"
+#line 85 "perly.y"
 {
 #if defined(YYDEBUG) && defined(DEBUGGING)
                    yydebug = (debug & 1);
@@ -1549,38 +1510,50 @@ case 1:
                }
 break;
 case 2:
-#line 91 "perly.y"
+#line 92 "perly.y"
 { newPROG(yyvsp[0].opval); }
 break;
 case 3:
-#line 95 "perly.y"
-{ yyval.opval = block_end(yyvsp[-3].ival,yyvsp[-2].ival,yyvsp[-1].opval); }
+#line 96 "perly.y"
+{ if (copline > (line_t)yyvsp[-3].ival)
+                             copline = yyvsp[-3].ival;
+                         yyval.opval = block_end(yyvsp[-2].ival, yyvsp[-1].opval); }
 break;
 case 4:
-#line 99 "perly.y"
-{ yyval.ival = block_start(); }
+#line 102 "perly.y"
+{ yyval.ival = block_start(TRUE); }
 break;
 case 5:
-#line 103 "perly.y"
-{ yyval.opval = Nullop; }
+#line 106 "perly.y"
+{ if (copline > (line_t)yyvsp[-3].ival)
+                             copline = yyvsp[-3].ival;
+                         yyval.opval = block_end(yyvsp[-2].ival, yyvsp[-1].opval); }
 break;
 case 6:
-#line 105 "perly.y"
-{ yyval.opval = yyvsp[-1].opval; }
+#line 112 "perly.y"
+{ yyval.ival = block_start(FALSE); }
 break;
 case 7:
-#line 107 "perly.y"
+#line 116 "perly.y"
+{ yyval.opval = Nullop; }
+break;
+case 8:
+#line 118 "perly.y"
+{ yyval.opval = yyvsp[-1].opval; }
+break;
+case 9:
+#line 120 "perly.y"
 {   yyval.opval = append_list(OP_LINESEQ,
                                (LISTOP*)yyvsp[-1].opval, (LISTOP*)yyvsp[0].opval);
                            pad_reset_pending = TRUE;
                            if (yyvsp[-1].opval && yyvsp[0].opval) hints |= HINT_BLOCK_SCOPE; }
 break;
-case 8:
-#line 114 "perly.y"
+case 10:
+#line 127 "perly.y"
 { yyval.opval = newSTATEOP(0, yyvsp[-1].pval, yyvsp[0].opval); }
 break;
-case 10:
-#line 117 "perly.y"
+case 12:
+#line 130 "perly.y"
 { if (yyvsp[-1].pval != Nullch) {
                              yyval.opval = newSTATEOP(0, yyvsp[-1].pval, newOP(OP_NULL, 0));
                            }
@@ -1590,467 +1563,501 @@ case 10:
                            }
                            expect = XSTATE; }
 break;
-case 11:
-#line 126 "perly.y"
+case 13:
+#line 139 "perly.y"
 { yyval.opval = newSTATEOP(0, yyvsp[-2].pval, yyvsp[-1].opval);
                          expect = XSTATE; }
 break;
-case 12:
-#line 131 "perly.y"
-{ yyval.opval = Nullop; }
-break;
-case 13:
-#line 133 "perly.y"
-{ yyval.opval = yyvsp[0].opval; }
-break;
 case 14:
-#line 135 "perly.y"
-{ yyval.opval = newLOGOP(OP_AND, 0, yyvsp[0].opval, yyvsp[-2].opval); }
+#line 144 "perly.y"
+{ yyval.opval = Nullop; }
 break;
 case 15:
-#line 137 "perly.y"
-{ yyval.opval = newLOGOP(OP_OR, 0, yyvsp[0].opval, yyvsp[-2].opval); }
+#line 146 "perly.y"
+{ yyval.opval = yyvsp[0].opval; }
 break;
 case 16:
-#line 139 "perly.y"
-{ yyval.opval = newLOOPOP(OPf_PARENS, 1, scalar(yyvsp[0].opval), yyvsp[-2].opval); }
+#line 148 "perly.y"
+{ yyval.opval = newLOGOP(OP_AND, 0, yyvsp[0].opval, yyvsp[-2].opval); }
 break;
 case 17:
-#line 141 "perly.y"
-{ yyval.opval = newLOOPOP(OPf_PARENS, 1, invert(scalar(yyvsp[0].opval)), yyvsp[-2].opval);}
+#line 150 "perly.y"
+{ yyval.opval = newLOGOP(OP_OR, 0, yyvsp[0].opval, yyvsp[-2].opval); }
 break;
 case 18:
-#line 145 "perly.y"
-{ yyval.opval = Nullop; }
+#line 152 "perly.y"
+{ yyval.opval = newLOOPOP(OPf_PARENS, 1, scalar(yyvsp[0].opval), yyvsp[-2].opval); }
 break;
 case 19:
-#line 147 "perly.y"
-{ yyval.opval = scope(yyvsp[0].opval); }
+#line 154 "perly.y"
+{ yyval.opval = newLOOPOP(OPf_PARENS, 1, yyvsp[0].opval, yyvsp[-2].opval);}
 break;
 case 20:
-#line 149 "perly.y"
-{ copline = yyvsp[-5].ival;
-                           yyval.opval = newSTATEOP(0, 0,
-                               newCONDOP(0, yyvsp[-3].opval, scope(yyvsp[-1].opval), yyvsp[0].opval));
-                           hints |= HINT_BLOCK_SCOPE; }
+#line 158 "perly.y"
+{ yyval.opval = Nullop; }
 break;
 case 21:
-#line 156 "perly.y"
-{ copline = yyvsp[-5].ival;
-                           yyval.opval = newCONDOP(0, yyvsp[-3].opval, scope(yyvsp[-1].opval), yyvsp[0].opval); }
+#line 160 "perly.y"
+{ yyval.opval = scope(yyvsp[0].opval); }
 break;
 case 22:
-#line 159 "perly.y"
+#line 162 "perly.y"
 { copline = yyvsp[-5].ival;
-                           yyval.opval = newCONDOP(0,
-                               invert(scalar(yyvsp[-3].opval)), scope(yyvsp[-1].opval), yyvsp[0].opval); }
+                           yyval.opval = newSTATEOP(0, Nullch,
+                                  newCONDOP(0, yyvsp[-3].opval, scope(yyvsp[-1].opval), yyvsp[0].opval));
+                           hints |= HINT_BLOCK_SCOPE; }
 break;
 case 23:
-#line 163 "perly.y"
+#line 169 "perly.y"
+{ copline = yyvsp[-6].ival;
+                           yyval.opval = block_end(yyvsp[-4].ival,
+                                  newCONDOP(0, yyvsp[-3].opval, scope(yyvsp[-1].opval), yyvsp[0].opval)); }
+break;
+case 24:
+#line 173 "perly.y"
+{ copline = yyvsp[-6].ival;
+                           yyval.opval = block_end(yyvsp[-4].ival,
+                                  newCONDOP(0, yyvsp[-3].opval, scope(yyvsp[-1].opval), yyvsp[0].opval)); }
+break;
+case 25:
+#line 177 "perly.y"
 { copline = yyvsp[-3].ival;
                            deprecate("if BLOCK BLOCK");
                            yyval.opval = newCONDOP(0, scope(yyvsp[-2].opval), scope(yyvsp[-1].opval), yyvsp[0].opval); }
 break;
-case 24:
-#line 167 "perly.y"
+case 26:
+#line 181 "perly.y"
 { copline = yyvsp[-3].ival;
                            deprecate("unless BLOCK BLOCK");
                            yyval.opval = newCONDOP(0, invert(scalar(scope(yyvsp[-2].opval))),
                                                scope(yyvsp[-1].opval), yyvsp[0].opval); }
 break;
-case 25:
-#line 174 "perly.y"
-{ yyval.opval = Nullop; }
-break;
-case 26:
-#line 176 "perly.y"
-{ yyval.opval = scope(yyvsp[0].opval); }
-break;
 case 27:
-#line 180 "perly.y"
-{ copline = yyvsp[-5].ival;
-                           yyval.opval = newSTATEOP(0, yyvsp[-6].pval,
-                                   newWHILEOP(0, 1, (LOOP*)Nullop,
-                                       yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval) ); }
+#line 188 "perly.y"
+{ yyval.opval = Nullop; }
 break;
 case 28:
-#line 185 "perly.y"
-{ copline = yyvsp[-5].ival;
-                           yyval.opval = newSTATEOP(0, yyvsp[-6].pval,
-                                   newWHILEOP(0, 1, (LOOP*)Nullop,
-                                       invert(scalar(yyvsp[-3].opval)), yyvsp[-1].opval, yyvsp[0].opval) ); }
+#line 190 "perly.y"
+{ yyval.opval = scope(yyvsp[0].opval); }
 break;
 case 29:
-#line 190 "perly.y"
-{ copline = yyvsp[-3].ival;
-                           yyval.opval = newSTATEOP(0, yyvsp[-4].pval,
-                                   newWHILEOP(0, 1, (LOOP*)Nullop,
-                                       scope(yyvsp[-2].opval), yyvsp[-1].opval, yyvsp[0].opval) ); }
+#line 194 "perly.y"
+{ copline = yyvsp[-6].ival;
+                           yyval.opval = block_end(yyvsp[-4].ival,
+                                  newSTATEOP(0, yyvsp[-7].pval,
+                                    newWHILEOP(0, 1, (LOOP*)Nullop,
+                                               yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval))); }
 break;
 case 30:
-#line 195 "perly.y"
-{ copline = yyvsp[-3].ival;
-                           yyval.opval = newSTATEOP(0, yyvsp[-4].pval,
-                                   newWHILEOP(0, 1, (LOOP*)Nullop,
-                                       invert(scalar(scope(yyvsp[-2].opval))), yyvsp[-1].opval, yyvsp[0].opval)); }
+#line 200 "perly.y"
+{ copline = yyvsp[-6].ival;
+                           yyval.opval = block_end(yyvsp[-4].ival,
+                                  newSTATEOP(0, yyvsp[-7].pval,
+                                    newWHILEOP(0, 1, (LOOP*)Nullop,
+                                               yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval))); }
 break;
 case 31:
-#line 200 "perly.y"
-{ yyval.opval = newFOROP(0, yyvsp[-7].pval, yyvsp[-6].ival, mod(yyvsp[-5].opval, OP_ENTERLOOP),
-                               yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval); }
+#line 206 "perly.y"
+{ copline = yyvsp[-3].ival;
+                           deprecate("while BLOCK BLOCK");
+                           yyval.opval = newSTATEOP(0, yyvsp[-4].pval,
+                                  newWHILEOP(0, 1, (LOOP*)Nullop,
+                                             scope(yyvsp[-2].opval), yyvsp[-1].opval, yyvsp[0].opval)); }
 break;
 case 32:
-#line 203 "perly.y"
-{ yyval.opval = newFOROP(0, yyvsp[-6].pval, yyvsp[-5].ival, Nullop, yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval); }
+#line 212 "perly.y"
+{ copline = yyvsp[-3].ival;
+                           deprecate("until BLOCK BLOCK");
+                           yyval.opval = newSTATEOP(0, yyvsp[-4].pval,
+                                  newWHILEOP(0, 1, (LOOP*)Nullop,
+                                             invert(scalar(scope(yyvsp[-2].opval))),
+                                             yyvsp[-1].opval, yyvsp[0].opval)); }
 break;
 case 33:
-#line 206 "perly.y"
-{  copline = yyvsp[-8].ival;
-                           yyval.opval = append_elem(OP_LINESEQ,
-                                   newSTATEOP(0, yyvsp[-9].pval, scalar(yyvsp[-6].opval)),
-                                   newSTATEOP(0, yyvsp[-9].pval,
-                                       newWHILEOP(0, 1, (LOOP*)Nullop,
-                                           scalar(yyvsp[-4].opval), yyvsp[0].opval, scalar(yyvsp[-2].opval)) )); }
+#line 219 "perly.y"
+{ yyval.opval = block_end(yyvsp[-6].ival,
+                                newFOROP(0, yyvsp[-9].pval, yyvsp[-8].ival, yyvsp[-5].opval, yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval)); }
 break;
 case 34:
-#line 213 "perly.y"
+#line 222 "perly.y"
+{ yyval.opval = block_end(yyvsp[-4].ival,
+                                newFOROP(0, yyvsp[-8].pval, yyvsp[-7].ival, mod(yyvsp[-6].opval, OP_ENTERLOOP),
+                                         yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval)); }
+break;
+case 35:
+#line 226 "perly.y"
+{ yyval.opval = block_end(yyvsp[-4].ival,
+                                newFOROP(0, yyvsp[-7].pval, yyvsp[-6].ival, Nullop, yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval)); }
+break;
+case 36:
+#line 230 "perly.y"
+{ copline = yyvsp[-9].ival;
+                           yyval.opval = block_end(yyvsp[-7].ival,
+                                  append_elem(OP_LINESEQ, scalar(yyvsp[-6].opval),
+                                    newSTATEOP(0, yyvsp[-10].pval,
+                                      newWHILEOP(0, 1, (LOOP*)Nullop,
+                                                 scalar(yyvsp[-4].opval),
+                                                 yyvsp[0].opval, scalar(yyvsp[-2].opval))))); }
+break;
+case 37:
+#line 238 "perly.y"
 { yyval.opval = newSTATEOP(0,
                                yyvsp[-2].pval, newWHILEOP(0, 1, (LOOP*)Nullop,
                                        Nullop, yyvsp[-1].opval, yyvsp[0].opval)); }
 break;
-case 35:
-#line 219 "perly.y"
+case 38:
+#line 244 "perly.y"
 { yyval.opval = Nullop; }
 break;
-case 37:
-#line 224 "perly.y"
+case 40:
+#line 249 "perly.y"
 { (void)scan_num("1"); yyval.opval = yylval.opval; }
 break;
-case 39:
-#line 229 "perly.y"
+case 42:
+#line 254 "perly.y"
+{ yyval.opval = invert(scalar(yyvsp[0].opval)); }
+break;
+case 43:
+#line 258 "perly.y"
+{ yyval.opval = yyvsp[0].opval; intro_my(); }
+break;
+case 44:
+#line 262 "perly.y"
+{ yyval.opval = yyvsp[0].opval; intro_my(); }
+break;
+case 45:
+#line 266 "perly.y"
+{ yyval.opval = yyvsp[0].opval; intro_my(); }
+break;
+case 46:
+#line 270 "perly.y"
+{ yyval.opval = yyvsp[0].opval; intro_my(); }
+break;
+case 47:
+#line 274 "perly.y"
 { yyval.pval = Nullch; }
 break;
-case 41:
-#line 234 "perly.y"
+case 49:
+#line 279 "perly.y"
 { yyval.ival = 0; }
 break;
-case 42:
-#line 236 "perly.y"
+case 50:
+#line 281 "perly.y"
 { yyval.ival = 0; }
 break;
-case 43:
-#line 238 "perly.y"
+case 51:
+#line 283 "perly.y"
 { yyval.ival = 0; }
 break;
-case 44:
-#line 240 "perly.y"
+case 52:
+#line 285 "perly.y"
 { yyval.ival = 0; }
 break;
-case 45:
-#line 244 "perly.y"
+case 53:
+#line 289 "perly.y"
 { newFORM(yyvsp[-2].ival, yyvsp[-1].opval, yyvsp[0].opval); }
 break;
-case 46:
-#line 246 "perly.y"
+case 54:
+#line 291 "perly.y"
 { newFORM(yyvsp[-1].ival, Nullop, yyvsp[0].opval); }
 break;
-case 47:
-#line 250 "perly.y"
+case 55:
+#line 295 "perly.y"
 { newSUB(yyvsp[-3].ival, yyvsp[-2].opval, yyvsp[-1].opval, yyvsp[0].opval); }
 break;
-case 48:
-#line 252 "perly.y"
+case 56:
+#line 297 "perly.y"
 { newSUB(yyvsp[-3].ival, yyvsp[-2].opval, yyvsp[-1].opval, Nullop); expect = XSTATE; }
 break;
-case 49:
-#line 256 "perly.y"
+case 57:
+#line 301 "perly.y"
 { yyval.opval = Nullop; }
 break;
-case 51:
-#line 261 "perly.y"
+case 59:
+#line 306 "perly.y"
 { yyval.ival = start_subparse(); }
 break;
-case 52:
-#line 265 "perly.y"
+case 60:
+#line 310 "perly.y"
 { package(yyvsp[-1].opval); }
 break;
-case 53:
-#line 267 "perly.y"
+case 61:
+#line 312 "perly.y"
 { package(Nullop); }
 break;
-case 54:
-#line 271 "perly.y"
+case 62:
+#line 316 "perly.y"
 { utilize(yyvsp[-5].ival, yyvsp[-4].ival, yyvsp[-3].opval, yyvsp[-2].opval, yyvsp[-1].opval); }
 break;
-case 55:
-#line 275 "perly.y"
+case 63:
+#line 320 "perly.y"
 { yyval.opval = newLOGOP(OP_AND, 0, yyvsp[-2].opval, yyvsp[0].opval); }
 break;
-case 56:
-#line 277 "perly.y"
+case 64:
+#line 322 "perly.y"
 { yyval.opval = newLOGOP(yyvsp[-1].ival, 0, yyvsp[-2].opval, yyvsp[0].opval); }
 break;
-case 58:
-#line 282 "perly.y"
+case 66:
+#line 327 "perly.y"
 { yyval.opval = yyvsp[-1].opval; }
 break;
-case 59:
-#line 284 "perly.y"
+case 67:
+#line 329 "perly.y"
 { yyval.opval = append_elem(OP_LIST, yyvsp[-2].opval, yyvsp[0].opval); }
 break;
-case 61:
-#line 289 "perly.y"
+case 69:
+#line 334 "perly.y"
 { yyval.opval = convert(yyvsp[-2].ival, OPf_STACKED,
                                prepend_elem(OP_LIST, newGVREF(yyvsp[-2].ival,yyvsp[-1].opval), yyvsp[0].opval) ); }
 break;
-case 62:
-#line 292 "perly.y"
+case 70:
+#line 337 "perly.y"
 { yyval.opval = convert(yyvsp[-4].ival, OPf_STACKED,
                                prepend_elem(OP_LIST, newGVREF(yyvsp[-4].ival,yyvsp[-2].opval), yyvsp[-1].opval) ); }
 break;
-case 63:
-#line 295 "perly.y"
+case 71:
+#line 340 "perly.y"
 { yyval.opval = convert(OP_ENTERSUB, OPf_STACKED,
                                append_elem(OP_LIST,
-                                   prepend_elem(OP_LIST, yyvsp[-5].opval, yyvsp[-1].opval),
+                                   prepend_elem(OP_LIST, scalar(yyvsp[-5].opval), yyvsp[-1].opval),
                                    newUNOP(OP_METHOD, 0, yyvsp[-3].opval))); }
 break;
-case 64:
-#line 300 "perly.y"
+case 72:
+#line 345 "perly.y"
 { yyval.opval = convert(OP_ENTERSUB, OPf_STACKED,
                                append_elem(OP_LIST,
                                    prepend_elem(OP_LIST, yyvsp[-1].opval, yyvsp[0].opval),
                                    newUNOP(OP_METHOD, 0, yyvsp[-2].opval))); }
 break;
-case 65:
-#line 305 "perly.y"
+case 73:
+#line 350 "perly.y"
 { yyval.opval = convert(OP_ENTERSUB, OPf_STACKED,
                                append_elem(OP_LIST,
                                    prepend_elem(OP_LIST, yyvsp[-3].opval, yyvsp[-1].opval),
                                    newUNOP(OP_METHOD, 0, yyvsp[-4].opval))); }
 break;
-case 66:
-#line 310 "perly.y"
+case 74:
+#line 355 "perly.y"
 { yyval.opval = convert(yyvsp[-1].ival, 0, yyvsp[0].opval); }
 break;
-case 67:
-#line 312 "perly.y"
+case 75:
+#line 357 "perly.y"
 { yyval.opval = convert(yyvsp[-3].ival, 0, yyvsp[-1].opval); }
 break;
-case 68:
-#line 314 "perly.y"
+case 76:
+#line 359 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED,
                            append_elem(OP_LIST,
                              prepend_elem(OP_LIST, newANONSUB(yyvsp[-2].ival, 0, yyvsp[-1].opval), yyvsp[0].opval),
                              yyvsp[-3].opval)); }
 break;
-case 71:
-#line 325 "perly.y"
+case 79:
+#line 370 "perly.y"
 { yyval.opval = newASSIGNOP(OPf_STACKED, yyvsp[-2].opval, yyvsp[-1].ival, yyvsp[0].opval); }
 break;
-case 72:
-#line 327 "perly.y"
+case 80:
+#line 372 "perly.y"
 { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); }
 break;
-case 73:
-#line 329 "perly.y"
+case 81:
+#line 374 "perly.y"
 {   if (yyvsp[-1].ival != OP_REPEAT)
                                scalar(yyvsp[-2].opval);
                            yyval.opval = newBINOP(yyvsp[-1].ival, 0, yyvsp[-2].opval, scalar(yyvsp[0].opval)); }
 break;
-case 74:
-#line 333 "perly.y"
+case 82:
+#line 378 "perly.y"
 { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); }
 break;
-case 75:
-#line 335 "perly.y"
+case 83:
+#line 380 "perly.y"
 { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); }
 break;
-case 76:
-#line 337 "perly.y"
+case 84:
+#line 382 "perly.y"
 { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); }
 break;
-case 77:
-#line 339 "perly.y"
+case 85:
+#line 384 "perly.y"
 { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); }
 break;
-case 78:
-#line 341 "perly.y"
+case 86:
+#line 386 "perly.y"
 { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); }
 break;
-case 79:
-#line 343 "perly.y"
+case 87:
+#line 388 "perly.y"
 { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); }
 break;
-case 80:
-#line 345 "perly.y"
+case 88:
+#line 390 "perly.y"
 { yyval.opval = newRANGE(yyvsp[-1].ival, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval));}
 break;
-case 81:
-#line 347 "perly.y"
+case 89:
+#line 392 "perly.y"
 { yyval.opval = newLOGOP(OP_AND, 0, yyvsp[-2].opval, yyvsp[0].opval); }
 break;
-case 82:
-#line 349 "perly.y"
+case 90:
+#line 394 "perly.y"
 { yyval.opval = newLOGOP(OP_OR, 0, yyvsp[-2].opval, yyvsp[0].opval); }
 break;
-case 83:
-#line 351 "perly.y"
+case 91:
+#line 396 "perly.y"
 { yyval.opval = newCONDOP(0, yyvsp[-4].opval, yyvsp[-2].opval, yyvsp[0].opval); }
 break;
-case 84:
-#line 353 "perly.y"
+case 92:
+#line 398 "perly.y"
 { yyval.opval = bind_match(yyvsp[-1].ival, yyvsp[-2].opval, yyvsp[0].opval); }
 break;
-case 85:
-#line 356 "perly.y"
+case 93:
+#line 401 "perly.y"
 { yyval.opval = newUNOP(OP_NEGATE, 0, scalar(yyvsp[0].opval)); }
 break;
-case 86:
-#line 358 "perly.y"
+case 94:
+#line 403 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
-case 87:
-#line 360 "perly.y"
+case 95:
+#line 405 "perly.y"
 { yyval.opval = newUNOP(OP_NOT, 0, scalar(yyvsp[0].opval)); }
 break;
-case 88:
-#line 362 "perly.y"
+case 96:
+#line 407 "perly.y"
 { yyval.opval = newUNOP(OP_COMPLEMENT, 0, scalar(yyvsp[0].opval));}
 break;
-case 89:
-#line 364 "perly.y"
+case 97:
+#line 409 "perly.y"
 { yyval.opval = newUNOP(OP_REFGEN, 0, mod(yyvsp[0].opval,OP_REFGEN)); }
 break;
-case 90:
-#line 366 "perly.y"
+case 98:
+#line 411 "perly.y"
 { yyval.opval = newUNOP(OP_POSTINC, 0,
                                        mod(scalar(yyvsp[-1].opval), OP_POSTINC)); }
 break;
-case 91:
-#line 369 "perly.y"
+case 99:
+#line 414 "perly.y"
 { yyval.opval = newUNOP(OP_POSTDEC, 0,
                                        mod(scalar(yyvsp[-1].opval), OP_POSTDEC)); }
 break;
-case 92:
-#line 372 "perly.y"
+case 100:
+#line 417 "perly.y"
 { yyval.opval = newUNOP(OP_PREINC, 0,
                                        mod(scalar(yyvsp[0].opval), OP_PREINC)); }
 break;
-case 93:
-#line 375 "perly.y"
+case 101:
+#line 420 "perly.y"
 { yyval.opval = newUNOP(OP_PREDEC, 0,
                                        mod(scalar(yyvsp[0].opval), OP_PREDEC)); }
 break;
-case 94:
-#line 378 "perly.y"
+case 102:
+#line 423 "perly.y"
 { yyval.opval = localize(yyvsp[0].opval,yyvsp[-1].ival); }
 break;
-case 95:
-#line 380 "perly.y"
+case 103:
+#line 425 "perly.y"
 { yyval.opval = sawparens(yyvsp[-1].opval); }
 break;
-case 96:
-#line 382 "perly.y"
+case 104:
+#line 427 "perly.y"
 { yyval.opval = sawparens(newNULLLIST()); }
 break;
-case 97:
-#line 384 "perly.y"
+case 105:
+#line 429 "perly.y"
 { yyval.opval = newANONLIST(yyvsp[-1].opval); }
 break;
-case 98:
-#line 386 "perly.y"
+case 106:
+#line 431 "perly.y"
 { yyval.opval = newANONLIST(Nullop); }
 break;
-case 99:
-#line 388 "perly.y"
+case 107:
+#line 433 "perly.y"
 { yyval.opval = newANONHASH(yyvsp[-2].opval); }
 break;
-case 100:
-#line 390 "perly.y"
+case 108:
+#line 435 "perly.y"
 { yyval.opval = newANONHASH(Nullop); }
 break;
-case 101:
-#line 392 "perly.y"
+case 109:
+#line 437 "perly.y"
 { yyval.opval = newANONSUB(yyvsp[-2].ival, yyvsp[-1].opval, yyvsp[0].opval); }
 break;
-case 102:
-#line 394 "perly.y"
+case 110:
+#line 439 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
-case 103:
-#line 396 "perly.y"
+case 111:
+#line 441 "perly.y"
 { yyval.opval = newBINOP(OP_GELEM, 0, newGVREF(0,yyvsp[-4].opval), yyvsp[-2].opval); }
 break;
-case 104:
-#line 398 "perly.y"
+case 112:
+#line 443 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
-case 105:
-#line 400 "perly.y"
+case 113:
+#line 445 "perly.y"
 { yyval.opval = newBINOP(OP_AELEM, 0, oopsAV(yyvsp[-3].opval), scalar(yyvsp[-1].opval)); }
 break;
-case 106:
-#line 402 "perly.y"
+case 114:
+#line 447 "perly.y"
 { yyval.opval = newBINOP(OP_AELEM, 0,
                                        ref(newAVREF(yyvsp[-4].opval),OP_RV2AV),
                                        scalar(yyvsp[-1].opval));}
 break;
-case 107:
-#line 406 "perly.y"
+case 115:
+#line 451 "perly.y"
 { assertref(yyvsp[-3].opval); yyval.opval = newBINOP(OP_AELEM, 0,
                                        ref(newAVREF(yyvsp[-3].opval),OP_RV2AV),
                                        scalar(yyvsp[-1].opval));}
 break;
-case 108:
-#line 410 "perly.y"
+case 116:
+#line 455 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
-case 109:
-#line 412 "perly.y"
+case 117:
+#line 457 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
-case 110:
-#line 414 "perly.y"
+case 118:
+#line 459 "perly.y"
 { yyval.opval = newUNOP(OP_AV2ARYLEN, 0, ref(yyvsp[0].opval, OP_AV2ARYLEN));}
 break;
-case 111:
-#line 416 "perly.y"
+case 119:
+#line 461 "perly.y"
 { yyval.opval = newBINOP(OP_HELEM, 0, oopsHV(yyvsp[-4].opval), jmaybe(yyvsp[-2].opval));
                            expect = XOPERATOR; }
 break;
-case 112:
-#line 419 "perly.y"
+case 120:
+#line 464 "perly.y"
 { yyval.opval = newBINOP(OP_HELEM, 0,
                                        ref(newHVREF(yyvsp[-5].opval),OP_RV2HV),
                                        jmaybe(yyvsp[-2].opval));
                            expect = XOPERATOR; }
 break;
-case 113:
-#line 424 "perly.y"
+case 121:
+#line 469 "perly.y"
 { assertref(yyvsp[-4].opval); yyval.opval = newBINOP(OP_HELEM, 0,
                                        ref(newHVREF(yyvsp[-4].opval),OP_RV2HV),
                                        jmaybe(yyvsp[-2].opval));
                            expect = XOPERATOR; }
 break;
-case 114:
-#line 429 "perly.y"
+case 122:
+#line 474 "perly.y"
 { yyval.opval = newSLICEOP(0, yyvsp[-1].opval, yyvsp[-4].opval); }
 break;
-case 115:
-#line 431 "perly.y"
+case 123:
+#line 476 "perly.y"
 { yyval.opval = newSLICEOP(0, yyvsp[-1].opval, Nullop); }
 break;
-case 116:
-#line 433 "perly.y"
+case 124:
+#line 478 "perly.y"
 { yyval.opval = prepend_elem(OP_ASLICE,
                                newOP(OP_PUSHMARK, 0),
                                    newLISTOP(OP_ASLICE, 0,
                                        list(yyvsp[-1].opval),
                                        ref(yyvsp[-3].opval, OP_ASLICE))); }
 break;
-case 117:
-#line 439 "perly.y"
+case 125:
+#line 484 "perly.y"
 { yyval.opval = prepend_elem(OP_HSLICE,
                                newOP(OP_PUSHMARK, 0),
                                    newLISTOP(OP_HSLICE, 0,
@@ -2058,38 +2065,38 @@ case 117:
                                        ref(oopsHV(yyvsp[-4].opval), OP_HSLICE)));
                            expect = XOPERATOR; }
 break;
-case 118:
-#line 446 "perly.y"
+case 126:
+#line 491 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
-case 119:
-#line 448 "perly.y"
+case 127:
+#line 493 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, 0, scalar(yyvsp[0].opval)); }
 break;
-case 120:
-#line 450 "perly.y"
+case 128:
+#line 495 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar(yyvsp[-2].opval)); }
 break;
-case 121:
-#line 452 "perly.y"
+case 129:
+#line 497 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED,
                            append_elem(OP_LIST, yyvsp[-1].opval, scalar(yyvsp[-3].opval))); }
 break;
-case 122:
-#line 455 "perly.y"
+case 130:
+#line 500 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED,
                            append_elem(OP_LIST, yyvsp[0].opval, scalar(yyvsp[-1].opval))); }
 break;
-case 123:
-#line 458 "perly.y"
+case 131:
+#line 503 "perly.y"
 { yyval.opval = newUNOP(OP_DOFILE, 0, scalar(yyvsp[0].opval)); }
 break;
-case 124:
-#line 460 "perly.y"
+case 132:
+#line 505 "perly.y"
 { yyval.opval = newUNOP(OP_NULL, OPf_SPECIAL, scope(yyvsp[0].opval)); }
 break;
-case 125:
-#line 462 "perly.y"
+case 133:
+#line 507 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB,
                            OPf_SPECIAL|OPf_STACKED,
                            prepend_elem(OP_LIST,
@@ -2098,8 +2105,8 @@ case 125:
                                    scalar(yyvsp[-2].opval)
                                )),Nullop)); dep();}
 break;
-case 126:
-#line 470 "perly.y"
+case 134:
+#line 515 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB,
                            OPf_SPECIAL|OPf_STACKED,
                            append_elem(OP_LIST,
@@ -2109,139 +2116,151 @@ case 126:
                                    scalar(yyvsp[-3].opval)
                                )))); dep();}
 break;
-case 127:
-#line 479 "perly.y"
+case 135:
+#line 524 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
                            prepend_elem(OP_LIST,
                                scalar(newCVREF(0,scalar(yyvsp[-2].opval))), Nullop)); dep();}
 break;
-case 128:
-#line 483 "perly.y"
+case 136:
+#line 528 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
                            prepend_elem(OP_LIST,
                                yyvsp[-1].opval,
                                scalar(newCVREF(0,scalar(yyvsp[-3].opval))))); dep();}
 break;
-case 129:
-#line 488 "perly.y"
+case 137:
+#line 533 "perly.y"
 { yyval.opval = newOP(yyvsp[0].ival, OPf_SPECIAL);
                            hints |= HINT_BLOCK_SCOPE; }
 break;
-case 130:
-#line 491 "perly.y"
+case 138:
+#line 536 "perly.y"
 { yyval.opval = newLOOPEX(yyvsp[-1].ival,yyvsp[0].opval); }
 break;
-case 131:
-#line 493 "perly.y"
+case 139:
+#line 538 "perly.y"
 { yyval.opval = newUNOP(OP_NOT, 0, scalar(yyvsp[0].opval)); }
 break;
-case 132:
-#line 495 "perly.y"
+case 140:
+#line 540 "perly.y"
 { yyval.opval = newOP(yyvsp[0].ival, 0); }
 break;
-case 133:
-#line 497 "perly.y"
+case 141:
+#line 542 "perly.y"
 { yyval.opval = newUNOP(yyvsp[-1].ival, 0, yyvsp[0].opval); }
 break;
-case 134:
-#line 499 "perly.y"
+case 142:
+#line 544 "perly.y"
 { yyval.opval = newUNOP(yyvsp[-1].ival, 0, yyvsp[0].opval); }
 break;
-case 135:
-#line 501 "perly.y"
+case 143:
+#line 546 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED,
                            append_elem(OP_LIST, yyvsp[0].opval, scalar(yyvsp[-1].opval))); }
 break;
-case 136:
-#line 504 "perly.y"
+case 144:
+#line 549 "perly.y"
 { yyval.opval = newOP(yyvsp[0].ival, 0); }
 break;
-case 137:
-#line 506 "perly.y"
+case 145:
+#line 551 "perly.y"
 { yyval.opval = newOP(yyvsp[-2].ival, 0); }
 break;
-case 138:
-#line 508 "perly.y"
+case 146:
+#line 553 "perly.y"
 { yyval.opval = newUNOP(OP_ENTERSUB, 0,
                                scalar(yyvsp[0].opval)); }
 break;
-case 139:
-#line 511 "perly.y"
+case 147:
+#line 556 "perly.y"
 { yyval.opval = newOP(yyvsp[-2].ival, OPf_SPECIAL); }
 break;
-case 140:
-#line 513 "perly.y"
+case 148:
+#line 558 "perly.y"
 { yyval.opval = newUNOP(yyvsp[-3].ival, 0, yyvsp[-1].opval); }
 break;
-case 141:
-#line 515 "perly.y"
+case 149:
+#line 560 "perly.y"
 { yyval.opval = pmruntime(yyvsp[-3].opval, yyvsp[-1].opval, Nullop); }
 break;
-case 142:
-#line 517 "perly.y"
+case 150:
+#line 562 "perly.y"
 { yyval.opval = pmruntime(yyvsp[-5].opval, yyvsp[-3].opval, yyvsp[-1].opval); }
 break;
-case 145:
-#line 523 "perly.y"
+case 153:
+#line 568 "perly.y"
 { yyval.opval = Nullop; }
 break;
-case 146:
-#line 525 "perly.y"
+case 154:
+#line 570 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
-case 147:
-#line 529 "perly.y"
+case 155:
+#line 574 "perly.y"
 { yyval.opval = Nullop; }
 break;
-case 148:
-#line 531 "perly.y"
+case 156:
+#line 576 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
-case 149:
-#line 533 "perly.y"
+case 157:
+#line 578 "perly.y"
 { yyval.opval = yyvsp[-1].opval; }
 break;
-case 150:
-#line 537 "perly.y"
+case 158:
+#line 581 "perly.y"
+{ yyval.ival = 0; }
+break;
+case 159:
+#line 582 "perly.y"
+{ yyval.ival = 1; }
+break;
+case 160:
+#line 586 "perly.y"
+{ in_my = 0; yyval.opval = my(yyvsp[0].opval); }
+break;
+case 161:
+#line 590 "perly.y"
 { yyval.opval = newCVREF(yyvsp[-1].ival,yyvsp[0].opval); }
 break;
-case 151:
-#line 541 "perly.y"
+case 162:
+#line 594 "perly.y"
 { yyval.opval = newSVREF(yyvsp[0].opval); }
 break;
-case 152:
-#line 545 "perly.y"
+case 163:
+#line 598 "perly.y"
 { yyval.opval = newAVREF(yyvsp[0].opval); }
 break;
-case 153:
-#line 549 "perly.y"
+case 164:
+#line 602 "perly.y"
 { yyval.opval = newHVREF(yyvsp[0].opval); }
 break;
-case 154:
-#line 553 "perly.y"
+case 165:
+#line 606 "perly.y"
 { yyval.opval = newAVREF(yyvsp[0].opval); }
 break;
-case 155:
-#line 557 "perly.y"
+case 166:
+#line 610 "perly.y"
 { yyval.opval = newGVREF(0,yyvsp[0].opval); }
 break;
-case 156:
-#line 561 "perly.y"
+case 167:
+#line 614 "perly.y"
 { yyval.opval = scalar(yyvsp[0].opval); }
 break;
-case 157:
-#line 563 "perly.y"
+case 168:
+#line 616 "perly.y"
 { yyval.opval = scalar(yyvsp[0].opval);  }
 break;
-case 158:
-#line 565 "perly.y"
+case 169:
+#line 618 "perly.y"
 { yyval.opval = scope(yyvsp[0].opval); }
 break;
-case 159:
-#line 568 "perly.y"
+case 170:
+#line 621 "perly.y"
 { yyval.opval = yyvsp[0].opval; }
 break;
-#line 2230 "y_tab.c"
+#line 2249 "perly.c"
     }
     yyssp -= yym;
     yystate = *yyssp;
index c6ec3a4..dd92764 100644 (file)
 #define FUNC0 282
 #define FUNC1 283
 #define FUNC 284
-#define RELOP 285
-#define EQOP 286
-#define MULOP 287
-#define ADDOP 288
-#define DOLSHARP 289
-#define DO 290
-#define LOCAL 291
-#define HASHBRACK 292
-#define NOAMP 293
-#define OROP 294
-#define ANDOP 295
-#define NOTOP 296
-#define LSTOP 297
-#define ASSIGNOP 298
-#define OROR 299
-#define ANDAND 300
-#define BITOROP 301
-#define BITANDOP 302
-#define UNIOP 303
-#define SHIFTOP 304
-#define MATCHOP 305
-#define UMINUS 306
-#define REFGEN 307
-#define POWOP 308
-#define PREINC 309
-#define PREDEC 310
-#define POSTINC 311
-#define POSTDEC 312
-#define ARROW 313
+#define UNIOP 285
+#define LSTOP 286
+#define RELOP 287
+#define EQOP 288
+#define MULOP 289
+#define ADDOP 290
+#define DOLSHARP 291
+#define DO 292
+#define HASHBRACK 293
+#define NOAMP 294
+#define LOCAL 295
+#define MY 296
+#define OROP 297
+#define ANDOP 298
+#define NOTOP 299
+#define ASSIGNOP 300
+#define OROR 301
+#define ANDAND 302
+#define BITOROP 303
+#define BITANDOP 304
+#define SHIFTOP 305
+#define MATCHOP 306
+#define UMINUS 307
+#define REFGEN 308
+#define POWOP 309
+#define PREINC 310
+#define PREDEC 311
+#define POSTINC 312
+#define POSTDEC 313
+#define ARROW 314
 typedef union {
     I32        ival;
     char *pval;
index b6f163f..e13747a 100644 (file)
--- a/vms/vms.c
+++ b/vms/vms.c
@@ -402,6 +402,7 @@ kill_file(char *name)
           set_errno(ENOENT); break;
         case RMS$_DEV:
           set_errno(ENODEV); break;
+        case RMS$_FNM:
         case RMS$_SYN:
         case SS$_INVFILFOROP:
           set_errno(EINVAL); break;
index 1e8d684..b2814ad 100644 (file)
 /* Assorted fiddling with sigs . . . */
 # include <signal.h>
 #define ABORT() abort()
+    /* VAXC's signal.h doesn't #define SIG_ERR, but provides BADSIG instead. */
+#if !defined(SIG_ERR) && defined(BADSIG)
+#  define SIG_ERR BADSIG
+#endif
+
 
 /* Used with our my_utime() routine in vms.c */
 struct utimbuf {
@@ -258,6 +263,9 @@ struct utimbuf {
     clock_t tms_cutime;   /* user time, children */
     clock_t tms_cstime;   /* system time, children - always 0 on VMS */
   };
+#else
+   /* The new headers change the times() prototype to tms from tbuffer */
+#  define tbuffer_t struct tms
 #endif
 
 /* Prior to VMS 7.0, the CRTL gmtime() routine was a stub which always
index 454e2dc..0c37b6b 100644 (file)
@@ -154,7 +154,9 @@ register char **env;
 
     tmpstr = walk(0,0,root,&i,P_MIN);
     str = str_make(STARTPERL);
-    str_cat(str, "\neval 'exec perl -S $0 \"$@\"'\n\
+    str_cat(str, "\neval 'exec ");
+    str_cat(str, BIN);
+    str_cat(str, "/perl -S $0 ${1+\"$@\"}'\n\
     if $running_under_some_shell;\n\
                        # this emulates #! processing on NIH machines.\n\
                        # (remove #! line above if indigestible)\n\n");
index 32f78fe..c024faf 100644 (file)
@@ -25,10 +25,11 @@ print "Extracting $file (with variable substitutions)\n";
 # You can use $Config{...} to use Configure variables.
 
 print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
-    eval 'exec perl -S \$0 "\$@"'
-       if 0;
+$Config{startperl}
+    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
 \$startperl = "$Config{startperl}";
+\$perlpath = "$Config{perlpath}";
 !GROK!THIS!
 
 # In the following, perl variables are not expanded during extraction.
@@ -241,8 +242,7 @@ while (@ARGV) {
 
 print <<"END";
 $startperl
-
-eval 'exec perl -S \$0 \${1+"\$@"}'
+    eval 'exec $perlpath -S \$0 \${1+"\$@"}'
        if \$running_under_some_shell;
 
 END
index 9d7297b..e5c5bd6 100644 (file)
@@ -25,10 +25,11 @@ print "Extracting $file (with variable substitutions)\n";
 # You can use $Config{...} to use Configure variables.
 
 print OUT <<"!GROK!THIS!";
-$Config{'startperl'}
-    eval 'exec perl -S \$0 "\$@"'
-       if 0;
+$Config{startperl}
+    eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
+       if \$running_under_some_shell;
 \$startperl = "$Config{startperl}";
+\$perlpath = "$Config{perlpath}";
 !GROK!THIS!
 
 # In the following, perl variables are not expanded during extraction.
@@ -366,7 +367,7 @@ unless ($debug) {
 
     print &q(<<"EOT");
 :      $startperl
-:      eval 'exec perl -S \$0 \${1+"\$@"}'
+:      eval 'exec $perlpath -S \$0 \${1+"\$@"}'
 :              if \$running_under_some_shell;
 :      
 EOT