From: Perl 5 Porters Date: Fri, 5 Sep 1997 00:00:00 +0000 (+0000) Subject: [inseparable changes from patch to perl 5.004_04] X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=fb73857aa0bfa8ed43d4d2f972c564c70a57e0c4;p=p5sagit%2Fp5-mst-13.2.git [inseparable changes from patch to perl 5.004_04] [editor's note: this one imported like a charm!] TESTS - Subject: Improve pragma/locale test 102 - and don't fail, just warn From: Jarkko Hietaniemi Files: t/pragma/locale.t Subject: Invalid test output in t/op/taint.t in trial 1 From: Dan Sugalski Files: t/op/taint.t t/op/taint.t prints out invalid ok messages for tests it skips. Rather than printing "ok 136" it prints "136 ok". p5p-msgid: 3.0.3.32.19970919160918.00857a50@stargate.lbcc.cc.or.us UTILITIES - Subject: Perldoc tiny patch to avoid $0 From: Ilya Zakharevich Files: utils/perldoc.PL Msg-ID: 199709122141.RAA16846@monk.mps.ohio-state.edu (applied based on p5p patch as commit 0b166b6635cf199f072db516b2a523ee659394d5) Subject: h2ph broken in 5.004_02 From: David Mazieres Files: utils/h2ph.PL Msg-ID: 199708201700.KAA02621@www.chapin.edu (applied based on p5p patch as commit 4a8e146e38ec2045f1f817a7cb578e1b1f80f39f) Subject: add key_t caddr_t to h2ph From: Tony Sanders Files: eg/sysvipc/ipcsem utils/h2ph.PL Msg-ID: 199708272301.RAA12803@austin.bsdi.com (applied based on p5p patch as commit 0806a92ffc3a74ca70aa81051cdf2a306cd0a8af) Subject: perldoc search ., lib and blib/* if -f 'Makefile.PL' From: Tim Bunce Files: utils/perldoc.PL Subject: perldoc finds wrong pod2man (from perldoc source) # We must look both in @INC for library modules and in PATH # for executables, like h2xs or perldoc itself. Unfortunately, searching PATH for installed perl executables like pod2man is INCORRECT. perldoc should start by searching the directory it was executed from, which might not be in the PATH at all. Credited: Joseph "Moof-in'" Hall p5p-msgid: 199708251732.KAA19299@gadget.cscaper.com Subject: 5.004m4t1: perlbug: NIS domainname gets into wrong places From: Andreas J. Koenig Files: utils/perlbug.PL Msg-ID: sfcg1qy38as.fsf@anna.in-berlin.de (applied based on p5p patch as commit 41f926b844140b7f7eaa9302113e45df3a9f9ff4) Subject: add better local patch info to perlbug From: Tim Bunce Files: utils/perlbug.PL Subject: perldoc - suggest modules if requested module not found From: Anthony David Files: utils/perldoc.PL private-msgid: 3439CD83.6969@netinfo.com.au Subject: perldoc mail::foo tries to read binary /usr/ucb/mail From: Tim Bunce Files: utils/perldoc.PL Subject: perldoc weirdness perldoc mail::imap yields: {joseph}:79% perldoc mail::foo can't open /usr/ucb/mail: Permission denied at ./pod2man line 362. Credited: Joseph "Moof-in'" Hall p5p-msgid: 199710082014.NAA00808@gadget.cscaper.com Subject: perldoc -f setpwent (for example) returns no descriptive text From: Tim Bunce Files: utils/perldoc.PL Subject: perldoc diffs: don't search auto - much faster From: "Joseph N. Hall" Files: utils/perldoc.PL Msg-ID: MailDrop1.2d7dPPC.971012211957@screechy.cscaper.com (applied based on p5p patch as commit 62b753c6ae4ab9bf22fbb6ec7ceac820bcef8fe4) --- fb73857aa0bfa8ed43d4d2f972c564c70a57e0c4 diff --cc Changes index 1675e31,1675e31..7475501 --- a/Changes +++ b/Changes @@@ -42,9 -42,9 +42,836 @@@ current addresses (as of March 1997) And the Keepers of the Patch Pumpkin: Charles Bailey ++ Tim Bunce Andy Dougherty Chip Salzenberg -- Tim Bunce ++ ++ ++---------------- ++Version 5.004_04 Maintenance release 4 for 5.004 ++---------------- ++ ++"1. Out of clutter, find simplicity. ++ 2. From discord, find harmony. ++ 3. In the middle of difficulty lies opportunity." ++ -- Albert Einstein, three rules of work ++ ++ ++ HEADLINES FOR THIS MAINTENANCE RELEASE ++ ++ Fixed gaps in tainting (readdir, readlink, gecos, bit vector ops). ++ Fixed memory leak in splice(@_). ++ Fixed debugger core dumps. ++ IO::Socket now sets autoflush by default. ++ Several perldoc bugs fixed, now faster and more helpful. ++ Fixed Win32 handle leak. ++ Many other improvements to Win32 support. ++ Many many other bug fixes and enhancements. ++ ++ ++ ------ BUILD PROCESS ------ ++ ++ Title: "ExtUtils::Liblist prints diagnostics to STDOUT (vs. STDERR)" ++ From: Andy Dougherty , jesse@ginger ++ (Jesse Glick) ++ Msg-ID: <199708290032.UAA15663@ginger>, ++ ++ Files: MANIFEST lib/ExtUtils/Liblist.pm ++ ++ Title: "Set LD_RUN_PATH when building suidperl" ++ From: Chip Salzenberg , Tony Sanders ++ ++ Msg-ID: <199708272226.QAA10206@austin.bsdi.com> ++ Files: Makefile.SH ++ ++ Title: "INSTALL version 1.26" ++ From: Andy Dougherty ++ Msg-ID: ++ Files: INSTALL ++ ++ Title: "Propagate MAKE=$(MAKE) through perl build" ++ From: Andy Dougherty ++ Msg-ID: ++ Files: Makefile.SH makedepend.SH x2p/Makefile.SH ext/util/make_ext ++ ++ Title: "update to installperl for perl5.004_02 to skip CVS dir" ++ From: Tony Sanders ++ Msg-ID: <199708272307.RAA13451@austin.bsdi.com> ++ Files: installperl ++ ++ Title: "makedepend loop on HP-UX 10.20" ++ Msg-ID: <1997Sep20.183731.2297443@cor.newman> ++ Files: Makefile.SH ++ ++ Title: "Tiny Grammaro in INSTALL" ++ From: koenig@anna.mind.de (Andreas J. Koenig) ++ Msg-ID: ++ Files: INSTALL ++ ++ Title: "Fix Configured osvers under Linux 1" ++ From: Andy Dougherty , Hugo van der ++ Sanden ++ Msg-ID: <199709241439.PAA17114@crypt.compulink.co.uk>, ++ ++ Files: Configure ++ ++ Title: "INSTALL-1.28" ++ From: Andy Dougherty ++ Msg-ID: ++ Files: INSTALL ++ ++ Title: "makedepend.SH fix for UNICOS" ++ From: Jarkko Hietaniemi ++ Msg-ID: <199710132039.XAA21459@alpha.hut.fi> ++ Files: makedepend.SH ++ ++ ------ CORE LANGUAGE ------ ++ ++ Title: "Re: "perl -d" dumps core when loading syslog.ph" ++ From: Jochen Wiedmann , Stephen McCamant ++ , ilya@math.ohio-state.edu (Ilya ++ Zakharevich) ++ Msg-ID: <1997Aug30.034921.2297381@cor.newman.upenn.edu>, ++ <3407639E.FEBF20BA@neckar-alb.de>, ++ ++ Files: pp_ctl.c ++ ++ Title: "Allow $obj->$coderef()" ++ From: Chip Salzenberg ++ Msg-ID: <199708291649.MAA23276@nielsenmedia.com> ++ Files: pp_hot.c ++ ++ Title: "Localize PV value in save_gp()", "typeglob differences in perl4 and ++ perl5" ++ From: Gurusamy Sarathy , Stephen McCamant ++ ++ Msg-ID: <199708272348.TAA03139@aatma.engin.umich.edu>, ++ ++ Files: scope.c t/op/ref.t ++ ++ Title: "Avoid assumption that STRLEN == I32" ++ From: Chip Salzenberg , Hallvard B Furuseth ++ ++ Msg-ID: <199708242310.BAA05497@bombur2.uio.no> ++ Files: hv.c ++ ++ Title: "Fix memory leak in splice(@_)" ++ From: "Tuomas J. Lukka" , Chip Salzenberg ++ ++ Msg-ID: ++ Files: proto.h av.c global.sym pp.c ++ ++ Title: "Fix line number of warnings in while() conditional", "misleading ++ uninit value warning" ++ From: Chip Salzenberg , Greg Bacon ++ ++ Msg-ID: <199708271607.LAA01403@crp-201.adtran.com> ++ Files: proto.h op.c perly.c perly.y ++ ++ Title: "-t and POSIX::isatty on IO::Handle objects", "Fix C<-t $handle>" ++ From: Chip Salzenberg , Greg Ward ++ ++ Msg-ID: <199708261754.NAA24826@bottom.bic.mni.mcgill.ca> ++ Files: pp_sys.c ++ ++ Title: "Fix output of invalid printf formats" ++ From: Chip Salzenberg , Hugo van der Sanden ++ ++ Msg-ID: <199708241529.QAA02457@crypt.compulink.co.uk> ++ Files: sv.c t/op/sprintf.t ++ ++ Title: "regexec.c regcppartblow declaration missing an arg" ++ From: Hugo van der Sanden ++ Msg-ID: <199708290059.BAA05808@crypt.compulink.co.uk> ++ Files: regexec.c ++ ++ Title: "taint readlink, readdir, gecos" ++ From: Jarkko Hietaniemi ++ Msg-ID: <199709131651.TAA13471@alpha.hut.fi> ++ Files: pod/perlfunc.pod pod/perlsec.pod pp_sys.c t/op/taint.t ++ ++ Title: "clean up old style package' usage in op.c" ++ From: Stephen Potter ++ Msg-ID: <199709151813.NAA14433@psisa.psa.pencom.com> ++ Files: op.c ++ ++ Title: "beautifying usage() code in perl.c" ++ From: "John L. Allen" <"John L. Allen"> ++ Msg-ID: ++ Files: perl.c ++ ++ Title: "debugger to fix core dumps, adds $^S" ++ From: Ilya Zakharevich ++ Msg-ID: <199709170823.EAA21359@monk.mps.ohio-state.edu> ++ Files: pod/perlvar.pod perl.h gv.c lib/perl5db.pl mg.c perl.c toke.c ++ ++ Title: "downgrade "my $foo masks earlier" from mandatory to "-w"" ++ From: Gurusamy Sarathy , Stephen Potter ++ ++ Msg-ID: <199709091832.NAA14763@psisa.psa.pencom.com>, ++ <199709102019.QAA09591@aatma.engin.umich.edu> ++ Files: pod/perldelta.pod pod/perldiag.pod op.c ++ ++ Title: "fix overridden glob() problems" ++ From: Gurusamy Sarathy ++ Msg-ID: <199709171645.MAA13988@aatma.engin.umich.edu> ++ Files: MANIFEST pod/perlsub.pod lib/File/DosGlob.pm op.c t/lib/dosglob.t ++ toke.c ++ ++ Title: "Reverse previous "Fix C" patch" ++ From: Chip Salzenberg , Kenneth Albanowski ++ , Tom Christiansen ++ ++ Msg-ID: <199707050155.VAA27394@rio.atlantic.net>, ++ <199708172326.RAA19344@jhereg.perl.com>, ++ ++ Files: toke.c ++ ++ Title: "printf type warning buglets in m3t2" ++ From: Hallvard B Furuseth ++ Msg-ID: <199708141017.MAA10225@bombur2.uio.no> ++ Files: regcomp.c regexec.c scope.c sv.c util.c x2p/util.c ++ ++ Title: "Localize PV value in save_gp()", "typeglob differences in perl4 and ++ perl5" ++ From: Gurusamy Sarathy , Stephen McCamant ++ ++ Msg-ID: <199708272348.TAA03139@aatma.engin.umich.edu>, ++ ++ Files: scope.c t/op/ref.t ++ ++ Title: "unpack now allows commas but -w warns", "unpack() difference ++ 5.003->5.004" ++ From: "John L. Allen" , Chip Salzenberg ++ , Jarkko Hietaniemi , ++ Jim Esten , Jim Esten ++ , timbo (Tim Bunce) ++ Msg-ID: <199709031632.LAA29584@wepco.com>, ++ <199709090257.WAA32670@rio.atlantic.net>, ++ <199709090917.MAA05602@alpha.hut.fi>, ++ <199709091000.LAA24094@toad.ig.co.uk>, ++ <341077FE.132F@wdynamic.com>, ++ ++ Files: pod/perldiag.pod pp.c ++ ++ Title: "5.004_04 trial 1 assorted minor details" ++ From: Hallvard B Furuseth ++ Msg-ID: ++ Files: Porting/pumpkin.pod hv.c op.c sv.c x2p/util.c ++ ++ Title: "A couple of 4_04t1 problems" ++ From: pmarquess@bfsec.bt.co.uk (Paul Marquess) ++ Msg-ID: <9709210959.AA28772@claudius.bfsec.bt.co.uk> ++ Files: lib/Cwd.pm perl.c ++ ++ Title: "Minor changes to ease port to MVS" ++ From: Len Johnson , SMTP%"BAHUFF@us.oracle.com" , ++ SMTP%"pfuntner@vnet.ibm.com" , pvhp@forte.com (Peter ++ Prymmer) ++ Msg-ID: <199709162058.NAA00952@mailsun2.us.oracle.com> ++ Files: unixish.h miniperlmain.c ++ ++ Title: "Truer version string and more robust perlbug" ++ From: "Michael A. Chase" , Hugo van der Sanden ++ ++ Msg-ID: <199709201514.QAA21187@crypt.compulink.co.uk>, ++ <1997Sep22.090701.2297448@cor.newman> ++ Files: perl.c utils/perlbug.PL ++ ++ Title: "Fix locale bug for constant (readonly) strings" ++ From: Jarkko Hietaniemi ++ Msg-ID: <199709262125.AAA28292@alpha.hut.fi> ++ Files: sv.c t/pragma/locale.t ++ ++ Title: "Enable truly global glob()" ++ From: Gurusamy Sarathy ++ Msg-ID: <199710080000.UAA18972@aatma.engin.umich.edu> ++ Files: op.c ++ ++ Title: "Fix for $0 truncation" ++ From: Tim Bunce ++ Msg-ID: <199710081703.SAA02653@toad.ig.co.uk> ++ Files: mg.c ++ ++ Title: "Fix for missing &import leaving stack untidy" ++ From: Chip Salzenberg ++ Msg-ID: <199709282252.SAA22915@nielsenmedia.com> ++ Files: pp_hot.c ++ ++ Title: "Larry's proto fix" ++ From: Chip Salzenberg ++ Msg-ID: <199709290004.UAA07559@nielsenmedia.com> ++ Files: op.c t/comp/proto.t ++ ++ Title: "Fix bugs with magical arrays and hashes (@ISA)" ++ From: Chip Salzenberg ++ Msg-ID: <199709232148.RAA29967@rio.atlantic.net> ++ Files: perl.h proto.h av.c global.sym gv.c mg.c pp.c pp_hot.c scope.c ++ t/op/method.t ++ ++ Title: "Perl_debug_log stream used for all DEBUG_*(...) macro uses" ++ From: Nick Ing-Simmons , Tim Bunce ++ Msg-ID: <199709230820.JAA11945@tiuk.ti.com> ++ Files: perl.c taint.c util.c ++ ++ Title: "Tainting bitwise vector ops" ++ From: Chip Salzenberg ++ Msg-ID: <199710061726.NAA16438@rio.atlantic.net> ++ Files: doop.c t/op/taint.t ++ ++ Title: "Enhance $^E on OS/2" ++ From: Ilya Zakharevich ++ Msg-ID: <199709232236.SAA04463@monk.mps.ohio-state.edu> ++ Files: pod/perlvar.pod mg.c os2/Changes ++ ++ Title: "option "!#... -- ..." in perl 5.004.03 seems not to work" ++ From: "John L. Allen" , Urs Thuermann ++ ++ Msg-ID: <199709232030.WAA30425@isnogud.escape.de>, ++ ++ Files: perl.c ++ ++ Title: "syswrite will again write a zero length buffer" ++ From: Cameron Simpson , Jarkko Hietaniemi , ++ aml@world.std.com (Andrew M. Langmead) ++ Msg-ID: <199710042107.AAA28561@alpha.hut.fi>, ++ <19971007104652-cameron-1-10391@sid.research.canon.com.au> ++ Files: pp_sys.c ++ ++ Title: "make Odd number of elements in hash list warning non-mandatory" ++ From: Jason Varsoke {81530} ++ Msg-ID: <199710021651.MAA15690@caesun7.msd.ray.com> ++ Files: pp.c pp_hot.c ++ ++ Title: "Fix defined() bug in m4t3 affecting LWP" ++ From: chip@atlantic.net@ig.co.uk () ++ Msg-ID: <199710101822.OAA14249@cyprus.atlantic.net> ++ Files: pp.c ++ ++ Title: "Include $archname in perl -v output" ++ From: Tim Bunce ++ Files: perl.c ++ ++ Title: "-I flag can easily lead to whitespace in @INC" ++ From: Kenneth Stephen , Tim Bunce , ++ pvhp@forte.com (Peter Prymmer) ++ Msg-ID: <199710130922.KAA07780@toad.ig.co.uk>, ++ <5040400007001448000002L082*@MHS>, ++ <9710132015.AA12457@forte.com> ++ Files: perl.c ++ ++ ------ DOCUMENTATION ------ ++ ++ Title: "perldiag.pod: gotcha in short pattern/char ops" ++ From: Jarkko Hietaniemi ++ Msg-ID: <199709050718.KAA31405@alpha.hut.fi> ++ Files: pod/perldiag.pod ++ ++ Title: "Documenting the perl-thanks address" ++ From: Tom Phoenix ++ Msg-ID: ++ Files: pod/perl.pod ++ ++ Title: "Missing section for @_ in perlvar." ++ From: abigail@fnx.com (Abigail) ++ Msg-ID: <199708142146.RAA13146@fnx.com> ++ Files: pod/perlvar.pod ++ ++ Title: "Promised information about AvHASH in perguts is not delivered" ++ From: mjd@plover.com ++ Files: pod/perlguts.pod ++ ++ Title: "perlfunc.doc - $_ aliasing in map, grep, foreach etc" ++ From: Ted Ashton ++ Msg-ID: <199708181852.OAA15901@ns.southern.edu> ++ Files: pod/perlfunc.pod ++ ++ Title: "-U Unsafe operations need -w to warn" ++ From: Tom Phoenix ++ Msg-ID: ++ Files: pod/perlrun.pod ++ ++ Title: "document the return value of syscall" ++ From: Hans Mulder ++ Msg-ID: <1997Sep7.160817.2297395@cor.newman> ++ Files: pod/perlfunc.pod ++ ++ Title: "minor fix for perltrap.pod" ++ From: abigail@fnx.com (Abigail) ++ Msg-ID: <199709170500.BAA14805@fnx.com> ++ Files: pod/perltrap.pod ++ ++ Title: "xsubpp: document advanced dynamic typemap usage" ++ From: "Rujith S. de Silva" ++ Files: pod/perlxs.pod ++ ++ Title: "Improved diagnostic docs for here-documents" ++ From: Tom Phoenix ++ Msg-ID: ++ Files: pod/perldiag.pod ++ ++ Title: "[POD patch] do-FILE forces scalar context." ++ From: Robin Houston ++ Msg-ID: <199709221553.QAA28409@carryon.oneworld.org> ++ Files: pod/perlfunc.pod ++ ++ Title: "perlop.pop. Behaviour of C vs C." ++ From: abigail@fnx.com (Abigail) ++ Msg-ID: <199709220107.VAA27064@fnx.com> ++ Files: pod/perlop.pod ++ ++ Title: "Clarify exec docs in perlfunc.pod" ++ From: Hugo van der Sanden ++ Msg-ID: <199710081353.OAA00834@crypt.compulink.co.uk> ++ Files: pod/perlfunc.pod ++ ++ Title: "Documentation patch for perlguts.pod--document tainting routines" ++ From: Dan Sugalski ++ Msg-ID: <3.0.3.32.19971007165226.02fd2cd4@osshe.edu> ++ Files: pod/perlguts.pod ++ ++ Title: "Man perlfunc: incorrect split example" ++ From: Joerg Porath ++ Msg-ID: <199709240620.IAA30928@pandora.hrz.tu-chemnitz.de> ++ Files: pod/perlfunc.pod ++ ++ Title: "Improve "Use of inherited AUTOLOAD for non-method" disgnostic" ++ From: rjray@uswest.com (Randy J. Ray) ++ Msg-ID: <199709231710.LAA08854@tremere.ecte.uswc.uswest.com> ++ Files: pod/perldiag.pod ++ ++ Title: "Document split-with-limit on empty string perl4/perl5 change" ++ From: "M.J.T. Guy" , Gisle Aas , Hugo ++ van der Sanden ++ Msg-ID: <199709221419.PAA03987@crypt.compulink.co.uk>, ++ ++ Files: pod/perlfunc.pod pod/perltrap.pod URI/URL/http.pm t/op/split.t ++ ++ Title: "Clarify close() docs" ++ From: Ilya Zakharevich ++ Msg-ID: <199710081653.MAA20611@monk.mps.ohio-state.edu> ++ Files: pod/perlfunc.pod ++ ++ Title: "perldiag log & sqrt - refer to Math::Complex package" ++ From: Jarkko Hietaniemi ++ Msg-ID: <199710042129.AAA20367@alpha.hut.fi> ++ Files: pod/perldiag.pod ++ ++ Title: "perlfunc.pod: sysread, syswrite docs" ++ From: Jarkko Hietaniemi ++ Msg-ID: <199710061910.WAA15266@alpha.hut.fi> ++ Files: pod/perlfunc.pod ++ ++ Title: "Document //gc" ++ From: abigail@fnx.com (Abigail) ++ Msg-ID: <199709232302.TAA27947@fnx.com> ++ Files: pod/perlop.pod ++ ++ Title: "repeating #! switches" ++ From: Chip Salzenberg , Robin Barker ++ ++ Msg-ID: <199709241736.NAA25855@rio.atlantic.net>, ++ <24778.9709241501@tempest.cise.npl.co.uk> ++ Files: pod/perlrun.pod ++ ++ Title: "Re: taint documentation bug" ++ From: Ken Estes , Tom Phoenix ++ Msg-ID: ++ Files: pod/perlsec.pod ++ ++ ------ LIBRARY AND EXTENSIONS ------ ++ ++ Title: "FileHandle.pm fails if Exporter has not been loaded previously" ++ From: jan.dubois@ibm.net (Jan Dubois) ++ Msg-ID: <3445e05b.17874041@smtp2.ibm.net> ++ Files: lib/FileHandle.pm ++ ++ Title: "Prefer startperl path over perlpath in MakeMaker" ++ From: Andreas Klussmann ++ Msg-ID: <199709162017.WAA05043@troubadix.infosys.heitec.net> ++ Files: lib/ExtUtils/MM_Unix.pm ++ ++ Title: "Sys::Hostname fails under Solaris 2.5 when setuid" ++ From: Patrick Hayes ++ Msg-ID: <199708201240.OAA04243@goblin.renault.fr> ++ Files: lib/Sys/Hostname.pm ++ ++ Title: "Cwd::getcwd cannot handle path contains '0' element" ++ From: Hironori Ikura , Hironori Ikura ++ , Stephen Zander ++ Msg-ID: <19970830060142J.hikura@matsu.tcc.co.jp>, ++ ++ Files: lib/Cwd.pm ++ ++ Title: "Getopt::Long 2.11" ++ From: JVromans@squirrel.nl (Johan Vromans) ++ Msg-ID: ++ Files: lib/Getopt/Long.pm ++ ++ Title: "IO::Socket autoflush by default, assume tcp and PeerAddr" ++ From: "M.J.T. Guy" , Andy Dougherty ++ , Gisle Aas ++ ++ Msg-ID: , ++ , ++ ++ Files: ext/IO/lib/IO/Socket.pm ++ ++ Title: "Syslog.pm and missing _PATH_LOG" ++ From: Ulrich Pfeifer ++ Msg-ID: ++ Files: lib/Sys/Syslog.pm ++ ++ Title: "Undocumented: $Test::Harness::switches" ++ From: Achim Bohnet ++ Msg-ID: <9708272110.AA26904@o09.xray.mpe.mpg.de> ++ Files: lib/Test/Harness.pm ++ ++ Title: "Patches for lib/Math/Complex.pm and t/lib/complex.t" ++ From: Jarkko Hietaniemi ++ Msg-ID: <199709102009.WAA27428@anna.in-berlin.de> ++ Files: lib/Math/Complex.pm t/lib/complex.t ++ ++ Title: "Win32: Install.pm not correctly comparing binary files." ++ From: Jeff Urlwin ++ Msg-ID: <01BCBFAA.E325C4A0.jurlwin@access.digex.net> ++ Files: lib/ExtUtils/Install.pm ++ ++ Title: "Document that File::Find doesn't follow symlinks" ++ From: Greg Ward ++ Msg-ID: <199708191853.OAA07111@bottom.bic.mni.mcgill.ca> ++ Files: lib/File/Find.pm ++ ++ Title: "fix subroutines called in a void context in perl5db.pl" ++ From: "M.J.T. Guy" ++ Msg-ID: ++ Files: lib/perl5db.pl ++ ++ Title: "xsubpp fix to allow #ifdef's around entire XSubs" ++ From: John Tobey ++ Msg-ID: <199709070034.AAA16457@remote119> ++ Files: lib/ExtUtils/xsubpp ++ ++ Title: "Banishing eval from getopt.pl and Getopt/Std.pm" ++ From: "John L. Allen" ++ Msg-ID: ++ Files: lib/getopt.pl lib/Getopt/Std.pm ++ ++ Title: "further complex number patches" ++ From: Jarkko Hietaniemi , d-lewart@uiuc.edu (Daniel S. Lewart) ++ Msg-ID: <199709221009.FAA21216@staff2.cso.uiuc.edu>, ++ <199709221216.PAA15130@alpha.hut.fi> ++ Files: lib/Math/Complex.pm t/lib/complex.t ++ ++ Title: "Trap Time::Local infinite loop" ++ From: Hugo van der Sanden ++ Msg-ID: <199710030030.BAA17372@crypt.compulink.co.uk> ++ Files: lib/Time/Local.pm ++ ++ Title: "Cosmetic Test::Harness patch" ++ From: Ilya Zakharevich ++ Msg-ID: <199710032226.SAA15354@monk.mps.ohio-state.edu> ++ Files: lib/Test/Harness.pm ++ ++ Title: "ExtUtil::Install sub my_cmp needs to binmode its files" ++ From: Gurusamy Sarathy , Stephen Potter ++ ++ Msg-ID: <199710010617.BAA02037@psisa.psa.pencom.com>, ++ <199710011819.OAA03288@aatma.engin.umich.edu> ++ Files: lib/ExtUtils/Install.pm ++ ++ Title: "Enable make test "TEST_FILES=t/*.t.were_failing"" ++ From: Ilya Zakharevich ++ Msg-ID: <199710032231.SAA15364@monk.mps.ohio-state.edu> ++ Files: lib/ExtUtils/MM_Unix.pm ++ ++ Title: "Fix for autouse.pm" ++ From: Ilya Zakharevich ++ Msg-ID: <199710071734.NAA19462@monk.mps.ohio-state.edu> ++ Files: lib/autouse.pm ++ ++ Title: "Math::Complex fixes - fixes problems on m68-linux" ++ From: Jarkko Hietaniemi ++ Msg-ID: <199709301422.HAA24368@koah.research.nokia.com> ++ Files: lib/Math/Complex.pm ++ ++ Title: "Updated CPAN.pm for 5.004_04" ++ From: koenig@anna.mind.de (Andreas J. Koenig) ++ Msg-ID: ++ Files: lib/CPAN.pm lib/CPAN/FirstTime.pm ++ ++ Title: "debugger bug with 'c subname'" ++ From: Ilya Zakharevich ++ Msg-ID: <199709232331.TAA04546@monk.mps.ohio-state.edu> ++ Files: lib/perl5db.pl ++ ++ Title: "Fix atan2 & restrict $t to (-pi,pi] instead of to [-pi,pi]" ++ From: Daniel S. Lewart, Jarkko Hietaniemi ++ ++ Msg-ID: <199710010939.CAA00964@koah.research.nokia.com> ++ Files: lib/Math/Complex.pm ++ ++ Title: "Cwd::fastcwd needs changes to work with tainting" ++ From: Hugo van der Sanden , Ulrich Pfeifer ++ , Tim Bunce ++ Msg-ID: ++ Files: lib/Cwd.pm ++ ++ Title: "use autouse: requires prototype now" ++ From: user@agate.berkeley.edu ++ Msg-ID: <9709220450.AA0380@tuzik.HIP.Berkeley.EDU> ++ Files: lib/autouse.pm ++ ++ Title: ""use base qw(Foo Bar);" to set @ISA at compile time" ++ From: Gisle Aas , Graham Barr , Graham Barr ++ , Tim Bunce , ++ jan.dubois@ibm.net (Jan Dubois), larry@wall.org (Larry ++ Wall) ++ Msg-ID: <199710022151.WAA21250@toad.ig.co.uk>, ++ <199710031613.JAA11286@wall.org>, ++ <199710040829.KAA16739@furu.g.aas.no>, ++ <3434E4C6.AE24135E@ti.com>, <343C2278.7DC1ADC6@pobox.com>, ++ <343ec306.50394803@smtp-gw01.ny.us.ibm.net> ++ Files: lib/base.pm ++ ++ Title: "Further Math/Complex.pm enhancements" ++ From: Jarkko Hietaniemi ++ Msg-ID: <199710132055.XAA02086@alpha.hut.fi> ++ Files: lib/Math/Complex.pm t/lib/complex.t ++ ++ Title: "Further Math::Complex fixes" ++ From: Jarkko Hietaniemi ++ Msg-ID: <199710120933.MAA01165@alpha.hut.fi> ++ Files: lib/Math/Complex.pm ++ ++ ------ OTHER CHANGES ------ ++ ++ Title: "POD patches w.r.t. $^S" ++ From: Ilya Zakharevich ++ Msg-ID: <199710030001.UAA14241@monk.mps.ohio-state.edu> ++ Files: ../pod/perlfunc.pod ../pod/perlvar.pod ++ ++ Title: "libperl.sl on HP-UX 10.20" ++ From: "Darren/Torin/Who Ever..." , Hugo van der Sanden ++ ++ Msg-ID: <199709250003.BAA18085@crypt.compulink.co.uk>, ++ <873emkbpit.fsf@perv.daft.com> ++ Files: ++ ++ Title: "myconfig / perl -V: remove randbits and add prototype" ++ From: Tim Bunce ++ Msg-ID: <199709290857.JAA07706@toad.ig.co.uk> ++ Files: myconfig ++ ++ Title: "Emacs CPerl update for 5.004_04" ++ From: Ilya Zakharevich ++ Msg-ID: <199710140835.EAA26825@monk.mps.ohio-state.edu> ++ Files: emacs/cperl-mode.el ++ ++ Title: "Enhance perly.fixer to help porters." ++ From: Tim Bunce ++ Files: perly.fixer ++ ++ ------ PORTABILITY - WIN32 ------ ++ ++ Title: "Fix win32/Makefile for perl95" ++ From: Gurusamy Sarathy ++ Files: win32/Makefile win32/makefile.mk ++ ++ Title: "Win32 archnames" ++ From: Bill Middleton , Gurusamy Sarathy ++ , Peter Prymmer , Tim ++ Bunce ++ Msg-ID: <199709111929.PAA22488@aatma.engin.umich.edu>, ++ <341719E4.4923@forte.com>, ++ ++ Files: win32/config_H.bc win32/config_H.vc ++ ++ Title: "pl2bat.bat -> pl2bat.pl change in win32/pod.mak" ++ From: jan.dubois@ibm.net (Jan Dubois) ++ Msg-ID: <3411ee6f.9143607@smtp-gw01.ny.us.ibm.net> ++ Files: win32/pod.mak ++ ++ Title: "Add test-notty target to Win32 Makefile" ++ From: jan.dubois@ibm.net (Jan Dubois) ++ Msg-ID: <343f5106.12461608@smtp2.ibm.net> ++ Files: win32/Makefile ++ ++ Title: "Bug in Win32::GetShortPathName" ++ From: Gurusamy Sarathy ++ Msg-ID: <199710092229.SAA21556@aatma.engin.umich.edu> ++ Files: win32/win32.c ++ ++ Title: "Fix NT handles leak." ++ From: Gurusamy Sarathy ++ Msg-ID: <199710111319.JAA10918@aatma.engin.umich.edu> ++ Files: win32/win32io.c win32/win32sck.c ++ ++ Title: "fix socket init duality on win32" ++ From: Gurusamy Sarathy ++ Msg-ID: <199710111523.LAA12407@aatma.engin.umich.edu> ++ Files: win32/win32sck.c ++ ++ ------ PORTABILITY - GENERAL ------ ++ ++ Title: "Tweak to hints/machten.sh: stop t/lib/complex.t from failing" ++ From: Dominic Dunlop ++ Msg-ID: ++ Files: hints/machten.sh ++ ++ Title: "Irix 6.2 build problem - so_locations" ++ From: "Billinghurst, David" ++ Msg-ID: ++ Files: hints/irix_6.sh ++ ++ Title: "Porting/pumpkin.pod version 1.13" ++ From: Andy Dougherty ++ Msg-ID: ++ Files: Porting/pumpkin.pod ++ ++ Title: "lib/timelocal.t fails test 1 for VMS 7.1" ++ From: Dan Sugalski ++ Msg-ID: <3.0.3.32.19970908112449.0087bc90@stargate.lbcc.cc.or.us> ++ Files: vms/vmsish.h vms/vms.c ++ ++ Title: "Patches to updated README.VMS for Perl 5.004_04" ++ From: Dan Sugalski ++ Msg-ID: <3.0.3.32.19970918100648.008b1c60@stargate.lbcc.cc.or.us> ++ Files: README.vms ++ ++ Title: "Fix perl build on Digital UNIX after JDK installs libnet.so" ++ From: Spider Boardman ++ Msg-ID: <199709191826.OAA18040@Orb.Nashua.NH.US> ++ Files: hints/dec_osf.sh ++ ++ Title: "Updated README.VMS for Perl 5.004_04" ++ From: Dan Sugalski ++ Msg-ID: <3.0.3.32.19970912091524.008a3620@stargate.lbcc.cc.or.us> ++ Files: README.vms ++ ++ Title: "Dynixptx hints" ++ From: bruce@aps.org ("Bruce P. Schuck") ++ Msg-ID: ++ Files: hints/dynixptx.sh ++ ++ Title: "Minor OS/2 patch for 4_03" ++ From: Ilya Zakharevich ++ Msg-ID: <199710032224.SAA15345@monk.mps.ohio-state.edu> ++ Files: os2/os2.c ++ ++ Title: "OS2::REXX improvements" ++ From: Ilya Zakharevich ++ Msg-ID: <199709272214.SAA08638@monk.mps.ohio-state.edu> ++ Files: os2/Changes os2/OS2/REXX/Makefile.PL os2/OS2/REXX/REXX.pm ++ ++ Title: "hints/qnx.sh update" ++ From: Norton Allen ++ Msg-ID: <199709261508.LAA07889@dolores.harvard.edu> ++ Files: hints/qnx.sh ++ ++ Title: "New hints file for IBM OS/390 OpenEdition (MVS)" ++ From: pvhp@forte.com (Peter Prymmer) ++ Msg-ID: <9709240106.AA26484@forte.com> ++ Files: hints/os390.sh ++ ++ Title: "OS/2 Hints" ++ From: Ilya Zakharevich ++ Msg-ID: <199710130631.CAA25426@monk.mps.ohio-state.edu> ++ Files: hints/os2.sh ++ ++ ------ TESTS ------ ++ ++ Title: "op/glob.t test failure under Win32 with CVS" ++ From: Warren Jones ++ Msg-ID: <97Aug26.091048pdt.35761-1@gateway.fluke.com> ++ Files: t/op/glob.t ++ ++ Title: "tests fail if localhost/loopback address not defined" ++ From: David McLean >, David McLean ++ ++ Msg-ID: <34048947.2944@icc.gsfc.nasa.gov> ++ Files: t/lib/io_sock.t t/lib/io_udp.t ++ ++ Title: "Improve pragma/locale test 102 - and don't fail, just warn" ++ From: Jarkko Hietaniemi ++ Files: t/pragma/locale.t ++ ++ Title: "Invalid test output in t/op/taint.t in trial 1" ++ From: Dan Sugalski ++ Msg-ID: <3.0.3.32.19970919160918.00857a50@stargate.lbcc.cc.or.us> ++ Files: t/op/taint.t ++ ++ Title: "Identify t/*/*.t test failing because of file permissions" ++ From: koenig@anna.mind.de (Andreas J. Koenig) ++ Msg-ID: ++ Files: t/TEST ++ ++ Title: "fix poor t/op/runlevel.t test" ++ From: Gurusamy Sarathy , Hugo van der Sanden ++ , Norton Allen ++ ++ Msg-ID: <199709261458.KAA28611@dolores.harvard.edu> ++ Files: t/op/runlevel.t ++ ++ ------ UTILITIES ------ ++ ++ Title: "Missing 'require' in auto-generated .pm by h2xs" ++ From: davidk@tor.securecomputing.com (David Kerry) ++ Msg-ID: <97Aug27.131618edt.11650@janus.tor.securecomputing.com> ++ Files: utils/h2xs.PL ++ ++ Title: "Perldoc tiny patch to avoid $0" ++ From: Ilya Zakharevich ++ Msg-ID: <199709122141.RAA16846@monk.mps.ohio-state.edu> ++ Files: utils/perldoc.PL ++ ++ Title: "h2ph broken in 5.004_02" ++ From: David Mazieres , ++ kstar@www.chapin.edu (Kurt D. Starsinic) ++ Msg-ID: <199708201454.KAA05122@reeducation-labor.lcs.mit.edu>, ++ <199708201700.KAA02621@www.chapin.edu> ++ Files: utils/h2ph.PL ++ ++ Title: "add key_t caddr_t to h2ph", "eg/sysvipc/ipcsem bug", "update ++ hints/bsdos.sh" ++ From: Tony Sanders ++ Msg-ID: <199708272301.RAA12803@austin.bsdi.com> ++ Files: eg/sysvipc/ipcsem utils/h2ph.PL ++ ++ Title: "perldoc search ., lib and blib/* if -f 'Makefile.PL'" ++ From: Tim Bunce ++ Msg-ID: <199708251732.KAA19299@gadget.cscaper.com> ++ Files: utils/perldoc.PL ++ ++ Title: "5.004m4t1: perlbug: NIS domainname gets into wrong places" ++ From: koenig@anna.mind.de (Andreas J. Koenig) ++ Msg-ID: ++ Files: utils/perlbug.PL ++ ++ Title: "add better local patch info to perlbug", "perlbug checks perl ++ build/run version changes" ++ From: Tim.Bunce@ig.co.uk ++ Files: utils/perlbug.PL ++ ++ Title: "perldoc - suggest modules if requested module not found" ++ From: Anthony David ++ Msg-ID: <3439CD83.6969@netinfo.com.au> ++ Files: utils/perldoc.PL ++ ++ Title: "perldoc mail::foo tries to read binary /usr/ucb/mail" ++ From: "Joseph Moof-in' Hall" , Tim Bunce ++ Msg-ID: <199710082014.NAA00808@gadget.cscaper.com> ++ Files: utils/perldoc.PL ++ ++ Title: "perldoc -f setpwent (for example) returns no descriptive text" ++ From: Tim Bunce ++ Files: utils/perldoc.PL ++ ++ Title: "perldoc diffs: don't search auto - much faster" ++ From: "Joseph N. Hall" ++ Msg-ID: ++ Files: utils/perldoc.PL ++ ---------------- diff --cc Configure index 13f37ef,13f37ef..eb7dd8a --- a/Configure +++ b/Configure @@@ -1764,7 -1764,7 +1764,6 @@@ EO ;; linux) osname=linux case "$3" in -- 1*) osvers=1 ;; *) osvers="$3" ;; esac ;; diff --cc INSTALL index ffb755a,ffb755a..488a1ce --- a/INSTALL +++ b/INSTALL @@@ -99,8 -99,8 +99,11 @@@ and Configure will use the defaults fro After it runs, Configure will perform variable substitution on all the *.SH files and offer to run make depend. --Configure supports a number of useful options. Run B --to get a listing. To compile with gcc, for example, you can run ++Configure supports a number of useful options. Run B to ++get a listing. See the Porting/Glossary file for a complete list of ++Configure variables you can set and their definitions. ++ ++To compile with gcc, for example, you should run sh Configure -Dcc=gcc @@@ -325,12 -325,12 +328,14 @@@ and the following directories for manua (Actually, Configure recognizes the SVR3-style /usr/local/man/l_man/man1 directories, if present, and uses those --instead.) The module man pages are stuck in that strange spot so that ++instead.) ++ ++The module man pages are stuck in that strange spot so that they don't collide with other man pages stored in /usr/local/man/man3, and so that Perl's man pages don't hide system man pages. On some systems, B would end up calling up Perl's less.pm module man --page, rather than the less program. (This location may change in a --future release of perl.) ++page, rather than the less program. (This default location will likely ++change to /usr/local/man/man3 in a future release of perl.) Note: Many users prefer to store the module man pages in /usr/local/man/man3. You can do this from the command line with @@@ -423,6 -423,6 +428,9 @@@ installed on multiple systems. Here's make test make install cd /tmp/perl5 ++ # Edit lib///Config.pm to change all the ++ # install* variables back to reflect where everything will ++ # really be installed. tar cvf ../perl5-archive.tar . # Then, on each machine where you want to install perl, cd /usr/local # Or wherever you specified as $prefix @@@ -459,14 -459,14 +467,17 @@@ compatibility, answer "y" On the other hand, if you are embedding perl into another application and want the maximum namespace protection, then you probably ought to --answer "n" when Configure asks if you want binary compatibility. ++answer "n" when Configure asks if you want binary compatibility, or ++disable it from the Configure command line with ++ ++ sh Configure -Ud_bincompat3 The default answer of "y" to maintain binary compatibility is probably appropriate for almost everyone. --In a related issue, old extensions may possibly be affected by the changes --in the Perl language in the current release. Please see pod/perldelta for --a description of what's changed. ++In a related issue, old extensions may possibly be affected by the ++changes in the Perl language in the current release. Please see ++pod/perldelta.pod for a description of what's changed. =head2 Selecting File IO mechanisms @@@ -626,7 -626,7 +637,7 @@@ to point to the perl build directory The only reliable answer is that you should specify a different directory for the architecture-dependent library for your -DDEBUGGING --version of perl. You can do this with by changing all the *archlib* ++version of perl. You can do this by changing all the *archlib* variables in config.sh, namely archlib, archlib_exp, and installarchlib, to point to your new architecture-dependent library. @@@ -1159,9 -1159,9 +1170,9 @@@ should run plain 'make' before 'make te complete build). If 'make test' doesn't say "All tests successful" then something went wrong. See the file t/README in the t subdirectory. --If you want to run make test in the background you should Note that you can't run the tests in background if this disables --opening of /dev/tty. ++opening of /dev/tty. You can use 'make test-notty' in that case but ++a few tty tests will be skipped. If make test bombs out, just cd to the t directory and run ./TEST by hand to see if it makes any difference. If individual tests @@@ -1174,10 -1174,10 +1185,10 @@@ individual subtests is to cd to the t d ./perl harness --(this assumes that most tests succeed, since harness uses ++(this assumes that most basic tests succeed, since harness uses complicated constructs). --You can also read the individual tests to see if there are any helpful ++You should also read the individual tests to see if there are any helpful comments that apply to your system. Note: One possible reason for errors is that some external programs @@@ -1343,13 -1343,13 +1354,13 @@@ to hand-edit some of the converted file correctly. For example, h2ph breaks spectacularly on type casting and certain structures. --=head installhtml --help ++=head1 installhtml --help Some sites may wish to make perl documentation available in HTML format. The installhtml utility can be used to convert pod --documentation into linked HTML files and install install them. ++documentation into linked HTML files and install them. --The following command-line is an example of the one we use to convert ++The following command-line is an example of one used to convert perl documentation: ./installhtml \ @@@ -1369,6 -1369,6 +1380,9 @@@ see warnings like "no title", "unexpect resolve" as the files are processed. We are aware of these problems (and would welcome patches for them). ++You may find it helpful to run installhtml twice. That should reduce ++the number of "cannot resolve" warnings. ++ =head1 cd pod && make tex && (process the latex files) Some sites may also wish to make the documentation in the pod/ directory @@@ -1417,10 -1417,10 +1431,14 @@@ generate the documentation =head1 AUTHOR --Andy Dougherty doughera@lafcol.lafayette.edu , borrowing very heavily --from the original README by Larry Wall, and also with lots of helpful --feedback from the perl5-porters@perl.org folks. ++Original author: Andy Dougherty doughera@lafcol.lafayette.edu , ++borrowing very heavily from the original README by Larry Wall, ++with lots of helpful feedback and additions from the ++perl5-porters@perl.org folks. ++ ++If you have problems or questions, please see L<"Reporting Problems"> ++above. =head1 LAST MODIFIED --$Id: INSTALL,v 1.22 1997/08/01 15:39:14 doughera Released $ ++$Id: INSTALL,v 1.28 1997/10/10 16:50:59 doughera Released $ diff --cc MANIFEST index 1977114,1977114..26a5409 --- a/MANIFEST +++ b/MANIFEST @@@ -206,7 -206,7 +206,6 @@@ ext/SDBM_File/typemap SDBM extension i ext/Socket/Makefile.PL Socket extension makefile writer ext/Socket/Socket.pm Socket extension Perl module ext/Socket/Socket.xs Socket extension external subroutines --ext/util/extliblist Used by extension Makefile.PL to make lib lists ext/util/make_ext Used by Makefile to execute extension Makefiles ext/util/mkbootstrap Turns ext/*/*_BS into bootstrap info form.h Public declarations for the above @@@ -275,6 -275,6 +274,7 @@@ hints/next_3_0.sh Hints for named archi hints/next_4.sh Hints for named architecture hints/opus.sh Hints for named architecture hints/os2.sh Hints for named architecture ++hints/os390.sh Hints for named architecture hints/powerux.sh Hints for named architecture hints/qnx.sh Hints for named architecture hints/sco.sh Hints for named architecture @@@ -400,6 -400,6 +400,7 @@@ lib/User/pwent.pm By-name interface to lib/abbrev.pl An abbreviation table builder lib/assert.pl assertion and panic with stack trace lib/autouse.pm Load and call a function only when it's used ++lib/base.pm Establish IS-A relationship at compile time lib/bigfloat.pl An arbitrary precision floating point package lib/bigint.pl An arbitrary precision integer arithmetic package lib/bigrat.pl An arbitrary precision rational arithmetic package @@@ -652,6 -652,6 +653,7 @@@ t/lib/db-btree.t See if DB_File work t/lib/db-hash.t See if DB_File works t/lib/db-recno.t See if DB_File works t/lib/dirhand.t See if DirHandle works ++t/lib/dosglob.t See if File::DosGlob works t/lib/english.t See if English works t/lib/env.t See if Env works t/lib/filecache.t See if FileCache works diff --cc Makefile.SH index 86fd6ed,86fd6ed..f2a4a9f --- a/Makefile.SH +++ b/Makefile.SH @@@ -52,6 -52,6 +52,9 @@@ true aixinstdir=`pwd | sed 's/\/UU$//'` linklibperl="-L $archlibexp/CORE -L $aixinstdir -lperl" ;; ++ hpux10*) ++ linklibperl="-L `pwd | sed 's/\/UU$//'` -Wl,+b$archlibexp/CORE -lperl" ++ ;; esac ;; *) pldlflags='' @@@ -303,13 -303,13 +306,13 @@@ perl: $& perlmain$(OBJ_EXT) $(LIBPERL) $(SHRPENV) $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o perl perlmain$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs) pureperl: $& perlmain$(OBJ_EXT) $(LIBPERL) $(DYNALOADER) $(static_ext) ext.libs -- purify $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o pureperl perlmain$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs) ++ $(SHRPENV) purify $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o pureperl perlmain$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs) purecovperl: $& perlmain$(OBJ_EXT) $(LIBPERL) $(DYNALOADER) $(static_ext) ext.libs -- purecov $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o purecovperl perlmain$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs) ++ $(SHRPENV) purecov $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o purecovperl perlmain$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs) quantperl: $& perlmain$(OBJ_EXT) $(LIBPERL) $(DYNALOADER) $(static_ext) ext.libs -- quantify $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o quantperl perlmain$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs) ++ $(SHRPENV) quantify $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o quantperl perlmain$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs) # This version, if specified in Configure, does ONLY those scripts which need # set-id emulation. Suidperl must be setuid root. It contains the "taint" @@@ -317,7 -317,7 +320,7 @@@ # has been invoked correctly. suidperl: $& sperl$(OBJ_EXT) perlmain$(OBJ_EXT) $(LIBPERL) $(DYNALOADER) $(static_ext) ext.libs -- $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o suidperl perlmain$(OBJ_EXT) sperl$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs) ++ $(SHRPENV) $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o suidperl perlmain$(OBJ_EXT) sperl$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs) !NO!SUBS! @@@ -341,6 -341,6 +344,8 @@@ preplibrary: miniperl lib/Config.pm $(p autosplit_lib_modules(@ARGV)' lib/*.pm lib/*/*.pm # Take care to avoid modifying lib/Config.pm without reason ++# (If trying to create a new port and having problems with the configpm script, ++# try 'make minitest' and/or commenting out the tests at the end of configpm.) lib/Config.pm: config.sh miniperl configpm ./miniperl configpm tmp sh mv-if-diff tmp lib/Config.pm @@@ -382,12 -382,12 +387,14 @@@ install.html: all installhtm run_byacc: FORCE @ echo 'Expect' 113 shift/reduce and 1 reduce/reduce conflict $(BYACC) -d perly.y ++ chmod 664 perly.c sh $(shellflags) ./perly.fixer y.tab.c perly.c sed -e 's/fprintf *( *stderr *,/PerlIO_printf(Perl_debug_log,/g' \ -e 's/y\.tab/perly/g' perly.c >perly.tmp && mv perly.tmp perly.c echo 'extern YYSTYPE yylval;' >>y.tab.h cmp -s y.tab.h perly.h && rm -f y.tab.h || mv y.tab.h perly.h -- - perl vms/vms_yfix.pl perly.c perly.h vms/perly_c.vms vms/perly_h.vms ++ chmod 664 vms/perly_c.vms vms/perly_h.vms ++ perl vms/vms_yfix.pl perly.c perly.h vms/perly_c.vms vms/perly_h.vms # We don't want to regenerate perly.c and perly.h, but they might # appear out-of-date after a patch is applied or a new distribution is @@@ -422,13 -422,13 +429,13 @@@ regen_headers: FORC # DynaLoader may be needed for extensions that use Makefile.PL. $(DYNALOADER): miniperl preplibrary FORCE -- @sh ext/util/make_ext static $@ LIBPERL_A=$(LIBPERL) ++ @sh ext/util/make_ext static $@ MAKE=$(MAKE) LIBPERL_A=$(LIBPERL) d_dummy $(dynamic_ext): miniperl preplibrary $(DYNALOADER) FORCE -- @sh ext/util/make_ext dynamic $@ LIBPERL_A=$(LIBPERL) ++ @sh ext/util/make_ext dynamic $@ MAKE=$(MAKE) LIBPERL_A=$(LIBPERL) s_dummy $(static_ext): miniperl preplibrary $(DYNALOADER) FORCE -- @sh ext/util/make_ext static $@ LIBPERL_A=$(LIBPERL) ++ @sh ext/util/make_ext static $@ MAKE=$(MAKE) LIBPERL_A=$(LIBPERL) clean: _tidy _mopup @@@ -453,7 -453,7 +460,7 @@@ _tidy -cd utils; $(MAKE) clean -cd x2p; $(MAKE) clean -@for x in $(DYNALOADER) $(dynamic_ext) $(static_ext) ; do \ -- sh ext/util/make_ext clean $$x ; \ ++ sh ext/util/make_ext clean $$x MAKE=$(MAKE) ; \ done # Do not 'make _cleaner' directly. @@@ -463,7 -463,7 +470,7 @@@ _cleaner -cd utils; $(MAKE) realclean -cd x2p; $(MAKE) realclean -@for x in $(DYNALOADER) $(dynamic_ext) $(static_ext) ; do \ -- sh ext/util/make_ext realclean $$x ; \ ++ sh ext/util/make_ext realclean $$x MAKE=$(MAKE) ; \ done rm -f *.orig */*.orig *~ */*~ core t/core t/c t/perl rm -rf $(addedbyconf) @@@ -482,11 -482,11 +489,13 @@@ lint: perly.c $(c) lint $(lintflags) $(defs) perly.c $(c) > perl.fuzz --# Need to unset during recursion to go out of loop ++# Need to unset during recursion to go out of loop. ++# The README below ensures that the dependency list is never empty and ++# that when MAKEDEPEND is empty $(FIRSTMAKEFILE) doesn't need rebuilding. MAKEDEPEND = Makefile makedepend --$(FIRSTMAKEFILE): $(MAKEDEPEND) ++$(FIRSTMAKEFILE): README $(MAKEDEPEND) $(MAKE) depend MAKEDEPEND= config.h: config_h.SH config.sh @@@ -497,7 -497,7 +506,7 @@@ perl.exp: perl_exp.SH config.s # When done, touch perlmain.c so that it doesn't get remade each time. depend: makedepend -- sh ./makedepend ++ sh ./makedepend MAKE=$(MAKE) - test -s perlmain.c && touch perlmain.c cd x2p; $(MAKE) depend @@@ -523,8 -523,8 +532,10 @@@ minitest: miniper - cd t && (rm -f perl$(EXE_EXT); $(LNS) ../miniperl$(EXE_EXT) perl$(EXE_EXT)) \ && ./perl TEST base/*.t comp/*.t cmd/*.t io/*.t op/*.t pragma/*.t 'BUILD PROCESS', @@@ -57,7 -57,7 +71,7 @@@ 'DOC' => 'DOCUMENTATION', 'LIB' => 'LIBRARY AND EXTENSIONS', 'PORT1' => 'PORTABILITY - WIN32', -- 'PORT2' => 'PORTABILITY - OTHER', ++ 'PORT2' => 'PORTABILITY - GENERAL', 'TEST' => 'TESTS', 'UTIL' => 'UTILITIES', 'OTHER' => 'OTHER CHANGES', @@@ -84,6 -84,6 +98,8 @@@ my %ls # Index: embed.h my($in, $prevline, $prevtype, $ls); ++my(@removed, @added); ++my $prologue = 1; # assume prologue till patch or /^exit\b/ seen foreach my $argv (@ARGV) { $in = $argv; @@@ -96,16 -96,16 +112,24 @@@ my $type; while () { unless (/^([-+*]{3}) / || /^(Index):/) { -- # not an interesting patch line but possibly meta-information ++ # not an interesting patch line ++ # but possibly meta-information or prologue ++ if ($prologue) { ++ push @added, $1 if /^touch\s+(\S+)/; ++ push @removed, $1 if /^rm\s+(?:-f)?\s*(\S+)/; ++ $prologue = 0 if /^exit\b/; ++ } next unless $::opt_m; -- $ls->{From}{$1}=1 if /^From:\s+(.*\S)/i; -- $ls->{Title}{$1}=1 if /^Subject:\s+(?:Re: )?(.*\S)/i; -- $ls->{'Msg-ID'}{$1}=1 if /^Message-Id:\s+(.*\S)/i; -- $ls->{Date}{$1}=1 if /^Date:\s+(.*\S)/i; ++ $ls->{From}{$1}=1,next if /^From:\s+(.*\S)/i; ++ $ls->{Title}{$1}=1,next if /^Subject:\s+(?:Re: )?(.*\S)/i; ++ $ls->{'Msg-ID'}{$1}=1,next if /^Message-Id:\s+(.*\S)/i; ++ $ls->{Date}{$1}=1,next if /^Date:\s+(.*\S)/i; ++ $ls->{$1}{$2}=1,next if /^([-\w]+):\s+(.*\S)/; next; } $type = $1; next if /^--- [0-9,]+ ----$/ || /^\*\*\* [0-9,]+ \*\*\*\*$/; ++ $prologue = 0; print "Last: $prevline","This: ${_}Got: $1\n\n" if $::opt_d; @@@ -113,12 -113,12 +137,12 @@@ # Patch copes with this, so must we. It's also handy for # documenting manual changes by simply adding Index: lines # to the file which describes the problem bing fixed. -- add_file($ls, $1), next if /^Index:\s+(.*)/; ++ add_file($ls, $1), next if /^Index:\s+(\S+)/; if ( ($type eq '---' and $prevtype eq '***') # Style 1 or ($type eq '+++' and $prevtype eq '---') # Style 2 ) { -- if (/^[-+*]{3} (\S+)\s+.*\d\d:\d\d:\d\d/) { # double check ++ if (/^[-+*]{3} (\S+)\s*(.*?\d\d:\d\d:\d\d)?/) { # double check add_file($ls, $1); } else { @@@ -141,9 -141,9 +165,9 @@@ print scalar(@ARGV)." files read.\n" if $::opt_v and @ARGV > 1; --my @ls = sort { -- $a->{category} cmp $b->{category} || $a->{in} cmp $b->{in} --} values %ls; ++# --- Firstly we filter and sort as needed --- ++ ++my @ls = values %ls; if ($::opt_f) { # filter out patches based on -f my $out; @@@ -158,6 -158,6 +182,24 @@@ } @ls; } ++@ls = sort { ++ $a->{category} cmp $b->{category} || $a->{in} cmp $b->{in} ++} @ls; ++ ++ ++# --- Handle special modes --- ++ ++if ($::opt_4) { ++ print map { "p4 delete $_\n" } @removed if @removed; ++ print map { "p4 add $_\n" } @added if @added; ++ my @patches = grep { $_->{is_in} } @ls; ++ my %patched = map { ($_, 1) } map { keys %{$_->{out}} } @patches; ++ delete @patched{@added}; ++ my @patched = sort keys %patched; ++ print map { "p4 edit $_\n" } @patched if @patched; ++ exit 0; ++} ++ if ($::opt_I) { my $n_patches = 0; my($in,$out); @@@ -171,12 -171,12 +213,16 @@@ my @all_out = sort keys %all_out; my @missing = grep { ! -f $_ } @all_out; print "$n_patches patch files patch ".@all_out." files (".@missing." missing)\n"; ++ print "(use -v to list patches which patch 'missing' files)\n" ++ if @missing && !$::opt_v; if ($::opt_v and @missing) { print "Missing files:\n"; foreach $out (@missing) { printf " %-20s\t%s\n", $out, $all_out{$out}; } } ++ print "Added files: @added\n" if @added; ++ print "Removed files: @removed\n" if @removed; exit 0+@missing; } @@@ -256,11 -256,11 +302,27 @@@ sub list_files_by_patch $name = $ls->{in} unless defined $name; my @meta; if ($::opt_m) { -- foreach(qw(Title From Msg-ID)) { -- next unless $ls->{$_}; -- my @list = sort keys %{$ls->{$_}}; -- push @meta, sprintf "%7s: ", $_; -- @list = map { "\"$_\"" } @list if $_ eq 'Title'; ++ my $meta; ++ foreach $meta (@show_meta) { ++ next unless $ls->{$meta}; ++ my @list = sort keys %{$ls->{$meta}}; ++ push @meta, sprintf "%7s: ", $meta; ++ if ($meta eq 'Title') { ++ @list = map { s/\[?PATCH\]?:?\s*//g; "\"$_\""; } @list ++ } ++ elsif ($meta eq 'From') { ++ # fix-up bizzare addresses from japan and ibm :-) ++ foreach(@list) { ++ s:\W+=?iso.*?<: <:; ++ s/\d\d-\w\w\w-\d{4}\s+\d\d:\S+\s*//; ++ } ++ } ++ elsif ($meta eq 'Msg-ID') { ++ my %from; # limit long threads to one msg-id per site ++ @list = map { ++ $from{(/@(.*?)>/ ? $1 : $_)}++ ? () : ($_); ++ } @list; ++ } push @meta, my_wrap(""," ", join(", ",@list)."\n"); } $name = "\n$name" if @meta and $name; diff --cc Porting/pumpkin.pod index 5260e65,5260e65..6706c6c --- a/Porting/pumpkin.pod +++ b/Porting/pumpkin.pod @@@ -41,6 -41,6 +41,10 @@@ Subscribe by sending the message (in th to perl5-porters-request@perl.org . ++Archives of the list are held at: ++ ++ http://www.rosat.mpe-garching.mpg.de/mailing-lists/perl-porters/ ++ =head1 How are Perl Releases Numbered? Perl version numbers are floating point numbers, such as 5.004. @@@ -73,9 -73,9 +77,10 @@@ In addition, there may be "developer" s are not official releases. They may contain unstable experimental features, and are subject to rapid change. Such developer sub-versions are numbered with sub-version numbers. For example, --version 5.004_04 is the 4'th developer version built on top of --5.004. It might include the _01, _02, and _03 changes, but it --also might not. Sub-versions are allowed to be subversive. ++version 5.003_04 is the 4'th developer version built on top of ++5.003. It might include the _01, _02, and _03 changes, but it ++also might not. Sub-versions are allowed to be subversive. (But see ++the next section for recent changes.) These sub-versions can also be used as floating point numbers, so you can do things such as @@@ -100,6 -100,6 +105,11 @@@ way to distribute important bug fixes w developers to untangle all the other problems in the current developer's release. ++Trial releases of bug-fix maintenance releases are announced on ++perl5-porters. Trial releases use the new subversion number (to avoid ++testers installing it over the previous release) and include a 'local ++patch' entry in patchlevel.h. ++ Watch for announcements of maintenance subversions in comp.lang.perl.announce. @@@ -1157,14 -1157,14 +1167,14 @@@ and/or fcntl() file locking. It's a me =back --=head1 AUTHOR -- --Andy Dougherty . ++=head1 AUTHORS --Additions by Chip Salzenberg . ++Original author: Andy Dougherty doughera@lafcol.lafayette.edu . ++Additions by Chip Salzenberg chip@perl.com and ++Tim Bunce Tim.Bunce@ig.co.uk . All opinions expressed herein are those of the authorZ<>(s). =head1 LAST MODIFIED --$Id: pumpkin.pod,v 1.10.1.1 1997/06/10 20:46:47 timbo Exp $ ++$Id: pumpkin.pod,v 1.13 1997/08/28 18:26:40 doughera Released $ diff --cc README.vms index 9a6a712,9a6a712..4b8c29d --- a/README.vms +++ b/README.vms @@@ -1,3 -1,3 +1,383 @@@ ++Last Revised 11-September-1997 by Dan Sugalski ++Originally by Charles Bailey ++ ++* Intro ++ ++The VMS port of Perl is as functionally complete as any other Perl port ++(and as complete as the ports on some Unix systems). The Perl binaries ++provide all the Perl system calls that are either available under VMS or ++reasonably emulated. There are some incompatibilites in process handling ++(e.g the fork/exec model for creating subprocesses doesn't do what you ++might expect under Unix), mainly because VMS and Unix handle processes and ++sub-processes very differently. ++ ++There are still some unimplemented system functions, and of coursse we ++could use modules implementing useful VMS system services, so if you'd like ++to lend a hand we'd love to have you. Join the Perl Porting Team Now! ++ ++The current sources and build procedures have been tested on a VAX using ++VaxC and Dec C, and on an AXP using Dec C. If you run into problems with ++other compilers, please let us know. ++ ++There are issues with varions versions of Dec C, so if you're not running a ++relatively modern version, check the Dec C issues section later on in this ++document. ++ ++* Other required software ++ ++In addition to VMS, you'll need: ++ 1) A C compiler. Dec C for AXP, or VAX C, Dec C, or gcc for the ++ VAX. ++ 2) A make tool. Dec's MMS (v2.6 or later), or MadGoat's free MMS ++ analog MMK (available from ftp.madgoat.com/madgoat) both work ++ just fine. Gnu Make might work, but it's been so long since ++ anyone's tested it that we're not sure. MMK's free, though, so ++ go ahead and use that. ++ ++ ++If you want to include socket support, you'll need a TCP stack and either ++Dec C, or socket libraries. See the Socket Support topic for more details. ++ ++* Compiling Perl ++ ++>From the top level of the Perl source directory, do this: ++ ++MMS/DESCRIP=[.VMS]DESCRIP.MMS ++ ++If you're on an Alpha, add /Macro=("__AXP__=1","decc=1") ++If you're using Dec C as your C compiler (you are on all alphas), add ++/Macro=("decc=1") ++If Vac C is your default C compiler and you want to use Dec C, add ++/Macro=("CC=CC/DECC") (Don't forget the /macro=("decc=1") ++If Dec C is your default C compiler and you want to use Vax C, add ++/Macro=("CC=CC/VAXC") ++If you want Socket support and are using the SOCKETSHR socket library, add ++/Macro=("SOCKETSHR_SOCKETS=1") ++If you want Socket support and are using the Dec C RTL socket interface ++(You must be using Dec C for this), add /Macro=("DECC_SOCKETS=1") ++ ++If you have multiple /macro= items, combine them together in one /Macro=() ++switch, with all the options inside the parentheses separated by commas. ++ ++Samples: ++ ++VMS AXP, with Socketshr sockets: ++ ++$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("decc=1","__AXP__=1","SOCKETSHR_SOCKETS=1") ++ ++VMS AXP with no sockets ++ ++$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("decc=1","__AXP__=1") ++ ++VMS AXP with the Dec C RTL sockets ++ ++$MMS/DESCRIP=[.VMS]/Macro=("decc=1","__AXP__=1","DECC_SOCKETS=1") ++ ++VMS VAX with default system compiler, no sockets ++ ++$MMS/DESCRIP=[.VMS]DESCRIP.MMS ++ ++VMS VAX with Dec C compiler, no sockets ++ ++$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("CC=CC/DECC","decc=1") ++ ++VMS VAX with Dec C compiler, Dec C RTL sockets ++ ++$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("CC=CC/DECC","decc=1","DECC_SOCKETS=1") ++ ++VMS VAX with Dec C compiler, Socketshr sockets ++ ++$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("CC=CC/DECC","decc=1","SOCKETSHR_SOCKETS=1") ++ ++Using Dec C is recommended over Vax C. The compiler is newer, and ++supported. (Vax C was decommisioned around 1993) Various older versions had ++some gotchas, so if you're using a version older than 5.2, check the Dec C ++Issues section. ++ ++We'll also point out that Dec C will get you at least a ten-fold increase ++in line-oriented IO over Vax C. The optimizer is amazingly better, too. If ++you can use Dec C, then you *really*, *really* should. ++ ++ ++Once you issue your MMS command, sit back and wait. Perl should build and ++link without a problem. If it doesn't, check the Gotchas to watch out for ++section. If that doesn't help, send some mail to the VMSPERL mailing list. ++Instructions are in the Mailing Lists section. ++ ++* Testing Perl ++ ++Once Perl has built cleanly, you need to test it to make sure things work. ++This step is very important--there are always things that can go wrong ++somehow and get you a dysfunctional Perl. ++ ++Testing is very easy, though, as there's a full test suite in the perl ++distribution. To run the tests, enter the *exact* MMS line you used to ++compile Perl and add the word "test" to the end, like this: ++ ++Compile Command: ++ ++$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("__AXP__=1","decc=1","DECCRTL_SOCKETS=1") ++ ++Test Command: ++ ++$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("__AXP__=1","decc=1","DECCRTL_SOCKETS=1") test ++ ++MMS will run all the tests. This may take some time, as there are a lot of ++tests. If any tests fail, there will be a note made on-screen. At the end ++of all the tests, a summary of the tests, the number passed and failed, and ++the time taken will be displayed. ++ ++If any tests fail, it means something's wrong with Perl. If the test suite ++hangs (some tests can take upwards of two or three minutes, or more if ++you're on an especially slow machine, depending on you machine speed, so ++don't be hasty), then the test *after* the last one displayed failed. Don't ++install Perl unless you're confident that you're OK. Regardless of how ++confident you are, make a bug report to the VMSPerl mailing list. ++ ++If one or more tests fail, you can get more info on the failure by issuing ++this command sequence: ++ ++$ SET DEFAULT [.T] ++$ @[-.VMS]TEST .typ -v [.subdir]test.T ++ ++where ".typ" is the file type of the Perl images you just built (if you ++didn't do anything special, use .EXE), and "[.subdir]test.T" is the test ++that failed. For example, with a normal Perl build, if the test indicated ++that [.op]time failed, then you'd do this: ++ ++$ SET DEFAULT [.T] ++$ @[-.VMS]TEST .EXE -v [.OP]TIME.T ++ ++When you send in a bug report for failed tests, please include the output ++from this command, which is run from the main source directory: ++ ++MCR []MINIPERL "-V" ++ ++Note that "-V" really is a capital V in double quotes. This will dump out a ++couple of screens worth of config info, and can help us diagnose the problem. ++ ++* Cleaning up and starting fresh ++ ++If you need to recompile from scratch, you have to make sure you clean up ++first. There's a procedure to do it--enter the *exact* MMS line you used to ++compile and add "realclean" at the end, like this: ++ ++Compile Command: ++ ++$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("__AXP__=1","decc=1","DECCRTL_SOCKETS=1") ++ ++Cleanup Command: ++ ++$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("__AXP__=1","decc=1","DECCRTL_SOCKETS=1") realclean ++ ++If you don't do this, things may behave erratically. They might not, too, ++so it's best to be sure and do it. ++ ++* Installing Perl ++ ++There are several steps you need to take to get Perl installed and ++running. At some point we'll have a working install in DESCRIP.MMS, but for ++right now the procedure's manual, and goes like this. ++ ++1) Create a directory somewhere and define the concealed logical PERL_ROOT ++to point to it. For example, DEFINE/TRANS=(CONC,TERM) PERL_ROOT dka200:[perl.] ++ ++2) Copy perl.exe into PERL_ROOT:[000000] ++ ++3) Copy everything in [.LIB] and [.UTILS] (including all the ++subdirectories!) to PERL_ROOT:[LIB] and PERL_ROOT:[UTILS]. ++ ++4) Either copy PERLSHR.EXE to SYS$SHARE, or to somewhere globally accessble ++and define the logical PERLSHR to point to it (DEFINE PERLSHR ++PERL_ROOT:[000000]PERLSHR.EXE or something like that). The PerlShr image ++should have W:RE protections on it. (Just W:E triggers increased security in ++the image activator. Not a huge problem, but Perl will need to have any ++other shared image it accesses INSTALLed. It's a huge pain, so don't unless ++you know what you're doing) ++ ++5) Either define the symbol PERL somewhere, such as ++SYS$MANAGER:SYLOGIN.COM, to be "PERL :== $PERL_ROOT:[000000]PERL.EXE", or ++install Perl into DCLTABLES.EXE )Check out the section "Installing Perl ++into DCLTABLES" for more info), or put the image in a directory that's in ++your DCL$PATH (if you're using VMS 6.2 or higher). ++ ++6) Optionally define the command PERLDOC as ++PERLDOC :== $PERL_ROOT:[000000]PERL PERL_ROOT:[LIB.POD]PERLDOC.COM -T ++ ++7) Optionally define the command PERLBUG (the Perl bug report generator) as ++PERLBUG :== $PERL_ROOT:[000000]PERL PERL_ROOT:[LIB]PERLBUG.COM" ++ ++* Installing Perl into DCLTABLES ++ ++Courtesy of Brad Hughes: ++ ++Put the following, modified to reflect where your .exe is, in PERL.CLD: ++ ++define verb perl ++image perl_root:[exe]perl.exe ++cliflags (foreign) ++ ++and then ++ ++$ set command perl /table=sys$common:[syslib]dcltables.exe - ++ /output=sys$common:[syslib]dcltables.exe ++$ install replace sys$common:[syslib]dcltables.exe ++ ++and you don't need perl :== $perl_root:[exe]perl.exe. ++ ++* Changing compile-time things ++ ++Most of the user-definable features of Perl are enabled or disabled in ++[.VMS]CONFIG.VMS. There's code in there to Do The Right Thing, but that may ++end up being the wrong thing for you. Make sure you understand what you're ++doing, since changes here can get you a busted perl. ++ ++Odds are that there's nothing here to change, unless you're on a version of ++VMS later than 6.2 and Dec C later than 5.6. Even if you are, the correct ++values will still be chosen, most likely. Poking around here should be ++unnecessary. ++ ++The one exception is the various *DIR install locations. Changing those ++requires changes in genconfig.pl as well. Be really careful if you need to ++change these,a s they can cause some fairly subtle problems. ++ ++* Extra things in the Perl distribution ++ ++In addition to the standard stuff that gets installed, there are two ++optional extensions, DCLSYM and STDIO, that are handy. Instructions for ++these two modules are in [.VMS.EXT.DCLSYM] and [.VMS.EXT.STDIO], ++respectively. ++ ++* Socket Support ++ ++Perl includes a number of functions for IP sockets, which are available if ++you choose to compile Perl with socket support. (See the section Compiling ++Perl for more info on selecting a socket stack) Since IP networking is an ++optional addition to VMS, there are several different IP stacks ++available. How well integrated they are into the system depends on the ++stack, your version of VMS, and the version of your C compiler. ++ ++The most portable solution uses the SOCKETSHR library. In combination with ++either UCX or NetLib, this supports all the major TCP stacks (Multinet, ++Pathways, TCPWare, UCX, and CMU) on all versions of VMS Perl runs on, with ++all the compilers on both VAX and Alpha. The socket interface is also ++consistent across versions of VMS and C compilers. It has a problem with ++UDP sockets when used with Multinet, though, so you should be aware of ++that. ++ ++The other solution available is to use the socket routines built into Dec ++C. Which routines are available depend on the version of VMS you're ++running, and require proper UCX emulation by your TCP/IP vendor. ++Relatively current versions of Multinet, TCPWare, Pathway, and UCX all ++provide the required libraries--check your manuals or release notes to see ++if your version is new enough. ++ ++* Reporting Bugs ++ ++If you come across what you think might be a bug in Perl, please report ++it. There's a script in PERL_ROOT:[UTILS], perlbug, that walks you through ++the process of creating a bug report. This script includes details of your ++installation, and is very handy. Completed bug reports should go to ++PERLBUG@PERL.COM. ++ ++* Gotchas to watch out for ++ ++Probably the single biggest gotcha in compiling Perl is giving the wrong ++switches to MMS/MMK when you build. If Perl's building oddly, double-check ++your switches. If you're on a VAX, be sure to add a /Macro=("decc=1") if ++you're using Dec C, and if you're on an alpha and using MMS, you'll need a ++/Macro=("__AXP__=1") ++ ++The next big gotcha is directory depth. Perl can create directories four ++and five levels deep during the build, so you don't have to be too deep to ++start to hit the RMS 8 level point. It's best to do a ++$DEFINE/TRANS=(CONC,TERM) PERLSRC disk:[dir.dir.dir.perldir.]" (note the ++trailing period) and $SET DEFAULT PERLSRC:[000000] before building. Perl ++modules can be just as bad (or worse), so watch out for them, too. ++ ++Finally, the third thing that bites people is leftover pieces from a failed ++build. If things go wrong, make sure you do a "(MMK|MMS|make) realclean" ++before you rebuild. ++ ++* Dec C issues ++ ++Note to DECC users: Some early versions (pre-5.2, some pre-4. If you're Dec ++C 5.x or higher, with current patches if anym you're fine) of the DECCRTL ++contained a few bugs which affect Perl performance: ++ - Newlines are lost on I/O through pipes, causing lines to run together. ++ This shows up as RMS RTB errors when reading from a pipe. You can ++ work around this by having one process write data to a file, and ++ then having the other read the file, instead of the pipe. This is ++ fixed in version 4 of DECC. ++ - The modf() routine returns a non-integral value for some values above ++ INT_MAX; the Perl "int" operator will return a non-integral value in ++ these cases. This is fixed in version 4 of DECC. ++ - On the AXP, if SYSNAM privilege is enabled, the CRTL chdir() routine ++ changes the process default device and directory permanently, even ++ though the call specified that the change should not persist after ++ Perl exited. This is fixed by DEC CSC patch AXPACRT04_061. ++ ++* Mailing Lists ++ ++There are several mailing lists available to the Perl porter. For VMS ++specific issues (including both Perl questions and installation problems) ++there is the VMSPERL mailing list. It's usually a low-volume (10-12 ++messages a week) mailing list. ++ ++The subscription address is VMSPERL-REQUEST@NEWMAN.UPENN.EDU. Send a mail ++message with just the words SUBSCRIBE VMSPERL in the body of the message. ++ ++The VMSPERL mailing list address is VMSPERL@NEWMAN.UPENN.EDU. Any mail ++sent there gets echoed to all subscribers of the list. ++ ++The Perl5-Porters list is for anyone involved in porting Perl to a ++platform. This includes you, if you want to participate. It's a high-volume ++list (60-100 messages a day during active development times), so be sure ++you want to be there. The subscription address is ++Perl5-Porters-request@perl.org. Send a message with just the word SUBSCRIBE ++in the body. The posting address is Perl5-Porters@perl.org. ++ ++* Acknowledgements ++ ++A real big thanks needs to go to Charles Bailey ++, who is ultimately responsible for Perl 5.004 ++running on VMS. Without him, nothing the rest of us have done would be at ++all important. ++ ++There are, of course, far too many people involved in the porting and testing ++of Perl to mention everyone who deserves it, so please forgive us if we've ++missed someone. That said, special thanks are due to the following: ++ Tim Adye ++ for the VMS emulations of getpw*() ++ David Denholm ++ for extensive testing and provision of pipe and SocketShr code, ++ Mark Pizzolato ++ for the getredirection() code ++ Rich Salz ++ for readdir() and related routines ++ Peter Prymmer ++ for extensive contributions to recent version support, ++ development of VMS-specific extensions, and dissemination ++ of information about VMS Perl, ++ the Stanford Synchrotron Radiation Laboratory and the ++ Laboratory of Nuclear Studies at Cornell University for ++ the the opportunity to test and develop for the AXP, ++and to the entire VMSperl group for useful advice and suggestions. In ++addition the perl5-porters deserve credit for their creativity and ++willingness to work with the VMS newcomers. Finally, the greatest debt of ++gratitude is due to Larry Wall , for having the ideas which ++have made our sleepless nights possible. ++ ++Thanks, ++The VMSperl group ++ ++ ++--------------------------------------------------------------------------- ++[Here's the pre-5.004_04 version of README.vms, for the record.] ++ Last revised: 19-Jan-1996 by Charles Bailey bailey@genetics.upenn.edu The VMS port of Perl is still under development. At this time, the Perl diff --cc av.c index 6b4c03d,6b4c03d..4a87eaf --- a/av.c +++ b/av.c @@@ -15,15 -15,15 +15,15 @@@ #include "EXTERN.h" #include "perl.h" --static void av_reify _((AV* av)); -- --static void ++void av_reify(av) AV* av; { I32 key; SV* sv; -- ++ ++ if (AvREAL(av)) ++ return; key = AvMAX(av) + 1; while (key > AvFILL(av) + 1) AvARRAY(av)[--key] = &sv_undef; @@@ -324,6 -324,6 +324,9 @@@ register AV *av SvPVX(av) = (char*)AvALLOC(av); } AvFILL(av) = -1; ++ ++ if (SvRMAGICAL(av)) ++ mg_clear((SV*)av); } void diff --cc configpm index 8ea1420,8ea1420..0c6a965 --- a/configpm +++ b/configpm @@@ -180,6 -180,6 +180,9 @@@ ENDOFSE print CONFIG <<'ENDOFTAIL'; ++# avoid Config..Exporter..UNIVERSAL search for DESTROY then AUTOLOAD ++sub DESTROY { } ++ tie %Config, 'Config'; 1; diff --cc doop.c index 763b1a9,763b1a9..571a9aa --- a/doop.c +++ b/doop.c @@@ -440,6 -440,6 +440,7 @@@ SV *right break; } } ++ SvTAINT(sv); } OP * diff --cc embed.h index 4be72d7,4be72d7..51e5f40 --- a/embed.h +++ b/embed.h @@@ -46,6 -46,6 +46,7 @@@ #define av_make Perl_av_make #define av_pop Perl_av_pop #define av_push Perl_av_push ++#define av_reify Perl_av_reify #define av_shift Perl_av_shift #define av_store Perl_av_store #define av_undef Perl_av_undef @@@ -325,6 -325,6 +326,7 @@@ #define magic_len Perl_magic_len #define magic_nextpack Perl_magic_nextpack #define magic_set Perl_magic_set ++#define magic_set_all_env Perl_magic_set_all_env #define magic_setamagic Perl_magic_setamagic #define magic_setarylen Perl_magic_setarylen #define magic_setbm Perl_magic_setbm diff --cc ext/DynaLoader/DynaLoader.pm index 04404b7,04404b7..712d575 --- a/ext/DynaLoader/DynaLoader.pm +++ b/ext/DynaLoader/DynaLoader.pm @@@ -12,16 -12,16 +12,21 @@@ package DynaLoader # # Tim.Bunce@ig.co.uk, August 1994 --use vars qw($VERSION); ++$VERSION = $VERSION = "1.03"; # avoid typo warning --$VERSION = "1.02"; -- --require Carp; require Config; require AutoLoader; *AUTOLOAD = \&AutoLoader::AUTOLOAD; ++# The following require can't be removed during maintenance ++# releases, sadly, because of the risk of buggy code that does ++# require Carp; Carp::croak "..."; without brackets dying ++# if Carp hasn't been loaded in earlier compile time. :-( ++# We'll let those bugs get found on the development track. ++require Carp if $] < 5.00450; ++ ++ # enable debug/trace messages from DynaLoader perl code $dl_debug = $ENV{PERL_DL_DEBUG} || 0 unless defined $dl_debug; @@@ -82,6 -82,6 +87,8 @@@ if ($dl_debug) 1; # End of main code ++sub croak { require Carp; Carp::croak(@_) } ++ # The bootstrap function cannot be autoloaded (without complications) # so we define it here: @@@ -91,11 -91,11 +98,14 @@@ sub bootstrap local($module) = $args[0]; local(@dirs, $file); -- Carp::confess("Usage: DynaLoader::bootstrap(module)") unless $module; ++ unless ($module) { ++ require Carp; ++ Carp::confess("Usage: DynaLoader::bootstrap(module)"); ++ } # A common error on platforms which don't support dynamic loading. # Since it's fatal and potentially confusing we give a detailed message. -- Carp::croak("Can't load module $module, dynamic loading not available in this perl.\n". ++ croak("Can't load module $module, dynamic loading not available in this perl.\n". " (You may need to build a new perl executable which either supports\n". " dynamic loading or has the $module module statically linked into it.)\n") unless defined(&dl_load_file); @@@ -119,16 -119,16 +129,17 @@@ next unless -d $dir; # skip over uninteresting directories # check for common cases to avoid autoload of dl_findfile -- last if ($file=_check_file("$dir/$modfname.$dl_dlext")); ++ my $try = "$dir/$modfname.$dl_dlext"; ++ last if $file = ($do_expand) ? dl_expandspec($try) : (-f $try && $try); # no luck here, save dir for possible later dl_findfile search -- push(@dirs, "-L$dir"); ++ push @dirs, $dir; } # last resort, let dl_findfile have a go in all known locations -- $file = dl_findfile(@dirs, map("-L$_",@INC), $modfname) unless $file; ++ $file = dl_findfile(map("-L$_",@dirs,@INC), $modfname) unless $file; -- Carp::croak("Can't find loadable object for module $module in \@INC (@INC)") -- unless $file; ++ croak("Can't locate loadable object for module $module in \@INC (\@INC contains: @INC)") ++ unless $file; # wording similar to error from 'require' my $bootname = "boot_$module"; $bootname =~ s/\W/_/g; @@@ -153,16 -153,16 +164,18 @@@ # it executed. my $libref = dl_load_file($file, $module->dl_load_flags) or -- Carp::croak("Can't load '$file' for module $module: ".dl_error()."\n"); ++ croak("Can't load '$file' for module $module: ".dl_error()."\n"); push(@dl_librefs,$libref); # record loaded object my @unresolved = dl_undef_symbols(); -- Carp::carp("Undefined symbols present after loading $file: @unresolved\n") -- if @unresolved; ++ if (@unresolved) { ++ require Carp; ++ Carp::carp("Undefined symbols present after loading $file: @unresolved\n"); ++ } my $boot_symbol_ref = dl_find_symbol($libref, $bootname) or -- Carp::croak("Can't find '$bootname' symbol in $file\n"); ++ croak("Can't find '$bootname' symbol in $file\n"); my $xs = dl_install_xsub("${module}::bootstrap", $boot_symbol_ref, $file); @@@ -173,12 -173,12 +186,12 @@@ } --sub _check_file { # private utility to handle dl_expandspec vs -f tests -- my($file) = @_; -- return $file if (!$do_expand && -f $file); # the common case -- return $file if ( $do_expand && ($file=dl_expandspec($file))); -- return undef; --} ++#sub _check_file { # private utility to handle dl_expandspec vs -f tests ++# my($file) = @_; ++# return $file if (!$do_expand && -f $file); # the common case ++# return $file if ( $do_expand && ($file=dl_expandspec($file))); ++# return undef; ++#} # Let autosplit and the autoloader deal with these functions: @@@ -243,7 -243,7 +256,8 @@@ sub dl_findfile foreach $name (@names) { my($file) = "$dir/$name"; print STDERR " checking in $dir for $name\n" if $dl_debug; -- $file = _check_file($file); ++ $file = ($do_expand) ? dl_expandspec($file) : (-f $file && $file); ++ #$file = _check_file($file); if ($file) { push(@found, $file); next arg; # no need to look any further @@@ -279,6 -279,6 +293,7 @@@ sub dl_expandspec my $file = $spec; # default output to input if ($Is_VMS) { # dl_expandspec should be defined in dl_vms.xs ++ require Carp; Carp::croak("dl_expandspec: should be defined in XS file!\n"); } else { return undef unless -f $file; diff --cc ext/util/make_ext index bfbcc83,bfbcc83..70a5d2e --- a/ext/util/make_ext +++ b/ext/util/make_ext @@@ -4,16 -4,16 +4,35 @@@ # It primarily used by the perl Makefile: # # d_dummy $(dynamic_ext): miniperl preplibrary FORCE --# ext/util/make_ext dynamic $@ ++# @sh ext/util/make_ext dynamic $@ MAKE=$(MAKE) LIBPERL_A=$(LIBPERL) # # It may be deleted in a later release of perl so try to # avoid using it for other purposes. target=$1; shift extspec=$1; shift ++makecmd=$1; shift # Should be something like MAKE=make passthru="$*" # allow extra macro=value to be passed through echo "" ++# Previously, $make was taken from config.sh. However, the user might ++# instead be running a possibly incompatible make. This might happen if ++# the user types "gmake" instead of a plain "make", for example. The ++# correct current value of MAKE will come through from the main perl ++# makefile as MAKE=/whatever/make in $makecmd. We'll be cautious in ++# case third party users of this script (are there any?) don't have the ++# MAKE=$(MAKE) argument, which was added after 5.004_03. ++case "$makecmd" in ++MAKE=*) ++ eval $makecmd ++ ;; ++*) echo 'ext/util/make_ext: WARNING: Please include MAKE=$(MAKE)' ++ echo ' in your call to make_ext. See ext/util/make_ext for details.' ++ exit 1 ++ ;; ++esac ++ ++ case $CONFIG in '') if test -f config.sh; then TOP=.; @@@ -107,10 -107,10 +126,10 @@@ clean) ; realclean) ;; *) # Give makefile an opportunity to rewrite itself. # reassure users that life goes on... -- $make config $passthru || echo "$make config failed, continuing anyway..." ++ $MAKE config $passthru || echo "$MAKE config failed, continuing anyway..." ;; esac --$make $makeopts $target $makeargs $passthru || exit ++$MAKE $makeopts $target $makeargs $passthru || exit exit $? diff --cc global.sym index a8d99d7,a8d99d7..864be81 --- a/global.sym +++ b/global.sym @@@ -310,6 -310,6 +310,7 @@@ av_le av_make av_pop av_push ++av_reify av_shift av_store av_undef @@@ -530,6 -530,6 +531,7 @@@ magic_setsubst magic_settaint magic_setuvar magic_setvec ++magic_set_all_env magic_wipepack magicname markstack_grow diff --cc gv.c index 6658259,6658259..fff3bcf --- a/gv.c +++ b/gv.c @@@ -170,8 -170,8 +170,8 @@@ I32 level gvp = (GV**)hv_fetch(stash, "ISA", 3, FALSE); av = (gvp && (gv = *gvp) && gv != (GV*)&sv_undef) ? GvAV(gv) : Nullav; -- /* create @.*::SUPER::ISA on demand */ -- if (!av) { ++ /* create and re-create @.*::SUPER::ISA on demand */ ++ if (!av || !SvMAGIC(av)) { char* packname = HvNAME(stash); STRLEN packlen = strlen(packname); @@@ -740,6 -740,6 +740,7 @@@ I32 sv_type case '7': case '8': case '9': ++ case '\023': ro_magicalize: SvREADONLY_on(GvSV(gv)); magicalize: diff --cc hints/linux.sh index 6a11a42,6a11a42..8ddb765 --- a/hints/linux.sh +++ b/hints/linux.sh @@@ -29,6 -29,6 +29,14 @@@ esa # gcc-2.6.3 defines _G_HAVE_BOOL to 1, but doesn't actually supply bool. ccflags="-Dbool=char -DHAS_BOOL $ccflags" ++# libc6, aka glibc2, seems to need STRUCT_TM_HASZONE defined. ++# Thanks to Bart Schuller ++# See Message-ID: <19971009002636.50729@tanglefoot> ++# This is currently commented out for maintenance releases ++# but should probably be uncommented for 5.005 or after ++# more widespread testing. ++#POSIX_cflags='ccflags="$ccflags -DSTRUCT_TM_HASZONE"' ++ # BSD compatability library no longer needed set `echo X "$libswanted "| sed -e 's/ bsd / /'` shift diff --cc hv.c index f63dff8,f63dff8..4eaae0f --- a/hv.c +++ b/hv.c @@@ -886,7 -886,7 +886,7 @@@ HV *hv } xhv->xhv_riter = -1; xhv->xhv_eiter = Null(HE*); -- return xhv->xhv_fill; ++ return xhv->xhv_fill; /* should be xhv->xhv_keys? May change later */ } HE * @@@ -962,7 -962,7 +962,10 @@@ register HE *entry I32 *retlen; { if (HeKLEN(entry) == HEf_SVKEY) { -- return SvPV(HeKEY_sv(entry), *(STRLEN*)retlen); ++ STRLEN len; ++ char *p = SvPV(HeKEY_sv(entry), len); ++ *retlen = len; ++ return p; } else { *retlen = HeKLEN(entry); diff --cc lib/AutoLoader.pm index c45483b,c45483b..2773a90 --- a/lib/AutoLoader.pm +++ b/lib/AutoLoader.pm @@@ -1,6 -1,6 +1,5 @@@ package AutoLoader; --use Carp; use vars qw(@EXPORT @EXPORT_OK); BEGIN { @@@ -42,7 -42,7 +41,9 @@@ AUTOLOAD } if ($@){ $@ =~ s/ at .*\n//; -- croak $@; ++ my $error = $@; ++ require Carp; ++ Carp::croak($error); } } } @@@ -83,7 -83,7 +84,11 @@@ sub import $path ="auto/$calldir/autosplit.ix"; eval { require $path; }; } -- carp $@ if ($@); ++ if ($@) { ++ my $error = $@; ++ require Carp; ++ Carp::carp($error); ++ } } } @@@ -169,6 -169,6 +174,7 @@@ Instead, they should define their own A lines: use AutoLoader; ++ use Carp; sub AUTOLOAD { my $constname; @@@ -183,7 -183,7 +189,7 @@@ croak "Your vendor has not defined constant $constname"; } } -- eval "sub $AUTOLOAD { $val }"; ++ *$AUTOLOAD = sub { $val }; # same as: eval "sub $AUTOLOAD { $val }"; goto &$AUTOLOAD; } diff --cc lib/Carp.pm index 351f83b,351f83b..685a793 --- a/lib/Carp.pm +++ b/lib/Carp.pm @@@ -53,7 -53,7 +53,7 @@@ $MaxArgLen = 64; # How much of e $MaxArgNums = 8; # How many arguments to print. 0 = all. require Exporter; --@ISA = Exporter; ++@ISA = ('Exporter'); @EXPORT = qw(confess croak carp); @EXPORT_OK = qw(cluck verbose); @EXPORT_FAIL = qw(verbose); # hook to enable verbose mode diff --cc lib/Cwd.pm index efcfeca,efcfeca..3bd0085 --- a/lib/Cwd.pm +++ b/lib/Cwd.pm @@@ -26,14 -26,14 +26,22 @@@ The getcwd() function re-implements th in Perl. The fastcwd() function looks the same as getcwd(), but runs faster. --It's also more dangerous because you might conceivably chdir() out of a --directory that you can't chdir() back into. ++It's also more dangerous because it might conceivably chdir() you out ++of a directory that it can't chdir() you back into. If fastcwd ++encounters a problem it will return undef but will probably leave you ++in a different directory. For a measure of extra security, if ++everything appears to have worked, the fastcwd() function will check ++that it leaves you in the same directory that it started in. If it has ++changed it will C with the message "Unstable directory path, ++current directory changed unexpectedly". That should never happen. The cwd() function looks the same as getcwd and fastgetcwd but is implemented using the most natural and safe form for the current architecture. For most systems it is identical to `pwd` (but without --the trailing line terminator). It is recommended that cwd (or another --*cwd() function) is used in I code to ensure portability. ++the trailing line terminator). ++ ++It is recommended that cwd (or another *cwd() function) is used in ++I code to ensure portability. If you ask to override your chdir() built-in function, then your PWD environment variable will be kept up to date. (See @@@ -101,7 -101,7 +109,7 @@@ sub getcw } if ($pst[0] == $cst[0] && $pst[1] == $cst[1]) { -- $dir = ''; ++ $dir = undef; } else { @@@ -125,9 -125,9 +133,9 @@@ while ($dir eq '.' || $dir eq '..' || $tst[0] != $pst[0] || $tst[1] != $pst[1]); } -- $cwd = "$dir/$cwd"; ++ $cwd = (defined $dir ? "$dir" : "" ) . "/$cwd" ; closedir(PARENT); -- } while ($dir); ++ } while (defined $dir); chop($cwd) unless $cwd eq '/'; # drop the trailing / $cwd; } @@@ -140,33 -140,33 +148,45 @@@ # # This is a faster version of getcwd. It's also more dangerous because # you might chdir out of a directory that you can't chdir back into. ++ ++# List of metachars taken from do_exec() in doio.c ++my $quoted_shell_meta = quotemeta('$&*(){}[]";\\|?<>~`'."'\n"); sub fastcwd { my($odev, $oino, $cdev, $cino, $tdev, $tino); my(@path, $path); local(*DIR); -- ($cdev, $cino) = stat('.'); ++ my($orig_cdev, $orig_cino) = stat('.'); ++ ($cdev, $cino) = ($orig_cdev, $orig_cino); for (;;) { my $direntry; ($odev, $oino) = ($cdev, $cino); -- chdir('..'); ++ chdir('..') || return undef; ($cdev, $cino) = stat('.'); last if $odev == $cdev && $oino == $cino; -- opendir(DIR, '.'); ++ opendir(DIR, '.') || return undef; for (;;) { $direntry = readdir(DIR); ++ last unless defined $direntry; next if $direntry eq '.'; next if $direntry eq '..'; -- last unless defined $direntry; ($tdev, $tino) = lstat($direntry); last unless $tdev != $odev || $tino != $oino; } closedir(DIR); ++ return undef unless defined $direntry; # should never happen unshift(@path, $direntry); } -- chdir($path = '/' . join('/', @path)); ++ $path = '/' . join('/', @path); ++ # At this point $path may be tainted (if tainting) and chdir would fail. ++ # To be more useful we untaint it then check that we landed where we started. ++ $path = $1 if $path =~ /^(.*)$/; # untaint ++ chdir($path) || return undef; ++ ($cdev, $cino) = stat('.'); ++ die "Unstable directory path, current directory changed unexpectedly" ++ if $cdev != $orig_cdev || $cino != $orig_cino; $path; } diff --cc lib/English.pm index 0cf62bd,0cf62bd..bbb6bd7 --- a/lib/English.pm +++ b/lib/English.pm @@@ -92,7 -92,7 +92,7 @@@ sub import *OSNAME ); --# The ground of all being. ++# The ground of all being. @ARG is deprecated (5.005 makes @_ lexical) *ARG = *_ ; diff --cc lib/ExtUtils/Install.pm index ff5dbf1,ff5dbf1..4400858 --- a/lib/ExtUtils/Install.pm +++ b/lib/ExtUtils/Install.pm @@@ -34,6 -34,6 +34,7 @@@ sub install use File::Copy qw(copy); use File::Find qw(find); use File::Path qw(mkpath); ++ use File::Compare qw(compare); my(%hash) = %$hash; my(%pack, %write, $dir, $warn_permissions); @@@ -96,7 -96,7 +97,7 @@@ my $diff = 0; if ( -f $targetfile && -s _ == $size) { # We have a good chance, we can skip this one -- $diff = my_cmp($_,$targetfile); ++ $diff = compare($_,$targetfile); } else { print "$_ differs\n" if $verbose>1; $diff++; @@@ -166,32 -166,32 +167,6 @@@ sub install_default },1,0,0); } --sub my_cmp { -- my($one,$two) = @_; -- local(*F,*T); -- my $diff = 0; -- open T, $two or return 1; -- open F, $one or Carp::croak("Couldn't open $one: $!"); -- my($fr, $tr, $fbuf, $tbuf, $size); -- $size = 1024; -- # print "Reading $one\n"; -- while ( $fr = read(F,$fbuf,$size)) { -- unless ( -- $tr = read(T,$tbuf,$size) and -- $tbuf eq $fbuf -- ){ -- # print "diff "; -- $diff++; -- last; -- } -- # print "$fr/$tr "; -- } -- # print "\n"; -- close F; -- close T; -- $diff; --} -- sub uninstall { my($fil,$verbose,$nonono) = @_; die "no packlist file found: $fil" unless -f $fil; @@@ -226,7 -226,7 +201,7 @@@ sub inc_uninstall my $diff = 0; if ( -f $targetfile && -s _ == -s $file) { # We have a good chance, we can skip this one -- $diff = my_cmp($file,$targetfile); ++ $diff = compare($file,$targetfile); } else { print "#$file and $targetfile differ\n" if $verbose>1; $diff++; @@@ -253,6 -253,6 +228,7 @@@ sub pm_to_blib use File::Basename qw(dirname); use File::Copy qw(copy); use File::Path qw(mkpath); ++ use File::Compare qw(compare); use AutoSplit; # my $my_req = $self->catfile(qw(auto ExtUtils Install forceunlink.al)); # require $my_req; # Hairy, but for the first @@@ -272,7 -272,7 +248,7 @@@ mkpath($autodir,0,0755); foreach (keys %$fromto) { next if -f $fromto->{$_} && -M $fromto->{$_} < -M $_; -- unless (my_cmp($_,$fromto->{$_})){ ++ unless (compare($_,$fromto->{$_})){ print "Skip $fromto->{$_} (unchanged)\n"; next; } diff --cc lib/ExtUtils/Liblist.pm index fed25ae,fed25ae..d821e83 --- a/lib/ExtUtils/Liblist.pm +++ b/lib/ExtUtils/Liblist.pm @@@ -24,7 -24,7 +24,7 @@@ sub _unix_os2_ext $potential_libs .= $Config{libs}; } return ("", "", "", "") unless $potential_libs; -- print STDOUT "Potential libraries are '$potential_libs':\n" if $verbose; ++ warn "Potential libraries are '$potential_libs':\n" if $verbose; my($so) = $Config{'so'}; my($libs) = $Config{'libs'}; @@@ -34,7 -34,7 +34,6 @@@ # compute $extralibs, $bsloadlibs and $ldloadlibs from # $potential_libs # this is a rewrite of Andy Dougherty's extliblist in perl -- # its home is in /ext/util my(@searchpath); # from "-L/path" entries in $potential_libs my(@libpath) = split " ", $Config{'libpth'}; @@@ -49,12 -49,12 +48,12 @@@ if ($thislib =~ s/^(-[LR])//){ # save path flag type my($ptype) = $1; unless (-d $thislib){ -- print STDOUT "$ptype$thislib ignored, directory does not exist\n" ++ warn "$ptype$thislib ignored, directory does not exist\n" if $verbose; next; } unless ($self->file_name_is_absolute($thislib)) { -- print STDOUT "Warning: $ptype$thislib changed to $ptype$pwd/$thislib\n"; ++ warn "Warning: $ptype$thislib changed to $ptype$pwd/$thislib\n"; $thislib = $self->catdir($pwd,$thislib); } push(@searchpath, $thislib); @@@ -65,7 -65,7 +64,7 @@@ # Handle possible library arguments. unless ($thislib =~ s/^-l//){ -- print STDOUT "Unrecognized argument in LIBS ignored: '$thislib'\n"; ++ warn "Unrecognized argument in LIBS ignored: '$thislib'\n"; next; } @@@ -125,10 -125,10 +124,10 @@@ # # , the compilation tools expand the environment variables.) } else { -- print STDOUT "$thislib not found in $thispth\n" if $verbose; ++ warn "$thislib not found in $thispth\n" if $verbose; next; } -- print STDOUT "'-l$thislib' found at $fullname\n" if $verbose; ++ warn "'-l$thislib' found at $fullname\n" if $verbose; my($fullnamedir) = dirname($fullname); push @ld_run_path, $fullnamedir unless $ld_run_path_seen{$fullnamedir}++; $found++; @@@ -174,7 -174,7 +173,7 @@@ } last; # found one here so don't bother looking further } -- print STDOUT "Note (probably harmless): " ++ warn "Note (probably harmless): " ."No library found for -l$thislib\n" unless $found_lib>0; } @@@ -202,7 -202,7 +201,7 @@@ sub _win32_ext $potential_libs .= " " if $potential_libs; $potential_libs .= $libs; } -- print STDOUT "Potential libraries are '$potential_libs':\n" if $verbose; ++ warn "Potential libraries are '$potential_libs':\n" if $verbose; # compute $extralibs from $potential_libs @@@ -218,13 -218,13 +217,13 @@@ # Handle possible linker path arguments. if ($thislib =~ s/^-L// and not -d $thislib) { -- print STDOUT "-L$thislib ignored, directory does not exist\n" ++ warn "-L$thislib ignored, directory does not exist\n" if $verbose; next; } elsif (-d $thislib) { unless ($self->file_name_is_absolute($thislib)) { -- print STDOUT "Warning: -L$thislib changed to -L$pwd/$thislib\n"; ++ warn "Warning: -L$thislib changed to -L$pwd/$thislib\n"; $thislib = $self->catdir($pwd,$thislib); } push(@searchpath, $thislib); @@@ -238,22 -238,22 +237,22 @@@ my($found_lib)=0; foreach $thispth (@searchpath, @libpath){ unless (-f ($fullname="$thispth\\$thislib")) { -- print STDOUT "$thislib not found in $thispth\n" if $verbose; ++ warn "$thislib not found in $thispth\n" if $verbose; next; } -- print STDOUT "'$thislib' found at $fullname\n" if $verbose; ++ warn "'$thislib' found at $fullname\n" if $verbose; $found++; $found_lib++; push(@extralibs, $fullname); last; } -- print STDOUT "Note (probably harmless): " ++ warn "Note (probably harmless): " ."No library found for '$thislib'\n" unless $found_lib>0; } return ('','','','') unless $found; $lib = join(' ',@extralibs); -- print "Result: $lib\n" if $verbose; ++ warn "Result: $lib\n" if $verbose; wantarray ? ($lib, '', $lib, '') : $lib; } @@@ -275,7 -275,7 +274,7 @@@ sub _vms_ext 'Xmu' => 'DECW$XMULIBSHR'); if ($Config{'vms_cc_type'} ne 'decc') { $libmap{'curses'} = 'VAXCCURSE'; } -- print STDOUT "Potential libraries are '$potential_libs'\n" if $verbose; ++ warn "Potential libraries are '$potential_libs'\n" if $verbose; # First, sort out directories and library names in the input foreach $lib (split ' ',$potential_libs) { @@@ -292,11 -292,11 +291,11 @@@ # path in a logical name.) foreach $dir (@dirs) { unless (-d $dir) { -- print STDOUT "Skipping nonexistent Directory $dir\n" if $verbose > 1; ++ warn "Skipping nonexistent Directory $dir\n" if $verbose > 1; $dir = ''; next; } -- print STDOUT "Resolving directory $dir\n" if $verbose; ++ warn "Resolving directory $dir\n" if $verbose; if ($self->file_name_is_absolute($dir)) { $dir = $self->fixpath($dir,1); } else { $dir = $self->catdir($cwd,$dir); } } @@@ -321,24 -321,24 +320,24 @@@ push(@variants,"lib$lib") if $lib !~ /[:>\]]/; } push(@variants,$lib); -- print STDOUT "Looking for $lib\n" if $verbose; ++ warn "Looking for $lib\n" if $verbose; foreach $variant (@variants) { foreach $dir (@dirs) { my($type); $name = "$dir$variant"; -- print "\tChecking $name\n" if $verbose > 2; ++ warn "\tChecking $name\n" if $verbose > 2; if (-f ($test = VMS::Filespec::rmsexpand($name))) { # It's got its own suffix, so we'll have to figure out the type if ($test =~ /(?:$so|exe)$/i) { $type = 'sh'; } elsif ($test =~ /(?:$lib_ext|olb)$/i) { $type = 'olb'; } elsif ($test =~ /(?:$obj_ext|obj)$/i) { -- print STDOUT "Note (probably harmless): " ++ warn "Note (probably harmless): " ."Plain object file $test found in library list\n"; $type = 'obj'; } else { -- print STDOUT "Note (probably harmless): " ++ warn "Note (probably harmless): " ."Unknown library type for $test; assuming shared\n"; $type = 'sh'; } @@@ -357,7 -357,7 +356,7 @@@ elsif (not length($ctype) and # If we've got a lib already, don't bother ( -f ($test = VMS::Filespec::rmsexpand($name,$obj_ext)) or -f ($test = VMS::Filespec::rmsexpand($name,'.obj')))) { -- print STDOUT "Note (probably harmless): " ++ warn "Note (probably harmless): " ."Plain object file $test found in library list\n"; $type = 'obj'; $name = $test unless $test =~ /obj;?\d*$/i; @@@ -370,11 -370,11 +369,11 @@@ if ($ctype) { eval '$' . $ctype . "{'$cand'}++"; die "Error recording library: $@" if $@; -- print STDOUT "\tFound as $cand (really $test), type $ctype\n" if $verbose > 1; ++ warn "\tFound as $cand (really $test), type $ctype\n" if $verbose > 1; next LIB; } } -- print STDOUT "Note (probably harmless): " ++ warn "Note (probably harmless): " ."No library found for $lib\n"; } @@@ -387,7 -387,7 +386,7 @@@ push(@libs, map { "$_/Library" } sort keys %olb); push(@libs, map { "$_/Share" } sort keys %sh); $lib = join(' ',@libs); -- print "Result: $lib\n" if $verbose; ++ warn "Result: $lib\n" if $verbose; wantarray ? ($lib, '', $lib, '') : $lib; } diff --cc lib/ExtUtils/MM_Unix.pm index 85b0c1b,85b0c1b..4f7a9e8 --- a/lib/ExtUtils/MM_Unix.pm +++ b/lib/ExtUtils/MM_Unix.pm @@@ -1127,7 -1127,7 +1127,12 @@@ sub fixin { # stolen from the pink Came # Now look (in reverse) for interpreter in absolute PATH (unless perl). if ($cmd eq "perl") { -- $interpreter = $Config{perlpath}; ++ if ($Config{startperl} =~ m,^\#!.*/perl,) { ++ $interpreter = $Config{startperl}; ++ $interpreter =~ s,^\#!,,; ++ } else { ++ $interpreter = $Config{perlpath}; ++ } } else { my(@absdirs) = reverse grep {$self->file_name_is_absolute} $self->path; $interpreter = ''; @@@ -2935,11 -2935,11 +2940,13 @@@ sub test if (!$tests && -d 't') { $tests = $Is_Win32 ? join(' ', ) : 't/*.t'; } ++ # note: 'test.pl' name is also hardcoded in init_dirscan() my(@m); push(@m," TEST_VERBOSE=0 TEST_TYPE=test_\$(LINKTYPE) TEST_FILE = test.pl ++TEST_FILES = $tests TESTDB_SW = -d testdb :: testdb_\$(LINKTYPE) @@@ -2953,8 -2953,8 +2960,8 @@@ test :: \$(TEST_TYPE push(@m, "\n"); push(@m, "test_dynamic :: pure_all\n"); -- push(@m, $self->test_via_harness('$(FULLPERL)', $tests)) if $tests; -- push(@m, $self->test_via_script('$(FULLPERL)', 'test.pl')) if -f "test.pl"; ++ push(@m, $self->test_via_harness('$(FULLPERL)', '$(TEST_FILES)')) if $tests; ++ push(@m, $self->test_via_script('$(FULLPERL)', '$(TEST_FILE)')) if -f "test.pl"; push(@m, "\n"); push(@m, "testdb_dynamic :: pure_all\n"); @@@ -2966,8 -2966,8 +2973,8 @@@ if ($self->needs_linking()) { push(@m, "test_static :: pure_all \$(MAP_TARGET)\n"); -- push(@m, $self->test_via_harness('./$(MAP_TARGET)', $tests)) if $tests; -- push(@m, $self->test_via_script('./$(MAP_TARGET)', 'test.pl')) if -f "test.pl"; ++ push(@m, $self->test_via_harness('./$(MAP_TARGET)', '$(TEST_FILES)')) if $tests; ++ push(@m, $self->test_via_script('./$(MAP_TARGET)', '$(TEST_FILE)')) if -f "test.pl"; push(@m, "\n"); push(@m, "testdb_static :: pure_all \$(MAP_TARGET)\n"); push(@m, $self->test_via_script('./$(MAP_TARGET) $(TESTDB_SW)', '$(TEST_FILE)')); diff --cc lib/File/DosGlob.pm index e0887d1,e0887d1..4597c71 --- a/lib/File/DosGlob.pm +++ b/lib/File/DosGlob.pm @@@ -100,16 -100,16 +100,55 @@@ sub doglob } # --# this can be used to override CORE::glob --# by saying C. ++# this can be used to override CORE::glob in a specific ++# package by saying C in that ++# namespace. # --sub glob { doglob(1,@_) } ++ ++# context (keyed by second cxix arg provided by core) ++my %iter; ++my %entries; ++ ++sub glob { ++ my $pat = shift; ++ my $cxix = shift; ++ ++ # glob without args defaults to $_ ++ $pat = $_ unless defined $pat; ++ ++ # assume global context if not provided one ++ $cxix = '_G_' unless defined $cxix; ++ $iter{$cxix} = 0 unless exists $iter{$cxix}; ++ ++ # if we're just beginning, do it all first ++ if ($iter{$cxix} == 0) { ++ $entries{$cxix} = [doglob(1,$pat)]; ++ } ++ ++ # chuck it all out, quick or slow ++ if (wantarray) { ++ delete $iter{$cxix}; ++ return @{delete $entries{$cxix}}; ++ } ++ else { ++ if ($iter{$cxix} = scalar @{$entries{$cxix}}) { ++ return shift @{$entries{$cxix}}; ++ } ++ else { ++ # return undef for EOL ++ delete $iter{$cxix}; ++ delete $entries{$cxix}; ++ return undef; ++ } ++ } ++} sub import { my $pkg = shift; my $callpkg = caller(0); my $sym = shift; -- *{$callpkg.'::'.$sym} = \&{$pkg.'::'.$sym} if $sym eq 'glob'; ++ *{$callpkg.'::'.$sym} = \&{$pkg.'::'.$sym} ++ if defined($sym) and $sym eq 'glob'; } 1; @@@ -125,11 -125,11 +164,14 @@@ perlglob.bat - a more capable perlglob. =head1 SYNOPSIS require 5.004; -- use File::DosGlob 'glob'; # override CORE::glob ++ ++ # override CORE::glob in current package ++ use File::DosGlob 'glob'; ++ @perlfiles = glob "..\\pe?l/*.p?"; print <..\\pe?l/*.p?>; -- # from the command line ++ # from the command line (overrides only in main::) > perl -MFile::DosGlob=glob -e "print <../pe*/*p?>" > perlglob ../pe*/*p? @@@ -155,7 -155,7 +197,10 @@@ to standard output While one may replace perlglob.exe with this, usage by overriding CORE::glob via importation should be much more efficient, because it avoids launching a separate process, and is therefore strongly --recommended. ++recommended. Note that it is currently possible to override ++builtins like glob() only on a per-package basis, not "globally". ++Thus, every namespace that wants to override glob() must explicitly ++request the override. See L. Extending it to csh patterns is left as an exercise to the reader. @@@ -178,6 -178,6 +223,10 @@@ Gurusamy Sarathy {'polar'} = [abs($rho), $theta]; ++ if ($rho < 0) { ++ $rho = -$rho; ++ $theta = ($theta <= 0) ? $theta + pi() : $theta - pi(); ++ } ++ $self->{'polar'} = [$rho, $theta]; $self->{p_dirty} = 0; $self->{c_dirty} = 1; return $self; @@@ -133,18 -133,18 +139,30 @@@ sub cplxe # # pi # --# The number defined as 2 * pi = 360 degrees ++# The number defined as pi = 180 degrees # use constant pi => 4 * atan2(1, 1); # --# log2inv ++# pit2 # --# Used in log10(). ++# The full circle ++# ++use constant pit2 => 2 * pi; ++ # ++# pip2 ++# ++# The quarter circle ++# ++use constant pip2 => pi / 2; --use constant log10inv => 1 / log(10); ++# ++# uplog10 ++# ++# Used in log10(). ++# ++use constant uplog10 => 1 / log(10); # # i @@@ -155,7 -155,7 +173,7 @@@ sub i () return $i if ($i); $i = bless {}; $i->{'cartesian'} = [0, 1]; -- $i->{'polar'} = [1, pi/2]; ++ $i->{'polar'} = [1, pip2]; $i->{c_dirty} = 0; $i->{p_dirty} = 0; return $i; @@@ -242,15 -242,15 +260,28 @@@ sub minus # Computes z1*z2. # sub multiply { -- my ($z1, $z2, $regular) = @_; -- my ($r1, $t1) = @{$z1->polar}; -- $z2 = cplxe(abs($z2), $z2 >= 0 ? 0 : pi) unless ref $z2; -- my ($r2, $t2) = @{$z2->polar}; -- unless (defined $regular) { -- $z1->set_polar([$r1 * $r2, $t1 + $t2]); ++ my ($z1, $z2, $regular) = @_; ++ if ($z1->{p_dirty} == 0 and ref $z2 and $z2->{p_dirty} == 0) { ++ # if both polar better use polar to avoid rounding errors ++ my ($r1, $t1) = @{$z1->polar}; ++ my ($r2, $t2) = @{$z2->polar}; ++ my $t = $t1 + $t2; ++ if ($t > pi()) { $t -= pit2 } ++ elsif ($t <= -pi()) { $t += pit2 } ++ unless (defined $regular) { ++ $z1->set_polar([$r1 * $r2, $t]); return $z1; ++ } ++ return (ref $z1)->emake($r1 * $r2, $t); ++ } else { ++ my ($x1, $y1) = @{$z1->cartesian}; ++ if (ref $z2) { ++ my ($x2, $y2) = @{$z2->cartesian}; ++ return (ref $z1)->make($x1*$x2-$y1*$y2, $x1*$y2+$y1*$x2); ++ } else { ++ return (ref $z1)->make($x1*$z2, $y1*$z2); ++ } } -- return (ref $z1)->emake($r1 * $r2, $t1 + $t2); } # @@@ -268,7 -268,7 +299,7 @@@ sub _divbyzero } my @up = caller(1); -- ++ $mess .= "Died at $up[1] line $up[2].\n"; die $mess; @@@ -281,20 -281,20 +312,45 @@@ # sub divide { my ($z1, $z2, $inverted) = @_; -- my ($r1, $t1) = @{$z1->polar}; -- $z2 = cplxe(abs($z2), $z2 >= 0 ? 0 : pi) unless ref $z2; -- my ($r2, $t2) = @{$z2->polar}; -- unless (defined $inverted) { -- _divbyzero "$z1/0" if ($r2 == 0); -- $z1->set_polar([$r1 / $r2, $t1 - $t2]); -- return $z1; -- } -- if ($inverted) { ++ if ($z1->{p_dirty} == 0 and ref $z2 and $z2->{p_dirty} == 0) { ++ # if both polar better use polar to avoid rounding errors ++ my ($r1, $t1) = @{$z1->polar}; ++ my ($r2, $t2) = @{$z2->polar}; ++ my $t; ++ if ($inverted) { _divbyzero "$z2/0" if ($r1 == 0); -- return (ref $z1)->emake($r2 / $r1, $t2 - $t1); -- } else { ++ $t = $t2 - $t1; ++ if ($t > pi()) { $t -= pit2 } ++ elsif ($t <= -pi()) { $t += pit2 } ++ return (ref $z1)->emake($r2 / $r1, $t); ++ } else { _divbyzero "$z1/0" if ($r2 == 0); -- return (ref $z1)->emake($r1 / $r2, $t1 - $t2); ++ $t = $t1 - $t2; ++ if ($t > pi()) { $t -= pit2 } ++ elsif ($t <= -pi()) { $t += pit2 } ++ return (ref $z1)->emake($r1 / $r2, $t); ++ } ++ } else { ++ my ($d, $x2, $y2); ++ if ($inverted) { ++ ($x2, $y2) = @{$z1->cartesian}; ++ $d = $x2*$x2 + $y2*$y2; ++ _divbyzero "$z2/0" if $d == 0; ++ return (ref $z1)->make(($x2*$z2)/$d, -($y2*$z2)/$d); ++ } else { ++ my ($x1, $y1) = @{$z1->cartesian}; ++ if (ref $z2) { ++ ($x2, $y2) = @{$z2->cartesian}; ++ $d = $x2*$x2 + $y2*$y2; ++ _divbyzero "$z1/0" if $d == 0; ++ my $u = ($x1*$x2 + $y1*$y2)/$d; ++ my $v = ($y1*$x2 - $x1*$y2)/$d; ++ return (ref $z1)->make($u, $v); ++ } else { ++ _divbyzero "$z1/0" if $z2 == 0; ++ return (ref $z1)->make($x1/$z2, $y1/$z2); ++ } ++ } } } @@@ -307,7 -307,7 +363,7 @@@ sub _zerotozero my $mess = "The zero raised to the zeroth power is not defined.\n"; my @up = caller(1); -- ++ $mess .= "Died at $up[1] line $up[2].\n"; die $mess; @@@ -330,14 -330,14 +386,7 @@@ sub power return 0 if ($z1z); return 1 if ($z2z or $z1 == 1); } -- $z2 = cplx($z2) unless ref $z2; -- unless (defined $inverted) { -- my $z3 = exp($z2 * log $z1); -- $z1->set_cartesian([@{$z3->cartesian}]); -- return $z1; -- } -- return exp($z2 * log $z1) unless $inverted; -- return exp($z1 * log $z2); ++ return $inverted ? exp($z1 * log $z2) : exp($z2 * log $z1); } # @@@ -364,7 -364,7 +413,8 @@@ sub negate my ($z) = @_; if ($z->{c_dirty}) { my ($r, $t) = @{$z->polar}; -- return (ref $z)->emake($r, pi + $t); ++ $t = ($t <= 0) ? $t + pi : $t - pi; ++ return (ref $z)->emake($r, $t); } my ($re, $im) = @{$z->cartesian}; return (ref $z)->make(-$re, -$im); @@@ -392,9 -392,9 +442,8 @@@ sub conjugate # sub abs { my ($z) = @_; -- return abs($z) unless ref $z; my ($r, $t) = @{$z->polar}; -- return abs($r); ++ return $r; } # @@@ -406,6 -406,6 +455,8 @@@ sub arg my ($z) = @_; return ($z < 0 ? pi : 0) unless ref $z; my ($r, $t) = @{$z->polar}; ++ if ($t > pi()) { $t -= pit2 } ++ elsif ($t <= -pi()) { $t += pit2 } return $t; } @@@ -416,7 -416,7 +467,9 @@@ # sub sqrt { my ($z) = @_; -- $z = cplx($z, 0) unless ref $z; ++ return $z >= 0 ? sqrt($z) : cplx(0, sqrt(-$z)) unless ref $z; ++ my ($re, $im) = @{$z->cartesian}; ++ return cplx($re < 0 ? (0, sqrt(-$re)) : (sqrt($re), 0)) if $im == 0; my ($r, $t) = @{$z->polar}; return (ref $z)->emake(sqrt($r), $t/2); } @@@ -428,9 -428,9 +481,10 @@@ # sub cbrt { my ($z) = @_; -- return cplx($z, 0) ** (1/3) unless ref $z; ++ return $z < 0 ? -exp(log(-$z)/3) : ($z > 0 ? exp(log($z)/3): 0) ++ unless ref $z; my ($r, $t) = @{$z->polar}; -- return (ref $z)->emake($r**(1/3), $t/3); ++ return (ref $z)->emake(exp(log($r)/3), $t/3); } # @@@ -442,7 -442,7 +496,7 @@@ sub _rootbad my $mess = "Root $_[0] not defined, root must be positive integer.\n"; my @up = caller(1); -- ++ $mess .= "Died at $up[1] line $up[2].\n"; die $mess; @@@ -464,7 -464,7 +518,7 @@@ sub root my ($r, $t) = ref $z ? @{$z->polar} : (abs($z), $z >= 0 ? 0 : pi); my @root; my $k; -- my $theta_inc = 2 * pi / $n; ++ my $theta_inc = pit2 / $n; my $rho = $r ** (1/$n); my $theta; my $complex = ref($z) || $package; @@@ -505,7 -505,7 +559,6 @@@ sub Im # sub exp { my ($z) = @_; -- $z = cplx($z, 0) unless ref $z; my ($x, $y) = @{$z->cartesian}; return (ref $z)->emake(exp($x), $y); } @@@ -513,7 -513,7 +566,7 @@@ # # _logofzero # --# Die on division by zero. ++# Die on logarithm of zero. # sub _logofzero { my $mess = "$_[0]: Logarithm of zero.\n"; @@@ -525,7 -525,7 +578,7 @@@ } my @up = caller(1); -- ++ $mess .= "Died at $up[1] line $up[2].\n"; die $mess; @@@ -538,11 -538,11 +591,14 @@@ # sub log { my ($z) = @_; -- $z = cplx($z, 0) unless ref $z; -- my ($x, $y) = @{$z->cartesian}; ++ unless (ref $z) { ++ _logofzero("log") if $z == 0; ++ return $z > 0 ? log($z) : cplx(log(-$z), pi); ++ } my ($r, $t) = @{$z->polar}; -- $t -= 2 * pi if ($t > pi() and $x < 0); -- $t += 2 * pi if ($t < -pi() and $x < 0); ++ _logofzero("log") if $r == 0; ++ if ($t > pi()) { $t -= pit2 } ++ elsif ($t <= -pi()) { $t += pit2 } return (ref $z)->make(log($r), $t); } @@@ -560,11 -560,11 +616,7 @@@ sub ln { Math::Complex::log(@_) # sub log10 { -- my ($z) = @_; -- -- return log(cplx($z, 0)) * log10inv unless ref $z; -- my ($r, $t) = @{$z->polar}; -- return (ref $z)->make(log($r) * log10inv, $t * log10inv); ++ return Math::Complex::log($_[0]) * uplog10; } # @@@ -587,7 -587,7 +639,6 @@@ sub logn # sub cos { my ($z) = @_; -- $z = cplx($z, 0) unless ref $z; my ($x, $y) = @{$z->cartesian}; my $ey = exp($y); my $ey_1 = 1 / $ey; @@@ -602,7 -602,7 +653,6 @@@ # sub sin { my ($z) = @_; -- $z = cplx($z, 0) unless ref $z; my ($x, $y) = @{$z->cartesian}; my $ey = exp($y); my $ey_1 = 1 / $ey; @@@ -656,7 -656,7 +706,7 @@@ sub cosec { Math::Complex::csc(@_) # # cot # --# Computes cot(z) = 1 / tan(z). ++# Computes cot(z) = cos(z) / sin(z). # sub cot { my ($z) = @_; @@@ -678,21 -678,21 +728,20 @@@ sub cotan { Math::Complex::cot(@_) # Computes the arc cosine acos(z) = -i log(z + sqrt(z*z-1)). # sub acos { -- my ($z) = @_; -- $z = cplx($z, 0) unless ref $z; -- my ($re, $im) = @{$z->cartesian}; -- return atan2(sqrt(1 - $re * $re), $re) -- if ($im == 0 and abs($re) <= 1.0); -- my $acos = ~i * log($z + sqrt($z*$z - 1)); -- if ($im == 0 || -- (abs($re) < 1 && abs($im) < 1) || -- (abs($re) > 1 && abs($im) > 1 -- && !($re > 1 && $im > 1) -- && !($re < -1 && $im < -1))) { -- # this rule really, REALLY, must be simpler -- return -$acos; -- } -- return $acos; ++ my $z = $_[0]; ++ return atan2(sqrt(1-$z*$z), $z) if (! ref $z) && abs($z) <= 1; ++ my ($x, $y) = ref $z ? @{$z->cartesian} : ($z, 0); ++ my $t1 = sqrt(($x+1)*($x+1) + $y*$y); ++ my $t2 = sqrt(($x-1)*($x-1) + $y*$y); ++ my $alpha = ($t1 + $t2)/2; ++ my $beta = ($t1 - $t2)/2; ++ $alpha = 1 if $alpha < 1; ++ if ($beta > 1) { $beta = 1 } ++ elsif ($beta < -1) { $beta = -1 } ++ my $u = atan2(sqrt(1-$beta*$beta), $beta); ++ my $v = log($alpha + sqrt($alpha*$alpha-1)); ++ $v = -$v if $y > 0 || ($y == 0 && $x < -1); ++ return $package->make($u, $v); } # @@@ -701,12 -701,12 +750,20 @@@ # Computes the arc sine asin(z) = -i log(iz + sqrt(1-z*z)). # sub asin { -- my ($z) = @_; -- $z = cplx($z, 0) unless ref $z; -- my ($re, $im) = @{$z->cartesian}; -- return atan2($re, sqrt(1 - $re * $re)) -- if ($im == 0 and abs($re) <= 1.0); -- return ~i * log(i * $z + sqrt(1 - $z*$z)); ++ my $z = $_[0]; ++ return atan2($z, sqrt(1-$z*$z)) if (! ref $z) && abs($z) <= 1; ++ my ($x, $y) = ref $z ? @{$z->cartesian} : ($z, 0); ++ my $t1 = sqrt(($x+1)*($x+1) + $y*$y); ++ my $t2 = sqrt(($x-1)*($x-1) + $y*$y); ++ my $alpha = ($t1 + $t2)/2; ++ my $beta = ($t1 - $t2)/2; ++ $alpha = 1 if $alpha < 1; ++ if ($beta > 1) { $beta = 1 } ++ elsif ($beta < -1) { $beta = -1 } ++ my $u = atan2($beta, sqrt(1-$beta*$beta)); ++ my $v = -log($alpha + sqrt($alpha*$alpha-1)); ++ $v = -$v if $y > 0 || ($y == 0 && $x < -1); ++ return $package->make($u, $v); } # @@@ -716,10 -716,10 +773,12 @@@ # sub atan { my ($z) = @_; -- $z = cplx($z, 0) unless ref $z; ++ return atan2($z, 1) unless ref $z; _divbyzero "atan(i)" if ( $z == i); _divbyzero "atan(-i)" if (-$z == i); -- return i/2*log((i + $z) / (i - $z)); ++ my $log = log((i + $z) / (i - $z)); ++ $ip2 = 0.5 * i unless defined $ip2; ++ return $ip2 * $log; } # @@@ -730,16 -730,16 +789,7 @@@ sub asec { my ($z) = @_; _divbyzero "asec($z)", $z if ($z == 0); -- $z = cplx($z, 0) unless ref $z; -- my ($re, $im) = @{$z->cartesian}; -- if ($im == 0 && abs($re) >= 1.0) { -- my $ire = 1 / $re; -- return atan2(sqrt(1 - $ire * $ire), $ire); -- } -- my $asec = acos(1 / $z); -- return ~$asec if $re < 0 && $re > -1 && $im == 0; -- return -$asec if $im && !($re > 0 && $im > 0) && !($re < 0 && $im < 0); -- return $asec; ++ return acos(1 / $z); } # @@@ -750,15 -750,15 +800,7 @@@ sub acsc { my ($z) = @_; _divbyzero "acsc($z)", $z if ($z == 0); -- $z = cplx($z, 0) unless ref $z; -- my ($re, $im) = @{$z->cartesian}; -- if ($im == 0 && abs($re) >= 1.0) { -- my $ire = 1 / $re; -- return atan2($ire, sqrt(1 - $ire * $ire)); -- } -- my $acsc = asin(1 / $z); -- return ~$acsc if $re < 0 && $re > -1 && $im == 0; -- return $acsc; ++ return asin(1 / $z); } # @@@ -775,8 -775,8 +817,7 @@@ sub acosec { Math::Complex::acsc(@_) # sub acot { my ($z) = @_; -- _divbyzero "acot($z)" if ($z == 0); -- $z = cplx($z, 0) unless ref $z; ++ return ($z >= 0) ? atan2(1, $z) : atan2(-1, -$z) unless ref $z; _divbyzero "acot(i)", if ( $z == i); _divbyzero "acot(-i)" if (-$z == i); return atan(1 / $z); @@@ -796,15 -796,15 +837,14 @@@ sub acotan { Math::Complex::acot(@_) # sub cosh { my ($z) = @_; -- my $real; ++ my $ex; unless (ref $z) { -- $z = cplx($z, 0); -- $real = 1; ++ $ex = exp($z); ++ return ($ex + 1/$ex)/2; } my ($x, $y) = @{$z->cartesian}; -- my $ex = exp($x); ++ $ex = exp($x); my $ex_1 = 1 / $ex; -- return cplx(0.5 * ($ex + $ex_1), 0) if $real; return (ref $z)->make(cos($y) * ($ex + $ex_1)/2, sin($y) * ($ex - $ex_1)/2); } @@@ -816,15 -816,15 +856,14 @@@ # sub sinh { my ($z) = @_; -- my $real; ++ my $ex; unless (ref $z) { -- $z = cplx($z, 0); -- $real = 1; ++ $ex = exp($z); ++ return ($ex - 1/$ex)/2; } my ($x, $y) = @{$z->cartesian}; -- my $ex = exp($x); ++ $ex = exp($x); my $ex_1 = 1 / $ex; -- return cplx(0.5 * ($ex - $ex_1), 0) if $real; return (ref $z)->make(cos($y) * ($ex - $ex_1)/2, sin($y) * ($ex + $ex_1)/2); } @@@ -894,14 -894,14 +933,19 @@@ sub cotanh { Math::Complex::coth(@_) # # acosh # --# Computes the arc hyperbolic cosine acosh(z) = log(z +- sqrt(z*z-1)). ++# Computes the arc hyperbolic cosine acosh(z) = log(z + sqrt(z*z-1)). # sub acosh { my ($z) = @_; -- $z = cplx($z, 0) unless ref $z; ++ unless (ref $z) { ++ return log($z + sqrt($z*$z-1)) if $z >= 1; ++ $z = cplx($z, 0); ++ } my ($re, $im) = @{$z->cartesian}; -- return log($re + sqrt(cplx($re*$re - 1, 0))) -- if ($im == 0 && $re < 0); ++ if ($im == 0) { ++ return cplx(log($re + sqrt($re*$re - 1)), 0) if $re >= 1; ++ return cplx(0, atan2(sqrt(1-$re*$re), $re)) if abs($re) <= 1; ++ } return log($z + sqrt($z*$z - 1)); } @@@ -912,7 -912,7 +956,6 @@@ # sub asinh { my ($z) = @_; -- $z = cplx($z, 0) unless ref $z; return log($z + sqrt($z*$z + 1)); } @@@ -923,14 -923,14 +966,13 @@@ # sub atanh { my ($z) = @_; ++ unless (ref $z) { ++ return log((1 + $z)/(1 - $z))/2 if abs($z) < 1; ++ $z = cplx($z, 0); ++ } _divbyzero 'atanh(1)', "1 - $z" if ($z == 1); _logofzero 'atanh(-1)' if ($z == -1); -- $z = cplx($z, 0) unless ref $z; -- my ($re, $im) = @{$z->cartesian}; -- if ($im == 0 && $re > 1) { -- return cplx(atanh(1 / $re), pi/2); -- } -- return log((1 + $z) / (1 - $z)) / 2; ++ return 0.5 * log((1 + $z) / (1 - $z)); } # @@@ -941,12 -941,12 +983,6 @@@ sub asech { my ($z) = @_; _divbyzero 'asech(0)', $z if ($z == 0); -- $z = cplx($z, 0) unless ref $z; -- my ($re, $im) = @{$z->cartesian}; -- if ($im == 0 && $re < 0) { -- my $ire = 1 / $re; -- return log($ire + sqrt(cplx($ire*$ire - 1, 0))); -- } return acosh(1 / $z); } @@@ -975,13 -975,13 +1011,12 @@@ sub acosech { Math::Complex::acsch(@_) # sub acoth { my ($z) = @_; ++ unless (ref $z) { ++ return log(($z + 1)/($z - 1))/2 if abs($z) > 1; ++ $z = cplx($z, 0); ++ } _divbyzero 'acoth(1)', "$z - 1" if ($z == 1); _logofzero 'acoth(-1)' if ($z == -1); -- $z = cplx($z, 0) unless ref $z; -- my ($re, $im) = @{$z->cartesian}; -- if ($im == 0 and abs($re) < 1) { -- return cplx(acoth(1/$re) , pi/2); -- } return log((1 + $z) / ($z - 1)) / 2; } @@@ -999,17 -999,17 +1034,23 @@@ sub acotanh { Math::Complex::acoth(@_) # sub atan2 { my ($z1, $z2, $inverted) = @_; -- my ($re1, $im1) = ref $z1 ? @{$z1->cartesian} : ($z1, 0); -- my ($re2, $im2) = ref $z2 ? @{$z2->cartesian} : ($z2, 0); -- my $tan; -- if (defined $inverted && $inverted) { # atan(z2/z1) -- return pi * ($re2 > 0 ? 1 : -1) if $re1 == 0 && $im1 == 0; -- $tan = $z2 / $z1; ++ my ($re1, $im1, $re2, $im2); ++ if ($inverted) { ++ ($re1, $im1) = ref $z2 ? @{$z2->cartesian} : ($z2, 0); ++ ($re2, $im2) = @{$z1->cartesian}; } else { -- return pi * ($re1 > 0 ? 1 : -1) if $re2 == 0 && $im2 == 0; -- $tan = $z1 / $z2; ++ ($re1, $im1) = @{$z1->cartesian}; ++ ($re2, $im2) = ref $z2 ? @{$z2->cartesian} : ($z2, 0); ++ } ++ if ($im2 == 0) { ++ return cplx(atan2($re1, $re2), 0) if $im1 == 0; ++ return cplx(($im1<=>0) * pip2, 0) if $re2 == 0; } -- return atan($tan); ++ my $w = atan($z1/$z2); ++ my ($u, $v) = ref $w ? @{$w->cartesian} : ($w, 0); ++ $u += pi if $re2 < 0; ++ $u -= pit2 if $u > pi; ++ return cplx($u, $v); } # @@@ -1017,7 -1017,7 +1058,7 @@@ # ->display_format # # Set (fetch if no argument) display format for all complex numbers that --# don't happen to have overrriden it via ->display_format ++# don't happen to have overridden it via ->display_format # # When called as a method, this actually sets the display format for # the current object. @@@ -1076,16 -1076,16 +1117,17 @@@ sub stringify_cartesian my $z = shift; my ($x, $y) = @{$z->cartesian}; my ($re, $im); ++ my $eps = 1e-14; -- $x = int($x + ($x < 0 ? -1 : 1) * 1e-14) -- if int(abs($x)) != int(abs($x) + 1e-14); -- $y = int($y + ($y < 0 ? -1 : 1) * 1e-14) -- if int(abs($y)) != int(abs($y) + 1e-14); ++ $x = int($x + ($x < 0 ? -1 : 1) * $eps) ++ if int(abs($x)) != int(abs($x) + $eps); ++ $y = int($y + ($y < 0 ? -1 : 1) * $eps) ++ if int(abs($y)) != int(abs($y) + $eps); -- $re = "$x" if abs($x) >= 1e-14; -- if ($y == 1) { $im = 'i' } -- elsif ($y == -1) { $im = '-i' } -- elsif (abs($y) >= 1e-14) { $im = $y . "i" } ++ $re = "$x" if abs($x) >= $eps; ++ if ($y == 1) { $im = 'i' } ++ elsif ($y == -1) { $im = '-i' } ++ elsif (abs($y) >= $eps) { $im = $y . "i" } my $str = ''; $str = $re if defined $re; @@@ -1110,10 -1110,10 +1152,9 @@@ sub stringify_polar return '[0,0]' if $r <= $eps; -- my $tpi = 2 * pi; -- my $nt = $t / $tpi; -- $nt = ($nt - int($nt)) * $tpi; -- $nt += $tpi if $nt < 0; # Range [0, 2pi] ++ my $nt = $t / pit2; ++ $nt = ($nt - int($nt)) * pit2; ++ $nt += pit2 if $nt < 0; # Range [0, 2pi] if (abs($nt) <= $eps) { $theta = 0 } elsif (abs(pi-$nt) <= $eps) { $theta = 'pi' } @@@ -1131,9 -1131,9 +1172,9 @@@ # Okay, number is not a real. Try to identify pi/n and friends... # -- $nt -= $tpi if $nt > pi; ++ $nt -= pit2 if $nt > pi; my ($n, $k, $kpi); -- ++ for ($k = 1, $kpi = pi; $k < 10; $k++, $kpi += pi) { $n = int($kpi / $nt + ($nt > 0 ? 1 : -1) * 0.5); if (abs($kpi/$n - $nt) <= $eps) { @@@ -1164,7 -1164,7 +1205,7 @@@ Math::Complex - complex numbers and ass =head1 SYNOPSIS use Math::Complex; -- ++ $z = Math::Complex->make(5, 6); $t = 4 - 3*i + $z; $j = cplxe(1, 2*pi/3); @@@ -1241,7 -1241,7 +1282,7 @@@ between this form and the cartesian for which is also expressed by this formula: -- z = rho * exp(i * theta) = rho * (cos theta + i * sin theta) ++ z = rho * exp(i * theta) = rho * (cos theta + i * sin theta) In other words, it's the projection of the vector onto the I and I axes. Mathematicians call I the I or I and I @@@ -1251,8 -1251,8 +1292,8 @@@ noted C The polar notation (also known as the trigonometric representation) is much more handy for performing multiplications and divisions of complex numbers, whilst the cartesian notation is better --suited for additions and substractions. Real numbers are on the I --axis, and therefore I is zero. ++suited for additions and subtractions. Real numbers are on the I ++axis, and therefore I is zero or I. All the common operations that can be performed on a real number have been defined to work on complex numbers as well, and are merely @@@ -1261,8 -1261,8 +1302,8 @@@ they keep their natural meaning when th the number is within their definition set. For instance, the C routine which computes the square root of --its argument is only defined for positive real numbers and yields a --positive real number (it is an application from B to B). ++its argument is only defined for non-negative real numbers and yields a ++non-negative real number (it is an application from B to B). If we allow it to return a complex number, then it can be extended to negative real numbers to become an application from B to B (the set of complex numbers): @@@ -1275,10 -1275,10 +1316,9 @@@ the following definition sqrt(z = [r,t]) = sqrt(r) * exp(i * t/2) --Indeed, a negative real number can be noted C<[x,pi]> --(the modulus I is always positive, so C<[x,pi]> is really C<-x>, a --negative number) --and the above definition states that ++Indeed, a negative real number can be noted C<[x,pi]> (the modulus ++I is always non-negative, so C<[x,pi]> is really C<-x>, a negative ++number) and the above definition states that sqrt([x,pi]) = sqrt(x) * exp(i*pi/2) = [sqrt(x),pi/2] = sqrt(x)*i @@@ -1342,7 -1342,7 +1382,6 @@@ the following (overloaded) operations a log(z1) = log(r1) + i*t1 sin(z1) = 1/2i (exp(i * z1) - exp(-i * z1)) cos(z1) = 1/2 (exp(i * z1) + exp(-i * z1)) -- abs(z1) = r1 atan2(z1, z2) = atan(z1/z2) The following extra operations are supported on both real and complex @@@ -1363,7 -1363,7 +1402,7 @@@ numbers cot(z) = 1 / tan(z) asin(z) = -i * log(i*z + sqrt(1-z*z)) -- acos(z) = -i * log(z + sqrt(z*z-1)) ++ acos(z) = -i * log(z + i*sqrt(1-z*z)) atan(z) = i/2 * log((i+z) / (i-z)) acsc(z) = asin(1 / z) @@@ -1377,7 -1377,7 +1416,7 @@@ csch(z) = 1 / sinh(z) sech(z) = 1 / cosh(z) coth(z) = 1 / tanh(z) -- ++ asinh(z) = log(z + sqrt(z*z+1)) acosh(z) = log(z + sqrt(z*z-1)) atanh(z) = 1/2 * log((1+z) / (1-z)) @@@ -1423,21 -1423,21 +1462,21 @@@ if you know the cartesian form of the n $z = 3 + 4*i; --if you like. To create a number using the trigonometric form, use either: ++if you like. To create a number using the polar form, use either: $z = Math::Complex->emake(5, pi/3); $x = cplxe(5, pi/3); instead. The first argument is the modulus, the second is the angle --(in radians, the full circle is 2*pi). (Mnmemonic: C is used as a --notation for complex numbers in the trigonometric form). ++(in radians, the full circle is 2*pi). (Mnemonic: C is used as a ++notation for complex numbers in the polar form). It is possible to write: $x = cplxe(-3, pi/4); but that will be silently converted into C<[3,-3pi/4]>, since the modulus --must be positive (it represents the distance to the origin in the complex ++must be non-negative (it represents the distance to the origin in the complex plane). =head1 STRINGIFICATION @@@ -1534,17 -1534,17 +1573,8 @@@ argument cannot be I, wh =head1 BUGS Saying C exports many mathematical routines in the --caller environment and even overrides some (C, C, C, --C, C). This is construed as a feature by the Authors, --actually... ;-) -- --The code is not optimized for speed, although we try to use the cartesian --form for addition-like operators and the trigonometric form for all --multiplication-like operators. -- --The arg() routine does not ensure the angle is within the range [-pi,+pi] --(a side effect caused by multiplication and division using the trigonometric --representation). ++caller environment and even overrides some (C, C). ++This is construed as a feature by the Authors, actually... ;-) All routines expect to be given real or complex numbers. Don't attempt to use BigFloat, since Perl has currently no rule to disambiguate a '+' @@@ -1555,6 -1555,6 +1585,8 @@@ operation (for instance) between two ov Raphael Manfredi > and Jarkko Hietaniemi >. ++Extensive patches by Daniel S. Lewart >. ++ =cut # eof diff --cc lib/Test/Harness.pm index 24e9148,24e9148..f5fc3d8 --- a/lib/Test/Harness.pm +++ b/lib/Test/Harness.pm @@@ -19,11 -19,11 +19,11 @@@ $VERSION = "1.1502" format STDOUT_TOP = Failed Test Status Wstat Total Fail Failed List of failed -------------------------------------------------------------------------------- ++------------------------------------------------------------------------------- . format STDOUT = --@<<<<<<<<<<<<<< @>> @>>>> @>>>> @>>> ^##.##% @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ++@<<<<<<<<<<<<<< @>> @>>>> @>>>> @>>> ^##.##% ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< { $curtest->{name}, $curtest->{estat}, $curtest->{wstat}, @@@ -32,6 -32,6 +32,8 @@@ $curtest->{percent}, $curtest->{canon} } ++~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ++ $curtest->{canon} . @@@ -110,7 -110,7 +112,8 @@@ sub runtests : $wstatus >> 8); if ($wstatus) { my ($failed, $canon, $percent) = ('??', '??'); -- print "dubious\n\tTest returned status $estatus (wstat $wstatus)\n"; ++ printf "dubious\n\tTest returned status $estatus (wstat %d, 0x%x)\n", ++ $wstatus,$wstatus; print "\t\t(VMS status is $estatus)\n" if $^O eq 'VMS'; if (corestatus($wstatus)) { # until we have a wait module if ($have_devel_corestack) { @@@ -321,6 -321,6 +324,10 @@@ The global variable $Test::Harness::ver used to let runtests() display the standard output of the script without altering the behavior otherwise. ++The global variable $Test::Harness::switches is exportable and can be ++used to set perl command line options used for running the test ++script(s). The default value is C<-w>. ++ =head1 EXPORT C<&runtests> is exported by Test::Harness per default. diff --cc lib/autouse.pm index a15d08a,a15d08a..ab95a19 --- a/lib/autouse.pm +++ b/lib/autouse.pm @@@ -49,9 -49,9 +49,9 @@@ sub import } my $load_sub = sub { -- unless ($INC{pm}) { -- require $pm; -- die $@ if $@; ++ unless ($INC{$pm}) { ++ eval {require $pm}; ++ die if $@; vet_import $module; } *$closure_import_func = \&{"${module}::$closure_func"}; @@@ -73,7 -73,7 +73,7 @@@ sub vet_import ($) my $module = shift; if (my $import = $module->can('import')) { croak "autoused module has unique import() method" -- unless defined(\&Exporter::import) ++ unless defined(&Exporter::import) && $import == \&Exporter::import; } } diff --cc lib/base.pm index e69de29,e69de29..e20a64b --- a/lib/base.pm +++ b/lib/base.pm @@@ -1,0 -1,0 +1,49 @@@ ++=head1 NAME ++ ++base - Establish IS-A relationship with base class at compile time ++ ++=head1 SYNOPSIS ++ ++ package Baz; ++ ++ use base qw(Foo Bar); ++ ++=head1 DESCRIPTION ++ ++Roughly similar in effect to ++ ++ BEGIN { ++ require Foo; ++ require Bar; ++ push @ISA, qw(Foo Bar); ++ } ++ ++This module was introduced with Perl 5.004_04. ++ ++=head1 BUGS ++ ++Needs proper documentation! ++ ++=cut ++ ++package base; ++ ++sub import { ++ my $class = shift; ++ ++ foreach my $base (@_) { ++ unless (defined %{"$base\::"}) { ++ eval "require $base"; ++ unless (defined %{"$base\::"}) { ++ require Carp; ++ Carp::croak("Base class package \"$base\" is empty.\n", ++ "\t(Perhaps you need to 'use' the module ", ++ "which defines that package first.)"); ++ } ++ } ++ } ++ ++ push @{caller(0) . '::ISA'}, @_; ++} ++ ++1; diff --cc lib/blib.pm index 2dd7802,2dd7802..9e0f6c0 --- a/lib/blib.pm +++ b/lib/blib.pm @@@ -47,7 -47,7 +47,6 @@@ sub impor my $dir = getcwd; if (@_) { -- print join(',',@_),"\n"; $dir = shift; $dir =~ s/blib$//; $dir =~ s,/+$,,; diff --cc lib/diagnostics.pm index 10016f3,10016f3..78bf445 --- a/lib/diagnostics.pm +++ b/lib/diagnostics.pm @@@ -175,6 -175,6 +175,8 @@@ if ($^O eq 'VMS') @trypod = ("$archlib/pod/perldiag.pod", "$privlib/pod/perldiag-$].pod", "$privlib/pod/perldiag.pod"); ++# handy for development testing of new warnings etc ++unshift @trypod, "./pod/perldiag.pod" if -e "pod/perldiag.pod"; ($PODFILE) = ((grep { -e } @trypod), $trypod[$#trypod])[0]; $DEBUG ||= 0; diff --cc lib/perl5db.pl index 469ebff,469ebff..d5dbfbd --- a/lib/perl5db.pl +++ b/lib/perl5db.pl @@@ -2,7 -2,7 +2,7 @@@ package DB # Debugger for Perl 5.00x; perl5db.pl patch level: --$VERSION = 1.00; ++$VERSION = 1.01; $header = "perl5db.pl version $VERSION"; # Enhanced by ilya@math.ohio-state.edu (Ilya Zakharevich) @@@ -808,9 -808,9 +808,11 @@@ sub DB last CMD; }; $cmd =~ /^c\b\s*([\w:]*)\s*$/ && do { end_report(), next CMD if $finished and $level <= 1; -- $i = $1; ++ $subname = $i = $1; if ($i =~ /\D/) { # subroutine name -- ($file,$i) = (find_sub($i) =~ /^(.*):(.*)$/); ++ $subname = $package."::".$subname ++ unless $subname =~ /::/; ++ ($file,$i) = (find_sub($subname) =~ /^(.*):(.*)$/); $i += 0; if ($i) { $filename = $file; @@@ -1128,7 -1128,7 +1130,11 @@@ sub sub $doret = -2 if $doret eq $#stack or $frame & 16; @ret; } else { -- $ret = &$sub; ++ if (defined wantarray) { ++ $ret = &$sub; ++ } else { ++ &$sub; undef $ret; ++ }; $single |= pop(@stack); ($frame & 4 ? ( (print $LINEINFO ' ' x $#stack, "out "), @@@ -1178,8 -1178,8 +1184,8 @@@ sub postponed_sub my $offset = $1 || 0; # Filename below can contain ':' my ($file,$i) = (find_sub($subname) =~ /^(.*):(\d+)-.*$/); -- $i += $offset; if ($i) { ++ $i += $offset; local *dbline = $main::{'_<' . $file}; local $^W = 0; # != 0 is magical below $had_breakpoints{$file}++; @@@ -1822,18 -1822,18 +1828,15 @@@ sub dbwarn local $doret = -2; local $SIG{__WARN__} = ''; local $SIG{__DIE__} = ''; -- eval { require Carp }; # If error/warning during compilation, -- # require may be broken. -- warn(@_, "\nPossible unrecoverable error"), warn("\nTry to decrease warnLevel `O'ption!\n"), return -- unless defined &Carp::longmess; -- #&warn("Entering dbwarn\n"); ++ eval { require Carp } if defined $^S; # If error/warning during compilation, ++ # require may be broken. ++ warn(@_, "\nCannot print stack trace, load with -MCarp option to see stack"), ++ return unless defined &Carp::longmess; my ($mysingle,$mytrace) = ($single,$trace); $single = 0; $trace = 0; my $mess = Carp::longmess(@_); ($single,$trace) = ($mysingle,$mytrace); -- #&warn("Warning in dbwarn\n"); &warn($mess); -- #&warn("Exiting dbwarn\n"); } sub dbdie { @@@ -1842,28 -1842,28 +1845,24 @@@ local $SIG{__DIE__} = ''; local $SIG{__WARN__} = ''; my $i = 0; my $ineval = 0; my $sub; -- #&warn("Entering dbdie\n"); -- if ($dieLevel != 2) { -- while ((undef,undef,undef,$sub) = caller(++$i)) { -- $ineval = 1, last if $sub eq '(eval)'; -- } -- { ++ if ($dieLevel > 2) { local $SIG{__WARN__} = \&dbwarn; -- &warn(@_) if $dieLevel > 2; # Ineval is false during destruction? -- } -- #&warn("dieing quietly in dbdie\n") if $ineval and $dieLevel < 2; -- die @_ if $ineval and $dieLevel < 2; ++ &warn(@_); # Yell no matter what ++ return; ++ } ++ if ($dieLevel < 2) { ++ die @_ if $^S; # in eval propagate } -- eval { require Carp }; # If error/warning during compilation, -- # require may be broken. -- die(@_, "\nUnrecoverable error") unless defined &Carp::longmess; ++ eval { require Carp } if defined $^S; # If error/warning during compilation, ++ # require may be broken. ++ die(@_, "\nCannot print stack trace, load with -MCarp option to see stack") ++ unless defined &Carp::longmess; # We do not want to debug this chunk (automatic disabling works # inside DB::DB, but not in Carp). my ($mysingle,$mytrace) = ($single,$trace); $single = 0; $trace = 0; my $mess = Carp::longmess(@_); ($single,$trace) = ($mysingle,$mytrace); -- #&warn("dieing loudly in dbdie\n"); die $mess; } diff --cc lib/vars.pm index e007baa,e007baa..5723ac6 --- a/lib/vars.pm +++ b/lib/vars.pm @@@ -1,5 -1,5 +1,39 @@@ package vars; ++require 5.002; ++ ++# The following require can't be removed during maintenance ++# releases, sadly, because of the risk of buggy code that does ++# require Carp; Carp::croak "..."; without brackets dying ++# if Carp hasn't been loaded in earlier compile time. :-( ++# We'll let those bugs get found on the development track. ++require Carp if $] < 5.00450; ++ ++sub import { ++ my $callpack = caller; ++ my ($pack, @imports, $sym, $ch) = @_; ++ foreach $sym (@imports) { ++ if ($sym =~ /::/) { ++ require Carp; ++ Carp::croak("Can't declare another package's variables"); ++ } ++ ($ch, $sym) = unpack('a1a*', $sym); ++ *{"${callpack}::$sym"} = ++ ( $ch eq "\$" ? \$ {"${callpack}::$sym"} ++ : $ch eq "\@" ? \@ {"${callpack}::$sym"} ++ : $ch eq "\%" ? \% {"${callpack}::$sym"} ++ : $ch eq "\*" ? \* {"${callpack}::$sym"} ++ : $ch eq "\&" ? \& {"${callpack}::$sym"} ++ : do { ++ require Carp; ++ Carp::croak("'$ch$sym' is not a valid variable name\n"); ++ }); ++ } ++}; ++ ++1; ++__END__ ++ =head1 NAME vars - Perl pragma to predeclare global variable names @@@ -30,24 -30,24 +64,3 @@@ later-loaded routines See L. =cut -- --require 5.002; --use Carp; -- --sub import { -- my $callpack = caller; -- my ($pack, @imports, $sym, $ch) = @_; -- foreach $sym (@imports) { -- croak "Can't declare another package's variables" if $sym =~ /::/; -- ($ch, $sym) = unpack('a1a*', $sym); -- *{"${callpack}::$sym"} = -- ( $ch eq "\$" ? \$ {"${callpack}::$sym"} -- : $ch eq "\@" ? \@ {"${callpack}::$sym"} -- : $ch eq "\%" ? \% {"${callpack}::$sym"} -- : $ch eq "\*" ? \* {"${callpack}::$sym"} -- : $ch eq "\&" ? \& {"${callpack}::$sym"} -- : croak "'$ch$sym' is not a valid variable name\n"); -- } --}; -- --1; diff --cc makedepend.SH index 89f650d,89f650d..7a89fa9 --- a/makedepend.SH +++ b/makedepend.SH @@@ -28,6 -28,6 +28,12 @@@ MAKE=$mak !GROK!THIS! $spitshell >>makedepend <<'!NO!SUBS!' ++# This script should be called with ++# sh ./makedepend MAKE=$(MAKE) ++case "$1" in ++ MAKE=*) eval $1 ;; ++esac ++ export PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh \$0; kill \$\$) case $CONFIG in @@@ -112,6 -112,6 +118,7 @@@ for file in `$cat .clist`; d $cppstdin $finc -I/usr/local/include -I. $cppflags $cppminus /d' \ ++ -e '/^#.*"-"/d' \ -e 's#\.[0-9][0-9]*\.c#'"$file.c#" \ -e 's/^[ ]*#[ ]*line/#/' \ -e '/^# *[0-9][0-9]* *[".\/]/!d' \ diff --cc malloc.c index c84db66,c84db66..e8e9ca3 --- a/malloc.c +++ b/malloc.c @@@ -649,8 -649,8 +649,8 @@@ realloc(mp, nbytes #ifdef PERL_CORE #ifdef DEBUGGING if (debug & 128) { -- PerlIO_printf(PerlIO_stderr(), "0x%lx: (%05lu) rfree\n",(unsigned long)res,(unsigned long)(an++)); -- PerlIO_printf(PerlIO_stderr(), "0x%lx: (%05lu) realloc %ld bytes\n", ++ PerlIO_printf(Perl_debug_log, "0x%lx: (%05lu) rfree\n",(unsigned long)res,(unsigned long)(an++)); ++ PerlIO_printf(Perl_debug_log, "0x%lx: (%05lu) realloc %ld bytes\n", (unsigned long)res,(unsigned long)(an++),(long)size); } #endif @@@ -814,7 -814,7 +814,7 @@@ int size } #ifdef PERL_CORE -- DEBUG_m(PerlIO_printf(PerlIO_stderr(), "sbrk malloc size %ld (reqsize %ld), left size %ld, give addr 0x%lx\n", ++ DEBUG_m(PerlIO_printf(Perl_debug_log, "sbrk malloc size %ld (reqsize %ld), left size %ld, give addr 0x%lx\n", size, reqsize, Perl_sbrk_oldsize, got)); #endif diff --cc mg.c index 7c7ea2a,7c7ea2a..ee87d47 --- a/mg.c +++ b/mg.c @@@ -357,8 -357,8 +357,15 @@@ MAGIC *mg } #else #ifdef OS2 -- sv_setnv(sv, (double)Perl_rc); -- sv_setpv(sv, os2error(Perl_rc)); ++ if (!(_emx_env & 0x200)) { /* Under DOS */ ++ sv_setnv(sv, (double)errno); ++ sv_setpv(sv, errno ? Strerror(errno) : ""); ++ } else { ++ if (errno != errno_isOS2) ++ Perl_rc = _syserrno(); ++ sv_setnv(sv, (double)Perl_rc); ++ sv_setpv(sv, os2error(Perl_rc)); ++ } #else sv_setnv(sv, (double)errno); sv_setpv(sv, errno ? Strerror(errno) : ""); @@@ -384,6 -384,6 +391,14 @@@ case '\020': /* ^P */ sv_setiv(sv, (IV)perldb); break; ++ case '\023': /* ^S */ ++ if (lex_state != LEX_NOTPARSING) ++ SvOK_off(sv); ++ else if (in_eval) ++ sv_setiv(sv, 1); ++ else ++ sv_setiv(sv, 0); ++ break; case '\024': /* ^T */ #ifdef BIG_TIME sv_setnv(sv, basetime); @@@ -654,6 -654,6 +669,28 @@@ MAGIC* mg } int ++magic_set_all_env(sv,mg) ++SV* sv; ++MAGIC* mg; ++{ ++#if defined(VMS) ++ die("Can't make list assignment to %%ENV on this system"); ++#else ++ if (localizing) { ++ HE* entry; ++ magic_clear_all_env(sv,mg); ++ hv_iterinit((HV*)sv); ++ while (entry = hv_iternext((HV*)sv)) { ++ I32 keylen; ++ my_setenv(hv_iterkey(entry, &keylen), ++ SvPV(hv_iterval((HV*)sv, entry), na)); ++ } ++ } ++#endif ++ return 0; ++} ++ ++int magic_clear_all_env(sv,mg) SV* sv; MAGIC* mg; @@@ -1601,16 -1601,16 +1638,28 @@@ MAGIC* mg s += strlen(s); /* See if all the arguments are contiguous in memory */ for (i = 1; i < origargc; i++) { -- if (origargv[i] == s + 1) ++ if (origargv[i] == s + 1 ++#ifdef OS2 ++ || origargv[i] == s + 2 ++#endif ++ ) s += strlen(++s); /* this one is ok too */ ++ else ++ break; } /* can grab env area too? */ -- if (origenviron && origenviron[0] == s + 1) { ++ if (origenviron && (origenviron[0] == s + 1 ++#ifdef OS2 ++ || (origenviron[0] == s + 9 && (s += 8)) ++#endif ++ )) { my_setenv("NoNe SuCh", Nullch); /* force copy of environment */ for (i = 0; origenviron[i]; i++) if (origenviron[i] == s + 1) s += strlen(++s); ++ else ++ break; } origalen = s - origargv[0]; } @@@ -1618,9 -1618,9 +1667,11 @@@ i = len; if (i >= origalen) { i = origalen; -- SvCUR_set(sv, i); -- *SvEND(sv) = '\0'; ++ /* don't allow system to limit $0 seen by script */ ++ /* SvCUR_set(sv, i); *SvEND(sv) = '\0'; */ Copy(s, origargv[0], i, char); ++ s = origargv[0]+i; ++ *s = '\0'; } else { Copy(s, origargv[0], i, char); diff --cc op.c index feae588,feae588..8e8811d --- a/op.c +++ b/op.c @@@ -125,7 -125,7 +125,7 @@@ char *name } croak("Can't use global %s in \"my\"",name); } -- if (AvFILL(comppad_name) >= 0) { ++ if (dowarn && AvFILL(comppad_name) >= 0) { SV **svp = AvARRAY(comppad_name); for (off = AvFILL(comppad_name); off > comppad_name_floor; off--) { if ((sv = svp[off]) @@@ -2771,7 -2771,7 +2771,8 @@@ OP *block if (expr) { if (once && expr->op_type == OP_CONST && !SvTRUE(((SVOP*)expr)->op_sv)) return block; /* do {} while 0 does once */ -- if (expr->op_type == OP_READLINE || expr->op_type == OP_GLOB) { ++ if (expr->op_type == OP_READLINE || expr->op_type == OP_GLOB ++ || (expr->op_type == OP_NULL && expr->op_targ == OP_GLOB)) { expr = newUNOP(OP_DEFINED, 0, newASSIGNOP(0, newSVREF(newGVOP(OP_GV, 0, defgv)), 0, expr) ); } @@@ -2795,10 -2795,10 +2796,11 @@@ } OP * --newWHILEOP(flags, debuggable, loop, expr, block, cont) ++newWHILEOP(flags, debuggable, loop, whileline, expr, block, cont) I32 flags; I32 debuggable; LOOP *loop; ++I32 whileline; OP *expr; OP *block; OP *cont; @@@ -2809,7 -2809,7 +2811,8 @@@ OP *op; OP *condop; -- if (expr && (expr->op_type == OP_READLINE || expr->op_type == OP_GLOB)) { ++ if (expr && (expr->op_type == OP_READLINE || expr->op_type == OP_GLOB ++ || (expr->op_type == OP_NULL && expr->op_targ == OP_GLOB))) { expr = newUNOP(OP_DEFINED, 0, newASSIGNOP(0, newSVREF(newGVOP(OP_GV, 0, defgv)), 0, expr) ); } @@@ -2819,8 -2819,8 +2822,14 @@@ if (cont) next = LINKLIST(cont); -- if (expr) ++ if (expr) { cont = append_elem(OP_LINESEQ, cont, newOP(OP_UNSTACK, 0)); ++ if ((line_t)whileline != NOLINE) { ++ copline = whileline; ++ cont = append_elem(OP_LINESEQ, cont, ++ newSTATEOP(0, Nullch, Nullop)); ++ } ++ } listop = append_list(OP_LINESEQ, (LISTOP*)block, (LISTOP*)cont); redo = LINKLIST(listop); @@@ -2878,10 -2878,10 +2887,10 @@@ newFOROP(I32 flags,char *label,line_t f #endif /* CAN_PROTOTYPE */ { LOOP *loop; ++ OP *wop; int padoff = 0; I32 iterflags = 0; -- copline = forline; if (sv) { if (sv->op_type == OP_RV2SV) { /* symbol table variable */ sv->op_type = OP_RV2GV; @@@ -2908,8 -2908,8 +2917,9 @@@ assert(!loop->op_next); Renew(loop, 1, LOOP); loop->op_targ = padoff; -- return newSTATEOP(0, label, newWHILEOP(flags, 1, loop, -- newOP(OP_ITER, 0), block, cont)); ++ wop = newWHILEOP(flags, 1, loop, forline, newOP(OP_ITER, 0), block, cont); ++ copline = forline; ++ return newSTATEOP(0, label, wop); } OP* @@@ -2993,7 -2993,7 +3003,7 @@@ CV* cv SV** ppad; I32 ix; -- PerlIO_printf(Perl_debug_log, "\tCV=0x%p (%s), OUTSIDE=0x%p (%s)\n", ++ PerlIO_printf(Perl_debug_log, "\tCV=0x%lx (%s), OUTSIDE=0x%lx (%s)\n", cv, (CvANON(cv) ? "ANON" : (cv == main_cv) ? "MAIN" @@@ -3016,7 -3016,7 +3026,7 @@@ for (ix = 1; ix <= AvFILL(pad_name); ix++) { if (SvPOK(pname[ix])) -- PerlIO_printf(Perl_debug_log, "\t%4d. 0x%p (%s\"%s\" %ld-%ld)\n", ++ PerlIO_printf(Perl_debug_log, "\t%4d. 0x%lx (%s\"%s\" %ld-%ld)\n", ix, ppad[ix], SvFAKE(pname[ix]) ? "FAKE " : "", SvPVX(pname[ix]), @@@ -3791,7 -3791,7 +3801,7 @@@ OP *op if (cLISTOP->op_first->op_type == OP_STUB) { op_free(op); op = newUNOP(type, OPf_SPECIAL, -- newGVOP(OP_GV, 0, gv_fetchpv("main'ARGV", TRUE, SVt_PVAV))); ++ newGVOP(OP_GV, 0, gv_fetchpv("main::ARGV", TRUE, SVt_PVAV))); } return ck_fun(op); } @@@ -3962,7 -3962,7 +3972,7 @@@ OP *op else { op_free(op); if (type == OP_FTTTY) -- return newGVOP(type, OPf_REF, gv_fetchpv("main'STDIN", TRUE, ++ return newGVOP(type, OPf_REF, gv_fetchpv("main::STDIN", TRUE, SVt_PVIO)); else return newUNOP(type, 0, newSVREF(newGVOP(OP_GV, 0, defgv))); @@@ -4112,7 -4112,7 +4122,13 @@@ OP ck_glob(op) OP *op; { -- GV *gv = gv_fetchpv("glob", FALSE, SVt_PVCV); ++ GV *gv; ++ ++ if ((op->op_flags & OPf_KIDS) && !cLISTOP->op_first->op_sibling) ++ append_elem(OP_GLOB, op, newSVREF(newGVOP(OP_GV, 0, defgv))); ++ ++ if (!((gv = gv_fetchpv("glob", FALSE, SVt_PVCV)) && GvIMPORTED_CV(gv))) ++ gv = gv_fetchpv("CORE::GLOBAL::glob", FALSE, SVt_PVCV); if (gv && GvIMPORTED_CV(gv)) { static int glob_index; @@@ -4127,10 -4127,10 +4143,10 @@@ append_elem(OP_LIST, op, scalar(newUNOP(OP_RV2CV, 0, newGVOP(OP_GV, 0, gv))))); -- return ck_subr(op); ++ op = newUNOP(OP_NULL, 0, ck_subr(op)); ++ op->op_targ = OP_GLOB; /* hint at what it used to be */ ++ return op; } -- if ((op->op_flags & OPf_KIDS) && !cLISTOP->op_first->op_sibling) -- append_elem(OP_GLOB, op, newSVREF(newGVOP(OP_GV, 0, defgv))); gv = newGVgen("main"); gv_IOadd(gv); append_elem(OP_GLOB, op, newGVOP(OP_GV, 0, gv)); @@@ -4617,7 -4617,7 +4633,8 @@@ OP *op prev = o; o = o->op_sibling; } -- if (proto && !optional && *proto == '$') ++ if (proto && !optional && ++ (*proto && *proto != '@' && *proto != '%' && *proto != ';')) return too_few_arguments(op, gv_ename(namegv)); return op; } diff --cc opcode.h index bdcf5f6,bdcf5f6..d962c1d --- a/opcode.h +++ b/opcode.h @@@ -2252,7 -2252,7 +2252,7 @@@ EXT U32 opargs[] = 0x0001111c, /* vec */ 0x0009111c, /* index */ 0x0009111c, /* rindex */ -- 0x0000210d, /* sprintf */ ++ 0x0000210f, /* sprintf */ 0x00002105, /* formline */ 0x0000099e, /* ord */ 0x0000098e, /* chr */ diff --cc os2/Changes index 146ce87,146ce87..4e0c4d4 --- a/os2/Changes +++ b/os2/Changes @@@ -158,3 -158,3 +158,8 @@@ before 5.004_02 will work. Perl will also look in the current directory first. Moreover, a bug with \; in PATH being non-separator is fixed. ++after 5.004_03: ++ $^E tracks calls to CRT now. (May break if Perl masks some ++ changes to errno?) ++ $0 may be edited to longer lengths (at least under OS/2). ++ OS2::REXX->loads looks in the OS/2-ish fashion too. diff --cc os2/OS2/REXX/Makefile.PL index c27cb0d,c27cb0d..0b43a36 --- a/os2/OS2/REXX/Makefile.PL +++ b/os2/OS2/REXX/Makefile.PL @@@ -2,7 -2,7 +2,7 @@@ use ExtUtils::MakeMaker WriteMakefile( NAME => 'OS2::REXX', -- VERSION => '0.2', ++ VERSION => '0.21', MAN3PODS => ' ', # Pods will be built by installman. XSPROTOARG => '-noprototypes', ); diff --cc os2/OS2/REXX/REXX.pm index 114e159,114e159..4580ede --- a/os2/OS2/REXX/REXX.pm +++ b/os2/OS2/REXX/REXX.pm @@@ -39,6 -39,6 +39,7 @@@ sub loa $handle = DynaLoader::dl_load_file("$_/$file.dll"); last if $handle; } ++ $handle = DynaLoader::dl_load_file($file) unless $handle; return undef unless $handle; eval "package OS2::REXX::$file; \@ISA = ('OS2::REXX');" . "sub AUTOLOAD {" @@@ -244,7 -244,7 +245,8 @@@ variables may be usable even without C< NAME is DLL name, without path and extension. Directories are searched WHERE first (list of dirs), then environment --paths PERL5REXX, PERLREXX or, as last resort, PATH. ++paths PERL5REXX, PERLREXX, PATH or, as last resort, OS/2-ish search ++is performed in default DLL path (without adding paths and extensions). The DLL is not unloaded when the variable dies. diff --cc patchlevel.h index 7881ec9,7881ec9..2adaed5 --- a/patchlevel.h +++ b/patchlevel.h @@@ -1,9 -1,9 +1,9 @@@ #define PATCHLEVEL 4 --#define SUBVERSION 3 ++#define SUBVERSION 4 /* local_patches -- list of locally applied less-than-subversion patches. -- If you're distributing such a patch, please give it a name and a ++ If you're distributing such a patch, please give it a tag name and a one-line description, placed just before the last NULL in the array below. If your patch fixes a bug in the perlbug database, please mention the bugid. If your patch *IS* dependent on a prior patch, @@@ -17,7 -17,7 +17,7 @@@ --- patchlevel.h *** 38,43 *** --- 38,44 --- -- ,"FOO1235 - some patch" ++ ,"MAINT_TRIAL_1 - 5.00x_0x maintenance release trial 1" ,"BAR3141 - another patch" ,"BAZ2718 - and another patch" + ,"MINE001 - my new patch" @@@ -36,6 -36,6 +36,7 @@@ This will prevent patch from choking if someone has previously applied different patches than you. */ ++/* The following line and terminating '};' are read by perlbug.PL. Don't alter. */ static char *local_patches[] = { NULL ,NULL diff --cc perl.c index 69b5c0e,69b5c0e..7df632d --- a/perl.c +++ b/perl.c @@@ -144,6 -144,6 +144,7 @@@ register PerlInterpreter *sv_interp #endif init_ids(); ++ lex_state = LEX_NOTPARSING; start_env.je_prev = NULL; start_env.je_ret = -1; @@@ -605,20 -605,20 +606,23 @@@ setuid perl scripts securely.\n") croak("No code specified for -e"); (void)PerlIO_putc(e_fp,'\n'); break; -- case 'I': ++ case 'I': /* -I handled both here and in moreswitches() */ forbid_setid("-I"); -- sv_catpv(sv,"-"); -- sv_catpv(sv,s); -- sv_catpv(sv," "); -- if (*++s) { -- incpush(s, TRUE); -- } -- else if (argv[1]) { -- incpush(argv[1], TRUE); -- sv_catpv(sv,argv[1]); ++ if (!*++s && (s=argv[1]) != Nullch) { argc--,argv++; -- sv_catpv(sv," "); } ++ while (s && isSPACE(*s)) ++ ++s; ++ if (s && *s) { ++ char *e, *p; ++ for (e = s; *e && !isSPACE(*e); e++) ; ++ p = savepvn(s, e-s); ++ incpush(p, TRUE); ++ sv_catpv(sv,"-I"); ++ sv_catpv(sv,p); ++ sv_catpv(sv," "); ++ Safefree(p); ++ } /* XXX else croak? */ break; case 'P': forbid_setid("-P"); @@@ -693,22 -693,22 +697,24 @@@ print \" \\@INC:\\n @INC\\n\";") if (*s) cddir = savepv(s); break; -- case '-': -- if (*++s) { /* catch use of gnu style long options */ -- if (strEQ(s, "version")) { -- s = "v"; -- goto reswitch; -- } -- if (strEQ(s, "help")) { -- s = "h"; -- goto reswitch; -- } -- croak("Unrecognized switch: --%s (-h will show valid options)",s); -- } -- argc--,argv++; -- goto switch_end; case 0: break; ++ case '-': ++ if (!*++s || isSPACE(*s)) { ++ argc--,argv++; ++ goto switch_end; ++ } ++ /* catch use of gnu style long options */ ++ if (strEQ(s, "version")) { ++ s = "v"; ++ goto reswitch; ++ } ++ if (strEQ(s, "help")) { ++ s = "h"; ++ goto reswitch; ++ } ++ s--; ++ /* FALL THROUGH */ default: croak("Unrecognized switch: -%s (-h will show valid options)",s); } @@@ -716,7 -716,7 +722,7 @@@ switch_end: if (!tainting && (s = getenv("PERL5OPT"))) { -- for (;;) { ++ while (s && *s) { while (isSPACE(*s)) s++; if (*s == '-') { @@@ -884,7 -884,7 +890,7 @@@ PerlInterpreter *sv_interp break; } -- DEBUG_r(PerlIO_printf(PerlIO_stderr(), "%s $` $& $' support.\n", ++ DEBUG_r(PerlIO_printf(Perl_debug_log, "%s $` $& $' support.\n", sawampersand ? "Enabling" : "Omitting")); if (!restartop) { @@@ -1299,30 -1299,30 +1305,39 @@@ char *name { /* This message really ought to be max 23 lines. * Removed -h because the user already knows that opton. Others? */ ++ ++ static char *usage[] = { ++"-0[octal] specify record separator (\\0, if no argument)", ++"-a autosplit mode with -n or -p (splits $_ into @F)", ++"-c check syntax only (runs BEGIN and END blocks)", ++"-d[:debugger] run scripts under debugger", ++"-D[number/list] set debugging flags (argument is a bit mask or flags)", ++"-e 'command' one line of script. Several -e's allowed. Omit [programfile].", ++"-F/pattern/ split() pattern for autosplit (-a). The //'s are optional.", ++"-i[extension] edit <> files in place (make backup if extension supplied)", ++"-Idirectory specify @INC/#include directory (may be used more than once)", ++"-l[octal] enable line ending processing, specifies line terminator", ++"-[mM][-]module.. executes `use/no module...' before executing your script.", ++"-n assume 'while (<>) { ... }' loop around your script", ++"-p assume loop like -n but print line also like sed", ++"-P run script through C preprocessor before compilation", ++"-s enable some switch parsing for switches after script name", ++"-S look for the script using PATH environment variable", ++"-T turn on tainting checks", ++"-u dump core after parsing script", ++"-U allow unsafe operations", ++"-v print version number and patchlevel of perl", ++"-V[:variable] print perl configuration information", ++"-w TURN WARNINGS ON FOR COMPILATION OF YOUR SCRIPT. Recommended.", ++"-x[directory] strip off text before #!perl line and perhaps cd to directory", ++"\n", ++NULL ++}; ++ char **p = usage; ++ printf("\nUsage: %s [switches] [--] [programfile] [arguments]", name); -- printf("\n -0[octal] specify record separator (\\0, if no argument)"); -- printf("\n -a autosplit mode with -n or -p (splits $_ into @F)"); -- printf("\n -c check syntax only (runs BEGIN and END blocks)"); -- printf("\n -d[:debugger] run scripts under debugger"); -- printf("\n -D[number/list] set debugging flags (argument is a bit mask or flags)"); -- printf("\n -e 'command' one line of script. Several -e's allowed. Omit [programfile]."); -- printf("\n -F/pattern/ split() pattern for autosplit (-a). The //'s are optional."); -- printf("\n -i[extension] edit <> files in place (make backup if extension supplied)"); -- printf("\n -Idirectory specify @INC/#include directory (may be used more than once)"); -- printf("\n -l[octal] enable line ending processing, specifies line terminator"); -- printf("\n -[mM][-]module.. executes `use/no module...' before executing your script."); -- printf("\n -n assume 'while (<>) { ... }' loop around your script"); -- printf("\n -p assume loop like -n but print line also like sed"); -- printf("\n -P run script through C preprocessor before compilation"); -- printf("\n -s enable some switch parsing for switches after script name"); -- printf("\n -S look for the script using PATH environment variable"); -- printf("\n -T turn on tainting checks"); -- printf("\n -u dump core after parsing script"); -- printf("\n -U allow unsafe operations"); -- printf("\n -v print version number and patchlevel of perl"); -- printf("\n -V[:variable] print perl configuration information"); -- printf("\n -w TURN WARNINGS ON FOR COMPILATION OF YOUR SCRIPT. Recommended."); -- printf("\n -x[directory] strip off text before #!perl line and perhaps cd to directory\n"); ++ while (*p) ++ printf("\n %s", *p++); } /* This routine handles any switches that can be given during run */ @@@ -1402,22 -1402,22 +1417,25 @@@ char *s inplace = savepv(s+1); /*SUPPRESS 530*/ for (s = inplace; *s && !isSPACE(*s); s++) ; -- *s = '\0'; -- break; -- case 'I': ++ if (*s) ++ *s++ = '\0'; ++ return s; ++ case 'I': /* -I handled both here and in parse_perl() */ forbid_setid("-I"); -- if (*++s) { ++ ++s; ++ while (*s && isSPACE(*s)) ++ ++s; ++ if (*s) { char *e, *p; for (e = s; *e && !isSPACE(*e); e++) ; p = savepvn(s, e-s); incpush(p, TRUE); Safefree(p); -- if (*e) -- return e; ++ s = e; } else croak("No space allowed after -I"); -- break; ++ return s; case 'l': minus_l = TRUE; s++; @@@ -1502,14 -1502,14 +1520,21 @@@ return s; case 'v': #if defined(SUBVERSION) && SUBVERSION > 0 -- printf("\nThis is perl, version 5.%03d_%02d", PATCHLEVEL, SUBVERSION); ++ printf("\nThis is perl, version 5.%03d_%02d built for %s", ++ PATCHLEVEL, SUBVERSION, ARCHNAME); #else -- printf("\nThis is perl, version %s",patchlevel); ++ printf("\nThis is perl, version %s built for %s", ++ patchlevel, ARCHNAME); ++#endif ++#if defined(LOCAL_PATCH_COUNT) ++ if (LOCAL_PATCH_COUNT > 0) ++ printf("\n(with %d registered patch%s, see perl -V for more detail)", ++ LOCAL_PATCH_COUNT, (LOCAL_PATCH_COUNT!=1) ? "es" : ""); #endif printf("\n\nCopyright 1987-1997, Larry Wall\n"); #ifdef MSDOS -- printf("\n\nMS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n"); ++ printf("\nMS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n"); #endif #ifdef DJGPP printf("djgpp v2 port (jpl5003c) by Hirofumi Watanabe, 1996\n"); diff --cc perl.h index e33122a,e33122a..fefceed --- a/perl.h +++ b/perl.h @@@ -1578,6 -1578,6 +1578,8 @@@ EXTCONST char* block_type[] #include "perly.h" ++#define LEX_NOTPARSING 11 /* borrowed from toke.c */ ++ typedef enum { XOPERATOR, XTERM, @@@ -1930,7 -1930,7 +1932,8 @@@ EXT MGVTBL vtbl_sv = {magic_get magic_set, magic_len, 0, 0}; --EXT MGVTBL vtbl_env = {0, 0, 0, magic_clear_all_env, ++EXT MGVTBL vtbl_env = {0, magic_set_all_env, ++ 0, magic_clear_all_env, 0}; EXT MGVTBL vtbl_envelem = {0, magic_setenv, 0, magic_clearenv, @@@ -1949,7 -1949,7 +1952,8 @@@ EXT MGVTBL vtbl_packelem = {magic_getpa EXT MGVTBL vtbl_dbline = {0, magic_setdbline, 0, 0, 0}; EXT MGVTBL vtbl_isa = {0, magic_setisa, -- 0, 0, 0}; ++ 0, magic_setisa, ++ 0}; EXT MGVTBL vtbl_isaelem = {0, magic_setisa, 0, 0, 0}; EXT MGVTBL vtbl_arylen = {magic_getarylen, diff --cc perly.c index 6bc37ff,6bc37ff..ae6a0da --- a/perly.c +++ b/perly.c @@@ -1643,7 -1643,7 +1643,7 @@@ case 27 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))); } ++ yyvsp[-6].ival, yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval))); } break; case 28: #line 192 "perly.y" @@@ -1651,7 -1651,7 +1651,7 @@@ 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))); } ++ yyvsp[-6].ival, yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval))); } break; case 29: #line 198 "perly.y" @@@ -1671,19 -1671,19 +1671,19 @@@ case 31 break; case 32: #line 209 "perly.y" --{ copline = yyvsp[-9].ival; -- yyval.opval = block_end(yyvsp[-7].ival, -- newSTATEOP(0, yyvsp[-10].pval, -- append_elem(OP_LINESEQ, scalar(yyvsp[-6].opval), -- newWHILEOP(0, 1, (LOOP*)Nullop, -- scalar(yyvsp[-4].opval), -- yyvsp[0].opval, scalar(yyvsp[-2].opval))))); } ++{ OP *forop = append_elem(OP_LINESEQ, ++ scalar(yyvsp[-6].opval), ++ newWHILEOP(0, 1, (LOOP*)Nullop, ++ yyvsp[-9].ival, scalar(yyvsp[-4].opval), ++ yyvsp[0].opval, scalar(yyvsp[-2].opval))); ++ copline = yyvsp[-9].ival; ++ yyval.opval = block_end(yyvsp[-7].ival, newSTATEOP(0, yyvsp[-10].pval, forop)); } break; case 33: #line 217 "perly.y" --{ yyval.opval = newSTATEOP(0, -- yyvsp[-2].pval, newWHILEOP(0, 1, (LOOP*)Nullop, -- Nullop, yyvsp[-1].opval, yyvsp[0].opval)); } ++{ yyval.opval = newSTATEOP(0, yyvsp[-2].pval, ++ newWHILEOP(0, 1, (LOOP*)Nullop, ++ NOLINE, Nullop, yyvsp[-1].opval, yyvsp[0].opval)); } break; case 34: #line 223 "perly.y" diff --cc perly.y index be6fe98,be6fe98..6313061 --- a/perly.y +++ b/perly.y @@@ -187,13 -187,13 +187,13 @@@ loop : label WHILE '(' remember mtexpr $$ = block_end($4, newSTATEOP(0, $1, newWHILEOP(0, 1, (LOOP*)Nullop, -- $5, $7, $8))); } ++ $2, $5, $7, $8))); } | label UNTIL '(' remember miexpr ')' mblock cont { copline = $2; $$ = block_end($4, newSTATEOP(0, $1, newWHILEOP(0, 1, (LOOP*)Nullop, -- $5, $7, $8))); } ++ $2, $5, $7, $8))); } | label FOR MY remember my_scalar '(' mexpr ')' mblock cont { $$ = block_end($4, newFOROP(0, $1, $2, $5, $7, $9, $10)); } @@@ -206,17 -206,17 +206,17 @@@ newFOROP(0, $1, $2, Nullop, $5, $7, $8)); } | label FOR '(' remember mnexpr ';' mtexpr ';' mnexpr ')' mblock /* basically fake up an initialize-while lineseq */ -- { copline = $2; -- $$ = block_end($4, -- newSTATEOP(0, $1, -- append_elem(OP_LINESEQ, scalar($5), -- newWHILEOP(0, 1, (LOOP*)Nullop, -- scalar($7), -- $11, scalar($9))))); } ++ { OP *forop = append_elem(OP_LINESEQ, ++ scalar($5), ++ newWHILEOP(0, 1, (LOOP*)Nullop, ++ $2, scalar($7), ++ $11, scalar($9))); ++ copline = $2; ++ $$ = block_end($4, newSTATEOP(0, $1, forop)); } | label block cont /* a block is a loop that happens once */ -- { $$ = newSTATEOP(0, -- $1, newWHILEOP(0, 1, (LOOP*)Nullop, -- Nullop, $2, $3)); } ++ { $$ = newSTATEOP(0, $1, ++ newWHILEOP(0, 1, (LOOP*)Nullop, ++ NOLINE, Nullop, $2, $3)); } ; nexpr : /* NULL */ diff --cc pod/perlapio.pod index 0db385e,0db385e..c963d23 --- a/pod/perlapio.pod +++ b/pod/perlapio.pod @@@ -29,8 -29,8 +29,8 @@@ perlapio - perl's IO abstraction interf int PerlIO_fileno(PerlIO *); PerlIO *PerlIO_fdopen(int, const char *); -- PerlIO *PerlIO_importFILE(FILE *); -- FILE *PerlIO_exportFILE(PerlIO *); ++ PerlIO *PerlIO_importFILE(FILE *, int flags); ++ FILE *PerlIO_exportFILE(PerlIO *, int flags); FILE *PerlIO_findFILE(PerlIO *); void PerlIO_releaseFILE(PerlIO *,FILE *); diff --cc pod/perldelta.pod index 8d191e8,8d191e8..7400940 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@@ -1163,7 -1163,7 +1163,7 @@@ increasing order of desperation) =item "my" variable %s masks earlier declaration in same scope --(S) A lexical variable has been redeclared in the same scope, effectively ++(W) 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 diff --cc pod/perldiag.pod index a4d9356,a4d9356..166e046 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@@ -35,7 -35,7 +35,7 @@@ if you want to localize a package varia =item "my" variable %s masks earlier declaration in same scope --(S) A lexical variable has been redeclared in the same scope, effectively ++(W) 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 @@@ -594,7 -594,7 +594,11 @@@ for us to go to. See L 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.) ++ print q(The character '(' starts a side comment.); ++ ++If you're getting this error from a here-document, you may have ++included unseen whitespace before or after your closing tag. A good ++programmer's editor will have a way to help you find these characters. =item Can't fork @@@ -778,13 -778,13 +782,16 @@@ of suidperl =item Can't take log of %g --(F) Logarithms are defined on only positive real numbers. ++(F) For ordinary real numbers, you can't take the logarithm of a ++negative number or zero. There's a Math::Complex package that comes ++standard with Perl, though, if you really want to do that for ++the negative numbers. =item Can't take sqrt of %g (F) For ordinary real numbers, you can't take the square root of a --negative number. There's a Complex package available for Perl, though, --if you really want to do that. ++negative number. There's a Math::Complex package that comes standard ++with Perl, though, if you really want to do that. =item Can't undef active subroutine @@@ -1315,10 -1315,10 +1322,14 @@@ See L =item Invalid type in pack: '%s' (F) The given character is not a valid pack type. See L. ++(W) The given character is not a valid pack type but used to be silently ++ignored. =item Invalid type in unpack: '%s' (F) The given character is not a valid unpack type. See L. ++(W) The given character is not a valid unpack type but used to be silently ++ignored. =item ioctl is not implemented @@@ -2015,6 -2015,6 +2026,11 @@@ an unintended loop in your inheritance (W) The internal sv_replace() function was handed a new SV with a reference count of other than 1. ++=item regexp *+ operand could be empty ++ ++(F) The part of the regexp subject to either the * or + quantifier ++could match an empty string. ++ =item regexp memory corruption (P) The regular expression engine got confused by what the regular @@@ -2082,6 -2082,6 +2098,7 @@@ or setgid bit set. This doesn't make m (F) The lexer couldn't find the final delimiter of a // or m{} construct. Remember that bracketing delimiters count nesting level. ++Missing the leading C<$> from a variable C<$m> may cause this error. =item %sseek() on unopened file @@@ -2252,11 -2252,11 +2269,13 @@@ L from variable C<$s> may cause this error. =item Substitution replacement not terminated (F) The lexer couldn't find the final delimiter of a s/// or s{}{} construct. Remember that bracketing delimiters count nesting level. ++Missing the leading C<$> from variable C<$s> may cause this error. =item substr outside of string @@@ -2413,7 -2413,7 +2432,8 @@@ it. See L =item Translation pattern not terminated (F) The lexer couldn't find the interior delimiter of a tr/// or tr[][] --construct. ++or y/// or y[][] construct. Missing the leading C<$> from variables ++C<$tr> or C<$y> may cause this error. =item Translation replacement not terminated @@@ -2635,6 -2635,6 +2655,10 @@@ non-methods. The simple fix for old co depend on inheriting C for non-methods from a base class named C, execute C<*AUTOLOAD = \&BaseClass::AUTOLOAD> during startup. ++In code that currently says C you ++should remove AutoLoader from @ISA and change C to ++C. ++ =item Use of %s is deprecated (D) The construct indicated is no longer recommended for use, generally diff --cc pod/perlfunc.pod index 4f3341d,4f3341d..aa1e82e --- a/pod/perlfunc.pod +++ b/pod/perlfunc.pod @@@ -551,23 -551,23 +551,30 @@@ 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. If the file handle came from a piped open C will --additionally return FALSE if one of the other system calls involved --fails or if the program exits with non-zero status. (If the problem was --that the program exited non-zero $! will be set to 0.) --You don't have to close FILEHANDLE if you are immediately --going to do another open() on it, because open() will close it for you. (See ++descriptor. ++ ++You don't have to close FILEHANDLE if you are immediately 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 --complete, in case you want to look at the output of the pipe --afterwards. Closing a pipe explicitly also puts the status value of --the command into C<$?>. Example: ++counter ($.), while the implicit close done by open() does not. ++ ++If the file handle came from a piped open C will additionally ++return FALSE if one of the other system calls involved fails or if the ++program exits with non-zero status. (If the only problem was that the ++program exited non-zero $! will be set to 0.) Also, closing a pipe will ++wait for the process executing on the pipe to complete, in case you ++want to look at the output of the pipe afterwards. Closing a pipe ++explicitly also puts the exit status value of the command into C<$?>. ++Example: -- open(OUTPUT, '|sort >foo'); # pipe to sort ++ open(OUTPUT, '|sort >foo') # pipe to sort ++ or die "Can't start sort: $!"; ... # print stuff to output -- close OUTPUT; # wait for sort to finish -- open(INPUT, 'foo'); # get sort's results ++ close OUTPUT # wait for sort to finish ++ or warn $! ? "Error closing sort pipe: $!" ++ : "Exit status $? from sort"; ++ open(INPUT, 'foo') # get sort's results ++ or die "Can't open 'foo' for input: $!"; FILEHANDLE may be an expression whose value gives the real filehandle name. @@@ -803,11 -803,11 +810,28 @@@ produce, respectivel See also exit() and warn(). ++If LIST is empty and $@ already contains a value (typically from a ++previous eval) that value is reused after appending "\t...propagated". ++This is useful for propagating exceptions: ++ ++ eval { ... }; ++ die unless $@ =~ /Expected exception/; ++ ++If $@ is empty then the string "Died" is used. ++ You can arrange for a callback to be called just before the die() does its deed, by setting the C<$SIG{__DIE__}> hook. The associated handler will be called with the error text and can change the error message, if --it sees fit, by calling die() again. See L for details on --setting C<%SIG> entries, and eval() for some examples. ++it sees fit, by calling die() again. See L for details on ++setting C<%SIG> entries, and L<"eval BLOCK"> for some examples. ++ ++Note that the C<$SIG{__DIE__}> hook is called even inside eval()ed ++blocks/strings. If one wants the hook to do nothing in such ++situations, put ++ ++ die @_ if $^S; ++ ++as the first line of the handler (see L). =item do BLOCK @@@ -830,7 -830,7 +854,7 @@@ from a Perl subroutine library is just like -- eval `cat stat.pl`; ++ scalar eval `cat stat.pl`; except that it's more efficient, more concise, keeps track of the current filename for error messages, and searches all the B<-I> @@@ -1030,10 -1030,10 +1054,10 @@@ in case 6 =item exec LIST --The exec() function executes a system command I, --unless the command does not exist and is executed directly instead of --via your system's command shell (see below). Use system() instead of --exec() if you want it to return. ++The exec() function executes a system command I - ++use system() instead of exec() if you want it to return. It fails and ++returns FALSE only if the command does not exist I it is executed ++directly instead of via your system's command shell (see below). If there is more than one argument in LIST, or if LIST is an array with more than one value, calls execvp(3) with the arguments in LIST. If @@@ -1532,8 -1532,8 +1556,10 @@@ supported, it can cause bizarre result array. Similarly, grep returns aliases into the original list, much like the way that L's index variable aliases the list elements. That is, modifying an element of a list returned by grep ++(for example, in a C, C or another C) actually modifies the element in the original list. ++See also L for an array composed of the results of the BLOCK or EXPR. =item hex EXPR =item hex @@@ -1764,6 -1764,6 +1790,8 @@@ In a scalar context, returns the ctime( $now_string = localtime; # e.g., "Thu Oct 13 04:54:34 1994" ++This scalar value is B locale dependent, see L, ++but instead a Perl builtin. Also see the Time::Local module, and the strftime(3) and mktime(3) function available via the POSIX module. @@@ -1812,6 -1812,6 +1840,12 @@@ is just a funny way to writ $hash{getkey($_)} = $_; } ++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. See also L for an array composed of those items of the ++original list for which the BLOCK or EXPR evaluates to true. ++ =item mkdir FILENAME,MODE Creates the directory specified by FILENAME, with permissions specified @@@ -1932,6 -1932,6 +1966,14 @@@ and those that don't is their text fil Plan9 that delimit lines with a single character, and that encode that character in C as '\n', do not need C. The rest need it. ++When opening a file, it's usually a bad idea to continue normal execution ++if the request failed, so C is frequently used in connection with ++C. Even if C won't do what you want (say, in a CGI script, ++where you want to make a nicely formatted error message (but there are ++modules which can help with that problem)) you should always check ++the return value from opening a file. The infrequent exception is when ++working with an unopened filehandle is actually what you want to do. ++ Examples: $ARTICLE = 100; @@@ -1939,12 -1939,12 +1981,16 @@@ while (
) {... open(LOG, '>>/usr/spool/news/twitlog'); # (log is reserved) ++ # if the open fails, output is discarded -- open(DBASE, '+/tmp/Tmp$$"); # $$ is our process id ++ open(EXTRACT, "|sort >/tmp/Tmp$$") # $$ is our process id ++ or die "Can't start sort: $!"; # process argument list of files along with any includes @@@ -3060,12 -3060,12 +3106,13 @@@ value.) The use of implicit split to @ If EXPR is omitted, splits the $_ string. If PATTERN is also omitted, splits on whitespace (after skipping any leading whitespace). Anything matching PATTERN is taken to be a delimiter separating the fields. (Note --that the delimiter may be longer than one character.) If LIMIT is --specified and is not negative, splits into no more than that many fields --(though it may split into fewer). If LIMIT is unspecified, trailing null --fields are stripped (which potential users of pop() would do well to --remember). If LIMIT is negative, it is treated as if an arbitrarily large --LIMIT had been specified. ++that the delimiter may be longer than one character.) ++ ++If LIMIT is specified and is not negative, splits into no more than ++that many fields (though it may split into fewer). If LIMIT is ++unspecified, trailing null fields are stripped (which potential users ++of pop() would do well to remember). If LIMIT is negative, it is ++treated as if an arbitrarily large LIMIT had been specified. A pattern matching the null string (not to be confused with a null pattern C, which is just one member of the set of patterns @@@ -3099,7 -3099,7 +3146,7 @@@ If you had the entire header of a norma you could split it up into fields and their values this way: $header =~ s/\n\s+/ /g; # fix continuation lines -- %hdrs = (UNIX_FROM => split /^(.*?):\s*/m, $header); ++ %hdrs = (UNIX_FROM => split /^(\S*?):\s*/m, $header); The pattern C may be replaced with an expression to specify patterns that vary at runtime. (To do runtime compilation only once, @@@ -3412,6 -3412,6 +3459,17 @@@ like numbers Note that Perl supports passing of up to only 14 arguments to your system call, which in practice should usually suffice. ++Syscall returns whatever value returned by the system call it calls. ++If the system call fails, syscall returns -1 and sets C<$!> (errno). ++Note that some system calls can legitimately return -1. The proper ++way to handle such calls is to assign C<$!=0;> before the call and ++check the value of <$!> if syscall returns -1. ++ ++There's a problem with C: it returns the file ++number of the read end of the pipe it creates. There is no way ++to retrieve the file number of the other end. You can avoid this ++problem by using C instead. ++ =item sysopen FILEHANDLE,FILENAME,MODE =item sysopen FILEHANDLE,FILENAME,MODE,PERMS @@@ -3441,12 -3441,12 +3499,12 @@@ into that kind of thing =item sysread FILEHANDLE,SCALAR,LENGTH Attempts to read LENGTH bytes of data into variable SCALAR from the --specified FILEHANDLE, using the system call read(2). It bypasses stdio, --so mixing this with other kinds of reads, print(), write(), seek(), or --tell() can cause confusion. Returns the number of bytes actually read, --or undef if there was an error. SCALAR will be grown or shrunk so that --the last byte actually read is the last byte of the scalar after the --read. ++specified FILEHANDLE, using the system call read(2). It bypasses ++stdio, so mixing this with other kinds of reads, print(), write(), ++seek(), or tell() can cause confusion because stdio usually buffers ++data. Returns the number of bytes actually read, or undef if there ++was an error. SCALAR will be grown or shrunk so that the last byte ++actually read is the last byte of the scalar after the read. An OFFSET may be specified to place the read data at some place in the string other than the beginning. A negative OFFSET specifies @@@ -3527,14 -3527,14 +3585,16 @@@ for details Attempts to write LENGTH bytes of data from variable SCALAR to the specified FILEHANDLE, using the system call write(2). It bypasses stdio, so mixing this with reads (other than sysread()), print(), --write(), seek(), or tell() may cause confusion. Returns the number of --bytes actually written, or undef if there was an error. If the length --is greater than the available data, only as much data as is available ++write(), seek(), or tell() may cause confusion because stdio usually ++buffers data. Returns the number of bytes actually written, or undef ++if there was an error. If the LENGTH is greater than the available ++data in the SCALAR after the OFFSET, only as much data as is available will be written. An OFFSET may be specified to write the data from some part of the string other than the beginning. A negative OFFSET specifies writing --that many bytes counting backwards from the end of the string. ++that many bytes counting backwards from the end of the string. In the ++case the SCALAR is empty you can use OFFSET but only zero offset. =item tell FILEHANDLE diff --cc pod/perlguts.pod index ecf8610,ecf8610..20a11ac --- a/pod/perlguts.pod +++ b/pod/perlguts.pod @@@ -1404,7 -1404,7 +1404,7 @@@ extensions =item AvFILL --See C. ++Same as C. =item av_clear @@@ -1851,6 -1851,6 +1851,11 @@@ Prepares a starting point to traverse I32 hv_iterinit _((HV* tb)); ++Note that hv_iterinit I returns the number of I in ++the hash and I the number of keys (as indicated in the Advanced ++Perl Programming book). This may change in future. Use the HvKEYS(hv) ++macro to find the number of keys in a hash. ++ =item hv_iterkey Returns the key from the current position of the hash iterator. See @@@ -2823,6 -2823,6 +2828,35 @@@ Dereferences an RV to return the SV SV* SvRV (SV* sv); ++=item SvTAINT ++ ++Taints an SV if tainting is enabled ++ ++ SvTAINT (SV* sv); ++ ++=item SvTAINTED ++ ++Checks to see if an SV is tainted. Returns TRUE if it is, FALSE if not. ++ ++ SvTAINTED (SV* sv); ++ ++=item SvTAINTED_off ++ ++Untaints an SV. Be I careful with this routine, as it short-circuits ++some of Perl's fundamental security features. XS module authors should ++not use this function unless they fully understand all the implications ++of unconditionally untainting the value. Untainting should be done in ++the standard perl fashion, via a carefully crafted regexp, rather than ++directly untainting variables. ++ ++ SvTAINTED_off (SV* sv); ++ ++=item SvTAINTED_on ++ ++Marks an SV as tainted. ++ ++ SvTAINTED_on (SV* sv); ++ =item sv_setiv Copies an integer into the given SV. diff --cc pod/perlipc.pod index 6b1f2ab,6b1f2ab..030463c --- a/pod/perlipc.pod +++ b/pod/perlipc.pod @@@ -71,9 -71,9 +71,9 @@@ values are "inherited" by functions cal } Sending a signal to a negative process ID means that you send the signal --to the entire Unix process-group. This code send a hang-up signal to all --processes in the current process group I the current process --itself: ++to the entire Unix process-group. This code sends a hang-up signal to all ++processes in the current process group (and sets $SIG{HUP} to IGNORE so ++it doesn't kill itself): { local $SIG{HUP} = 'IGNORE'; diff --cc pod/perlop.pod index 5685902,5685902..17728df --- a/pod/perlop.pod +++ b/pod/perlop.pod @@@ -567,6 -567,6 +567,15 @@@ the same character fore and aft, but th s{}{} Substitution yes tr{}{} Translation no ++Note that there can be whitespace between the operator and the quoting ++characters, except when C<#> is being used as the quoting character. ++C is parsed as being the string C, which C is the ++operator C followed by a comment. Its argument will be taken from the ++next line. This allows you to write: ++ ++ s {foo} # Replace foo ++ {bar} # with bar. ++ For constructs that do interpolation, variables beginning with "C<$>" or "C<@>" are interpolated, as are the following sequences: @@@ -619,9 -619,9 +628,9 @@@ patterns local to the current package a This usage is vaguely deprecated, and may be removed in some future version of Perl. --=item m/PATTERN/gimosx ++=item m/PATTERN/cgimosx --=item /PATTERN/gimosx ++=item /PATTERN/cgimosx Searches a string for a pattern match, and in a scalar context returns true (1) or false (''). If no string is specified via the C<=~> or @@@ -634,6 -634,6 +643,7 @@@ when C is in effect Options are: ++ c Do not reset search position on a failed match when /g is in effect. g Match globally, i.e., find all occurrences. i Do case-insensitive pattern matching. m Treat string as multiple lines. diff --cc pod/perlrun.pod index 1e3279e,1e3279e..a847133 --- a/pod/perlrun.pod +++ b/pod/perlrun.pod @@@ -62,6 -62,6 +62,11 @@@ getting a - instead of a complete switc execute standard input instead of your script. And a partial B<-I> switch could also cause odd results. ++Some switches do care if they are processed twice, for instance combinations ++of B<-l> and B<-0>. Either put all the switches after the 32 character ++boundary (if applicable), or replace the use of B<-0>I by ++C. ++ Parsing of the #! switches starts wherever "perl" is mentioned in the line. The sequences "-*" and "- " are specifically ignored so that you could, if you were so inclined, say @@@ -500,7 -500,7 +505,9 @@@ Perl allows Perl to do unsafe operations. Currently the only "unsafe" operations are the unlinking of directories while running as superuser, and running setuid programs with fatal taint checks turned into --warnings. ++warnings. Note that the B<-w> switch (or the C<$^W> variable) must ++be used along with this option to actually B the ++taint-check warnings. =item B<-v> diff --cc pod/perlsec.pod index 1a1ae21,1a1ae21..7388479 --- a/pod/perlsec.pod +++ b/pod/perlsec.pod @@@ -18,25 -18,25 +18,28 @@@ user or group IDs. The setuid bit in U setgid bit mode 02000; either or both may be set. You can also enable taint mode explicitly by using the B<-T> command line flag. This flag is I suggested for server programs and any program run on behalf of --someone else, such as a CGI script. ++someone else, such as a CGI script. Once taint mode is on, it's on for ++the remainder of your script. While in this mode, Perl takes special precautions called I to prevent both obvious and subtle traps. Some of these checks are reasonably simple, such as verifying that path directories aren't writable by others; careful programmers have always used checks like these. Other checks, however, are best supported by the language itself, --and it is these checks especially that contribute to making a setuid Perl ++and it is these checks especially that contribute to making a set-id Perl program more secure than the corresponding C program. --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, locale information (see L), --and file input are marked as "tainted". Tainted data may not be used --directly or indirectly in any command that 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 taintedness is associated with each ++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, locale information (see ++L), results of certain system calls (readdir, readlink, ++the gecos field of getpw* calls), and all file input are marked as ++"tainted". Tainted data may not be used directly or indirectly in any ++command that invokes a sub-shell, nor in any command that modifies ++files, directories, or processes. Any variable set ++to a value derived from tainted data will itself be tainted, ++even if it is logically impossible for the tainted data ++to alter the variable. Because taintedness is associated with each scalar value, some elements of an array can be tainted and others not. For example: @@@ -90,8 -90,8 +93,9 @@@ doing something like the last example a =head2 Laundering and Detecting Tainted Data To test whether a variable contains tainted data, and whose use would thus --trigger an "Insecure dependency" message, you can use the following --I function. ++trigger an "Insecure dependency" message, check your nearby CPAN mirror ++for the F module, which should become available around November ++1997. Or you may be able to use the following I function. sub is_tainted { return ! eval { @@@ -172,8 -172,8 +176,8 @@@ makes sure you set the PATH It's also possible to get into trouble with other operations that don't care whether they use tainted values. Make judicious use of the file tests in dealing with any user-supplied filenames. When possible, do --opens and such after setting C<$E = $E>. (Remember group IDs, --too!) Perl doesn't prevent you from opening tainted filenames for reading, ++opens and such B properly dropping any special user (or group!) ++privileges. Perl doesn't prevent you from opening tainted filenames for reading, so be careful what you print out. The tainting mechanism is intended to prevent stupid mistakes, not to remove the need for thought. @@@ -199,30 -199,30 +203,36 @@@ doing something it shouldn't Here's a way to do backticks reasonably safely. Notice how the B 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, tainting --is turned off, however, so be careful what you call and what you pass it. ++never call the shell at all. use English; -- die unless defined $pid = open(KID, "-|"); ++ die "Can't fork: $!" unless defined $pid = open(KID, "-|"); if ($pid) { # parent while () { # do something } close KID; } else { ++ my @temp = ($EUID, $EGID); $EUID = $UID; $EGID = $GID; # XXX: initgroups() not called ++ # Make sure privs are really gone ++ ($EUID, $EGID) = @temp; ++ die "Can't drop privileges" unless ++ $UID == $EUID and ++ $GID eq $EGID; # String test $ENV{PATH} = "/bin:/usr/bin"; -- exec 'myprog', 'arg1', 'arg2'; ++ exec 'myprog', 'arg1', 'arg2' or die "can't exec myprog: $!"; } --A similar strategy would work for wildcard expansion via C. ++A similar strategy would work for wildcard expansion via C, although ++you can use C instead. Taint checking is most useful when although you trust yourself not to have written a program to give away the farm, you don't necessarily trust those who end up using it not to try to trick it into doing something bad. This --is the kind of security checking that's useful for setuid programs and ++is the kind of security checking that's useful for set-id programs and programs launched on someone else's behalf, like CGI programs. This is quite different, however, from not even trusting the writer of the @@@ -236,28 -236,28 +246,28 @@@ are trapped and namespace access is car =head2 Security Bugs Beyond the obvious problems that stem from giving special privileges to --systems as flexible as scripts, on many versions of Unix, setuid scripts ++systems as flexible as scripts, on many versions of Unix, set-id scripts are inherently insecure right from the start. The problem is a race condition in the kernel. Between the time the kernel opens the file to --see which interpreter to run and when the (now-setuid) interpreter turns ++see which interpreter to run and when the (now-set-id) interpreter turns around and reopens the file to interpret it, the file in question may have changed, especially if you have symbolic links on your system. Fortunately, sometimes this kernel "feature" can be disabled. Unfortunately, there are two ways to disable it. The system can simply --outlaw scripts with the setuid bit set, which doesn't help much. --Alternately, it can simply ignore the setuid bit on scripts. If the ++outlaw scripts with any set-id bit set, which doesn't help much. ++Alternately, it can simply ignore the set-id bits on scripts. If the latter is true, Perl can emulate the setuid and setgid mechanism when it notices the otherwise useless setuid/gid bits on Perl scripts. It does this via a special executable called B that is automatically invoked for you if it's needed. --However, if the kernel setuid script feature isn't disabled, Perl will --complain loudly that your setuid script is insecure. You'll need to --either disable the kernel setuid script feature, or put a C wrapper around ++However, if the kernel set-id script feature isn't disabled, Perl will ++complain loudly that your set-id script is insecure. You'll need to ++either disable the kernel set-id script feature, or put a C wrapper around the script. A C wrapper is just a compiled program that does nothing except call your Perl program. Compiled programs are not subject to the --kernel bug that plagues setuid scripts. Here's a simple wrapper, written ++kernel bug that plagues set-id scripts. Here's a simple wrapper, written in C: #define REAL_PATH "/path/to/script" @@@ -278,7 -278,7 +288,7 @@@ for each of them In recent years, vendors have begun to supply systems free of this inherent security bug. On such systems, when the kernel passes the name --of the setuid script to open to the interpreter, rather than using a ++of the set-id script to open to the interpreter, rather than using a pathname subject to meddling, it instead passes I. This is a special file already opened on the script, so that there can be no race condition for evil scripts to exploit. On these systems, Perl should be diff --cc pod/perlsub.pod index d08426a,d08426a..16babd2 --- a/pod/perlsub.pod +++ b/pod/perlsub.pod @@@ -872,6 -872,6 +872,12 @@@ via the import syntax, and these names chdir $somewhere; sub chdir { ... } ++To unambiguously refer to the builtin form, one may precede the ++builtin name with the special package qualifier C. For example, ++saying C will always refer to the builtin C, even ++if the current package has imported some other subroutine called ++C<&open()> from elsewhere. ++ Library modules should not in general export builtin names like "open" or "chdir" as part of their default @EXPORT list, because these may sneak into someone else's namespace and change the semantics unexpectedly. @@@ -887,6 -887,6 +893,10 @@@ and it would import the open override, they would get the default imports without the overrides. ++Note that such overriding is restricted to the package that requests ++the import. Some means of "globally" overriding builtins may become ++available in future. ++ =head2 Autoloading If you call a subroutine that is undefined, you would ordinarily get an diff --cc pod/perlvar.pod index 6487fdd,6487fdd..75f4e6d --- a/pod/perlvar.pod +++ b/pod/perlvar.pod @@@ -18,9 -18,9 +18,9 @@@ long names in the current package. Som generally borrowed from B. To go a step further, those variables that depend on the currently --selected filehandle may instead be set by calling an object method on --the FileHandle object. (Summary lines below for this contain the word --HANDLE.) First you must say ++selected filehandle may instead (and preferably) be set by calling an ++object method on the FileHandle object. (Summary lines below for this ++contain the word HANDLE.) First you must say use FileHandle; @@@ -42,6 -42,6 +42,12 @@@ A few of these variables are considere you try to assign to this variable, either directly or indirectly through a reference, you'll raise a run-time exception. ++The following list is ordered by scalar variables first, then the ++arrays, then the hashes (except $^M was added in the wrong place). ++This is somewhat obscured by the fact that %ENV and %SIG are listed as ++$ENV{expr} and $SIG{expr}. ++ ++ =over 8 =item $ARG @@@ -438,16 -438,16 +444,13 @@@ operator. (Mnemonic: What just went ba =item $^E 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.) ++C<$!>, if available. (If not, it's just C<$!> again.) 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 ++code of the last call to OS/2 API either via CRT, or directly from perl. The caveats mentioned in the description of C<$!> apply here, too. (Mnemonic: Extra error explanation.) --Note that under OS/2 C<$!> and C<$^E> do not track each other, so if an --OS/2-specific call is performed, you may need to check both. -- =item $EVAL_ERROR =item $@ @@@ -597,8 -597,8 +600,8 @@@ C<$^F> at the time of the open, not th =item $^H --The current set of syntax checks enabled by C. See the --documentation of C for more details. ++The current set of syntax checks enabled by C and other block ++scoped compiler hints. See the documentation of C for more details. =item $INPLACE_EDIT @@@ -607,6 -607,6 +610,20 @@@ The current value of the inplace-edit extension. Use C to disable inplace editing. (Mnemonic: value of B<-i> switch.) ++=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 -DPERL_EMERGENCY_SBRK and used Perl's malloc. Then ++ ++ $^M = 'a' x (1<<16); ++ ++would allocate a 64K buffer for use when in emergency. See the F ++file for information on how to enable this option. As a disincentive to ++casual use of this advanced feature, there is no L long name for ++this variable. ++ =item $OSNAME =item $^O @@@ -653,6 -653,6 +670,12 @@@ Start with single-step on Note that some bits may be relevent at compile-time only, some at run-time only. This is a new mechanism and the details may change. ++=item $^S ++ ++Current state of the interpreter. Undefined if parsing of the current ++module/eval is not finished (may happen in $SIG{__DIE__} and ++$SIG{__WARN__} handlers). True if inside an eval, othewise false. ++ =item $BASETIME =item $^T @@@ -699,6 -699,6 +722,11 @@@ to get the machine-dependent library pr use lib '/mypath/libdir/'; use SomeMod; ++=item @_ ++ ++Within a subroutine the array @_ contains the parameters passed to that ++subroutine. See L. ++ =item %INC The hash %INC contains entries for each filename that has @@@ -707,25 -707,25 +735,25 @@@ specified, and the value is the locatio The C command uses this array to determine whether a given file has already been included. --=item $ENV{expr} ++=item %ENV $ENV{expr} The hash %ENV contains your current environment. Setting a value in C changes the environment for child processes. --=item $SIG{expr} ++=item %SIG $SIG{expr} The hash %SIG is used to set signal handlers for various signals. Example: sub handler { # 1st argument is signal name -- local($sig) = @_; ++ my($sig) = @_; print "Caught a SIG$sig--shutting down\n"; close(LOG); exit(0); } -- $SIG{'INT'} = 'handler'; -- $SIG{'QUIT'} = 'handler'; ++ $SIG{'INT'} = \&handler; ++ $SIG{'QUIT'} = \&handler; ... $SIG{'INT'} = 'DEFAULT'; # restore default action $SIG{'QUIT'} = 'IGNORE'; # ignore SIGQUIT @@@ -733,8 -733,8 +761,8 @@@ The %SIG array contains values for only the signals actually set within the Perl script. Here are some other examples: -- $SIG{PIPE} = Plumber; # SCARY!! -- $SIG{"PIPE"} = "Plumber"; # just fine, assumes main::Plumber ++ $SIG{"PIPE"} = Plumber; # SCARY!! ++ $SIG{"PIPE"} = "Plumber"; # assumes main::Plumber (not recommended) $SIG{"PIPE"} = \&Plumber; # just fine; assume current Plumber $SIG{"PIPE"} = Plumber(); # oops, what did Plumber() return?? @@@ -775,21 -775,21 +803,30 @@@ argument. When a __DIE__ hook routine processing continues as it would have in the absence of the hook, unless the hook routine itself exits via a C, a loop exit, or a die(). The C<__DIE__> handler is explicitly disabled during the call, so that you --can die from a C<__DIE__> handler. Similarly for C<__WARN__>. See --L, L and L. -- --=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 -DPERL_EMERGENCY_SBRK and used Perl's malloc. Then -- -- $^M = 'a' x (1<<16); -- --would allocate a 64K buffer for use when in emergency. See the F --file for information on how to enable this option. As a disincentive to --casual use of this advanced feature, there is no L long name for --this variable. ++can die from a C<__DIE__> handler. Similarly for C<__WARN__>. ++ ++Note that the C<$SIG{__DIE__}> hook is called even inside eval()ed ++blocks/strings. See L, L for how to ++circumvent this. ++ ++Note that C<__DIE__>/C<__WARN__> handlers are very special in one ++respect: they may be called to report (probable) errors found by the ++parser. In such a case the parser may be in inconsistent state, so ++any attempt to evaluate Perl code from such a handler will probably ++result in a segfault. This means that calls which result/may-result ++in parsing Perl should be used with extreme causion, like this: ++ ++ require Carp if defined $^S; ++ Carp::confess("Something wrong") if defined &Carp::confess; ++ die "Something wrong, but could not load Carp to give backtrace... ++ To see backtrace try starting Perl with -MCarp switch"; ++ ++Here the first line will load Carp I it is the parser who ++called the handler. The second line will print backtrace and die if ++Carp was available. The third line will be executed only if Carp was ++not available. ++ ++See L, L and L for ++additional info. =back diff --cc pp.c index 8a31fff,8a31fff..3513dda --- a/pp.c +++ b/pp.c @@@ -440,6 -440,6 +440,68 @@@ PP(pp_bless RETURN; } ++PP(pp_gelem) ++{ ++ GV *gv; ++ SV *sv; ++ SV *ref; ++ char *elem; ++ dSP; ++ ++ sv = POPs; ++ elem = SvPV(sv, na); ++ gv = (GV*)POPs; ++ ref = Nullsv; ++ sv = Nullsv; ++ switch (elem ? *elem : '\0') ++ { ++ case 'A': ++ if (strEQ(elem, "ARRAY")) ++ ref = (SV*)GvAV(gv); ++ break; ++ case 'C': ++ if (strEQ(elem, "CODE")) ++ ref = (SV*)GvCVu(gv); ++ break; ++ case 'F': ++ if (strEQ(elem, "FILEHANDLE")) /* XXX deprecate in 5.005 */ ++ ref = (SV*)GvIOp(gv); ++ break; ++ case 'G': ++ if (strEQ(elem, "GLOB")) ++ ref = (SV*)gv; ++ break; ++ case 'H': ++ if (strEQ(elem, "HASH")) ++ ref = (SV*)GvHV(gv); ++ break; ++ case 'I': ++ if (strEQ(elem, "IO")) ++ ref = (SV*)GvIOp(gv); ++ break; ++ case 'N': ++ if (strEQ(elem, "NAME")) ++ sv = newSVpv(GvNAME(gv), GvNAMELEN(gv)); ++ break; ++ case 'P': ++ if (strEQ(elem, "PACKAGE")) ++ sv = newSVpv(HvNAME(GvSTASH(gv)), 0); ++ break; ++ case 'S': ++ if (strEQ(elem, "SCALAR")) ++ ref = GvSV(gv); ++ break; ++ } ++ if (ref) ++ sv = newRV(ref); ++ if (sv) ++ sv_2mortal(sv); ++ else ++ sv = &sv_undef; ++ XPUSHs(sv); ++ RETURN; ++} ++ /* Pattern matching */ PP(pp_study) @@@ -567,11 -567,11 +629,11 @@@ PP(pp_defined RETPUSHNO; switch (SvTYPE(sv)) { case SVt_PVAV: -- if (AvMAX(sv) >= 0 || SvRMAGICAL(sv)) ++ if (AvMAX(sv) >= 0 || SvGMAGICAL(sv)) RETPUSHYES; break; case SVt_PVHV: -- if (HvARRAY(sv) || SvRMAGICAL(sv)) ++ if (HvARRAY(sv) || SvGMAGICAL(sv)) RETPUSHYES; break; case SVt_PVCV: @@@ -2324,7 -2324,7 +2386,7 @@@ PP(pp_anonhash SV *val = NEWSV(46, 0); if (MARK < SP) sv_setsv(val, *++MARK); -- else ++ else if (dowarn) warn("Odd number of elements in hash list"); (void)hv_store_ent(hv,key,val,0); } @@@ -2383,6 -2383,6 +2445,12 @@@ PP(pp_splice newlen = SP - MARK; diff = newlen - length; ++ if (newlen && !AvREAL(ary)) { ++ if (AvREIFY(ary)) ++ av_reify(ary); ++ else ++ assert(AvREAL(ary)); /* would leak, so croak */ ++ } if (diff < 0) { /* shrinking the area */ if (newlen) { @@@ -2694,6 -2694,6 +2762,7 @@@ PP(pp_unpack register U32 culong; double cdouble; static char* bitcount = 0; ++ int commas = 0; if (gimme != G_ARRAY) { /* arrange to do first one only */ /*SUPPRESS 530*/ @@@ -2727,6 -2727,6 +2796,10 @@@ switch(datumtype) { default: croak("Invalid type in unpack: '%c'", (int)datumtype); ++ case ',': /* grandfather in commas but with a warning */ ++ if (commas++ == 0 && dowarn) ++ warn("Invalid type in unpack: '%c'", (int)datumtype); ++ break; case '%': if (len == 1 && pat[-1] != '1') len = 16; @@@ -3479,6 -3479,6 +3552,7 @@@ PP(pp_pack char *aptr; float afloat; double adouble; ++ int commas = 0; items = SP - MARK; MARK++; @@@ -3502,6 -3502,6 +3576,10 @@@ switch(datumtype) { default: croak("Invalid type in pack: '%c'", (int)datumtype); ++ case ',': /* grandfather in commas but with a warning */ ++ if (commas++ == 0 && dowarn) ++ warn("Invalid type in pack: '%c'", (int)datumtype); ++ break; case '%': DIE("%% may only be used in unpack"); case '@': @@@ -4113,6 -4113,6 +4191,11 @@@ PP(pp_split } if (realarray) { SWITCHSTACK(ary, oldstack); ++ if (SvSMAGICAL(ary)) { ++ PUTBACK; ++ mg_set((SV*)ary); ++ SPAGAIN; ++ } if (gimme == G_ARRAY) { EXTEND(SP, iters); Copy(AvARRAY(ary), SP + 1, iters, SV*); diff --cc pp_hot.c index 82372d0,82372d0..e1f4476 --- a/pp_hot.c +++ b/pp_hot.c @@@ -76,68 -76,68 +76,6 @@@ PP(pp_gv RETURN; } --PP(pp_gelem) --{ -- GV *gv; -- SV *sv; -- SV *ref; -- char *elem; -- dSP; -- -- sv = POPs; -- elem = SvPV(sv, na); -- gv = (GV*)POPs; -- ref = Nullsv; -- sv = Nullsv; -- switch (elem ? *elem : '\0') -- { -- case 'A': -- if (strEQ(elem, "ARRAY")) -- ref = (SV*)GvAV(gv); -- break; -- case 'C': -- if (strEQ(elem, "CODE")) -- ref = (SV*)GvCVu(gv); -- break; -- case 'F': -- if (strEQ(elem, "FILEHANDLE")) /* XXX deprecate in 5.005 */ -- ref = (SV*)GvIOp(gv); -- break; -- case 'G': -- if (strEQ(elem, "GLOB")) -- ref = (SV*)gv; -- break; -- case 'H': -- if (strEQ(elem, "HASH")) -- ref = (SV*)GvHV(gv); -- break; -- case 'I': -- if (strEQ(elem, "IO")) -- ref = (SV*)GvIOp(gv); -- break; -- case 'N': -- if (strEQ(elem, "NAME")) -- sv = newSVpv(GvNAME(gv), GvNAMELEN(gv)); -- break; -- case 'P': -- if (strEQ(elem, "PACKAGE")) -- sv = newSVpv(HvNAME(GvSTASH(gv)), 0); -- break; -- case 'S': -- if (strEQ(elem, "SCALAR")) -- ref = GvSV(gv); -- break; -- } -- if (ref) -- sv = newRV(ref); -- if (sv) -- sv_2mortal(sv); -- else -- sv = &sv_undef; -- XPUSHs(sv); -- RETURN; --} -- PP(pp_and) { dSP; @@@ -628,7 -628,7 +566,8 @@@ PP(pp_aassign *(relem++) = sv; didstore = av_store(ary,i++,sv); if (magic) { -- mg_set(sv); ++ if (SvSMAGICAL(sv)) ++ mg_set(sv); if (!didstore) SvREFCNT_dec(sv); } @@@ -655,13 -655,13 +594,14 @@@ *(relem++) = tmpstr; didstore = hv_store_ent(hash,sv,tmpstr,0); if (magic) { -- mg_set(tmpstr); ++ if (SvSMAGICAL(tmpstr)) ++ mg_set(tmpstr); if (!didstore) SvREFCNT_dec(tmpstr); } TAINT_NOT; } -- if (relem == lastrelem) ++ if (relem == lastrelem && dowarn) warn("Odd number of elements in hash list"); } break; @@@ -1755,8 -1755,8 +1695,11 @@@ PP(pp_entersub if (!SvROK(sv)) { char *sym; -- if (sv == &sv_yes) /* unfound import, ignore */ ++ if (sv == &sv_yes) { /* unfound import, ignore */ ++ if (hasargs) ++ SP = stack_base + POPMARK; RETURN; ++ } if (SvGMAGICAL(sv)) { mg_get(sv); sym = SvPOKp(sv) ? SvPVX(sv) : Nullch; @@@ -2089,6 -2089,6 +2032,14 @@@ PP(pp_method char* packname; STRLEN packlen; ++ if (SvROK(TOPs)) { ++ sv = SvRV(TOPs); ++ if (SvTYPE(sv) == SVt_PVCV) { ++ SETs(sv); ++ RETURN; ++ } ++ } ++ name = SvPV(TOPs, na); sv = *(stack_base + TOPMARK + 1); diff --cc pp_sys.c index d0915e0,d0915e0..d574b2e --- a/pp_sys.c +++ b/pp_sys.c @@@ -1369,7 -1369,7 +1369,7 @@@ PP(pp_send if (-offset > blen) DIE("Offset outside string"); offset += blen; -- } else if (offset >= blen) ++ } else if (offset >= blen && blen > 0) DIE("Offset outside string"); } else offset = 0; @@@ -2402,16 -2402,16 +2402,20 @@@ PP(pp_fttty dSP; int fd; GV *gv; -- char *tmps; -- if (op->op_flags & OPf_REF) { ++ char *tmps = Nullch; ++ ++ if (op->op_flags & OPf_REF) gv = cGVOP->op_gv; -- tmps = ""; -- } ++ else if (isGV(TOPs)) ++ gv = (GV*)POPs; ++ else if (SvROK(TOPs) && isGV(SvRV(TOPs))) ++ gv = (GV*)SvRV(POPs); else gv = gv_fetchpv(tmps = POPp, FALSE, SVt_PVIO); ++ if (GvIO(gv) && IoIFP(GvIOp(gv))) fd = PerlIO_fileno(IoIFP(GvIOp(gv))); -- else if (isDIGIT(*tmps)) ++ else if (tmps && isDIGIT(*tmps)) fd = atoi(tmps); else RETPUSHUNDEF; @@@ -2705,6 -2705,6 +2709,9 @@@ PP(pp_readlink char buf[MAXPATHLEN]; int len; ++#ifndef INCOMPLETE_TAINTS ++ TAINT; ++#endif tmps = POPp; len = readlink(tmps, buf, sizeof buf); EXTEND(SP, 1); @@@ -2881,6 -2881,6 +2888,7 @@@ PP(pp_readdir register Direntry_t *dp; GV *gv = (GV*)POPs; register IO *io = GvIOn(gv); ++ SV *sv; if (!io || !IoDIRP(io)) goto nope; @@@ -2889,20 -2889,20 +2897,28 @@@ /*SUPPRESS 560*/ while (dp = (Direntry_t *)readdir(IoDIRP(io))) { #ifdef DIRNAMLEN -- XPUSHs(sv_2mortal(newSVpv(dp->d_name, dp->d_namlen))); ++ sv = newSVpv(dp->d_name, dp->d_namlen); #else -- XPUSHs(sv_2mortal(newSVpv(dp->d_name, 0))); ++ sv = newSVpv(dp->d_name, 0); ++#endif ++#ifndef INCOMPLETE_TAINTS ++ SvTAINTED_on(sv); #endif ++ XPUSHs(sv_2mortal(sv)); } } else { if (!(dp = (Direntry_t *)readdir(IoDIRP(io)))) goto nope; #ifdef DIRNAMLEN -- XPUSHs(sv_2mortal(newSVpv(dp->d_name, dp->d_namlen))); ++ sv = newSVpv(dp->d_name, dp->d_namlen); #else -- XPUSHs(sv_2mortal(newSVpv(dp->d_name, 0))); ++ sv = newSVpv(dp->d_name, 0); #endif ++#ifndef INCOMPLETE_TAINTS ++ SvTAINTED_on(sv); ++#endif ++ XPUSHs(sv_2mortal(sv)); } RETURN; @@@ -4063,6 -4063,6 +4079,9 @@@ PP(pp_gpwent #endif PUSHs(sv = sv_mortalcopy(&sv_no)); sv_setpv(sv, pwent->pw_gecos); ++#ifndef INCOMPLETE_TAINTS ++ SvTAINTED_on(sv); ++#endif PUSHs(sv = sv_mortalcopy(&sv_no)); sv_setpv(sv, pwent->pw_dir); PUSHs(sv = sv_mortalcopy(&sv_no)); diff --cc proto.h index 84b8f06,84b8f06..463b498 --- a/proto.h +++ b/proto.h @@@ -23,6 -23,6 +23,7 @@@ I32 av_len _((AV* ar)) AV* av_make _((I32 size, SV** svp)); SV* av_pop _((AV* ar)); void av_push _((AV* ar, SV* val)); ++void av_reify _((AV* ar)); SV* av_shift _((AV* ar)); SV** av_store _((AV* ar, I32 key, SV* val)); void av_undef _((AV* ar)); @@@ -223,6 -223,6 +224,7 @@@ int magic_setsubstr _((SV* sv, MAGIC* m int magic_settaint _((SV* sv, MAGIC* mg)); int magic_setuvar _((SV* sv, MAGIC* mg)); int magic_setvec _((SV* sv, MAGIC* mg)); ++int magic_set_all_env _((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)); @@@ -316,7 -316,7 +318,8 @@@ SV* newSVpvf _((const char* pat, ...)) SV* newSVrv _((SV* rv, char* classname)); SV* newSVsv _((SV* old)); OP* newUNOP _((I32 type, I32 flags, OP* first)); --OP* newWHILEOP _((I32 flags, I32 debuggable, LOOP* loop, OP* expr, OP* block, OP* cont)); ++OP* newWHILEOP _((I32 flags, I32 debuggable, LOOP* loop, ++ I32 whileline, OP* expr, OP* block, OP* cont)); PerlIO* nextargv _((GV* gv)); char* ninstr _((char* big, char* bigend, char* little, char* lend)); OP* oopsCV _((OP* o)); diff --cc regcomp.c index 3e30253,3e30253..d99d6c7 --- a/regcomp.c +++ b/regcomp.c @@@ -257,8 -257,8 +257,8 @@@ PMOP* pm if (sawplus && (!sawopen || !regsawback)) r->reganch |= ROPT_SKIP; /* x+ must match 1st of run */ -- DEBUG_r(PerlIO_printf(Perl_debug_log, "first %d next %d offset %d\n", -- OP(first), OP(NEXTOPER(first)), first - scan)); ++ DEBUG_r(PerlIO_printf(Perl_debug_log, "first %d next %d offset %ld\n", ++ OP(first), OP(NEXTOPER(first)), (long)(first - scan))); /* * If there's something expensive in the r.e., find the * longest literal string that must appear and make it the @@@ -702,7 -702,7 +702,7 @@@ I32 *flagp } if (!(flags&HASWIDTH) && op != '?') -- FAIL("regexp *+ operand could be empty"); ++ FAIL("regexp *+ operand could be empty"); /* else may core dump */ nextchar(); @@@ -1539,13 -1539,13 +1539,13 @@@ regexp *r op = OP(s); /* where, what */ regprop(sv, s); -- PerlIO_printf(Perl_debug_log, "%2d%s", s - r->program, SvPVX(sv)); ++ PerlIO_printf(Perl_debug_log, "%2ld%s", (long)(s - r->program), SvPVX(sv)); next = regnext(s); s += regarglen[(U8)op]; if (next == NULL) /* Next ptr. */ PerlIO_printf(Perl_debug_log, "(0)"); else -- PerlIO_printf(Perl_debug_log, "(%d)", (s-r->program)+(next-s)); ++ PerlIO_printf(Perl_debug_log, "(%ld)", (long)(s-r->program)+(next-s)); s += 3; if (op == ANYOF) { s += 33; diff --cc regexec.c index 271dc4d,271dc4d..c640d67 --- a/regexec.c +++ b/regexec.c @@@ -143,7 -143,7 +143,8 @@@ regcppop( * 0 > length [ "foobar" =~ / ( (foo) | (bar) )* /x ]->[1] */ static void --regcppartblow() ++regcppartblow(base) ++I32 base; { I32 i = SSPOPINT; U32 paren; @@@ -160,6 -160,6 +161,7 @@@ if (paren <= *reglastparen && regendp[paren] == endp) regstartp[paren] = startp; } ++ assert(savestack_ix == base); } #define regcpblow(cp) leave_scope(cp) @@@ -664,8 -664,8 +666,8 @@@ char *prog if (regnarrate) { SV *prop = sv_newmortal(); regprop(prop, scan); -- PerlIO_printf(Perl_debug_log, "%*s%2d%-8.8s\t<%.10s>\n", -- regindent*2, "", scan - regprogram, ++ PerlIO_printf(Perl_debug_log, "%*s%2ld%-8.8s\t<%.10s>\n", ++ regindent*2, "", (long)(scan - regprogram), SvPVX(prop), locinput); } #else diff --cc scope.c index 98d99a4,98d99a4..3006f1a --- a/scope.c +++ b/scope.c @@@ -165,7 -165,7 +165,12 @@@ save_gp(gv, empty GV *gv; I32 empty; { -- SSCHECK(3); ++ SSCHECK(6); ++ SSPUSHIV((IV)SvLEN(gv)); ++ SvLEN(gv) = 0; /* forget that anything was allocated here */ ++ SSPUSHIV((IV)SvCUR(gv)); ++ SSPUSHPTR(SvPVX(gv)); ++ SvPOK_off(gv); SSPUSHPTR(SvREFCNT_inc(gv)); SSPUSHPTR(GvGP(gv)); SSPUSHINT(SAVEt_GP); @@@ -188,26 -188,26 +193,50 @@@ AV save_ary(gv) GV *gv; { ++ AV *oav, *av; ++ SSCHECK(3); SSPUSHPTR(gv); -- SSPUSHPTR(GvAVn(gv)); ++ SSPUSHPTR(oav = GvAVn(gv)); SSPUSHINT(SAVEt_AV); GvAV(gv) = Null(AV*); -- return GvAVn(gv); ++ av = GvAVn(gv); ++ if (SvMAGIC(oav)) { ++ SvMAGIC(av) = SvMAGIC(oav); ++ SvFLAGS(av) |= SvMAGICAL(oav); ++ SvMAGICAL_off(oav); ++ SvMAGIC(oav) = 0; ++ localizing = 1; ++ SvSETMAGIC((SV*)av); ++ localizing = 0; ++ } ++ return av; } HV * save_hash(gv) GV *gv; { ++ HV *ohv, *hv; ++ SSCHECK(3); SSPUSHPTR(gv); -- SSPUSHPTR(GvHVn(gv)); ++ SSPUSHPTR(ohv = GvHVn(gv)); SSPUSHINT(SAVEt_HV); GvHV(gv) = Null(HV*); -- return GvHVn(gv); ++ hv = GvHVn(gv); ++ if (SvMAGIC(ohv)) { ++ SvMAGIC(hv) = SvMAGIC(ohv); ++ SvFLAGS(hv) |= SvMAGICAL(ohv); ++ SvMAGICAL_off(ohv); ++ SvMAGIC(ohv) = 0; ++ localizing = 1; ++ SvSETMAGIC((SV*)hv); ++ localizing = 0; ++ } ++ return hv; } void @@@ -463,14 -463,14 +492,38 @@@ I32 base case SAVEt_AV: /* array reference */ av = (AV*)SSPOPPTR; gv = (GV*)SSPOPPTR; -- SvREFCNT_dec(GvAV(gv)); ++ if (GvAV(gv)) { ++ AV *goner = GvAV(gv); ++ SvMAGIC(av) = SvMAGIC(goner); ++ SvFLAGS(av) |= SvMAGICAL(goner); ++ SvMAGICAL_off(goner); ++ SvMAGIC(goner) = 0; ++ SvREFCNT_dec(goner); ++ } GvAV(gv) = av; ++ if (SvMAGICAL(av)) { ++ localizing = 2; ++ SvSETMAGIC((SV*)av); ++ localizing = 0; ++ } break; case SAVEt_HV: /* hash reference */ hv = (HV*)SSPOPPTR; gv = (GV*)SSPOPPTR; -- SvREFCNT_dec(GvHV(gv)); ++ if (GvHV(gv)) { ++ HV *goner = GvHV(gv); ++ SvMAGIC(hv) = SvMAGIC(goner); ++ SvFLAGS(hv) |= SvMAGICAL(goner); ++ SvMAGICAL_off(goner); ++ SvMAGIC(goner) = 0; ++ SvREFCNT_dec(goner); ++ } GvHV(gv) = hv; ++ if (SvMAGICAL(hv)) { ++ localizing = 2; ++ SvSETMAGIC((SV*)hv); ++ localizing = 0; ++ } break; case SAVEt_INT: /* int reference */ ptr = SSPOPPTR; @@@ -512,11 -512,11 +565,17 @@@ gv = (GV*)SSPOPPTR; (void)sv_clear((SV*)gv); break; -- case SAVEt_GP: /* scalar reference */ ++ case SAVEt_GP: /* scalar reference */ ptr = SSPOPPTR; gv = (GV*)SSPOPPTR; gp_free(gv); GvGP(gv) = (GP*)ptr; ++ if (SvPOK(gv) && SvLEN(gv) > 0) { ++ Safefree(SvPVX(gv)); ++ } ++ SvPVX(gv) = (char *)SSPOPPTR; ++ SvCUR(gv) = (STRLEN)SSPOPIV; ++ SvLEN(gv) = (STRLEN)SSPOPIV; SvREFCNT_dec(gv); break; case SAVEt_FREESV: @@@ -615,7 -615,7 +674,7 @@@ voi cx_dump(cx) CONTEXT* cx; { -- PerlIO_printf(Perl_debug_log, "CX %d = %s\n", cx - cxstack, block_type[cx->cx_type]); ++ PerlIO_printf(Perl_debug_log, "CX %ld = %s\n", (long)(cx - cxstack), block_type[cx->cx_type]); if (cx->cx_type != CXt_SUBST) { PerlIO_printf(Perl_debug_log, "BLK_OLDSP = %ld\n", (long)cx->blk_oldsp); PerlIO_printf(Perl_debug_log, "BLK_OLDCOP = 0x%lx\n", (long)cx->blk_oldcop); diff --cc sv.c index 6e40732,6e40732..d9596cb --- a/sv.c +++ b/sv.c @@@ -3005,7 -3005,7 +3005,7 @@@ sv_collxfrm(sv, nxp if (SvREADONLY(sv)) { SAVEFREEPV(xf); *nxp = xlen; -- return xf; ++ return xf + sizeof(collation_ix); } if (! mg) { sv_magic(sv, 0, 'o', 0, 0); @@@ -3215,8 -3215,8 +3215,8 @@@ thats_really_all_folks *bp = '\0'; SvCUR_set(sv, bp - (STDCHAR*)SvPVX(sv)); /* set length */ DEBUG_P(PerlIO_printf(Perl_debug_log, -- "Screamer: done, len=%d, string=|%.*s|\n", -- SvCUR(sv),(int)SvCUR(sv),SvPVX(sv))); ++ "Screamer: done, len=%ld, string=|%.*s|\n", ++ (long)SvCUR(sv),(int)SvCUR(sv),SvPVX(sv))); } else { @@@ -4122,7 -4122,7 +4122,6 @@@ IV iv int sign; UV uv; char *p; -- int i; sv_setpvn(sv, "", 0); if (iv >= 0) { @@@ -4649,10 -4649,10 +4648,21 @@@ sv_vcatpvfn(sv, pat, patlen, args, svar sv_catpv(msg, "end of string"); warn("%_", msg); /* yes, this is reentrant */ } -- /* output mangled stuff */ ++ ++ /* output mangled stuff ... */ ++ if (c == '\0') ++ --q; eptr = p; elen = q - p; -- break; ++ ++ /* ... right here, because formatting flags should not apply */ ++ SvGROW(sv, SvCUR(sv) + elen + 1); ++ p = SvEND(sv); ++ memcpy(p, eptr, elen); ++ p += elen; ++ *p = '\0'; ++ SvCUR(sv) = p - SvPVX(sv); ++ continue; /* not "break" */ } have = esignlen + zeros + elen; diff --cc t/comp/proto.t index 197ea78,197ea78..d1cfede --- a/t/comp/proto.t +++ b/t/comp/proto.t @@@ -16,7 -16,7 +16,7 @@@ BEGIN use strict; --print "1..74\n"; ++print "1..76\n"; my $i = 1; @@@ -375,3 -375,3 +375,16 @@@ sub an_array_ref (\@) an_array_ref @array; print "not " unless @array == 4; print @array; ++ ++# correctly note too-short parameter lists that don't end with '$', ++# a possible regression. ++ ++sub foo1 ($\@); ++eval q{ foo1 "s" }; ++print "not " unless $@ =~ /^Not enough/; ++print "ok ", $i++, "\n"; ++ ++sub foo2 ($\%); ++eval q{ foo2 "s" }; ++print "not " unless $@ =~ /^Not enough/; ++print "ok ", $i++, "\n"; diff --cc t/lib/complex.t index c05f40f,c05f40f..3390334 --- a/t/lib/complex.t +++ b/t/lib/complex.t @@@ -1,10 -1,10 +1,15 @@@ #!./perl --# $RCSfile$ ++# $RCSfile: complex.t,v $ # # Regression tests for the Math::Complex pacakge --# -- Raphael Manfredi, September 1996 --# -- Jarkko Hietaniemi, March-April 1997 ++# -- Raphael Manfredi September 1996 ++# -- Jarkko Hietaniemi March-October 1997 ++# -- Daniel S. Lewart September-October 1997 ++ ++$VERSION = '1.05'; ++ ++# $Id: complex.t,v 1.1 1997/10/15 10:02:15 jhi Exp jhi $ BEGIN { chdir 't' if -d 't'; @@@ -13,9 -13,9 +18,14 @@@ use Math::Complex; ++my ($args, $op, $target, $test, $test_set, $try, $val, $zvalue, @set, @val); ++ $test = 0; $| = 1; --@script = (); ++my @script = ( ++ 'my ($res, $s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10, $z0,$z1,$z2);' . ++ "\n\n" ++); my $eps = 1e-11; while () { @@@ -58,7 -58,7 +68,7 @@@ sub test_dbz # push(@script, qq(print "# '$op'\n";)); push(@script, qq(eval '$op';)); push(@script, qq(print 'not ' unless (\$@ =~ /Division by zero/);)); -- push(@script, qq(print "ok $test\n";)); ++ push(@script, qq( print "ok $test\\n";\n)); } } @@@ -71,7 -71,7 +81,7 @@@ sub test_loz # push(@script, qq(print "# '$op'\n";)); push(@script, qq(eval '$op';)); push(@script, qq(print 'not ' unless (\$@ =~ /Logarithm of zero/);)); -- push(@script, qq(print "ok $test\n";)); ++ push(@script, qq( print "ok $test\\n";\n)); } } @@@ -99,7 -99,7 +109,10 @@@ test_dbz 'acoth(1)', ); ++my $zero = cplx(0, 0); ++ test_loz( ++ 'log($zero)', 'atanh(-1)', 'acoth(-1)', ); @@@ -112,7 -112,7 +125,7 @@@ sub test_ztz # push(@script, qq(print "# 0**0\n";)); push(@script, qq(eval 'cplx(0)**cplx(0)';)); push(@script, qq(print 'not ' unless (\$@ =~ /zero raised to the/);)); -- push(@script, qq(print "ok $test\n";)); ++ push(@script, qq( print "ok $test\\n";\n)); } test_ztz; @@@ -126,7 -126,7 +139,7 @@@ sub test_broot # push(@script, qq(print "# root(2, $op)\n";)); push(@script, qq(eval 'root(2, $op)';)); push(@script, qq(print 'not ' unless (\$@ =~ /root must be/);)); -- push(@script, qq(print "ok $test\n";)); ++ push(@script, qq( print "ok $test\\n";\n)); } } @@@ -173,11 -173,11 +186,11 @@@ sub test # check the op= works push @script, <cartesian} : (\$z0, 0)); ++ my \$za = cplx(ref \$z0 ? \@{\$z0->cartesian} : (\$z0, 0)); my (\$z1r, \$z1i) = ref \$z1 ? \@{\$z1->cartesian} : (\$z1, 0); -- my \$zb = cplx(\$z1r, \$z1i); ++ my \$zb = cplx(\$z1r, \$z1i); \$za $op= \$zb; my (\$zbr, \$zbi) = \@{\$zb->cartesian}; @@@ -187,7 -187,7 +200,7 @@@ EO $test++; # check that the rhs has not changed push @script, qq(print "not " unless (\$zbr == \$z1r and \$zbi == \$z1i);); -- push @script, qq(print "ok $test\n";); ++ push @script, qq( print "ok $test\\n";\n); push @script, "}\n"; } } @@@ -249,6 -249,6 +262,17 @@@ sub check print "# '$try' expected: '$expected' got: '$got' for $args\n"; } } ++ ++sub addsq { ++ my ($z1, $z2) = @_; ++ return ($z1 + i*$z2) * ($z1 - i*$z2); ++} ++ ++sub subsq { ++ my ($z1, $z2) = @_; ++ return ($z1 + $z2) * ($z1 - $z2); ++} ++ __END__ &+;= (3,4):(3,4):(6,8) @@@ -372,13 -372,13 +396,13 @@@ |'abs(z)':'r' |'acot(z)':'acotan(z)' |'acsc(z)':'acosec(z)' --|'abs(acsc(z))':'abs(asin(1 / z))' --|'abs(asec(z))':'abs(acos(1 / z))' ++|'acsc(z)':'asin(1 / z)' ++|'asec(z)':'acos(1 / z)' |'cbrt(z)':'cbrt(r) * exp(i * t/3)' |'cos(acos(z))':'z' --|'cos(z) ** 2 + sin(z) ** 2':1 ++|'addsq(cos(z), sin(z))':1 |'cos(z)':'cosh(i*z)' --|'cosh(z) ** 2 - sinh(z) ** 2':1 ++|'subsq(cosh(z), sinh(z))':1 |'cot(acot(z))':'z' |'cot(z)':'1 / tan(z)' |'cot(z)':'cotan(z)' @@@ -430,6 -430,6 +454,20 @@@ |'atan(tan(z))':'z' |'atanh(tanh(z))':'z' ++&log ++(-2.0,0):( 0.69314718055995, 3.14159265358979) ++(-1.0,0):( 0 , 3.14159265358979) ++(-0.5,0):( -0.69314718055995, 3.14159265358979) ++( 0.5,0):( -0.69314718055995, 0 ) ++( 1.0,0):( 0 , 0 ) ++( 2.0,0):( 0.69314718055995, 0 ) ++ ++&log ++( 2, 3):( 1.28247467873077, 0.98279372324733) ++(-2, 3):( 1.28247467873077, 2.15879893034246) ++(-2,-3):( 1.28247467873077, -2.15879893034246) ++( 2,-3):( 1.28247467873077, -0.98279372324733) ++ &sin (-2.0,0):( -0.90929742682568, 0 ) (-1.0,0):( -0.84147098480790, 0 ) @@@ -777,3 -777,3 +815,4 @@@ ( 2,-3):( 0.14694666622553, 0.23182380450040) # eof ++ diff --cc t/lib/dosglob.t index e69de29,e69de29..7398a14 --- a/t/lib/dosglob.t +++ b/t/lib/dosglob.t @@@ -1,0 -1,0 +1,94 @@@ ++#!./perl ++ ++# ++# test glob() in File::DosGlob ++# ++ ++BEGIN { ++ chdir 't' if -d 't'; ++ @INC = '../lib'; ++} ++ ++print "1..9\n"; ++ ++# override it in main:: ++use File::DosGlob 'glob'; ++ ++# test if $_ takes as the default ++$_ = "lib/a*.t"; ++my @r = glob; ++print "not " if $_ ne 'lib/a*.t'; ++print "ok 1\n"; ++# we should have at least abbrev.t, anydbm.t, autoloader.t ++print "# |@r|\nnot " if @r < 3; ++print "ok 2\n"; ++ ++# check if <*/*> works ++@r = <*/a*.t>; ++# atleast {argv,abbrev,anydbm,autoloader,append,arith,array,assignwarn,auto}.t ++print "not " if @r < 9; ++print "ok 3\n"; ++my $r = scalar @r; ++ ++# check if scalar context works ++@r = (); ++while (defined($_ = <*/a*.t>)) { ++ print "# $_\n"; ++ push @r, $_; ++} ++print "not " if @r != $r; ++print "ok 4\n"; ++ ++# check if array context works ++@r = (); ++for (<*/a*.t>) { ++ print "# $_\n"; ++ push @r, $_; ++} ++print "not " if @r != $r; ++print "ok 5\n"; ++ ++# test if implicit assign to $_ in while() works ++@r = (); ++while (<*/a*.t>) { ++ print "# $_\n"; ++ push @r, $_; ++} ++print "not " if @r != $r; ++print "ok 6\n"; ++ ++# test if explicit glob() gets assign magic too ++my @s = (); ++while (glob '*/a*.t') { ++ print "# $_\n"; ++ push @s, $_; ++} ++print "not " if "@r" ne "@s"; ++print "ok 7\n"; ++ ++# how about in a different package, like? ++package Foo; ++use File::DosGlob 'glob'; ++@s = (); ++while (glob '*/a*.t') { ++ print "# $_\n"; ++ push @s, $_; ++} ++print "not " if "@r" ne "@s"; ++print "ok 8\n"; ++ ++# test if different glob ops maintain independent contexts ++@s = (); ++while (<*/a*.t>) { ++ my $i = 0; ++ print "# $_ <"; ++ push @s, $_; ++ while (<*/b*.t>) { ++ print " $_"; ++ $i++; ++ } ++ print " >\n"; ++} ++print "not " if "@r" ne "@s"; ++print "ok 9\n"; ++ diff --cc t/op/method.t index 21d7c8f,21d7c8f..d955705 --- a/t/op/method.t +++ b/t/op/method.t @@@ -4,7 -4,7 +4,7 @@@ # test method calls and autoloading. # --print "1..20\n"; ++print "1..24\n"; @A::ISA = 'B'; @B::ISA = 'C'; @@@ -25,6 -25,6 +25,14 @@@ test( A->d, "C::d"); # Update hash tab test (A->d, "D::d"); # Update hash table; { ++ local @A::ISA = qw(C); # Update hash table with split() assignment ++ test (A->d, "C::d"); ++ $#A::ISA = -1; ++ test (eval { A->d } || "fail", "fail"); ++} ++test (A->d, "D::d"); ++ ++{ local *B::d; eval 'sub B::d {"B::d1"}'; # Import now. test (A->d, "B::d1"); # Update hash table; @@@ -109,3 -109,3 +117,6 @@@ test(Y->f(), "B: In Y::f, 3"); # Which test(A->eee(), "new B: In A::eee, 4"); # We get a correct $autoload test(A->eee(), "new B: In A::eee, 4"); # Which sticks ++ ++# this test added due to bug discovery ++test(defined(@{"unknown_package::ISA"}) ? "defined" : "undefined", "undefined"); diff --cc t/op/misc.t index 660049b,660049b..6156ac2 --- a/t/op/misc.t +++ b/t/op/misc.t @@@ -1,5 -1,5 +1,8 @@@ #!./perl ++# NOTE: Please don't add tests to this file unless they *need* to be run in ++# separate executable and can't simply use eval. ++ chdir 't' if -d 't'; @INC = "../lib"; $ENV{PERL5LIB} = "../lib"; @@@ -18,8 -18,8 +21,8 @@@ $CAT = (($^O eq 'MSWin32') ? '.\perl - for (@prgs){ my $switch; -- if (s/^\s*-\w+//){ -- $switch = $&; ++ if (s/^\s*(-\w.*)//){ ++ $switch = $1; } my($prog,$expected) = split(/\nEXPECT\n/, $_); if ($^O eq 'MSWin32') { diff --cc t/op/ref.t index e83a04f,e83a04f..9fcc8ac --- a/t/op/ref.t +++ b/t/op/ref.t @@@ -1,6 -1,6 +1,6 @@@ #!./perl --print "1..50\n"; ++print "1..51\n"; # Test glob operations. @@@ -223,12 -223,12 +223,20 @@@ sub moe::DESTROY { print "# moe\nok 4 print "# left block\n"; ++# another glob test ++ ++$foo = "not ok 48"; ++{ local(*bar) = "foo" } ++$bar = "ok 48"; ++local(*bar) = *bar; ++print "$bar\n"; ++ package FINALE; { -- $ref3 = bless ["ok 50\n"]; # package destruction -- my $ref2 = bless ["ok 49\n"]; # lexical destruction -- local $ref1 = bless ["ok 48\n"]; # dynamic destruction ++ $ref3 = bless ["ok 51\n"]; # package destruction ++ my $ref2 = bless ["ok 50\n"]; # lexical destruction ++ local $ref1 = bless ["ok 49\n"]; # dynamic destruction 1; # flush any temp values on stack } diff --cc t/op/split.t index b449ba9,b449ba9..0724652 --- a/t/op/split.t +++ b/t/op/split.t @@@ -2,7 -2,7 +2,7 @@@ # $RCSfile: split.t,v $$Revision: 4.1 $$Date: 92/08/07 18:28:26 $ --print "1..16\n"; ++print "1..20\n"; $FS = ':'; @@@ -76,3 -76,3 +76,17 @@@ print "$a|$b" eq "2|4" ? "ok 15\n" : "n local(undef, $a, undef, $b) = qw(1 2 3 4); print "$a|$b" eq "2|4" ? "ok 16\n" : "not ok 16\n"; } ++ ++# check splitting of null string ++$_ = join('|', split(/x/, '',-1), 'Z'); ++print $_ eq "Z" ? "ok 17\n" : "#$_\nnot ok 17\n"; ++ ++$_ = join('|', split(/x/, '', 1), 'Z'); ++print $_ eq "Z" ? "ok 18\n" : "#$_\nnot ok 18\n"; ++ ++$_ = join('|', split(/(p+)/,'',-1), 'Z'); ++print $_ eq "Z" ? "ok 19\n" : "#$_\nnot ok 19\n"; ++ ++$_ = join('|', split(/.?/, '',-1), 'Z'); ++print $_ eq "Z" ? "ok 20\n" : "#$_\nnot ok 20\n"; ++ diff --cc t/op/sprintf.t index 8e1ef69,8e1ef69..1450ae3 --- a/t/op/sprintf.t +++ b/t/op/sprintf.t @@@ -2,7 -2,7 +2,32 @@@ # $RCSfile: sprintf.t,v $$Revision: 4.1 $$Date: 92/08/07 18:28:27 $ --print "1..1\n"; ++print "1..4\n"; ++$^W = 1; ++$SIG{__WARN__} = sub { ++ if ($_[0] =~ /^Invalid conversion/) { ++ $w++; ++ } else { ++ warn @_; ++ } ++}; ++ ++$w = 0; $x = sprintf("%3s %-4s%%foo %5d%c%3.1f","hi",123,456,65,3.0999); --if ($x eq ' hi 123 %foo 456A3.1') {print "ok 1\n";} else {print "not ok 1 '$x'\n";} ++if ($x eq ' hi 123 %foo 456A3.1' && $w == 0) { ++ print "ok 1\n"; ++} else { ++ print "not ok 1 '$x'\n"; ++} ++ ++for $i (2 .. 4) { ++ $f = ('%6 .6s', '%6. 6s', '%6.6 s')[$i - 2]; ++ $w = 0; ++ $x = sprintf($f, ''); ++ if ($x eq $f && $w == 1) { ++ print "ok $i\n"; ++ } else { ++ print "not ok $i '$x' '$f' '$w'\n"; ++ } ++} diff --cc t/op/subst.t index 3b4734e,3b4734e..efea970 --- a/t/op/subst.t +++ b/t/op/subst.t @@@ -2,7 -2,7 +2,7 @@@ # $RCSfile: s.t,v $$Revision: 4.1 $$Date: 92/08/07 18:28:22 $ --print "1..61\n"; ++print "1..62\n"; $x = 'foo'; $_ = "x"; @@@ -234,3 -234,3 +234,8 @@@ print exp_vars('foo $(DIR)/yyy bar',0) $_ = "abcd"; s/../$x = $&, m#.#/eg; print $x eq "cd" ? "ok 61\n" : "not ok 61\n"; ++ ++# check parsing of split subst with comment ++eval 's{foo} # this is a comment, not a delimiter ++ {bar};'; ++print @? ? "not ok 62\n" : "ok 62\n"; diff --cc t/op/taint.t index e170f28,e170f28..8437c43 --- a/t/op/taint.t +++ b/t/op/taint.t @@@ -82,7 -82,7 +82,7 @@@ print PROG 'print "@ARGV\n"', "\n" close PROG; my $echo = "$Invoke_Perl $ECHO"; --print "1..135\n"; ++print "1..140\n"; # First, let's make sure that Perl is checking the dangerous # environment variables. Maybe they aren't set yet, so we'll @@@ -515,3 -515,3 +515,60 @@@ else test 134, tainted $corge[1]; test 135, not tainted $corge[2]; } ++ ++# Test for system/library calls returning string data of dubious origin. ++{ ++ # No reliable %Config check for getpw* ++ if (eval { setpwent(); getpwent(); 1 }) { ++ setpwent(); ++ my @getpwent = getpwent(); ++ die "getpwent: $!\n" unless (@getpwent); ++ test 136,( not tainted $getpwent[0] ++ and not tainted $getpwent[1] ++ and not tainted $getpwent[2] ++ and not tainted $getpwent[3] ++ and not tainted $getpwent[4] ++ and not tainted $getpwent[5] ++ and tainted $getpwent[6] # gecos ++ and not tainted $getpwent[7] ++ and not tainted $getpwent[8]); ++ endpwent(); ++ } else { ++ print "# getpwent() is not available\n"; ++ print "ok 136\n"; ++ } ++ ++ if ($Config{d_readdir}) { # pretty hard to imagine not ++ local(*D); ++ opendir(D, "op") or die "opendir: $!\n"; ++ my $readdir = readdir(D); ++ test 137, tainted $readdir; ++ closedir(OP); ++ } else { ++ print "# readdir() is not available\n"; ++ print "ok 137\n"; ++ } ++ ++ if ($Config{d_readlink} && $Config{d_symlink}) { ++ my $symlink = "sl$$"; ++ unlink($symlink); ++ symlink("/something/naughty", $symlink) or die "symlink: $!\n"; ++ my $readlink = readlink($symlink); ++ test 138, tainted $readlink; ++ unlink($symlink); ++ } else { ++ print "# readlink() or symlink() is not available\n"; ++ print "ok 138\n"; ++ } ++} ++ ++# test bitwise ops (regression bug) ++{ ++ my $why = "y"; ++ my $j = "x" | $why; ++ test 139, not tainted $j; ++ $why = $TAINT."y"; ++ $j = "x" | $why; ++ test 140, tainted $j; ++} ++ diff --cc t/pragma/locale.t index e1ec5a8,e1ec5a8..8e296db --- a/t/pragma/locale.t +++ b/t/pragma/locale.t @@@ -394,13 -394,13 +394,26 @@@ for (map { chr } 0..255) } print "ok 101\n"; ++# Test for read-onlys. ++ ++{ ++ no locale; ++ $a = "qwerty"; ++ { ++ use locale; ++ print "not " if $a cmp "qwerty"; ++ } ++} ++print "ok 102\n"; ++ ++# This test must be the last one because its failure is not fatal. # The @Locale should be internally consistent. # Thanks to Hallvard Furuseth # for inventing a way to test for ordering consistency # without requiring any particular order. # ++$jhi;#@iki.fi --print "# testing 102\n"; ++print "# testing 103\n"; { my ($from, $to, $lesser, $greater, @test, %test, $test, $yes, $no, $sign); @@@ -422,14 -422,14 +435,14 @@@ ( $no.' ($lesser lt $greater)', # 0 $no.' ($lesser le $greater)', # 1 -- $no.' ($lesser ne $greater)', # 2 -- $yes.' ($lesser eq $greater)', # 3 ++ 'not ($lesser ne $greater)', # 2 ++ ' ($lesser eq $greater)', # 3 $yes.' ($lesser ge $greater)', # 4 $yes.' ($lesser gt $greater)', # 5 $yes.' ($greater lt $lesser )', # 6 $yes.' ($greater le $lesser )', # 7 -- $no.' ($greater ne $lesser )', # 8 -- $yes.' ($greater eq $lesser )', # 9 ++ 'not ($greater ne $lesser )', # 8 ++ ' ($greater eq $lesser )', # 9 $no.' ($greater ge $lesser )', # 10 $no.' ($greater gt $lesser )', # 11 'not (($lesser cmp $greater) == -$sign)' # 12 @@@ -438,7 -438,7 +451,7 @@@ $test = 0; for my $ti (@test) { $test{$ti} = eval $ti ; $test ||= $test{$ti} } if ($test) { -- print "# failed 102 at:\n"; ++ print "# failed 103 at:\n"; print "# lesser = '$lesser'\n"; print "# greater = '$greater'\n"; print "# lesser cmp greater = ", $lesser cmp $greater, "\n"; @@@ -453,11 -453,11 +466,10 @@@ print "\n"; } -- print 'not '; ++ warn "The locale definition on your system may have errors.\n"; last; } } } --print "ok 102\n"; # eof diff --cc taint.c index cd9e4ec,cd9e4ec..6776272 --- a/taint.c +++ b/taint.c @@@ -14,7 -14,7 +14,7 @@@ char *s { char *ug; -- DEBUG_u(PerlIO_printf(PerlIO_stderr(), ++ DEBUG_u(PerlIO_printf(Perl_debug_log, "%s %d %d %d\n", s, tainted, uid, euid)); if (tainted) { diff --cc toke.c index 276ebbb,276ebbb..b2e8aac --- a/toke.c +++ b/toke.c @@@ -66,6 -66,6 +66,8 @@@ static struct * can get by with a single comparison (if the compiler is smart enough). */ ++/* #define LEX_NOTPARSING 11 is done in perl.h. */ ++ #define LEX_NORMAL 10 #define LEX_INTERPNORMAL 9 #define LEX_INTERPCASEMOD 8 @@@ -3973,7 -3973,7 +3975,7 @@@ I32 len case 4: if (strEQ(d,"grep")) return KEY_grep; if (strEQ(d,"goto")) return KEY_goto; -- if (strEQ(d,"glob")) return -KEY_glob; ++ if (strEQ(d,"glob")) return KEY_glob; break; case 6: if (strEQ(d,"gmtime")) return -KEY_gmtime; @@@ -4950,13 -4950,13 +4952,8 @@@ char *start register char *to; I32 brackets = 1; -- if (isSPACE(*s)) { -- /* "#" is allowed as delimiter if on same line */ -- while (*s == ' ' || *s == '\t') -- s++; -- if (isSPACE(*s)) -- s = skipspace(s); -- } ++ if (isSPACE(*s)) ++ s = skipspace(s); CLINE; term = *s; multi_start = curcop->cop_line; diff --cc util.c index 2f222fa,2f222fa..819ab4e --- a/util.c +++ b/util.c @@@ -188,9 -188,9 +188,9 @@@ MEM_SIZE size size *= count; ptr = malloc(size?size:1); /* malloc(0) is NASTY on our system */ #if !(defined(I286) || defined(atarist)) -- DEBUG_m(PerlIO_printf(PerlIO_stderr(), "0x%x: (%05d) calloc %ld x %ld bytes\n",ptr,an++,(long)count,(long)size)); ++ DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%x: (%05d) calloc %ld x %ld bytes\n",ptr,an++,(long)count,(long)size)); #else -- DEBUG_m(PerlIO_printf(PerlIO_stderr(), "0x%lx: (%05d) calloc %ld x %ld bytes\n",ptr,an++,(long)count,(long)size)); ++ DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) calloc %ld x %ld bytes\n",ptr,an++,(long)count,(long)size)); #endif if (ptr != Nullch) { memset((void*)ptr, 0, size); @@@ -691,7 -691,7 +691,7 @@@ perl_init_i18nl10n(printwarn && strnNE(*e, "LC_ALL=", 7) && (p = strchr(*e, '='))) PerlIO_printf(PerlIO_stderr(), "\t%.*s = \"%s\",\n", -- (p - *e), *e, p + 1); ++ (int)(p - *e), *e, p + 1); } } diff --cc utils/h2ph.PL index d48571f,7c36f21..1b469da --- a/utils/h2ph.PL +++ b/utils/h2ph.PL @@@ -50,7 -50,7 +50,7 @@@ die "Destination directory $Dest_dir do short ushort u_short int uint u_int long ulong u_long -- FILE ++ FILE key_t caddr_t END @isatype{@isatype} = (1) x @isatype; @@@ -191,9 -191,9 +191,10 @@@ exit $Exit sub expr { while ($_ ne '') { ++ s/^\&//; # hack for things that take the address of s/^(\s+)// && do {$new .= ' '; next;}; s/^(0x[0-9a-fA-F]+)// && do {$new .= $1; next;}; -- s/^(\d+)[LlUu]*// && do {$new .= $1; next;}; ++ s/^(\d+)\s*[LlUu]*// && do {$new .= $1; next;}; s/^("(\\"|[^"])*")// && do {$new .= $1; next;}; s/^'((\\"|[^"])*)'// && do { if ($curargs{$1}) { diff --cc utils/perlbug.PL index 6b670fc,0827db8..724df6b --- a/utils/perlbug.PL +++ b/utils/perlbug.PL @@@ -26,18 -26,18 +26,22 @@@ open PATCH_LEVEL, "<../patchlevel.h" o my $patchlevel_date = (stat PATCH_LEVEL)[9]; while () { -- last if index($_, "static\tchar\t*local_patches[] = {") >= 0; ++ last if $_ =~ /^\s*static\s+char.*?local_patches\[\]\s*=\s*{\s*$/; }; --my $patches; ++my @patches; while () { -- last if /^}/; ++ last if /^\s*}/; chomp; s/^\s+,?"?//; s/"?,?$//; s/(['\\])/\\$1/g; -- $patches .= "'$_',\n" unless $_ eq 'NULL'; ++ push @patches, $_ unless $_ eq 'NULL'; }; ++my $patch_desc = "'" . join("',\n\t'", @patches) . "'"; ++my @patch_tags = map { my $p=$_; $p=~s/\s.*//; $p } @patches; ++my $patch_tags = join " ", map { "+$_" } @patch_tags; ++$patch_tags .= " " if $patch_tags; close PATCH_LEVEL; @@@ -56,8 -56,8 +60,13 @@@ $Config{startperl eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}' if \$running_under_some_shell; ++my \$config_tag1 = '$] - $Config{cf_time}'; ++ my \$patchlevel_date = $patchlevel_date; --my \@patches = ( $patches ); ++my \$patch_tags = '$patch_tags'; ++my \@patches = ( ++ $patch_desc ++); !GROK!THIS! # In the following, perl variables are not expanded during extraction. @@@ -80,7 -80,7 +89,7 @@@ use strict sub paraprint; --my($Version) = "1.19"; ++my($Version) = "1.20"; # Changed in 1.06 to skip Mail::Send and Mail::Util if not available. # Changed in 1.07 to see more sendmail execs, and added pipe output. @@@ -104,6 -104,6 +113,7 @@@ # Changed in 1.19 '-ok' default not '-v' # add local patch information # warn on '-ok' if this is an old system; add '-okay' ++# Changed in 1.20 Added patchlevel.h reading and version/config checks # TODO: - Allow the user to re-name the file on mail failure, and # make sure failure (transmission-wise) of Mail::Send is @@@ -114,6 -114,6 +124,8 @@@ my( $file, $usefile, $cc, $address, $pe $subject, $from, $verbose, $ed, $fh, $me, $Is_MSWin32, $Is_VMS, $msg, $body, $andcc, %REP, $ok); ++my $config_tag2 = "$] - $Config{cf_time}"; ++ Init(); if($::opt_h) { Help(); exit; } @@@ -204,8 -204,8 +216,8 @@@ EO $::opt_S = 1; # don't prompt for send $::opt_C = 1; # don't send a copy to the local admin $::opt_s = 1; -- $subject = "OK: perl $] on" -- ." $::Config{'osname'} $::Config{'osvers'} $subject"; ++ $subject = "OK: perl $] ${patch_tags}on" ++ ." $::Config{'archname'} $::Config{'osvers'} $subject"; $::opt_b = 1; $body = "Perl reported to build OK on this system.\n"; $ok = 1; @@@ -534,9 -531,9 +543,13 @@@ EO sub Dump { local(*OUT) = @_; -- print OUT <) { -- if(/^=head/) { -- close(TEST); -- return 1; -- } ++ my($file, $readit) = @_; ++ return 1 if !$readit && $file =~ /\.pod$/i; ++ local($_); ++ open(TEST,"<$file"); ++ while() { ++ if(/^=head/) { ++ close(TEST); ++ return 1; } -- close(TEST); -- return 0; ++ } ++ close(TEST); ++ return 0; } sub minus_f_nocase { my($file) = @_; # on a case-forgiving file system we can simply use -f $file if ($Is_VMS or $Is_MSWin32 or $^O eq 'os2') { -- return ( -f $file ) ? $file : ''; ++ return $file if -f $file and -r _; ++ warn "Ignored $file: unreadable\n" unless -r _; ++ return ''; } local *DIR; local($")="/"; my(@p,$p,$cip); foreach $p (split(/\//, $file)){ -- if (-d ("@p/$p")){ ++ my $try = "@p/$p"; ++ stat $try; ++ if (-d _){ push @p, $p; -- } elsif (-f ("@p/$p")) { -- return "@p/$p"; ++ if ( $p eq $global_target) { ++ $tmp_path = join ('/', @p); ++ my $path_f = 0; ++ for (@global_found) { ++ $path_f = 1 if $_ eq $tmp_path; ++ } ++ push (@global_found, $tmp_path) unless $path_f; ++ print STDERR "Found as @p but directory\n" if $opt_v; ++ } ++ } elsif (-f _ && -r _) { ++ return $try; ++ } elsif (-f _) { ++ warn "Ignored $try: unreadable\n"; } else { my $found=0; my $lcp = lc $p; @@@ -161,49 -162,53 +189,64 @@@ closedir DIR; return "" unless $found; push @p, $cip; -- return "@p" if -f "@p"; ++ return "@p" if -f "@p" and -r _; ++ warn "Ignored $file: unreadable\n" if -f _; } } return; # is not a file -- } ++} -- sub searchfor { -- my($recurse,$s,@dirs) = @_; -- $s =~ s!::!/!g; -- $s = VMS::Filespec::unixify($s) if $Is_VMS; -- return $s if -f $s && containspod($s); -- printf STDERR "looking for $s in @dirs\n" if $opt_v; -- my $ret; -- my $i; -- my $dir; -- for ($i=0;$i<@dirs;$i++) { -- $dir = $dirs[$i]; -- ($dir = VMS::Filespec::unixpath($dir)) =~ s!/$!! if $Is_VMS; -- if (( $ret = minus_f_nocase "$dir/$s.pod") -- or ( $ret = minus_f_nocase "$dir/$s.pm" and containspod($ret)) -- or ( $ret = minus_f_nocase "$dir/$s" and containspod($ret)) -- or ( $Is_VMS and -- $ret = minus_f_nocase "$dir/$s.com" and containspod($ret)) ++ ++sub check_file { ++ my($file) = @_; ++ return minus_f_nocase($file) && containspod($file) ? $file : ""; ++} ++ ++ ++sub searchfor { ++ my($recurse,$s,@dirs) = @_; ++ $s =~ s!::!/!g; ++ $s = VMS::Filespec::unixify($s) if $Is_VMS; ++ return $s if -f $s && containspod($s); ++ printf STDERR "Looking for $s in @dirs\n" if $opt_v; ++ my $ret; ++ my $i; ++ my $dir; ++ $global_target = (split('/', $s))[-1]; ++ for ($i=0; $i<@dirs; $i++) { ++ $dir = $dirs[$i]; ++ ($dir = VMS::Filespec::unixpath($dir)) =~ s!/$!! if $Is_VMS; ++ if ( ( $ret = check_file "$dir/$s.pod") ++ or ( $ret = check_file "$dir/$s.pm") ++ or ( $ret = check_file "$dir/$s") ++ or ( $Is_VMS and ++ $ret = check_file "$dir/$s.com") or ( $^O eq 'os2' and -- $ret = minus_f_nocase "$dir/$s.cmd" and containspod($ret)) ++ $ret = check_file "$dir/$s.cmd") or ( ($Is_MSWin32 or $^O eq 'os2') and -- $ret = minus_f_nocase "$dir/$s.bat" and containspod($ret)) -- or ( $ret = minus_f_nocase "$dir/pod/$s.pod") -- or ( $ret = minus_f_nocase "$dir/pod/$s" and containspod($ret))) -- { return $ret; } -- -- if($recurse) { -- opendir(D,$dir); - my(@newdirs) = grep(-d,map("$dir/$_",grep(!/^\.\.?$/,readdir(D)))); - closedir(D); - @newdirs = map((s/.dir$//,$_)[1],@newdirs) if $Is_VMS; - next unless @newdirs; - print STDERR "Also looking in @newdirs\n" if $opt_v; - push(@dirs,@newdirs); - } - } - return (); - } - my @newdirs = map "$dir/$_", grep { - not /^\.\.?$/ and - not /^auto$/ and # save time! don't search auto dirs - -d "$dir/$_" - } readdir D; - closedir(D); - @newdirs = map((s/.dir$//,$_)[1],@newdirs) if $Is_VMS; - next unless @newdirs; - print STDERR "Also looking in @newdirs\n" if $opt_v; - push(@dirs,@newdirs); - } - } - return (); - } ++ $ret = check_file "$dir/$s.bat") ++ or ( $ret = check_file "$dir/pod/$s.pod") ++ or ( $ret = check_file "$dir/pod/$s") ++ ) { ++ return $ret; ++ } ++ ++ if ($recurse) { ++ opendir(D,$dir); ++ my @newdirs = map "$dir/$_", grep { ++ not /^\.\.?$/ and ++ not /^auto$/ and # save time! don't search auto dirs ++ -d "$dir/$_" ++ } readdir D; ++ closedir(D); ++ next unless @newdirs; ++ @newdirs = map((s/.dir$//,$_)[1],@newdirs) if $Is_VMS; ++ print STDERR "Also looking in @newdirs\n" if $opt_v; ++ push(@dirs,@newdirs); ++ } ++ } ++ return (); ++} foreach (@pages) { @@@ -230,12 -235,12 +273,24 @@@ @searchdirs = grep(!/^\.$/,@INC); -- @files= searchfor(1,$_,@searchdirs); if( @files ) { print STDERR "Loosely found as @files\n" if $opt_v; } else { -- print STDERR "No documentation found for '$_'\n"; ++ print STDERR "No documentation found for \"$_\".\n"; ++ if (@global_found) { ++ print STDERR "However, try\n"; ++ my $dir = $file = ""; ++ for $dir (@global_found) { ++ opendir(DIR, $dir) or die "$!"; ++ while ($file = readdir(DIR)) { ++ next if ($file =~ /^\./); ++ $file =~ s/\.(pm|pod)$//; ++ print STDERR "\tperldoc $_\::$file\n"; ++ } ++ closedir DIR; ++ } ++ } } } push(@found,@files); @@@ -290,13 -295,13 +345,16 @@@ if ($opt_f) # Look for our function my $found = 0; ++ my @pod; while () { if (/^=item\s+\Q$opt_f\E\b/o) { -- $found++; ++ $found = 1; } elsif (/^=item/) { -- last if $found; ++ last if $found > 1; } -- push(@pod, $_) if $found; ++ next unless $found; ++ push @pod, $_; ++ ++$found if /^\w/; # found descriptive text } if (@pod) { if ($opt_t) { diff --cc vms/perly_c.vms index 60b0f54,60b0f54..ded0cf4 --- a/vms/perly_c.vms +++ b/vms/perly_c.vms @@@ -1646,7 -1646,7 +1646,7 @@@ case 27 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))); } ++ yyvsp[-6].ival, yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval))); } break; case 28: #line 192 "perly.y" @@@ -1654,7 -1654,7 +1654,7 @@@ 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))); } ++ yyvsp[-6].ival, yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval))); } break; case 29: #line 198 "perly.y" @@@ -1674,19 -1674,19 +1674,19 @@@ case 31 break; case 32: #line 209 "perly.y" --{ copline = yyvsp[-9].ival; -- yyval.opval = block_end(yyvsp[-7].ival, -- newSTATEOP(0, yyvsp[-10].pval, -- append_elem(OP_LINESEQ, scalar(yyvsp[-6].opval), -- newWHILEOP(0, 1, (LOOP*)Nullop, -- scalar(yyvsp[-4].opval), -- yyvsp[0].opval, scalar(yyvsp[-2].opval))))); } ++{ OP *forop = append_elem(OP_LINESEQ, ++ scalar(yyvsp[-6].opval), ++ newWHILEOP(0, 1, (LOOP*)Nullop, ++ yyvsp[-9].ival, scalar(yyvsp[-4].opval), ++ yyvsp[0].opval, scalar(yyvsp[-2].opval))); ++ copline = yyvsp[-9].ival; ++ yyval.opval = block_end(yyvsp[-7].ival, newSTATEOP(0, yyvsp[-10].pval, forop)); } break; case 33: #line 217 "perly.y" --{ yyval.opval = newSTATEOP(0, -- yyvsp[-2].pval, newWHILEOP(0, 1, (LOOP*)Nullop, -- Nullop, yyvsp[-1].opval, yyvsp[0].opval)); } ++{ yyval.opval = newSTATEOP(0, yyvsp[-2].pval, ++ newWHILEOP(0, 1, (LOOP*)Nullop, ++ NOLINE, Nullop, yyvsp[-1].opval, yyvsp[0].opval)); } break; case 34: #line 223 "perly.y" diff --cc win32/Makefile index 9e4437f,9e4437f..7a98f84 --- a/win32/Makefile +++ b/win32/Makefile @@@ -201,6 -201,6 +201,11 @@@ WIN32_OBJ = win32.obj win32io.obj \ win32sck.obj ++PERL95_OBJ = perl95.obj \ ++ win32mt.obj \ ++ win32iomt.obj \ ++ win32sckmt.obj ++ DLL_OBJ = perllib.obj $(DYNALOADER).obj CORE_H = ..\av.h \ @@@ -356,9 -356,9 +361,15 @@@ perl95.obj : perl95. win32iomt.obj : win32io.c $(CC) $(CFLAGS) -MT -c $(OBJOUT_FLAG)win32iomt.obj win32io.c --$(PERL95EXE): $(PERLDLL) $(CONFIGPM) perl95.obj win32iomt.obj ++win32sckmt.obj : win32sck.c ++ $(CC) $(CFLAGS) -MT -c $(OBJOUT_FLAG)win32sckmt.obj win32sck.c ++ ++win32mt.obj : win32.c ++ $(CC) $(CFLAGS) -MT -c $(OBJOUT_FLAG)win32mt.obj win32.c ++ ++$(PERL95EXE): $(PERLDLL) $(CONFIGPM) $(PERL95_OBJ) $(LINK32) -subsystem:console -out:perl95.exe $(LINK_FLAGS) \ -- perl95.obj win32iomt.obj $(PERLIMPLIB) ++ $(PERL95_OBJ) $(PERLIMPLIB) copy perl95.exe $@ del perl95.exe @@@ -469,10 -469,10 +480,18 @@@ minitest : $(MINIPERL) $(GLOBEXE) $(CON $(MINIPERL) -I..\lib test base/*.t comp/*.t cmd/*.t io/*.t op/*.t pragma/*.t cd ..\win32 --test : all ++test-prep : all $(XCOPY) $(PERLEXE) ..\t\$(NULL) $(XCOPY) $(PERLDLL) ..\t\$(NULL) $(XCOPY) $(GLOBEXE) ..\t\$(NULL) ++ ++test : test-prep ++ cd ..\t ++ $(PERLEXE) -I..\lib harness ++ cd ..\win32 ++ ++test-notty : test-prep ++ set PERL_SKIP_TTY_TEST=1 cd ..\t $(PERLEXE) -I..\lib harness cd ..\win32 diff --cc win32/makefile.mk index 4696dcb,4696dcb..dbac98f --- a/win32/makefile.mk +++ b/win32/makefile.mk @@@ -267,6 -267,6 +267,11 @@@ WIN32_OBJ = win32.obj win32io.obj \ win32sck.obj ++PERL95_OBJ = perl95.obj \ ++ win32mt.obj \ ++ win32iomt.obj \ ++ win32sckmt.obj ++ DLL_OBJ = perllib.obj $(DYNALOADER).obj CORE_H = ..\av.h \ @@@ -455,9 -455,9 +460,15 @@@ perl95.obj : perl95. win32iomt.obj : win32io.c $(CC) $(CFLAGS) -MT -c $(OBJOUT_FLAG)win32iomt.obj win32io.c --$(PERL95EXE): $(PERLDLL) $(CONFIGPM) perl95.obj win32iomt.obj ++win32sckmt.obj : win32sck.c ++ $(CC) $(CFLAGS) -MT -c $(OBJOUT_FLAG)win32sckmt.obj win32sck.c ++ ++win32mt.obj : win32.c ++ $(CC) $(CFLAGS) -MT -c $(OBJOUT_FLAG)win32mt.obj win32.c ++ ++$(PERL95EXE): $(PERLDLL) $(CONFIGPM) $(PERL95_OBJ) $(LINK32) -subsystem:console -out:perl95.exe $(LINK_FLAGS) \ -- perl95.obj win32iomt.obj $(PERLIMPLIB) ++ $(PERL95_OBJ) $(PERLIMPLIB) copy perl95.exe $@ del perl95.exe diff --cc win32/win32io.c index 12bc645,12bc645..eeb6846 --- a/win32/win32io.c +++ b/win32/win32io.c @@@ -238,6 -238,6 +238,7 @@@ my_flock(int fd, int oper #undef LK_ERR #undef LK_LEN ++EXT int my_fclose(FILE *pf); #ifdef PERLDLL __declspec(dllexport) @@@ -259,7 -259,7 +260,7 @@@ WIN32_IOSUBSYSTEM win32stdio = fopen, /* (*pfunc_fopen)(const char *path, const char *mode); */ fdopen, /* (*pfunc_fdopen)(int fh, const char *mode); */ freopen, /* (*pfunc_freopen)(const char *path, const char *mode, FILE *pf); */ -- fclose, /* (*pfunc_fclose)(FILE *pf); */ ++ my_fclose, /* (*pfunc_fclose)(FILE *pf); */ fputs, /* (*pfunc_fputs)(const char *s,FILE *pf); */ fputc, /* (*pfunc_fputc)(int c,FILE *pf); */ ungetc, /* (*pfunc_ungetc)(int c,FILE *pf); */ diff --cc win32/win32sck.c index d541a7e,d541a7e..3653fc8 --- a/win32/win32sck.c +++ b/win32/win32sck.c @@@ -227,11 -227,11 +227,11 @@@ myfdopen(int fd, char *mode int retval; if (hWinSockDll == 0) -- LoadWinSock(); ++ return(fdopen(fd, mode)); retval = pgetsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen); if(retval == SOCKET_ERROR && pWSAGetLastError() == WSAENOTSOCK) { -- return(_fdopen(fd, mode)); ++ return(fdopen(fd, mode)); } /* @@@ -258,7 -258,7 +258,7 @@@ u_lon win32_htonl(u_long hostlong) { if(hWinSockDll == 0) -- LoadWinSock(); ++ StartSockets(); return phtonl(hostlong); } @@@ -267,7 -267,7 +267,7 @@@ u_shor win32_htons(u_short hostshort) { if(hWinSockDll == 0) -- LoadWinSock(); ++ StartSockets(); return phtons(hostshort); } @@@ -276,7 -276,7 +276,7 @@@ u_lon win32_ntohl(u_long netlong) { if(hWinSockDll == 0) -- LoadWinSock(); ++ StartSockets(); return pntohl(netlong); } @@@ -285,7 -285,7 +285,7 @@@ u_shor win32_ntohs(u_short netshort) { if(hWinSockDll == 0) -- LoadWinSock(); ++ StartSockets(); return pntohs(netshort); } @@@ -503,6 -503,6 +503,22 @@@ win32_socket(int af, int type, int prot return s; } ++#undef fclose ++int ++my_fclose (FILE *pf) ++{ ++ int osf, retval; ++ if (hWinSockDll == 0) /* No WinSockDLL? */ ++ return(fclose(pf)); /* Then not a socket. */ ++ osf = TO_SOCKET(fileno(pf)); /* Get it now before it's gone! */ ++ retval = fclose(pf); /* Must fclose() before closesocket() */ ++ if (osf != -1 ++ && pclosesocket(osf) == SOCKET_ERROR ++ && WSAGetLastError() != WSAENOTSOCK) ++ retval = EOF; ++ return retval; ++} ++ struct hostent * win32_gethostbyaddr(const char *addr, int len, int type) { @@@ -576,7 -576,7 +592,7 @@@ char FAR win32_inet_ntoa(struct in_addr in) { if(hWinSockDll == 0) -- LoadWinSock(); ++ StartSockets(); return pinet_ntoa(in); } @@@ -585,7 -585,7 +601,7 @@@ unsigned lon win32_inet_addr(const char FAR *cp) { if(hWinSockDll == 0) -- LoadWinSock(); ++ StartSockets(); return pinet_addr(cp); diff --cc x2p/Makefile.SH index 0ca3ff3,0ca3ff3..65a3d75 --- a/x2p/Makefile.SH +++ b/x2p/Makefile.SH @@@ -132,7 -132,7 +132,7 @@@ lint lint $(lintflags) $(defs) $(c) > a2p.fuzz depend: $(mallocsrc) ../makedepend -- sh ../makedepend ++ sh ../makedepend MAKE=$(MAKE) clist: echo $(c) | tr ' ' '\012' >.clist diff --cc x2p/util.c index e8b666f,e8b666f..469beb0 --- a/x2p/util.c +++ b/x2p/util.c @@@ -33,8 -33,8 +33,8 @@@ MEM_SIZE size ptr = malloc(size ? size : 1); #ifdef DEBUGGING if (debug & 128) -- fprintf(stderr,"0x%lx: (%05d) malloc %d bytes\n",(unsigned long)ptr, -- an++,size); ++ fprintf(stderr,"0x%lx: (%05d) malloc %ld bytes\n",(unsigned long)ptr, ++ an++,(long)size); #endif if (ptr != Nullch) return ptr; @@@ -59,7 -59,7 +59,7 @@@ MEM_SIZE size #ifdef DEBUGGING if (debug & 128) { fprintf(stderr,"0x%lx: (%05d) rfree\n",(unsigned long)where,an++); -- fprintf(stderr,"0x%lx: (%05d) realloc %d bytes\n",(unsigned long)ptr,an++,size); ++ fprintf(stderr,"0x%lx: (%05d) realloc %ld bytes\n",(unsigned long)ptr,an++,(long)size); } #endif if (ptr != Nullch)