summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2000-02-22 17:10:22 +0000
committerJarkko Hietaniemi <jhi@iki.fi>2000-02-22 17:10:22 +0000
commitd3a4b2ba6901538e050a5a3fced30a16ff8fb9b0 (patch)
tree6a9ea92eb1a04fc898f4eb6457c778bf1cc1b7c5
parent68435ea717a7cd7f41241ff44917b542abd94222 (diff)
parentda2094fd55cfc73caee2f71b349588c60a542297 (diff)
downloadperl-d3a4b2ba6901538e050a5a3fced30a16ff8fb9b0.tar.gz
Integrate with Sarathy.
p4raw-id: //depot/cfgperl@5203
-rw-r--r--Changes187
-rw-r--r--MANIFEST2
-rw-r--r--README.epoc21
-rw-r--r--djgpp/config.over1
-rw-r--r--djgpp/configure.bat2
-rw-r--r--djgpp/djgppsed.sh3
-rw-r--r--epoc/config.sh39
-rw-r--r--epoc/createpkg.pl14
-rw-r--r--ext/B/B.xs9
-rw-r--r--ext/B/B/CC.pm44
-rw-r--r--ext/B/B/Deparse.pm72
-rw-r--r--ext/B/B/Xref.pm50
-rw-r--r--ext/IO/lib/IO/Socket/INET.pm14
-rw-r--r--ext/attrs/attrs.pm2
-rw-r--r--lib/English.pm5
-rwxr-xr-xlib/ExtUtils/xsubpp6
-rw-r--r--lib/Pod/Checker.pm400
-rw-r--r--lib/Pod/Find.pm16
-rw-r--r--lib/Pod/InputObjects.pm4
-rw-r--r--lib/Pod/ParseUtils.pm68
-rw-r--r--lib/Pod/Parser.pm118
-rw-r--r--lib/Pod/Select.pm4
-rw-r--r--lib/Pod/Usage.pm4
-rw-r--r--op.c6
-rw-r--r--perl.c5
-rw-r--r--pod/Win32.pod6
-rw-r--r--pod/perldelta.pod108
-rw-r--r--pod/perlfunc.pod62
-rw-r--r--pod/perlhist.pod1
-rw-r--r--pod/perlipc.pod2
-rw-r--r--pod/perlop.pod23
-rw-r--r--pod/perlthrtut.pod26
-rw-r--r--pod/perlvar.pod24
-rw-r--r--pod/perlxs.pod19
-rw-r--r--pp_ctl.c12
-rw-r--r--sv.c142
-rwxr-xr-xt/comp/require.t18
-rwxr-xr-xt/lib/glob-basic.t6
-rwxr-xr-xt/lib/glob-case.t5
-rwxr-xr-xt/lib/glob-global.t6
-rwxr-xr-xt/lib/glob-taint.t5
-rw-r--r--t/lib/io_unix.t1
-rwxr-xr-xt/op/ver.t55
-rwxr-xr-xt/pod/poderrs.t5
-rw-r--r--t/pod/poderrs.xr65
-rwxr-xr-xt/pod/special_seqs.t17
-rw-r--r--t/pod/special_seqs.xr13
-rw-r--r--t/pragma/warn/doop23
-rw-r--r--t/pragma/warn/pp22
-rw-r--r--t/pragma/warn/sv19
-rw-r--r--t/pragma/warn/toke19
-rw-r--r--t/pragma/warn/utf846
-rw-r--r--toke.c183
-rw-r--r--utils/perlbug.PL4
54 files changed, 1344 insertions, 689 deletions
diff --git a/Changes b/Changes
index aeac5505a6..05ebea5423 100644
--- a/Changes
+++ b/Changes
@@ -95,6 +95,193 @@ Version v5.5.660 Development release working toward v5.6
----------------
____________________________________________________________________________
+[ 5198] By: gsar on 2000/02/22 10:45:54
+ Log: PodParser-1.093 update (from Brad Appleton's site)
+ Branch: perl
+ ! lib/Pod/Checker.pm lib/Pod/Find.pm lib/Pod/InputObjects.pm
+ ! lib/Pod/ParseUtils.pm lib/Pod/Parser.pm lib/Pod/Select.pm
+ ! lib/Pod/Usage.pm t/pod/poderrs.t t/pod/poderrs.xr
+ ! t/pod/special_seqs.t t/pod/special_seqs.xr
+____________________________________________________________________________
+[ 5197] By: gsar on 2000/02/22 10:24:13
+ Log: integrate cfgperl contents into mainline, update Changes
+ Branch: perl
+ ! Changes pod/perlhist.pod
+ !> Configure Porting/Glossary Porting/config.sh Porting/config_H
+ !> config_h.SH hints/solaris_2.sh malloc.c perl.h
+ !> pod/perldelta.pod
+____________________________________________________________________________
+[ 5196] By: gsar on 2000/02/22 10:10:36
+ Log: dos-djgpp updates (from Laszlo Molnar <laszlo.molnar@eth.ericsson.se>)
+ Branch: perl
+ ! djgpp/config.over djgpp/configure.bat djgpp/djgppsed.sh
+ ! t/lib/glob-basic.t t/lib/glob-case.t t/lib/glob-global.t
+ ! t/lib/glob-taint.t t/lib/io_unix.t
+____________________________________________________________________________
+[ 5195] By: gsar on 2000/02/22 10:01:49
+ Log: s/undef/NO_INIT/g in change#5183
+ Branch: perl
+ ! lib/ExtUtils/xsubpp pod/perlxs.pod
+____________________________________________________________________________
+[ 5194] By: gsar on 2000/02/22 09:44:07
+ Log: perlipc bug (spotted by Ben Low)
+ Branch: perl
+ ! pod/perlipc.pod
+____________________________________________________________________________
+[ 5193] By: gsar on 2000/02/22 09:38:58
+ Log: EPOC port update (from Olaf Flebbe <O.Flebbe@science-computing.de>)
+ Branch: perl
+ ! README.epoc epoc/config.sh epoc/createpkg.pl perl.c
+____________________________________________________________________________
+[ 5192] By: gsar on 2000/02/22 09:26:06
+ Log: improvements for high-bit text literals (from Gisle Aas)
+ Branch: perl
+ ! t/pragma/warn/doop t/pragma/warn/pp t/pragma/warn/sv
+ ! t/pragma/warn/toke t/pragma/warn/utf8 toke.c
+____________________________________________________________________________
+[ 5191] By: gsar on 2000/02/22 07:35:47
+ Log: allow C<print v10>, $h{v13.10} etc.
+ Branch: perl
+ ! t/op/ver.t toke.c
+____________________________________________________________________________
+[ 5190] By: gsar on 2000/02/22 05:35:27
+ Log: adjust for lost fp precision in require version check
+ Branch: perl
+ ! pp_ctl.c t/comp/require.t
+____________________________________________________________________________
+[ 5189] By: jhi on 2000/02/22 05:14:35
+ Log: Check the alignment of long doubles if they are to be used;
+ regen Configure.
+ Branch: cfgperl
+ ! Configure Porting/Glossary Porting/config.sh Porting/config_H
+ ! config_h.SH
+ Branch: metaconfig
+ ! U/compline/alignbytes.U
+____________________________________________________________________________
+[ 5188] By: gsar on 2000/02/22 04:45:57
+ Log: use same treatment for EINVAL as for ETIMEDOUT
+ Branch: perl
+ ! ext/IO/lib/IO/Socket/INET.pm
+____________________________________________________________________________
+[ 5187] By: gsar on 2000/02/21 23:15:12
+ Log: type mismatch
+ Branch: perl
+ ! sv.c
+____________________________________________________________________________
+[ 5186] By: gsar on 2000/02/21 21:10:26
+ Log: remove dual-valueness of v-strings (i.e., they are pure strings
+ now); avoid the word "tuple" to describe strings represented as
+ character ordinals; usurp $PERL_VERSION for $^V as suggested by
+ Larry, deprecate $] ; adjust the documentation and testsuite
+ accordingly
+ Branch: perl
+ ! MANIFEST lib/English.pm op.c pod/perldelta.pod
+ ! pod/perlfunc.pod pod/perlop.pod pod/perlvar.pod
+ ! t/comp/require.t t/op/ver.t toke.c
+____________________________________________________________________________
+[ 5185] By: jhi on 2000/02/21 20:36:05
+ Log: detypo
+ Branch: cfgperl
+ ! perl.h
+____________________________________________________________________________
+[ 5184] By: gsar on 2000/02/21 18:37:38
+ Log: clarify "use Module VERSION LIST" (from Robin Barker)
+ Branch: perl
+ ! pod/perlfunc.pod
+____________________________________________________________________________
+[ 5183] By: gsar on 2000/02/21 18:31:42
+ Log: allow optional XSUB parameters without being forced to use a
+ default (from Hugo van der Sanden)
+ Branch: perl
+ ! lib/ExtUtils/xsubpp pod/perlfunc.pod pod/perlxs.pod
+____________________________________________________________________________
+[ 5182] By: jhi on 2000/02/21 18:22:47
+ Log: Add Solaris LP64 notes.
+ Branch: cfgperl
+ ! hints/solaris_2.sh
+____________________________________________________________________________
+[ 5181] By: gsar on 2000/02/21 16:53:39
+ Log: generalize "%v" format into a flag for any integral format type:
+ "%vd", "%v#o", "%*vX", etc are allowed
+ Branch: perl
+ ! perl.c pod/perldelta.pod pod/perlfunc.pod sv.c t/op/ver.t
+ ! utils/perlbug.PL
+____________________________________________________________________________
+[ 5180] By: gsar on 2000/02/21 07:11:00
+ Log: detypo
+ Branch: perl
+ ! ext/B/B.xs
+____________________________________________________________________________
+[ 5179] By: gsar on 2000/02/21 07:08:38
+ Log: undo accidental delete
+ Branch: perl
+ ! ext/B/B.pm ext/B/B.xs
+____________________________________________________________________________
+[ 5178] By: gsar on 2000/02/21 07:02:16
+ Log: get Compiler "working" under useithreads
+ Branch: perl
+ ! ext/B/B.pm ext/B/B.xs ext/B/B/C.pm ext/B/B/CC.pm
+ ! ext/B/B/Deparse.pm ext/B/B/Xref.pm
+____________________________________________________________________________
+[ 5177] By: jhi on 2000/02/21 03:16:24
+ Log: Thou shalt not printf longs with %d.
+ Branch: cfgperl
+ ! malloc.c
+____________________________________________________________________________
+[ 5176] By: jhi on 2000/02/21 01:37:35
+ Log: Integrate with Sarathy.
+ Branch: cfgperl
+ +> t/pragma/warn/9enabled
+ !> (integrate 63 files)
+____________________________________________________________________________
+[ 5175] By: gsar on 2000/02/21 00:25:00
+ Log: misplaced braces
+ Branch: perl
+ ! malloc.c
+____________________________________________________________________________
+[ 5174] By: gsar on 2000/02/21 00:09:16
+ Log: more malloc.c tweaks for change#5070
+ Branch: perl
+ ! malloc.c
+____________________________________________________________________________
+[ 5173] By: gsar on 2000/02/21 00:01:17
+ Log: malloc.c fixups in change#5170 need to fetch thx pointer
+ Branch: perl
+ ! malloc.c
+____________________________________________________________________________
+[ 5172] By: gsar on 2000/02/20 23:52:39
+ Log: missing file in change#5170
+ Branch: perl
+ + t/pragma/warn/9enabled
+____________________________________________________________________________
+[ 5171] By: gsar on 2000/02/20 23:49:17
+ Log: skip conditionally defined symbols in change#5162
+ Branch: perl
+ ! makedef.pl
+____________________________________________________________________________
+[ 5170] By: gsar on 2000/02/20 22:58:09
+ Log: lexical warnings update, ability to inspect bitmask in calling
+ scope, among other things (from Paul Marquess)
+ Branch: perl
+ ! MANIFEST lib/warnings.pm malloc.c mg.c op.c pod/perldiag.pod
+ ! pod/perlfunc.pod pod/perllexwarn.pod pp.c pp_ctl.c pp_hot.c
+ ! regcomp.c regexec.c sv.c t/op/substr.t t/pragma/warn/op
+ ! t/pragma/warn/pp t/pragma/warn/pp_ctl t/pragma/warn/pp_hot
+ ! t/pragma/warn/regcomp t/pragma/warn/regexec t/pragma/warn/sv
+ ! t/pragma/warn/toke toke.c warnings.h warnings.pl
+____________________________________________________________________________
+[ 5169] By: gsar on 2000/02/20 22:22:28
+ Log: windows fixes for virtualizing child std{in,out,err} handles,
+ attempts to lock uninitialized critical section in files that
+ were never explicitly opened (from Doug Lankshear)
+ Branch: perl
+ ! iperlsys.h win32/perlhost.h win32/win32.c win32/win32.h
+____________________________________________________________________________
+[ 5168] By: gsar on 2000/02/20 20:19:11
+ Log: update Changes, credits
+ Branch: perl
+ ! Changes
+____________________________________________________________________________
[ 5167] By: gsar on 2000/02/20 18:54:27
Log: avoid reading out-of-bounds memory when matching against reference
Branch: perl
diff --git a/MANIFEST b/MANIFEST
index 1d8e59cd1c..fa557fd995 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1390,7 +1390,7 @@ t/op/undef.t See if undef works
t/op/universal.t See if UNIVERSAL class works
t/op/unshift.t See if unshift works
t/op/vec.t See if vectors work
-t/op/ver.t See if version tuples work
+t/op/ver.t See if v-strings and the %v format flag work
t/op/wantarray.t See if wantarray works
t/op/write.t See if write works
t/pod/emptycmd.t Test empty pod directives
diff --git a/README.epoc b/README.epoc
index 2ff36fd8f9..b4bcca60e4 100644
--- a/README.epoc
+++ b/README.epoc
@@ -4,7 +4,7 @@ Perl 5 README file for the EPOC operating system.
Olaf Flebbe <o.flebbe@gmx.de>
http://www.linuxstart.com/~oflebbe/perl/perl5.html
-2000-01-08
+2000-02-20
=====================================================================
Introduction
@@ -13,9 +13,9 @@ Introduction
EPOC is a OS for palmtops and mobile phones. For more informations look at:
http://www.symbian.com/
-This is a port of Perl version 5.005_63 to EPOC. It runs on the Perl
-Series 5, Series 5mx. I have no reports about the Psion Revo, the
-Ericcson (??) and the Psion NetBook. I only have acess to an Series 5.
+This is a port of Perl version 5.5.650 to EPOC. It runs on the Perl
+Series 5, Series 5mx and the Psion Revo. I have no reports for other
+EPOC devices.
Features are left out, because of restrictions of the POSIX support.
@@ -105,8 +105,6 @@ The following things are left out of this perl port:
directory very well (i.e. not at all, but it tries hard to emulate
one) See PATH.
-+ sockets seems to work now!
-
+ You need the shell eshell.exe in order to run perl.exe and supply
it with arguments.
@@ -132,15 +130,13 @@ Sorry, this is far too short.
Unpack the sources.
- Build a native miniperl...
+ Build a native perl from this sources...
cp epoc/* .
- for i in *.SH ; do
- sh $i
- done
+ ./Configure -S
make perl
cp miniperl.native miniperl
make perl
- perl linkit perlmain.o lib/auto/DynaLoader/DynaLoader.a \
+ perl link.pl perlmain.o lib/auto/DynaLoader/DynaLoader.a \
lib/auto/Data/Dumper.a \
lib/auto/File/Glob/Glob.a lib/auto/IO/IO.a \
lib/auto/Socket/Socket.a perl.a `cat ext.libs`
@@ -149,10 +145,9 @@ Sorry, this is far too short.
====================================================================
-TODO
+Wish List
====================================================================
-- Get the HTTPD::* working (Hey, It worked the first time for me!)
- Threads ?
- Acess to the GUI?
diff --git a/djgpp/config.over b/djgpp/config.over
index f47e7fca91..1f567b4174 100644
--- a/djgpp/config.over
+++ b/djgpp/config.over
@@ -29,6 +29,7 @@ repair()
-e 's/byteload/ByteLoader/'\
-e 's=devel/peek=Devel/Peek='\
-e 's=devel/dprof=Devel/DProf='\
+ -e 's=sys/sys=Sys/Sys='\
-e 's=file/=='\
-e 's=File/=='\
-e 's=glob=='\
diff --git a/djgpp/configure.bat b/djgpp/configure.bat
index e7d41d7130..370f5ed048 100644
--- a/djgpp/configure.bat
+++ b/djgpp/configure.bat
@@ -33,5 +33,5 @@ echo Running sed...
sh djgpp/djgppsed.sh
echo Running Configure...
-sh Configure %1 %2 %3 %4 %5 %6 %7 %8 %9
+sh Configure -DPERL_EXTERNAL_GLOB %1 %2 %3 %4 %5 %6 %7 %8 %9
:end
diff --git a/djgpp/djgppsed.sh b/djgpp/djgppsed.sh
index b62acfd6e9..bb95ad8538 100644
--- a/djgpp/djgppsed.sh
+++ b/djgpp/djgppsed.sh
@@ -24,6 +24,7 @@ SDBHASH='s=dbhash\.tmp=dbhash_tmp=g'
SSTAT='s=\.\(stat\.\)=_\1=g'
STMP2='s=tmp2=tm2=g'
SPACKLIST='s=\.\(packlist\)=_\1=g'
+SDOTTMP='s=\.tmp=_tmp=g'
sed -e $SCONFIG -e $SGREPTMP -e $SECHOTMP -e $SDDC -e $SOUT -e 's=\.\( \./\$file\)$=sh\1=g' Configure |tr -d '\r' >s; mv -f s Configure
sed -e $SEXISTS -e $SLIST -e $SCONFIG Makefile.SH |tr -d '\r' >s; mv -f s Makefile.SH
@@ -33,7 +34,7 @@ sed -e $SEXISTS -e $SPACKLIST installperl >s; mv -f s installperl
sed -e $SPOD2HTML lib/Pod/Html.pm |tr -d '\r' >s; mv -f s lib/Pod/Html.pm
sed -e $SCC -e $SLIST -e $SFILEC -e $SCOR -e $SDEPTMP -e $SHSED makedepend.SH |tr -d '\r' >s; mv -f s makedepend.SH
sed -e $SCPP t/comp/cpp.aux |tr -d '\r' >s; mv -f s t/comp/cpp.aux
-sed -e $SARGV t/io/argv.t >s; mv -f s t/io/argv.t
+sed -e $SARGV -e $SDOTTMP t/io/argv.t >s; mv -f s t/io/argv.t
sed -e $SABC t/io/inplace.t >s; mv -f s t/io/inplace.t
sed -e $SDBMX t/lib/anydbm.t >s; mv -f s t/lib/anydbm.t
sed -e $SDBMX -e $SDBHASH t/lib/gdbm.t >s; mv -f s t/lib/gdbm.t
diff --git a/epoc/config.sh b/epoc/config.sh
index 533bdccdc9..fda0bf04b8 100644
--- a/epoc/config.sh
+++ b/epoc/config.sh
@@ -34,8 +34,8 @@ apirevision=''
apisubversion=''
apiversion=''
ar='arm-pe-ar'
-archlib='/perl/lib/5.5.640/epoc'
-archlibexp='/perl/lib/5.5.640/epoc'
+archlib='/perl/lib/5.5.650/epoc'
+archlibexp='/perl/lib/5.5.650/epoc'
archname64=''
archname='epoc'
archobjs='epoc.o epocish.o epoc_stubs.o'
@@ -575,8 +575,8 @@ pmake=''
pr=''
prefix=''
prefixexp=''
-privlib='/perl/lib/5.5.640'
-privlibexp='/perl/lib/5.5.640'
+privlib='/perl/lib/5.5.650'
+privlibexp='/perl/lib/5.5.650'
prototype='define'
ptrsize='4'
randbits='31'
@@ -620,10 +620,10 @@ sig_name_init='"ZERO", 0'
sig_num='0'
sig_num_init='0, 0'
signal_t='void'
-sitearch='/perl/lib/site_perl/5.5.640/epoc'
-sitearchexp='/perl/lib/site_perl/5.5.640/epoc'
-sitelib='/perl/lib/site_perl/5.5.640/'
-sitelibexp='/perl/lib/site_perl/5.5.640/'
+sitearch='/perl/lib/site_perl/5.5.650/epoc'
+sitearchexp='/perl/lib/site_perl/5.5.650/epoc'
+sitelib='/perl/lib/site_perl/5.5.650/'
+sitelibexp='/perl/lib/site_perl/5.5.650/'
siteprefix=''
siteprefixexp=''
sizetype='size_t'
@@ -691,7 +691,7 @@ vendorlib=''
vendorlibexp=''
vendorprefix=''
vendorprefixexp=''
-version='5.5.640'
+version='5.5.650'
vi=''
voidflags='15'
xlibpth=''
@@ -714,10 +714,10 @@ config_arg10=''
config_arg11=''
PERL_REVISION=5
PERL_VERSION=5
-PERL_SUBVERSION=640
+PERL_SUBVERSION=650
PERL_API_REVISION=5
PERL_API_VERSION=5
-PERL_API_SUBVERSION=640
+PERL_API_SUBVERSION=650
CONFIGDOTSH=true
# Variables propagated from previous config.sh file.
pp_sys_cflags=''
@@ -761,4 +761,19 @@ i_ustat='undef'
use64bits='define'
uidsize='2'
gidsize='2'
-
+ivdformat='"ld"'
+uvuformat='"lu"'
+uvoformat='"lo"'
+uvxformat='"lx"'
+uidformat='"hu"'
+gidformat='"hu"'
+d_strtold='undef'
+d_strtoll='undef'
+d_strtouq='undef'
+d_nv_preserves_uv='define'
+use5005threads='undef'
+useithreads='undef'
+d_iconv='undef'
+i_iconv='undef'
+inc_version_list=' '
+inc_version_list_init='0'
diff --git a/epoc/createpkg.pl b/epoc/createpkg.pl
index 7270504974..6977bd385f 100644
--- a/epoc/createpkg.pl
+++ b/epoc/createpkg.pl
@@ -3,17 +3,17 @@
use File::Find;
use Cwd;
-$VERSION="5.005";
-$PATCH=63;
-$EPOC_VERSION=16;
+$VERSION="5.5";
+$PATCH="650";
+$EPOC_VERSION=19;
$CROSSCOMPILEPATH=cwd;
-$CROSSREPLACEPATH="H:\\devel\\perl5.005_63";
+$CROSSREPLACEPATH="H:\\devel\\perl5.5.650";
sub filefound {
my $f = $File::Find::name;
- return if ( $f =~ /unicode|CPAN|ExtUtils|IPC|User|DB.pm|\.a$|\.ld$|\.exists$/i);
+ return if ( $f =~ /CVS|unicode|CPAN|ExtUtils|IPC|User|DB.pm|\.a$|\.ld$|\.exists$/i);
my $back = $f;
$back =~ s|$CROSSCOMPILEPATH||;
@@ -22,7 +22,7 @@ sub filefound {
my $psiback = $back;
- $psiback =~ s/\\lib\\/\\perl\\lib\\$VERSION$PATCH\\/i;
+ $psiback =~ s/\\lib\\/\\perl\\lib\\$VERSION.$PATCH\\/i;
print OUT "\"$CROSSREPLACEPATH$back\"-\"!:$psiback\"\n" if ( -f $f );
;
@@ -35,6 +35,6 @@ print OUT "#{\"perl$VERSION\"},(0x100051d8),$PATCH,$EPOC_VERSION,0\n";
print OUT "\"$CROSSREPLACEPATH\\perlmain.exe\"-\"!:\\perl.exe\"\n";
find(\&filefound, cwd.'/lib');
-print OUT "@\"G:\\lib\\stdlib.sis\",(0x010002c3)\n"
+print OUT "@\"G:\\lib\\stdlib.sis\",(0x0100002c3)\n"
diff --git a/ext/B/B.xs b/ext/B/B.xs
index df0b501075..d0ee8e463a 100644
--- a/ext/B/B.xs
+++ b/ext/B/B.xs
@@ -95,6 +95,11 @@ cc_opclass(pTHX_ OP *o)
if (o->op_type == OP_SASSIGN)
return ((o->op_private & OPpASSIGN_BACKWARDS) ? OPc_UNOP : OPc_BINOP);
+#ifdef USE_ITHREADS
+ if (o->op_type == OP_GV || o->op_type == OP_GVSV || o->op_type == OP_AELEMFAST)
+ return OPc_PADOP;
+#endif
+
switch (PL_opargs[o->op_type] & OA_CLASS_MASK) {
case OA_BASEOP:
return OPc_BASEOP;
@@ -685,8 +690,8 @@ PMOP_precomp(o)
if (rx)
sv_setpvn(ST(0), rx->precomp, rx->prelen);
-#define SVOP_sv(o) cSVOPx_sv(o)
-#define SVOP_gv(o) cGVOPx_gv(o)
+#define SVOP_sv(o) cSVOPo->op_sv
+#define SVOP_gv(o) ((GV*)cSVOPo->op_sv)
MODULE = B PACKAGE = B::SVOP PREFIX = SVOP_
diff --git a/ext/B/B/CC.pm b/ext/B/B/CC.pm
index cf0e81f92e..c5ca2a3df5 100644
--- a/ext/B/B/CC.pm
+++ b/ext/B/B/CC.pm
@@ -6,6 +6,7 @@
# License or the Artistic License, as specified in the README file.
#
package B::CC;
+use Config;
use strict;
use B qw(main_start main_root class comppadlist peekop svref_2object
timing_info init_av sv_undef amagic_generation
@@ -223,7 +224,8 @@ sub save_or_restore_lexical_state {
next unless ref($lex);
${$lexstate{$bblock}}{$lex->{iv}} = $lex->{flags} ;
}
- }else{
+ }
+ else {
foreach my $lex (@pad) {
next unless ref($lex);
my $old_flags=${$lexstate{$bblock}}{$lex->{iv}} ;
@@ -586,9 +588,16 @@ sub pp_padsv {
sub pp_const {
my $op = shift;
my $sv = $op->sv;
- my $obj = $constobj{$$sv};
- if (!defined($obj)) {
- $obj = $constobj{$$sv} = new B::Stackobj::Const ($sv);
+ my $obj;
+ # constant could be in the pad (under useithreads)
+ if ($$sv) {
+ $obj = $constobj{$$sv};
+ if (!defined($obj)) {
+ $obj = $constobj{$$sv} = new B::Stackobj::Const ($sv);
+ }
+ }
+ else {
+ $obj = $pad[$op->targ];
}
push(@stack, $obj);
return $op->next;
@@ -656,10 +665,17 @@ sub pp_sort {
write_back_stack();
doop($op);
return $op->next;
-}
+}
+
sub pp_gv {
my $op = shift;
- my $gvsym = $op->gv->save;
+ my $gvsym;
+ if ($Config{useithreads}) {
+ $gvsym = $pad[$op->padix]->as_sv;
+ }
+ else {
+ $gvsym = $op->gv->save;
+ }
write_back_stack();
runtime("XPUSHs((SV*)$gvsym);");
return $op->next;
@@ -667,7 +683,13 @@ sub pp_gv {
sub pp_gvsv {
my $op = shift;
- my $gvsym = $op->gv->save;
+ my $gvsym;
+ if ($Config{useithreads}) {
+ $gvsym = $pad[$op->padix]->as_sv;
+ }
+ else {
+ $gvsym = $op->gv->save;
+ }
write_back_stack();
if ($op->private & OPpLVAL_INTRO) {
runtime("XPUSHs(save_scalar($gvsym));");
@@ -679,7 +701,13 @@ sub pp_gvsv {
sub pp_aelemfast {
my $op = shift;
- my $gvsym = $op->gv->save;
+ my $gvsym;
+ if ($Config{useithreads}) {
+ $gvsym = $pad[$op->padix]->as_sv;
+ }
+ else {
+ $gvsym = $op->gv->save;
+ }
my $ix = $op->private;
my $flag = $op->flags & OPf_MOD;
write_back_stack();
diff --git a/ext/B/B/Deparse.pm b/ext/B/B/Deparse.pm
index f8bcc7c8df..cd53c112d8 100644
--- a/ext/B/B/Deparse.pm
+++ b/ext/B/B/Deparse.pm
@@ -8,6 +8,7 @@
package B::Deparse;
use Carp 'cluck', 'croak';
+use Config;
use B qw(class main_root main_start main_cv svref_2object opnumber
OPf_WANT OPf_WANT_VOID OPf_WANT_SCALAR OPf_WANT_LIST
OPf_KIDS OPf_REF OPf_STACKED OPf_SPECIAL
@@ -251,18 +252,19 @@ sub walk_sub {
walk_tree($op, sub {
my $op = shift;
if ($op->name eq "gv") {
+ my $gv = $self->maybe_padgv($op);
if ($op->next->name eq "entersub") {
- next if $self->{'subs_done'}{$ {$op->gv}}++;
- next if class($op->gv->CV) eq "SPECIAL";
- $self->todo($op->gv, $op->gv->CV, 0);
- $self->walk_sub($op->gv->CV);
+ next if $self->{'subs_done'}{$$gv}++;
+ next if class($gv->CV) eq "SPECIAL";
+ $self->todo($gv, $gv->CV, 0);
+ $self->walk_sub($gv->CV);
} elsif ($op->next->name eq "enterwrite"
or ($op->next->name eq "rv2gv"
and $op->next->next->name eq "enterwrite")) {
- next if $self->{'forms_done'}{$ {$op->gv}}++;
- next if class($op->gv->FORM) eq "SPECIAL";
- $self->todo($op->gv, $op->gv->FORM, 1);
- $self->walk_sub($op->gv->FORM);
+ next if $self->{'forms_done'}{$$gv}++;
+ next if class($gv->FORM) eq "SPECIAL";
+ $self->todo($gv, $gv->FORM, 1);
+ $self->walk_sub($gv->FORM);
}
}
});
@@ -455,7 +457,7 @@ sub deparse_format {
$op = $op->sibling; # skip nextstate
my @exprs;
$kid = $op->first->sibling; # skip pushmark
- push @text, $kid->sv->PV;
+ push @text, $self->const_sv($kid)->PV;
$kid = $kid->sibling;
for (; not null $kid; $kid = $kid->sibling) {
push @exprs, $self->deparse($kid, 0);
@@ -984,7 +986,7 @@ sub pp_require {
if (class($op) eq "UNOP" and $op->first->name eq "const"
and $op->first->private & OPpCONST_BARE)
{
- my $name = $op->first->sv->PV;
+ my $name = $self->const_sv($op->first)->PV;
$name =~ s[/][::]g;
$name =~ s/\.pm//g;
return "require($name)";
@@ -1008,6 +1010,7 @@ sub pp_scalar {
sub padval {
my $self = shift;
my $targ = shift;
+ #cluck "curcv was undef" unless $self->{curcv};
return (($self->{'curcv'}->PADLIST->ARRAY)[1]->ARRAY)[$targ];
}
@@ -1537,7 +1540,7 @@ sub pp_truncate {
my $fh;
if ($op->flags & OPf_SPECIAL) {
# $kid is an OP_CONST
- $fh = $kid->sv->PV;
+ $fh = $self->const_sv($kid)->PV;
} else {
$fh = $self->deparse($kid, 6);
$fh = "+$fh" if not $parens and substr($fh, 0, 1) eq "(";
@@ -1876,22 +1879,37 @@ sub pp_threadsv {
return $self->maybe_local($op, $cx, "\$" . $threadsv_names[$op->targ]);
}
+sub maybe_padgv {
+ my $self = shift;
+ my $op = shift;
+ my $gv;
+ if ($Config{useithreads}) {
+ $gv = $self->padval($op->padix);
+ }
+ else {
+ $gv = $op->gv;
+ }
+ return $gv;
+}
+
sub pp_gvsv {
my $self = shift;
my($op, $cx) = @_;
- return $self->maybe_local($op, $cx, "\$" . $self->gv_name($op->gv));
+ my $gv = $self->maybe_padgv($op);
+ return $self->maybe_local($op, $cx, "\$" . $self->gv_name($gv));
}
sub pp_gv {
my $self = shift;
my($op, $cx) = @_;
- return $self->gv_name($op->gv);
+ my $gv = $self->maybe_padgv($op);
+ return $self->gv_name($gv);
}
sub pp_aelemfast {
my $self = shift;
my($op, $cx) = @_;
- my $gv = $op->gv;
+ my $gv = $self->maybe_padgv($op);
return "\$" . $self->gv_name($gv) . "[" . $op->private . "]";
}
@@ -1927,7 +1945,7 @@ sub pp_rv2av {
my($op, $cx) = @_;
my $kid = $op->first;
if ($kid->name eq "const") { # constant list
- my $av = $kid->sv;
+ my $av = $self->const_sv($kid);
return "(" . join(", ", map(const($_), $av->ARRAY)) . ")";
} else {
return $self->maybe_local($op, $cx, $self->rv2x($op, $cx, "\@"));
@@ -2083,13 +2101,13 @@ sub method {
}
$obj = $self->deparse($obj, 24);
if ($meth->name eq "method_named") {
- $meth = $meth->sv->PV;
+ $meth = $self->const_sv($meth)->PV;
} else {
$meth = $meth->first;
if ($meth->name eq "const") {
# As of 5.005_58, this case is probably obsoleted by the
# method_named case above
- $meth = $meth->sv->PV; # needs to be bare
+ $meth = $self->const_sv($meth)->PV; # needs to be bare
} else {
$meth = $self->deparse($meth, 1);
}
@@ -2202,7 +2220,7 @@ sub pp_entersub {
$amper = "&";
$kid = "{" . $self->deparse($kid, 0) . "}";
} elsif ($kid->first->name eq "gv") {
- my $gv = $kid->first->gv;
+ my $gv = $self->maybe_padgv($kid->first);
if (class($gv->CV) ne "SPECIAL") {
$proto = $gv->CV->PV if $gv->CV->FLAGS & SVf_POK;
}
@@ -2347,13 +2365,23 @@ sub const {
}
}
+sub const_sv {
+ my $self = shift;
+ my $op = shift;
+ my $sv = $op->sv;
+ # the constant could be in the pad (under useithreads)
+ $sv = $self->padval($op->targ) unless $$sv;
+ return $sv;
+}
+
sub pp_const {
my $self = shift;
my($op, $cx) = @_;
# if ($op->private & OPpCONST_BARE) { # trouble with `=>' autoquoting
-# return $op->sv->PV;
+# return $self->const_sv($op)->PV;
# }
- return const($op->sv);
+ my $sv = $self->const_sv($op);
+ return const($sv);
}
sub dq {
@@ -2361,7 +2389,7 @@ sub dq {
my $op = shift;
my $type = $op->name;
if ($type eq "const") {
- return uninterp(escape_str(unback($op->sv->PV)));
+ return uninterp(escape_str(unback($self->const_sv($op)->PV)));
} elsif ($type eq "concat") {
return $self->dq($op->first) . $self->dq($op->last);
} elsif ($type eq "uc") {
@@ -2650,7 +2678,7 @@ sub re_dq {
my $op = shift;
my $type = $op->name;
if ($type eq "const") {
- return uninterp($op->sv->PV);
+ return uninterp($self->const_sv($op)->PV);
} elsif ($type eq "concat") {
return $self->re_dq($op->first) . $self->re_dq($op->last);
} elsif ($type eq "uc") {
diff --git a/ext/B/B/Xref.pm b/ext/B/B/Xref.pm
index 53b655c82e..0a5ceabda1 100644
--- a/ext/B/B/Xref.pm
+++ b/ext/B/B/Xref.pm
@@ -85,6 +85,7 @@ Malcolm Beattie, mbeattie@sable.ox.ac.uk.
=cut
use strict;
+use Config;
use B qw(peekop class comppadlist main_start svref_2object walksymtable
OPpLVAL_INTRO SVf_POK
);
@@ -133,10 +134,10 @@ sub process {
sub load_pad {
my $padlist = shift;
- my ($namelistav, @namelist, $ix);
+ my ($namelistav, $vallistav, @namelist, $ix);
@pad = ();
return if class($padlist) eq "SPECIAL";
- ($namelistav) = $padlist->ARRAY;
+ ($namelistav,$vallistav) = $padlist->ARRAY;
@namelist = $namelistav->ARRAY;
for ($ix = 1; $ix < @namelist; $ix++) {
my $namesv = $namelist[$ix];
@@ -144,6 +145,17 @@ sub load_pad {
my ($type, $name) = $namesv->PV =~ /^(.)([^\0]*)(\0.*)?$/;
$pad[$ix] = ["(lexical)", $type, $name];
}
+ if ($Config{useithreads}) {
+ my (@vallist);
+ @vallist = $vallistav->ARRAY;
+ for ($ix = 1; $ix < @vallist; $ix++) {
+ my $valsv = $vallist[$ix];
+ next unless class($valsv) eq "GV";
+ # these pad GVs don't have corresponding names, so same @pad
+ # array can be used without collisions
+ $pad[$ix] = [$valsv->STASH->NAME, "*", $valsv->NAME];
+ }
+ }
}
sub xref {
@@ -229,23 +241,45 @@ sub pp_rv2gv { deref($top, "*"); }
sub pp_gvsv {
my $op = shift;
- my $gv = $op->gv;
- $top = [$gv->STASH->NAME, '$', $gv->NAME];
+ my $gv;
+ if ($Config{useithreads}) {
+ $top = $pad[$op->padix];
+ $top = UNKNOWN unless $top;
+ $top->[1] = '$';
+ }
+ else {
+ $gv = $op->gv;
+ $top = [$gv->STASH->NAME, '$', $gv->NAME];
+ }
process($top, $op->private & OPpLVAL_INTRO ? "intro" : "used");
}
sub pp_gv {
my $op = shift;
- my $gv = $op->gv;
- $top = [$gv->STASH->NAME, "*", $gv->NAME];
+ my $gv;
+ if ($Config{useithreads}) {
+ $top = $pad[$op->padix];
+ $top = UNKNOWN unless $top;
+ $top->[1] = '*';
+ }
+ else {
+ $gv = $op->gv;
+ $top = [$gv->STASH->NAME, "*", $gv->NAME];
+ }
process($top, $op->private & OPpLVAL_INTRO ? "intro" : "used");
}
sub pp_const {
my $op = shift;
my $sv = $op->sv;
- $top = ["?", "",
- (class($sv) ne "SPECIAL" && $sv->FLAGS & SVf_POK) ? $sv->PV : "?"];
+ # constant could be in the pad (under useithreads)
+ if ($$sv) {
+ $top = ["?", "",
+ (class($sv) ne "SPECIAL" && $sv->FLAGS & SVf_POK) ? $sv->PV : "?"];
+ }
+ else {
+ $top = $pad[$op->targ];
+ }
}
sub pp_method {
diff --git a/ext/IO/lib/IO/Socket/INET.pm b/ext/IO/lib/IO/Socket/INET.pm
index af64c9603e..696e988802 100644
--- a/ext/IO/lib/IO/Socket/INET.pm
+++ b/ext/IO/lib/IO/Socket/INET.pm
@@ -12,11 +12,13 @@ use IO::Socket;
use Socket;
use Carp;
use Exporter;
-use Errno qw(EINVAL); # EINVAL appears portable
+use Errno;
@ISA = qw(IO::Socket);
$VERSION = "1.25";
+my $EINVAL = exists(&Errno::EINVAL) ? Errno::EINVAL() : 1;
+
IO::Socket::INET->register_domain( AF_INET );
my %socket_type = ( tcp => SOCK_STREAM,
@@ -117,7 +119,7 @@ sub configure {
$laddr = defined $laddr ? inet_aton($laddr)
: INADDR_ANY;
- return _error($sock, EINVAL, "Bad hostname '",$arg->{LocalAddr},"'")
+ return _error($sock, $EINVAL, "Bad hostname '",$arg->{LocalAddr},"'")
unless(defined $laddr);
$arg->{PeerAddr} = $arg->{PeerHost}
@@ -139,7 +141,7 @@ sub configure {
if(defined $raddr) {
@raddr = $sock->_get_addr($raddr, $arg->{MultiHomed});
- return _error($sock, EINVAL, "Bad hostname '",$arg->{PeerAddr},"'")
+ return _error($sock, $EINVAL, "Bad hostname '",$arg->{PeerAddr},"'")
unless @raddr;
}
@@ -169,13 +171,13 @@ sub configure {
$raddr = shift @raddr;
- return _error($sock, EINVAL, 'Cannot determine remote port')
+ return _error($sock, $EINVAL, 'Cannot determine remote port')
unless($rport || $type == SOCK_DGRAM || $type == SOCK_RAW);
last
unless($type == SOCK_STREAM || defined $raddr);
- return _error($sock, EINVAL, "Bad hostname '",$arg->{PeerAddr},"'")
+ return _error($sock, $EINVAL, "Bad hostname '",$arg->{PeerAddr},"'")
unless defined $raddr;
# my $timeout = ${*$sock}{'io_socket_timeout'};
@@ -192,7 +194,7 @@ sub configure {
# if ($timeout) {
# my $new_timeout = $timeout - (time() - $before);
# return _error($sock,
-# (exists(&Errno::ETIMEDOUT) ? &Errno::ETIMEDOUT : EINVAL),
+# (exists(&Errno::ETIMEDOUT) ? Errno::ETIMEDOUT() : $EINVAL),
# "Timeout") if $new_timeout <= 0;
# ${*$sock}{'io_socket_timeout'} = $new_timeout;
# }
diff --git a/ext/attrs/attrs.pm b/ext/attrs/attrs.pm
index f744e36c66..2070632558 100644
--- a/ext/attrs/attrs.pm
+++ b/ext/attrs/attrs.pm
@@ -20,7 +20,7 @@ attrs - set/get attributes of a subroutine (deprecated)
NOTE: Use of this pragma is deprecated. Use the syntax
- sub foo : locked, method { }
+ sub foo : locked method { }
to declare attributes instead. See also L<attributes>.
diff --git a/lib/English.pm b/lib/English.pm
index 2953a80af9..f6e3ec0021 100644
--- a/lib/English.pm
+++ b/lib/English.pm
@@ -87,7 +87,6 @@ sub import {
*EGID
*PROGRAM_NAME
*PERL_VERSION
- *PERL_VERSION_TUPLE
*ACCUMULATOR
*DEBUGGING
*SYSTEM_FD_MAX
@@ -167,8 +166,7 @@ sub import {
# Internals.
- *PERL_VERSION = *] ;
- *PERL_VERSION_TUPLE = *^V ;
+ *PERL_VERSION = *^V ;
*ACCUMULATOR = *^A ;
*COMPILING = *^C ;
*DEBUGGING = *^D ;
@@ -187,5 +185,6 @@ sub import {
# *ARRAY_BASE = *[ ;
# *OFMT = *# ;
# *MULTILINE_MATCHING = ** ;
+# *OLD_PERL_VERSION = *] ;
1;
diff --git a/lib/ExtUtils/xsubpp b/lib/ExtUtils/xsubpp
index 431d75ad84..49d167dc0b 100755
--- a/lib/ExtUtils/xsubpp
+++ b/lib/ExtUtils/xsubpp
@@ -1576,7 +1576,11 @@ sub generate_init {
eval qq/print "\\t$var;\\n"/;
warn $@ if $@;
}
- $deferred .= eval qq/"\\n\\tif (items < $num)\\n\\t $var = $defaults{$var};\\n\\telse {\\n$expr;\\n\\t}\\n"/;
+ if ($defaults{$var} eq 'NO_INIT') {
+ $deferred .= eval qq/"\\n\\tif (items >= $num) {\\n$expr;\\n\\t}\\n"/;
+ } else {
+ $deferred .= eval qq/"\\n\\tif (items < $num)\\n\\t $var = $defaults{$var};\\n\\telse {\\n$expr;\\n\\t}\\n"/;
+ }
warn $@ if $@;
} elsif ($ScopeThisXSUB or $expr !~ /^\t\$var =/) {
if ($name_printed) {
diff --git a/lib/Pod/Checker.pm b/lib/Pod/Checker.pm
index c661c7527e..b5f980bba7 100644
--- a/lib/Pod/Checker.pm
+++ b/lib/Pod/Checker.pm
@@ -10,7 +10,7 @@
package Pod::Checker;
use vars qw($VERSION);
-$VERSION = 1.096; ## Current version of this package
+$VERSION = 1.097; ## Current version of this package
require 5.004; ## requires this Perl version or later
use Pod::ParseUtils; ## for hyperlinks and lists
@@ -111,6 +111,11 @@ very robust conversions.
=over 4
+=item * empty =headn
+
+A heading (C<=head1> or C<=head2>) without any text? That ain't no
+heading!
+
=item * =over on line I<N> without closing =back
The C<=over> command does not have a corresponding C<=back> before the
@@ -134,7 +139,7 @@ A standalone C<=end> command was found.
=item * Nested =begin's
-There were at least two concecutive C<=begin> commands without
+There were at least two consecutive C<=begin> commands without
the corresponding C<=end>. Only one C<=begin> may be active at
a time.
@@ -168,13 +173,29 @@ does not make sense.
=item * garbled entity I<STRING>
-The I<STRING> found cannot be interpreted as an character entity.
+The I<STRING> found cannot be interpreted as a character entity.
+
+=item * Entity number out of range
+
+An entity specified by number (dec, hex, oct) is out of range (1-255).
=item * malformed link LE<lt>E<gt>
The link found cannot be parsed because it does not conform to the
syntax described in L<perlpod>.
+=item * nonempty ZE<lt>E<gt>
+
+The C<ZE<lt>E<gt>> sequence is supposed to be empty.
+
+=item * Spurious text after =pod / =cut
+
+The commands C<=pod> and C<=cut> do not take any arguments.
+
+=item * Spurious character(s) after =back
+
+The C<=back> command does not take any arguments.
+
=back
=head2 Warnings
@@ -183,14 +204,43 @@ These may not necessarily cause trouble, but indicate mediocre style.
=over 4
+=item * multiple occurence of link target I<name>
+
+The POD file has some C<=item> and/or C<=head> commands that have
+the same text. Potential hyperlinks to such a text cannot be unique then.
+
+=item * line containing nothing but whitespace in paragraph
+
+There is some whitespace on a seemingly empty line. POD is very sensitive
+to such things, so this is flagged. B<vi> users switch on the B<list>
+option to avoid this problem.
+
+=item * file does not start with =head
+
+The file starts with a different POD directive than head.
+This is most probably something you do not want.
+
=item * No numeric argument for =over
The C<=over> command is supposed to have a numeric argument (the
indentation).
-=item * Spurious character(s) after =back
+=item * previous =item has no contents
-The C<=back> command does not take any arguments.
+There is a list C<=item> right above the flagged line that has no
+text contents. You probably want to delete empty items.
+
+=item * preceding non-item paragraph(s)
+
+A list introduced by C<=over> starts with a text or verbatim paragraph,
+but continues with C<=item>s. Move the non-item paragraph out of the
+C<=over>/C<=back> block.
+
+=item * =item type mismatch (I<one> vs. I<two>)
+
+A list started with e.g. a bulletted C<=item> and continued with a
+numbered one. This is obviously inconsistent. For most translators the
+type of the I<first> C<=item> determines the type of the list.
=item * I<N> unescaped C<E<lt>E<gt>> in paragraph
@@ -198,14 +248,14 @@ Angle brackets not written as C<E<lt>ltE<gt>> and C<E<lt>gtE<gt>>
can potentially cause errors as they could be misinterpreted as
markup commands.
-=item * Non-standard entity
+=item * Unknown entity
A character entity was found that does not belong to the standard
-ISO set.
+ISO set or the POD specials C<verbar> and C<sol>.
=item * No items in =over
-The list does not contain any items.
+The list opened with C<=over> does not contain any items.
=item * No argument for =item
@@ -214,6 +264,12 @@ by C<*> to indicate an unordered list, by a number (optionally followed
by a dot) to indicate an ordered (numbered) list or simple text for a
definition list.
+=item * empty section in previous paragraph
+
+The previous section (introduced by a C<=head> command) does not contain
+any text. This usually indicates that something is missing. Note: A
+C<=head1> followed immediately by C<=head2> does not trigger this warning.
+
=item * Verbatim paragraph in NAME section
The NAME section (C<=head1 NAME>) should consist of a single paragraph
@@ -395,6 +451,10 @@ my %ENTITIES = (
iquest => '¿',
'times' => '×', # times is a keyword in perl
divide => '÷',
+
+# some POD special entities
+ verbar => '|',
+ sol => '/'
);
##---------------------------------------------------------------------------
@@ -413,6 +473,7 @@ sub podchecker( $ ; $ % ) {
## Now create a pod checker
my $checker = new Pod::Checker(%options);
+ $checker->parseopts(-process_cut_cmd => 1);
## Now check the pod document for errors
$checker->parse_from_file($infile, $outfile);
@@ -427,15 +488,15 @@ sub podchecker( $ ; $ % ) {
## Method definitions begin here
##-------------------------------
-sub new {
- my $this = shift;
- my $class = ref($this) || $this;
- my %params = @_;
- my $self = {%params};
- bless $self, $class;
- $self->initialize();
- return $self;
-}
+## sub new {
+## my $this = shift;
+## my $class = ref($this) || $this;
+## my %params = @_;
+## my $self = {%params};
+## bless $self, $class;
+## $self->initialize();
+## return $self;
+## }
sub initialize {
my $self = shift;
@@ -462,6 +523,10 @@ sub poderror {
chomp( my $msg = ($opts{-msg} || "")."@_" );
my $line = (exists $opts{-line}) ? " at line $opts{-line}" : "";
my $file = (exists $opts{-file}) ? " in file $opts{-file}" : "";
+ unless (exists $opts{-severity}) {
+ ## See if can find severity in message prefix
+ $opts{-severity} = $1 if ( $msg =~ s/^\**\s*([A-Z]{3,}):\s+// );
+ }
my $severity = (exists $opts{-severity}) ? "*** $opts{-severity}: " : "";
## Increment error count and print message "
@@ -487,9 +552,12 @@ sub name {
sub node {
my ($self,$text) = @_;
if(defined $text) {
- $text =~ s/[\s\n]+$//; # strip trailing whitespace
- # add node
+ $text =~ s/\s+$//s; # strip trailing whitespace
+ $text =~ s/\s+/ /gs; # collapse whitespace
+ # add node, order important!
push(@{$self->{_nodes}}, $text);
+ # keep also a uniqueness counter
+ $self->{_unique_nodes}->{$text}++;
return $text;
}
@{$self->{_nodes}};
@@ -508,56 +576,63 @@ sub hyperlink {
## overrides for Pod::Parser
sub end_pod {
- ## Do some final checks and
- ## print the number of errors found
- my $self = shift;
- my $infile = $self->input_file();
- my $out_fh = $self->output_handle();
-
- if(@{$self->{_list_stack}}) {
- # _TODO_ display, but don't count them for now
- my $list;
- while($list = shift(@{$self->{_list_stack}})) {
- $self->poderror({ -line => 'EOF', -file => $infile,
- -severity => 'ERROR', -msg => "=over on line " .
- $list->start() . " without closing =back" }); #"
- }
- }
-
- # check validity of document internal hyperlinks
- # first build the node names from the paragraph text
- my %nodes;
- foreach($self->node()) {
- $nodes{$_} = 1;
- if(/^(\S+)\s+/) {
- # we have more than one word. Use the first as a node, too.
- # This is used heavily in perlfunc.pod
- $nodes{$1} ||= 2; # derived node
- }
- }
- foreach($self->hyperlink()) {
- my $line = '';
- s/^(\d+):// && ($line = $1);
- if($_ && !$nodes{$_}) {
- $self->poderror({ -line => $line, -file => $infile,
- -severity => 'ERROR',
- -msg => "unresolved internal link `$_'"});
- }
- }
-
- ## Print the number of errors found
- my $num_errors = $self->num_errors();
- if ($num_errors > 0) {
- printf $out_fh ("$infile has $num_errors pod syntax %s.\n",
+ ## Do some final checks and
+ ## print the number of errors found
+ my $self = shift;
+ my $infile = $self->input_file();
+ my $out_fh = $self->output_handle();
+
+ if(@{$self->{_list_stack}}) {
+ # _TODO_ display, but don't count them for now
+ my $list;
+ while(($list = $self->_close_list('EOF',$infile)) &&
+ $list->indent() ne 'auto') {
+ $self->poderror({ -line => 'EOF', -file => $infile,
+ -severity => 'ERROR', -msg => "=over on line " .
+ $list->start() . " without closing =back" }); #"
+ }
+ }
+
+ # check validity of document internal hyperlinks
+ # first build the node names from the paragraph text
+ my %nodes;
+ foreach($self->node()) {
+ $nodes{$_} = 1;
+ if(/^(\S+)\s+/) {
+ # we have more than one word. Use the first as a node, too.
+ # This is used heavily in perlfunc.pod
+ $nodes{$1} ||= 2; # derived node
+ }
+ }
+ foreach($self->hyperlink()) {
+ my $line = '';
+ s/^(\d+):// && ($line = $1);
+ if($_ && !$nodes{$_}) {
+ $self->poderror({ -line => $line, -file => $infile,
+ -severity => 'ERROR',
+ -msg => "unresolved internal link '$_'"});
+ }
+ }
+ foreach(grep($self->{_unique_nodes}->{$_} > 1,
+ keys %{$self->{_unique_nodes}})) {
+ $self->poderror({ -line => '-', -file => $infile,
+ -severity => 'WARNING',
+ -msg => "multiple occurence of link target '$_'"});
+ }
+
+ ## Print the number of errors found
+ my $num_errors = $self->num_errors();
+ if ($num_errors > 0) {
+ printf $out_fh ("$infile has $num_errors pod syntax %s.\n",
($num_errors == 1) ? "error" : "errors");
- }
- elsif($self->{_commands} == 0) {
- print $out_fh "$infile does not contain any pod commands.\n";
- $self->num_errors(-1);
- }
- else {
- print $out_fh "$infile pod syntax OK.\n";
- }
+ }
+ elsif($self->{_commands} == 0) {
+ print $out_fh "$infile does not contain any pod commands.\n";
+ $self->num_errors(-1);
+ }
+ else {
+ print $out_fh "$infile pod syntax OK.\n";
+ }
}
# check a POD command directive
@@ -568,10 +643,15 @@ sub command {
my $arg; # this will hold the command argument
if (! $VALID_COMMANDS{$cmd}) {
$self->poderror({ -line => $line, -file => $file, -severity => 'ERROR',
- -msg => "Unknown command \"$cmd\"" });
+ -msg => "Unknown command '$cmd'" });
}
else {
- $self->{_commands}++; # found a valid command
+ # found a valid command
+ if(!$self->{_commands}++ && $cmd !~ /^head/) {
+ $self->poderror({ -line => $line, -file => $file,
+ -severity => 'WARNING',
+ -msg => "file does not start with =head" });
+ }
## check syntax of particular command
if($cmd eq 'over') {
# check for argument
@@ -585,10 +665,7 @@ sub command {
-msg => "No numeric argument for =over"});
}
# start a new list
- unshift(@{$self->{_list_stack}}, Pod::List->new(
- -indent => $indent,
- -start => $line,
- -file => $file));
+ $self->_open_list($indent,$line,$file);
}
elsif($cmd eq 'item') {
# are we in a list?
@@ -597,22 +674,60 @@ sub command {
-severity => 'ERROR',
-msg => "=item without previous =over" });
# auto-open in case we encounter many more
- unshift(@{$self->{_list_stack}},
- Pod::List->new(
- -indent => 'auto',
- -start => $line,
- -file => $file));
+ $self->_open_list('auto',$line,$file);
+ }
+ my $list = $self->{_list_stack}->[0];
+ # check whether the previous item had some contents
+ if(defined $self->{_list_item_contents} &&
+ $self->{_list_item_contents} == 0) {
+ $self->poderror({ -line => $line, -file => $file,
+ -severity => 'WARNING',
+ -msg => "previous =item has no contents" });
+ }
+ if($list->{_has_par}) {
+ $self->poderror({ -line => $line, -file => $file,
+ -severity => 'WARNING',
+ -msg => "preceding non-item paragraph(s)" });
+ delete $list->{_has_par};
}
# check for argument
$arg = $self->interpolate_and_check($paragraph, $line, $file);
- unless($arg && $arg =~ /(\S+)/) {
+ if($arg && $arg =~ /(\S+)/) {
+ $arg =~ s/[\s\n]+$//;
+ my $type;
+ if($arg =~ /^[*]\s*(\S*.*)/) {
+ $type = 'bullet';
+ $self->{_list_item_contents} = $1 ? 1 : 0;
+ $arg = $1;
+ }
+ elsif($arg =~ /^\d+\.?\s*(\S*)/) {
+ $type = 'number';
+ $self->{_list_item_contents} = $1 ? 1 : 0;
+ $arg = $1;
+ }
+ else {
+ $type = 'definition';
+ $self->{_list_item_contents} = 1;
+ }
+ my $first = $list->type();
+ if($first && $first ne $type) {
+ $self->poderror({ -line => $line, -file => $file,
+ -severity => 'WARNING',
+ -msg => "=item type mismatch ('$first' vs. '$type')"});
+ }
+ else { # first item
+ $list->type($type);
+ }
+ }
+ else {
$self->poderror({ -line => $line, -file => $file,
-severity => 'WARNING',
-msg => "No argument for =item" });
$arg = ' '; # empty
+ $self->{_list_item_contents} = 0;
}
# add this item
- $self->{_list_stack}[0]->item($arg);
+ $list->item($arg);
# remember this node
$self->node($arg);
}
@@ -628,11 +743,11 @@ sub command {
$arg = $self->interpolate_and_check($paragraph, $line,$file);
if($arg && $arg =~ /\S/) {
$self->poderror({ -line => $line, -file => $file,
- -severity => 'WARNING',
+ -severity => 'ERROR',
-msg => "Spurious character(s) after =back" });
}
# close list
- my $list = shift @{$self->{_list_stack}};
+ my $list = $self->_close_list($line,$file);
# check for empty lists
if(!$list->item() && $self->{-warnings}) {
$self->poderror({ -line => $line, -file => $file,
@@ -642,11 +757,22 @@ sub command {
}
}
}
- elsif($cmd =~ /^head/) {
+ elsif($cmd =~ /^head(\d+)/) {
+ if(defined $self->{_commands_in_head} &&
+ $self->{_commands_in_head} == 0 &&
+ defined $self->{_last_head} &&
+ $self->{_last_head} >= $1) {
+ $self->poderror({ -line => $line, -file => $file,
+ -severity => 'WARNING',
+ -msg => "empty section in previous paragraph"});
+ }
+ $self->{_commands_in_head} = -1;
+ $self->{_last_head} = $1;
# check if there is an open list
if(@{$self->{_list_stack}}) {
my $list;
- while($list = shift(@{$self->{_list_stack}})) {
+ while(($list = $self->_close_list($line,$file)) &&
+ $list->indent() ne 'auto') {
$self->poderror({ -line => $line, -file => $file,
-severity => 'ERROR',
-msg => "=over on line ". $list->start() .
@@ -655,9 +781,14 @@ sub command {
}
# remember this node
$arg = $self->interpolate_and_check($paragraph, $line,$file);
- $self->node($arg) if($arg);
+ $arg =~ s/[\s\n]+$//s;
+ $self->node($arg);
+ unless(length($arg)) {
+ $self->poderror({ -line => $line, -file => $file,
+ -severity => 'ERROR',
+ -msg => "empty =$cmd"});
+ }
if($cmd eq 'head1') {
- $arg =~ s/[\s\n]+$//;
$self->{_current_head1} = $arg;
} else {
$self->{_current_head1} = '';
@@ -711,12 +842,48 @@ sub command {
}
$arg = ''; # do not expand paragraph below
}
+ elsif($cmd =~ /^(pod|cut)$/) {
+ # check for argument
+ $arg = $self->interpolate_and_check($paragraph, $line,$file);
+ if($arg && $arg =~ /(\S+)/) {
+ $self->poderror({ -line => $line, -file => $file,
+ -severity => 'ERROR',
+ -msg => "Spurious text after =$cmd"});
+ }
+ }
+ $self->{_commands_in_head}++;
## Check the interior sequences in the command-text
$self->interpolate_and_check($paragraph, $line,$file)
unless(defined $arg);
}
}
+sub _open_list
+{
+ my ($self,$indent,$line,$file) = @_;
+ my $list = Pod::List->new(
+ -indent => $indent,
+ -start => $line,
+ -file => $file);
+ unshift(@{$self->{_list_stack}}, $list);
+ undef $self->{_list_item_contents};
+ $list;
+}
+
+sub _close_list
+{
+ my ($self,$line,$file) = @_;
+ my $list = shift(@{$self->{_list_stack}});
+ if(defined $self->{_list_item_contents} &&
+ $self->{_list_item_contents} == 0) {
+ $self->poderror({ -line => $line, -file => $file,
+ -severity => 'WARNING',
+ -msg => "previous =item has no contents" });
+ }
+ undef $self->{_list_item_contents};
+ $list;
+}
+
# process a block of some text
sub interpolate_and_check {
my ($self, $paragraph, $line, $file) = @_;
@@ -754,7 +921,7 @@ sub _check_ptree {
if (! $VALID_SEQUENCES{$cmd}) {
$self->poderror({ -line => $line, -file => $file,
-severity => 'ERROR',
- -msg => qq(Unknown interior-sequence "$cmd")});
+ -msg => qq(Unknown interior-sequence '$cmd')});
# expand it anyway
$text .= $self->_check_ptree($contents, $line, $file, "$nestlist$cmd");
next;
@@ -775,9 +942,28 @@ sub _check_ptree {
next;
}
my $ent = $$contents[0];
- if($ent =~ /^\d+$/) {
+ my $val;
+ if($ent =~ /^0x[0-9a-f]+$/i) {
+ # hexadec entity
+ $val = hex($ent);
+ }
+ elsif($ent =~ /^0\d+$/) {
+ # octal
+ $val = oct($ent);
+ }
+ elsif($ent =~ /^\d+$/) {
# numeric entity
- $text .= chr($ent);
+ $val = $ent;
+ }
+ if(defined $val) {
+ if($val>0 && $val<256) {
+ $text .= chr($val);
+ }
+ else {
+ $self->poderror({ -line => $line, -file => $file,
+ -severity => 'ERROR',
+ -msg => "Entity number out of range " . $_->raw_text()});
+ }
}
elsif($ENTITIES{$ent}) {
# known ISO entity
@@ -786,7 +972,7 @@ sub _check_ptree {
else {
$self->poderror({ -line => $line, -file => $file,
-severity => 'WARNING',
- -msg => "Non-standard entity " . $_->raw_text()});
+ -msg => "Unknown entity " . $_->raw_text()});
$text .= "E<$ent>";
}
}
@@ -824,8 +1010,15 @@ sub _check_ptree {
# add the guts
$text .= $self->_check_ptree($contents, $line, $file, "$nestlist$cmd");
}
- else {
- # check, but add nothing to $text (X<>, Z<>)
+ elsif($cmd eq 'Z') {
+ if(length($contents->raw_text())) {
+ $self->poderror({ -line => $line, -file => $file,
+ -severity => 'ERROR',
+ -msg => "Nonempty Z<>"});
+ }
+ }
+ else { # X<>
+ # check, but add nothing to $text
$self->_check_ptree($contents, $line, $file, "$nestlist$cmd");
}
}
@@ -836,8 +1029,11 @@ sub _check_ptree {
# process a block of verbatim text
sub verbatim {
- ## Nothing to check
+ ## Nothing particular to check
my ($self, $paragraph, $line_num, $pod_para) = @_;
+
+ $self->_preproc_par($paragraph);
+
if($self->{_current_head1} eq 'NAME') {
my ($file, $line) = $pod_para->file_line;
$self->poderror({ -line => $line, -file => $file,
@@ -851,6 +1047,8 @@ sub textblock {
my ($self, $paragraph, $line_num, $pod_para) = @_;
my ($file, $line) = $pod_para->file_line;
+ $self->_preproc_par($paragraph);
+
# skip this paragraph if in a =begin block
unless($self->{_have_begin}) {
my $block = $self->interpolate_and_check($paragraph, $line,$file);
@@ -863,4 +1061,18 @@ sub textblock {
}
}
+sub _preproc_par
+{
+ my $self = shift;
+ $_[0] =~ s/[\s\n]+$//;
+ if($_[0]) {
+ $self->{_commands_in_head}++;
+ $self->{_list_item_contents}++ if(defined $self->{_list_item_contents});
+ if(@{$self->{_list_stack}} && !$self->{_list_stack}->[0]->item()) {
+ $self->{_list_stack}->[0]->{_has_par} = 1;
+ }
+ }
+}
+
1;
+
diff --git a/lib/Pod/Find.pm b/lib/Pod/Find.pm
index 399bbba252..038b090b42 100644
--- a/lib/Pod/Find.pm
+++ b/lib/Pod/Find.pm
@@ -3,7 +3,8 @@
#
# Author: Marek Rouchal <marek@saftsack.fs.uni-bayreuth.de>
#
-# borrowing code from Nick Ing-Simmon's PodToHtml
+# Copyright (C) 1999-2000 by Marek Rouchal (and borrowing code
+# from Nick Ing-Simmon's PodToHtml). All rights reserved.
# This file is part of "PodParser". Pod::Find is free software;
# you can redistribute it and/or modify it under the same terms
# as Perl itself.
@@ -12,8 +13,8 @@
package Pod::Find;
use vars qw($VERSION);
-$VERSION = 0.10; ## Current version of this package
-require 5.005; ## requires this Perl version or later
+$VERSION = 0.11; ## Current version of this package
+require 5.004; ## requires this Perl version or later
#############################################################################
@@ -113,7 +114,9 @@ use vars qw(@ISA @EXPORT_OK $VERSION);
# package global variables
my $SIMPLIFY_RX;
-# return a hash of the
+# return a hash of the POD files found
+# first argument may be a hashref (options),
+# rest is a list of directories to search recursively
sub pod_find
{
my %opts;
@@ -145,7 +148,8 @@ sub pod_find
# * remove e.g. 5.00503
# * remove pod/ if followed by *.pod (e.g. in pod/perlfunc.pod)
$SIMPLIFY_RX =
- qr!^(?i:site_perl/|$Config::Config{archname}/|\d+\.\d+([_.]?\d+)?/|pod/(?=.*?\.pod$))*!o;
+ qq!^(?i:site_perl/|\Q$Config::Config{archname}\E/|\\d+\\.\\d+([_.]?\\d+)?/|pod/(?=.*?\\.pod\$))*!;
+
}
my %dirs_visited;
@@ -166,7 +170,7 @@ sub pod_find
}
next;
}
- my $root_rx = qr!^\Q$try\E/!;
+ my $root_rx = qq!^\Q$try\E/!;
File::Find::find( sub {
my $item = $File::Find::name;
if(-d) {
diff --git a/lib/Pod/InputObjects.pm b/lib/Pod/InputObjects.pm
index 1432895e91..174759aa9c 100644
--- a/lib/Pod/InputObjects.pm
+++ b/lib/Pod/InputObjects.pm
@@ -2,7 +2,7 @@
# Pod/InputObjects.pm -- package which defines objects for input streams
# and paragraphs and commands when parsing POD docs.
#
-# Copyright (C) 1996-1999 by Bradford Appleton. All rights reserved.
+# Copyright (C) 1996-2000 by Bradford Appleton. All rights reserved.
# This file is part of "PodParser". PodParser is free software;
# you can redistribute it and/or modify it under the same terms
# as Perl itself.
@@ -11,7 +11,7 @@
package Pod::InputObjects;
use vars qw($VERSION);
-$VERSION = 1.090; ## Current version of this package
+$VERSION = 1.093; ## Current version of this package
require 5.004; ## requires this Perl version or later
#############################################################################
diff --git a/lib/Pod/ParseUtils.pm b/lib/Pod/ParseUtils.pm
index a66e8f5e8b..2b3734fef9 100644
--- a/lib/Pod/ParseUtils.pm
+++ b/lib/Pod/ParseUtils.pm
@@ -1,7 +1,7 @@
#############################################################################
# Pod/ParseUtils.pm -- helpers for POD parsing and conversion
#
-# Copyright (C) 1999 by Marek Rouchal. All rights reserved.
+# Copyright (C) 1999-2000 by Marek Rouchal. All rights reserved.
# This file is part of "PodParser". PodParser is free software;
# you can redistribute it and/or modify it under the same terms
# as Perl itself.
@@ -305,32 +305,38 @@ sub parse {
#warn "DEBUG: link=$_\n";
# only page
- if(m!^(\w+(?:::\w+)*)\s*(\(\w*\)|)$!) {
- $page = $1 . $2;
+ # problem: a lot of people use (), or (1) or the like to indicate
+ # man page sections. But this collides with L<func()> that is supposed
+ # to point to an internal funtion...
+ # I would like the following better, here and below:
+ #if(m!^(\w+(?:::\w+)*)$!) {
+ my $page_rx = '[\w.]+(?:::[\w.]+)*';
+ if(m!^($page_rx)$!o) {
+ $page = $1;
$type = 'page';
}
- # alttext, page and section
- elsif(m!^(.+?)\s*[|]\s*(\w+(?:::\w+)*)\s*(\(\w*\)|)\s*/\s*"(.+)"$!) {
- ($alttext, $page, $node) = ($1, $2 . $3, $4);
+ # alttext, page and "section"
+ elsif(m!^(.+?)\s*[|]\s*($page_rx)\s*/\s*"(.+)"$!o) {
+ ($alttext, $page, $node) = ($1, $2, $3);
$type = 'section';
}
- # page and section
- elsif(m!^(\w+(?:::\w+)*)\s*(\(\w*\)|)\s*/\s*"(.+)"$!) {
- ($page, $node) = ($1 . $2, $3);
+ # page and "section"
+ elsif(m!^($page_rx)\s*/\s*"(.+)"$!o) {
+ ($page, $node) = ($1, $2);
$type = 'section';
}
# page and item
- elsif(m!^(\w+(?:::\w+)*)\s*(\(\w*\)|)\s*/\s*(.+)$!) {
- ($page, $node) = ($1 . $2, $3);
+ elsif(m!^($page_rx)\s*/\s*(.+)$!o) {
+ ($page, $node) = ($1, $2);
$type = 'item';
}
- # only section
- elsif(m!^(?:/\s*|)"(.+)"$!) {
+ # only "section"
+ elsif(m!^/?"(.+)"$!) {
$node = $1;
$type = 'section';
}
# only item
- elsif(m!^/(.+)$!) {
+ elsif(m!^\s*/(.+)$!) {
$node = $1;
$type = 'item';
}
@@ -340,16 +346,16 @@ sub parse {
$type = 'hyperlink';
}
# alttext, page and item
- elsif(m!^(.+?)\s*[|]\s*(\w+(?:::\w+)*)\s*(\(\w*\)|)\s*/\s*(.+)$!) {
- ($alttext, $page, $node) = ($1, $2 . $3, $4);
+ elsif(m!^(.+?)\s*[|]\s*($page_rx)\s*/\s*(.+)$!o) {
+ ($alttext, $page, $node) = ($1, $2, $3);
$type = 'item';
}
# alttext and page
- elsif(m!^(.+?)\s*[|]\s*(\w+(?:::\w+)*)\s*(\(\w*\)|)$!) {
- ($alttext, $page) = ($1, $2 . $3);
+ elsif(m!^(.+?)\s*[|]\s*($page_rx)$!o) {
+ ($alttext, $page) = ($1, $2);
$type = 'page';
}
- # alttext and section
+ # alttext and "section"
elsif(m!^(.+?)\s*[|]\s*(?:/\s*|)"(.+)"$!) {
($alttext, $node) = ($1,$2);
$type = 'section';
@@ -368,9 +374,17 @@ sub parse {
$node = $_;
$type = 'item';
}
+ # collapse whitespace in nodes
+ $node =~ s/\s+/ /gs;
- if($page =~ /[(]\w*[)]$/) {
- $self->warning("section in `$page' deprecated");
+ #if($page =~ /[(]\w*[)]$/) {
+ # $self->warning("section in '$page' deprecated");
+ #}
+ if($node =~ m:[|/]:) {
+ $self->warning("node '$node' contains non-escaped | or /");
+ }
+ if($alttext =~ m:[|/]:) {
+ $self->warning("alternative text '$node' contains non-escaped | or /");
}
$self->{-page} = $page;
$self->{-node} = $node;
@@ -559,18 +573,24 @@ sub link {
my $self = shift;
my $link = $self->page() || '';
if($self->node()) {
+ my $node = $self->node();
+ $text =~ s/\|/E<verbar>/g;
+ $text =~ s:/:E<sol>:g;
if($self->type() eq 'section') {
- $link .= ($link ? '/' : '') . '"' . $self->node() . '"';
+ $link .= ($link ? '/' : '') . '"' . $node . '"';
}
elsif($self->type() eq 'hyperlink') {
$link = $self->node();
}
else { # item
- $link .= '/' . $self->node();
+ $link .= '/' . $node;
}
}
if($self->alttext()) {
- $link = $self->alttext() . '|' . $link;
+ my $text = $self->alttext();
+ $text =~ s/\|/E<verbar>/g;
+ $text =~ s:/:E<sol>:g;
+ $link = "$text|$link";
}
$link;
}
diff --git a/lib/Pod/Parser.pm b/lib/Pod/Parser.pm
index c727142506..bafabba093 100644
--- a/lib/Pod/Parser.pm
+++ b/lib/Pod/Parser.pm
@@ -1,7 +1,7 @@
#############################################################################
# Pod/Parser.pm -- package which defines a base class for parsing POD docs.
#
-# Copyright (C) 1996-1999 by Bradford Appleton. All rights reserved.
+# Copyright (C) 1996-2000 by Bradford Appleton. All rights reserved.
# This file is part of "PodParser". PodParser is free software;
# you can redistribute it and/or modify it under the same terms
# as Perl itself.
@@ -10,7 +10,7 @@
package Pod::Parser;
use vars qw($VERSION);
-$VERSION = 1.091; ## Current version of this package
+$VERSION = 1.093; ## Current version of this package
require 5.004; ## requires this Perl version or later
#############################################################################
@@ -55,9 +55,9 @@ Pod::Parser - base class for creating POD filters and translators
sub interior_sequence {
my ($parser, $seq_command, $seq_argument) = @_;
## Expand an interior sequence; sample actions might be:
- return "*$seq_argument*" if ($seq_command = 'B');
- return "`$seq_argument'" if ($seq_command = 'C');
- return "_${seq_argument}_'" if ($seq_command = 'I');
+ return "*$seq_argument*" if ($seq_command eq 'B');
+ return "`$seq_argument'" if ($seq_command eq 'C');
+ return "_${seq_argument}_'" if ($seq_command eq 'I');
## ... other sequence commands and their resulting text
}
@@ -142,8 +142,8 @@ For the most part, the B<Pod::Parser> base class should be able to
do most of the input parsing for you and leave you free to worry about
how to intepret the commands and translate the result.
-Note that all we have described here in this quick overview is
-the simplest most straightforward use of B<Pod::Parser> to do stream-based
+Note that all we have described here in this quick overview is the
+simplest most straightforward use of B<Pod::Parser> to do stream-based
parsing. It is also possible to use the B<Pod::Parser::parse_text> function
to do more sophisticated tree-based parsing. See L<"TREE-BASED PARSING">.
@@ -599,7 +599,7 @@ Please note that the B<preprocess_line()> method is invoked I<before>
the B<preprocess_paragraph()> method. After all (possibly preprocessed)
lines in a paragraph have been assembled together and either it has been
determined that the paragraph is part of the POD documentation from one
-of the selected sections or the C<-want_nonPODs> option is true,
+of the selected sections or the C<-want_nonPODs> option is true,
then B<preprocess_paragraph()> is invoked.
The base class implementation of this method returns the given text.
@@ -718,13 +718,6 @@ is a reference to the parse-tree object.
=cut
-## This global regex is used to see if the text before a '>' inside
-## an interior sequence looks like '-' or '=', but not '--', '==',
-## '!=', '$-', '$=' or <<op>>=
-use vars qw( $ARROW_RE );
-$ARROW_RE = join('', qw{ (?: [^-+*/=!&|%^x.<>$]= | [^-$]- )$ });
-#$ARROW_RE = qr/(?:[^-+*/=!&|%^x.<>$]+=|[^-$]+-)$/; ## 5.005+ only!
-
sub parse_text {
my $self = shift;
local $_ = '';
@@ -738,7 +731,7 @@ sub parse_text {
my $text = shift;
my $line = shift;
my $file = $self->input_file();
- my ($cmd, $prev) = ('', '');
+ my $cmd = "";
## Convert method calls into closures, for our convenience
my $xseq_sub = $expand_seq;
@@ -757,7 +750,7 @@ sub parse_text {
ref $xseq_sub or $xseq_sub = sub { shift()->$expand_seq(@_) };
ref $xtext_sub or $xtext_sub = sub { shift()->$expand_text(@_) };
ref $xptree_sub or $xptree_sub = sub { shift()->$expand_ptree(@_) };
-
+
## Keep track of the "current" interior sequence, and maintain a stack
## of "in progress" sequences.
##
@@ -769,52 +762,82 @@ sub parse_text {
##
my $seq = Pod::ParseTree->new();
my @seq_stack = ($seq);
+ my ($ldelim, $rdelim) = ('', '');
## Iterate over all sequence starts/stops, newlines, & text
## (NOTE: split with capturing parens keeps the delimiters)
$_ = $text;
- for ( split /([A-Z]<|>|\n)/ ) {
- ## Keep track of line count
- ++$line if ($_ eq "\n");
- ## Look for the beginning of a sequence
- if ( /^([A-Z])(<)$/ ) {
+ my @tokens = split /([A-Z]<(?:<+\s+)?)/;
+ while ( @tokens ) {
+ $_ = shift @tokens;
+ ## Look for the beginning of a sequencd
+ if ( /^([A-Z])(<(?:<+\s+)?)$/ ) {
## Push a new sequence onto the stack of those "in-progress"
+ ($cmd, $ldelim) = ($1, $2);
$seq = Pod::InteriorSequence->new(
- -name => ($cmd = $1),
- -ldelim => $2, -rdelim => '',
- -file => $file, -line => $line
+ -name => $cmd,
+ -ldelim => $ldelim, -rdelim => '',
+ -file => $file, -line => $line
);
+ $ldelim =~ s/\s+$//, ($rdelim = $ldelim) =~ tr/</>/;
(@seq_stack > 1) and $seq->nested($seq_stack[-1]);
push @seq_stack, $seq;
}
- ## Look for sequence ending (preclude '->' and '=>' inside C<...>)
- elsif ( (@seq_stack > 1) and
- /^>$/ and ($cmd ne 'C' or $prev !~ /$ARROW_RE/o) )
- {
- ## End of current sequence, record terminating delimiter
- $seq->rdelim($_);
- ## Pop it off the stack of "in progress" sequences
- pop @seq_stack;
- ## Append result to its parent in current parse tree
- $seq_stack[-1]->append($expand_seq ? &$xseq_sub($self,$seq) : $seq);
- ## Remember the current cmd-name
- $cmd = (@seq_stack > 1) ? $seq_stack[-1]->name : '';
+ ## Look for sequence ending
+ elsif ( @seq_stack > 1 ) {
+ ## Make sure we match the right kind of closing delimiter
+ my ($seq_end, $post_seq) = ("", "");
+ if ( ($ldelim eq '<' and /\A(.*?)(>)/s)
+ or /\A(.*?)(\s+$rdelim)/s )
+ {
+ ## Found end-of-sequence, capture the interior and the
+ ## closing the delimiter, and put the rest back on the
+ ## token-list
+ $post_seq = substr($_, length($1) + length($2));
+ ($_, $seq_end) = ($1, $2);
+ (length $post_seq) and unshift @tokens, $post_seq;
+ }
+ if (length) {
+ ## In the middle of a sequence, append this text to it, and
+ ## dont forget to "expand" it if that's what the caller wanted
+ $seq->append($expand_text ? &$xtext_sub($self,$_,$seq) : $_);
+ $_ .= $seq_end;
+ }
+ if (length $seq_end) {
+ ## End of current sequence, record terminating delimiter
+ $seq->rdelim($seq_end);
+ ## Pop it off the stack of "in progress" sequences
+ pop @seq_stack;
+ ## Append result to its parent in current parse tree
+ $seq_stack[-1]->append($expand_seq ? &$xseq_sub($self,$seq)
+ : $seq);
+ ## Remember the current cmd-name and left-delimiter
+ $cmd = (@seq_stack > 1) ? $seq_stack[-1]->name : '';
+ $ldelim = (@seq_stack > 1) ? $seq_stack[-1]->ldelim : '';
+ $ldelim =~ s/\s+$//, ($rdelim = $ldelim) =~ tr/</>/;
+ }
}
elsif (length) {
## In the middle of a sequence, append this text to it, and
## dont forget to "expand" it if that's what the caller wanted
$seq->append($expand_text ? &$xtext_sub($self,$_,$seq) : $_);
}
- ## Remember the "current" sequence and the previously seen token
- ($seq, $prev) = ( $seq_stack[-1], $_ );
+ ## Keep track of line count
+ $line += tr/\n//;
+ ## Remember the "current" sequence
+ $seq = $seq_stack[-1];
}
## Handle unterminated sequences
my $errorsub = (@seq_stack > 1) ? $self->errorsub() : undef;
while (@seq_stack > 1) {
($cmd, $file, $line) = ($seq->name, $seq->file_line);
+ $ldelim = $seq->ldelim;
+ ($rdelim = $ldelim) =~ tr/</>/;
+ $rdelim =~ s/^(\S+)(\s*)$/$2$1/;
pop @seq_stack;
- my $errmsg = "** Unterminated $cmd<...> at $file line $line\n";
+ my $errmsg = "*** WARNING: unterminated ${cmd}${ldelim}...${rdelim}".
+ " at line $line in file $file\n";
(ref $errorsub) and &{$errorsub}($errmsg)
or (defined $errorsub) and $self->$errorsub($errmsg)
or warn($errmsg);
@@ -1034,9 +1057,20 @@ sub parse_from_filehandle {
++$plines;
}
- ## See of this line is blank and ends the current paragraph.
+ ## See if this line is blank and ends the current paragraph.
## If it isnt, then keep iterating until it is.
- next unless (($textline =~ /^\s*$/) && (length $paragraph));
+ next unless (($textline =~ /^(\s*)$/) && (length $paragraph));
+
+ ## Issue a warning about any non-empty blank lines
+ if ( length($1) > 1 ) {
+ my $errorsub = $self->errorsub();
+ my $file = $self->input_file();
+ my $errmsg = "*** WARNING: line containing nothing but whitespace".
+ " in paragraph at line $nlines in file $file\n";
+ (ref $errorsub) and &{$errorsub}($errmsg)
+ or (defined $errorsub) and $self->$errorsub($errmsg)
+ or warn($errmsg);
+ }
## Now process the paragraph
parse_paragraph($self, $paragraph, ($nlines - $plines) + 1);
diff --git a/lib/Pod/Select.pm b/lib/Pod/Select.pm
index 94ded8697a..150dfca1fe 100644
--- a/lib/Pod/Select.pm
+++ b/lib/Pod/Select.pm
@@ -1,7 +1,7 @@
#############################################################################
# Pod/Select.pm -- function to select portions of POD docs
#
-# Copyright (C) 1996-1999 by Bradford Appleton. All rights reserved.
+# Copyright (C) 1996-2000 by Bradford Appleton. All rights reserved.
# This file is part of "PodParser". PodParser is free software;
# you can redistribute it and/or modify it under the same terms
# as Perl itself.
@@ -10,7 +10,7 @@
package Pod::Select;
use vars qw($VERSION);
-$VERSION = 1.090; ## Current version of this package
+$VERSION = 1.093; ## Current version of this package
require 5.004; ## requires this Perl version or later
#############################################################################
diff --git a/lib/Pod/Usage.pm b/lib/Pod/Usage.pm
index aa3a009dcf..9f01a52ebb 100644
--- a/lib/Pod/Usage.pm
+++ b/lib/Pod/Usage.pm
@@ -1,7 +1,7 @@
#############################################################################
# Pod/Usage.pm -- print usage messages for the running script.
#
-# Copyright (C) 1996-1999 by Bradford Appleton. All rights reserved.
+# Copyright (C) 1996-2000 by Bradford Appleton. All rights reserved.
# This file is part of "PodParser". PodParser is free software;
# you can redistribute it and/or modify it under the same terms
# as Perl itself.
@@ -10,7 +10,7 @@
package Pod::Usage;
use vars qw($VERSION);
-$VERSION = 1.090; ## Current version of this package
+$VERSION = 1.093; ## Current version of this package
require 5.004; ## requires this Perl version or later
=head1 NAME
diff --git a/op.c b/op.c
index c8276e0c00..04a84b8e6a 100644
--- a/op.c
+++ b/op.c
@@ -3109,14 +3109,14 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *id, OP *arg)
if (version != Nullop) {
SV *vesv = ((SVOP*)version)->op_sv;
- if (arg == Nullop && !SvNIOK(vesv)) {
+ if (arg == Nullop && !SvNIOKp(vesv)) {
arg = version;
}
else {
OP *pack;
SV *meth;
- if (version->op_type != OP_CONST || !SvNIOK(vesv))
+ if (version->op_type != OP_CONST || !SvNIOKp(vesv))
Perl_croak(aTHX_ "Version number must be constant number");
/* Make copy of id so we don't free it twice */
@@ -3137,7 +3137,7 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *id, OP *arg)
/* Fake up an import/unimport */
if (arg && arg->op_type == OP_STUB)
imop = arg; /* no import on explicit () */
- else if (SvNIOK(((SVOP*)id)->op_sv)) {
+ else if (SvNIOKp(((SVOP*)id)->op_sv)) {
imop = Nullop; /* use 5.0; */
}
else {
diff --git a/perl.c b/perl.c
index eba7e5cd65..d1bbb274d7 100644
--- a/perl.c
+++ b/perl.c
@@ -2122,7 +2122,7 @@ Perl_moreswitches(pTHX_ char *s)
s++;
return s;
case 'v':
- printf(Perl_form(aTHX_ "\nThis is perl, v%v built for %s",
+ printf(Perl_form(aTHX_ "\nThis is perl, v%vd built for %s",
PL_patchlevel, ARCHNAME));
#if defined(LOCAL_PATCH_COUNT)
if (LOCAL_PATCH_COUNT > 0)
@@ -2166,6 +2166,9 @@ Perl_moreswitches(pTHX_ char *s)
#ifdef __MINT__
printf("MiNT port by Guido Flohr, 1997-1999\n");
#endif
+#ifdef EPOC
+ printf("EPOC port by Olaf Flebbe, 1999-2000\n");
+#endif
#ifdef BINARY_BUILD_NOTICE
BINARY_BUILD_NOTICE;
#endif
diff --git a/pod/Win32.pod b/pod/Win32.pod
index 08043e83ec..37c5cbd43d 100644
--- a/pod/Win32.pod
+++ b/pod/Win32.pod
@@ -132,8 +132,8 @@ same value.
=item Win32::GetLongPathName(PATHNAME)
-[CORE] Returns a representaion of PATHNAME comprised of longname
-compnents (if any). The result may not necessarily be longer
+[CORE] Returns a representaion of PATHNAME composed of longname
+components (if any). The result may not necessarily be longer
than PATHNAME. No attempt is made to convert PATHNAME to the
absolute path. Compare with Win32::GetShortPathName and
Win32::GetFullPathName.
@@ -156,7 +156,7 @@ for Windows NT. In scalar context it returns just the ID.
=item Win32::GetShortPathName(PATHNAME)
-[CORE] Returns a representation of PATHNAME comprised only of
+[CORE] Returns a representation of PATHNAME composed only of
short (8.3) path components. The result may not necessarily be
shorter than PATHNAME. Compare with Win32::GetFullPathName and
Win32::GetLongPathName.
diff --git a/pod/perldelta.pod b/pod/perldelta.pod
index 2bedcdb6c9..f9e9f04b69 100644
--- a/pod/perldelta.pod
+++ b/pod/perldelta.pod
@@ -57,6 +57,33 @@ cases remains unchanged:
See L<perldata>.
+=head2 Perl's version numbering has changed
+
+Beginning with Perl version 5.6, the version number convention has been
+changed to a "dotted integer" scheme that is more commonly found in open
+source projects.
+
+Maintenance versions of v5.6.0 will be released as v5.6.1, v5.6.2 etc.
+The next development series following v5.6 will be numbered v5.7.x,
+beginning with v5.7.0, and the next major production release following
+v5.6 will be v5.8.
+
+The English module now sets $PERL_VERSION to $^V (a string value) rather
+than C<$]> (a numeric value). (This is a potential incompatibility.
+Send us a report via perlbug if you are affected by this.)
+
+The v1.2.3 syntax is also now legal in Perl.
+See L<Support for strings represented as a vector of ordinals> for more on that.
+
+To cope with the new versioning system's use of at least three significant
+digits for each version component, the method used for incrementing the
+subversion number has also changed slightly. We assume that versions older
+than v5.6 have been incrementing the subversion component in multiples of
+10. Versions after v5.6.0 will increment them by 1. Thus, using the new
+notation, 5.005_03 is the same as v5.5.30, and the first maintenance
+version following v5.6.0 will be v5.6.1, which amounts to a floating point
+value of 5.006_001).
+
=item Possibly changed pseudo-random number generator
In 5.005_0x and earlier, perl's rand() function used the C library
@@ -286,29 +313,6 @@ create new threads from Perl (i.e., C<use Thread;> will not work with
interpreter threads). C<use Thread;> continues to be available when you
ask for -Duse5005threads, bugs and all.
-=head2 Perl's version numbering has changed
-
-Beginning with Perl version 5.6, the version number convention has been
-changed to a "dotted tuple" scheme that is more commonly found in open
-source projects.
-
-Maintenance versions of v5.6.0 will be released as v5.6.1, v5.6.2 etc.
-The next development series following v5.6 will be numbered v5.7.x,
-beginning with v5.7.0, and the next major production release following
-v5.6 will be v5.8.
-
-The v1.2.3 syntax is also now legal in Perl. See L<Support for version tuples>
-for more on that.
-
-To cope with the new versioning system's use of at least three significant
-digits for each version component, the method used for incrementing the
-subversion number has also changed slightly. We assume that versions older
-than v5.6 have been incrementing the subversion component in multiples of
-10. Versions after v5.6 will increment them by 1. Thus, using the new
-notation, 5.005_03 is the same as v5.5.30, and the first maintenance
-version following v5.6 will be v5.6.1, which amounts to a floating point
-value of 5.006_001).
-
=head2 New Configure flags
The following new flags may be enabled on the Configure command line
@@ -455,36 +459,42 @@ mostly useful as an alternative to the C<vars> pragma, but also provides
the opportunity to introduce typing and other attributes for such
variables. See L<perlfunc/our>.
-=head2 Support for version tuples
+=head2 Support for strings represented as a vector of ordinals
-Literals of the form v1.2.3.4 are now parsed as the utf8 string
-C<"\x{1}\x{2}\x{3}\x{4}">. This allows comparing version numbers using
-regular string comparison operators C<eq>, C<ne>, C<lt>, C<gt> etc.
+Literals of the form v1.2.3.4 are now parsed as a string composed of
+of characters with the specified ordinals. This is an alternative, more
+readable way to construct (possibly unicode) strings instead of
+interpolating characters, as in C<"\x{1}\x{2}\x{3}\x{4}">.
-These "dotted tuples" are dual-valued. They are both strings of utf8
-characters, and floating point numbers. Thus v1.2.3.4 has the string
-value C<"\x{1}\x{2}\x{3}\x{4}"> and the numeric value 1.002_003_004.
-As another example, v5.5.640 has the string value C<"\x{5}\x{5}\x{280}">
-(remember 280 hexadecimal is 640 decimal) and the numeric value
-5.005_64.
+Strings written in this form are also useful to represent version "numbers".
+It is easy to compare such version "numbers" (which are really just plain
+strings) using any of the usual string comparison operators C<eq>, C<ne>,
+C<lt>, C<gt>, etc., or perform bitwise string operations on them using C<|>,
+C<&>, etc.
In conjunction with the new C<$^V> magic variable (which contains
-the perl version in this format), such literals can be used to
-check if you're running a particular version of Perl.
+the perl version as a string), such literals can be used as a readable way
+to check if you're running a particular version of Perl:
+ # this will parse in older versions of Perl also
if ($^V and $^V gt v5.5.640) {
- # new style version numbers are supported
+ # new features supported
}
-C<require> and C<use> also support such literals:
+C<require> and C<use> also have some special magic to support such literals.
+They will be interpreted as a version rather than as a module name:
+
+ require v5.6.0; # croak if $^V lt v5.6.0
+ use v5.6.0; # same, but croaks at compile-time
- require v5.6.0; # croak if $^V lt v5.6.0
- use v5.6.0; # same, but croaks at compile-time
+Also, C<sprintf> and C<printf> support the Perl-specific format flag C<%v>
+to print ordinals of characters in arbitrary strings:
-C<sprintf> and C<printf> support the Perl-specific format type C<%v>
-to print arbitrary strings as dotted tuples.
+ printf "v%vd", $^V; # prints current version, such as "v5.5.650"
+ printf "%*vX", ":", $addr; # formats IPv6 address
+ printf "%*vb", "", $bits; # displays bitstring as contiguous 0's and 1's
- printf "v%v", $^V; # prints current version, such as "v5.5.650"
+See L<perlop/"Strings of Character"> for additional information.
=head2 Weak references
@@ -851,9 +861,12 @@ only during normal running are warranted. See L<perlvar>.
=head2 New variable $^V contains Perl version in v5.6.0 format
-C<$^V> contains the Perl version number as a version tuple that
-can be used in string or numeric comparisons. See
-C<Support for version tuples> for an example.
+C<$^V> contains the Perl version number as a string composed of
+characters whose ordinals match the version numbers, so that it may
+be used in string comparisons.
+
+See C<Support for strings represented as a vector of ordinals> for an
+example.
=head2 Optional Y2K warnings
@@ -1388,6 +1401,11 @@ For other details, see L<Benchmark>.
The Devel::Peek module provides access to the internal representation
of Perl variables and data. It is a data debugging tool for the XS programmer.
+=item English
+
+$PERL_VERSION now stands for C<$^V> (a string value) rather than for C<$]>
+(a numeric value).
+
=item ExtUtils::MakeMaker
change#4135, also needs docs in module pod
diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index e11364d509..f4cee09073 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -3549,9 +3549,17 @@ rename(2) manpage or equivalent system documentation for details.
=item require
Demands some semantics specified by EXPR, or by C<$_> if EXPR is not
-supplied. If a version number or tuple is specified, or if EXPR is
-numeric, demands that the current version of Perl
-(C<$^V> or C<$]> or $PERL_VERSION) be equal or greater than EXPR.
+supplied.
+
+If a VERSION is specified as a literal of the form v5.6.0,
+demands that the current version of Perl (C<$^V> or $PERL_VERSION) be
+at least as recent as that version, at run time. (For compatibility
+with older versions of Perl, a numeric argument will also be interpreted
+as VERSION.) Compare with L</use>, which can do a similar check at
+compile time.
+
+ require v5.6.0; # run time version check
+ require 5.005_03; # same, number still supported for compatibility
Otherwise, demands that a library file be included if it hasn't already
been included. The file is included via the do-FILE mechanism, which is
@@ -4337,10 +4345,6 @@ In addition, Perl permits the following widely-supported conversions:
%n special: *stores* the number of characters output so far
into the next variable in the parameter list
-And the following Perl-specific conversion:
-
- %v a string, output as a tuple of integers ("Perl" is 80.101.114.108)
-
Finally, for backward (and we do mean "backward") compatibility, Perl
permits these unnecessary but widely-supported conversions:
@@ -4366,9 +4370,13 @@ and the conversion letter:
h interpret integer as C type "short" or "unsigned short"
If no flags, interpret integer as C type "int" or "unsigned"
-There is also one Perl-specific flag:
+There are also two Perl-specific flags:
V interpret integer as Perl's standard integer type
+ v interpret string as a vector of integers, output as
+ numbers separated either by dots, or by an arbitrary
+ string received from the argument list when the flag
+ is preceded by C<*>
Where a number would appear in the flags, an asterisk (C<*>) may be
used instead, in which case Perl uses the next item in the parameter
@@ -4376,6 +4384,13 @@ list as the given number (that is, as the field width or precision).
If a field width obtained through C<*> is negative, it has the same
effect as the C<-> flag: left-justification.
+The C<v> flag is useful for displaying ordinal values of characters
+in arbitrary strings:
+
+ printf "version is v%vd\n", $^V; # Perl's version
+ printf "address is %*vX\n", ":", $addr; # IPv6 address
+ printf "bits are %*vb\n", "", $bits; # random bitstring
+
If C<use locale> is in effect, the character used for the decimal
point in formatted real numbers is affected by the LC_NUMERIC locale.
See L<perllocale>.
@@ -5222,12 +5237,14 @@ Note the LIST is prepended whole, not one element at a time, so the
prepended elements stay in the same order. Use C<reverse> to do the
reverse.
+=item use Module VERSION LIST
+
+=item use Module VERSION
+
=item use Module LIST
=item use Module
-=item use Module VERSION LIST
-
=item use VERSION
Imports some semantics into the current package from the named module,
@@ -5238,13 +5255,17 @@ package. It is exactly equivalent to
except that Module I<must> be a bareword.
-If the first argument to C<use> is a number or a version tuple, it is
-treated as a version instead of a module name. If the version
-of the Perl interpreter is less than VERSION, then an error message
-is printed and Perl exits immediately.
+VERSION, which can be specified as a literal of the form v5.6.0, demands
+that the current version of Perl (C<$^V> or $PERL_VERSION) be at least
+as recent as that version. (For compatibility with older versions of Perl,
+a numeric literal will also be interpreted as VERSION.) If the version
+of the running Perl interpreter is less than VERSION, then an error
+message is printed and Perl exits immediately without attempting to
+parse the rest of the file. Compare with L</require>, which can do a
+similar check at run time.
- use 5.005_03; # version number
- use v5.6.0; # version tuple
+ use v5.6.0; # compile time version check
+ use 5.005_03; # same, number still supported for compatibility
This is often useful if you need to check the current Perl version before
C<use>ing library modules that have changed in incompatible ways from
@@ -5271,9 +5292,12 @@ That is exactly equivalent to
If the VERSION argument is present between Module and LIST, then the
C<use> will call the VERSION method in class Module with the given
version as an argument. The default VERSION method, inherited from
-the Universal class, croaks if the given version is larger than the
-value of the variable C<$Module::VERSION>. (Note that there is not a
-comma after VERSION!)
+the UNIVERSAL class, croaks if the given version is larger than the
+value of the variable C<$Module::VERSION>.
+
+Again, there is a distinction between omitting LIST (C<import> called
+with no arguments) and an explicit empty LIST C<()> (C<import> not
+called). Note that there is no comma after VERSION!
Because this is a wide-open interface, pragmas (compiler directives)
are also implemented this way. Currently implemented pragmas are:
diff --git a/pod/perlhist.pod b/pod/perlhist.pod
index 7a8d1e5879..0e1df8abd3 100644
--- a/pod/perlhist.pod
+++ b/pod/perlhist.pod
@@ -334,6 +334,7 @@ the strings?).
5.005_63 1999-Dec-09
5.5.640 2000-Feb-02
5.5.650 2000-Feb-08 5.6 beta1
+ 5.5.660 2000-Feb-22 5.6 beta2
=head2 SELECTED RELEASE SIZES
diff --git a/pod/perlipc.pod b/pod/perlipc.pod
index 3034197e14..3649e4f883 100644
--- a/pod/perlipc.pod
+++ b/pod/perlipc.pod
@@ -126,7 +126,7 @@ or even the more elaborate:
use POSIX ":sys_wait_h";
sub REAPER {
my $child;
- while ($child = waitpid(-1,WNOHANG)) {
+ while (($child = waitpid(-1,WNOHANG)) > 0) {
$Kid_Status{$child} = $?;
}
$SIG{CHLD} = \&REAPER; # still loathe sysV
diff --git a/pod/perlop.pod b/pod/perlop.pod
index d932704666..7cb3450032 100644
--- a/pod/perlop.pod
+++ b/pod/perlop.pod
@@ -1802,17 +1802,18 @@ operation you intend by using C<""> or C<0+>, as in the examples below.
See L<perlfunc/vec> for information on how to manipulate individual bits
in a bit vector.
-=head2 Version tuples
-
-A literal of the form C<v1.20.300.4000> is parsed as a dual-valued quantity.
-It has the string value of C<"\x{1}\x{14}\x{12c}\x{fa0}"> (i.e., a UTF-8
-string) and a numeric value of C<1 + 20/1000 + 300/1000000 + 4000/1000000000>.
-This is useful for representing Unicode strings, and for comparing version
-numbers using the string comparison operators, C<cmp>, C<gt>, C<lt> etc.
-
-Such "version tuples" or "vectors" are accepted by both C<require> and
-C<use>. The C<$^V> variable contains the running Perl interpreter's
-version in this format. See L<perlvar/$^V>.
+=head2 Strings of Character
+
+A literal of the form C<v1.20.300.4000> is parsed as a string composed
+of characters with the specified ordinals. This provides an alternative,
+more readable way to construct strings, rather than use the somewhat less
+readable interpolation form C<"\x{1}\x{14}\x{12c}\x{fa0}">. This is useful
+for representing Unicode strings, and for comparing version "numbers"
+using the string comparison operators, C<cmp>, C<gt>, C<lt> etc.
+
+Such literals are accepted by both C<require> and C<use> for doing a version
+check. The C<$^V> special variable also contains the running Perl
+interpreter's version in this form. See L<perlvar/$^V>.
=head2 Integer Arithmetic
diff --git a/pod/perlthrtut.pod b/pod/perlthrtut.pod
index fc88561da7..88849dd662 100644
--- a/pod/perlthrtut.pod
+++ b/pod/perlthrtut.pod
@@ -722,8 +722,7 @@ subroutine's behavior while your program is actually running.
The basic subroutine lock looks like this:
- sub test_sub {
- use attrs qw(locked);
+ sub test_sub :locked {
}
This ensures that only one thread will be executing this subroutine at
@@ -738,8 +737,7 @@ it. A more elaborate example looks like this:
new Thread \&thread_sub, 3;
new Thread \&thread_sub, 4;
- sub sync_sub {
- use attrs qw(locked);
+ sub sync_sub :locked {
my $CallingThread = shift @_;
print "In sync_sub for thread $CallingThread\n";
yield;
@@ -754,8 +752,8 @@ it. A more elaborate example looks like this:
print "$ThreadID is done with sync_sub\n";
}
-The use attrs qw(locked) locks sync_sub(), and if you run this, you
-can see that only one thread is in it at any one time.
+The C<locked> attribute tells perl to lock sync_sub(), and if you run
+this, you can see that only one thread is in it at any one time.
=head2 Methods
@@ -793,8 +791,7 @@ method attribute indicates whether the subroutine is really a method.
return bless [@_], $class;
}
- sub per_object {
- use attrs qw(locked method);
+ sub per_object :locked :method {
my ($class, $thrnum) = @_;
print "In per_object for thread $thrnum\n";
yield;
@@ -802,8 +799,7 @@ method attribute indicates whether the subroutine is really a method.
print "Exiting per_object for thread $thrnum\n";
}
- sub one_at_a_time {
- use attrs qw(locked);
+ sub one_at_a_time :locked {
my ($class, $thrnum) = @_;
print "In one_at_a_time for thread $thrnum\n";
yield;
@@ -817,8 +813,8 @@ thread is ever in one_at_a_time() at once.
=head2 Locking A Subroutine
-You can lock a subroutine as you would lock a variable. Subroutine
-locks work the same as a C<use attrs qw(locked)> in the subroutine,
+You can lock a subroutine as you would lock a variable. Subroutine locks
+work the same as specifying a C<locked> attribute for the subroutine,
and block all access to the subroutine for other threads until the
lock goes out of scope. When the subroutine isn't locked, any number
of threads can be in it at once, and getting a lock on a subroutine
@@ -827,10 +823,10 @@ subroutine looks like this:
lock(\&sub_to_lock);
-Simple enough. Unlike use attrs, which is a compile time option,
-locking and unlocking a subroutine can be done at runtime at your
+Simple enough. Unlike the C<locked> attribute, which is a compile time
+option, locking and unlocking a subroutine can be done at runtime at your
discretion. There is some runtime penalty to using lock(\&sub) instead
-of use attrs qw(locked), so make sure you're choosing the proper
+of the C<locked> attribute, so make sure you're choosing the proper
method to do the locking.
You'd choose lock(\&sub) when writing modules and code to run on both
diff --git a/pod/perlvar.pod b/pod/perlvar.pod
index 285a0d5863..6b4c659d3d 100644
--- a/pod/perlvar.pod
+++ b/pod/perlvar.pod
@@ -699,8 +699,6 @@ As of release 5 of Perl, assignment to C<$[> is treated as a compiler
directive, and cannot influence the behavior of any other file.
Its use is highly discouraged.
-=item $PERL_VERSION
-
=item $]
The version + patchlevel / 1000 of the Perl interpreter. This variable
@@ -713,7 +711,10 @@ of perl in the right bracket?) Example:
See also the documentation of C<use VERSION> and C<require VERSION>
for a convenient way to fail if the running Perl interpreter is too old.
-See C<$^V> for a more modern representation of the Perl version.
+The use of this variable is deprecated. The floating point representation
+can sometimes lead to inaccurate numeric comparisons. See C<$^V> for a
+more modern representation of the Perl version that allows accurate string
+comparisons.
=item $COMPILING
@@ -905,24 +906,23 @@ The time at which the program began running, in seconds since the
epoch (beginning of 1970). The values returned by the B<-M>, B<-A>,
and B<-C> filetests are based on this value.
-=item $PERL_VERSION_TUPLE
+=item $PERL_VERSION
=item $^V
The revision, version, and subversion of the Perl interpreter, represented
-as a "version tuple". Version tuples have both a numeric value and a
-string value. The numeric value is a floating point number that amounts
-to revision + version/1000 + subversion/1000000, and the string value
-is made of characters possibly in the UTF-8 range:
-C<chr($revision) . chr($version) . chr($subversion)>.
+as a string composed of characters with those ordinals. Thus in Perl v5.6.0
+it equals C<chr(5) . chr(6) . chr(0)> and will return true for
+C<$^V eq v5.6.0>. Note that the characters in this string value can
+potentially be in Unicode range.
This can be used to determine whether the Perl interpreter executing a
script is in the right range of versions. (Mnemonic: use ^V for Version
-control.) Example:
+Control.) Example:
- warn "No "our" declarations!\n" if $^V and $^V lt v5.6;
+ warn "No "our" declarations!\n" if $^V and $^V lt v5.6.0;
-See also the documentation of C<use VERSION> and C<require VERSION>
+See the documentation of C<use VERSION> and C<require VERSION>
for a convenient way to fail if the running Perl interpreter is too old.
See also C<$]> for an older representation of the Perl version.
diff --git a/pod/perlxs.pod b/pod/perlxs.pod
index a2755b8f2d..7359d34818 100644
--- a/pod/perlxs.pod
+++ b/pod/perlxs.pod
@@ -502,9 +502,9 @@ C<ST(1)>.
=head2 Default Parameter Values
-Default values for XSUB arguments can be specified by
-placing an assignment statement in the parameter list. The
-default value may be a number or a string. Defaults should
+Default values for XSUB arguments can be specified by placing an
+assignment statement in the parameter list. The default value may
+be a number, a string or the special string C<NO_INIT>. Defaults should
always be used on the right-most parameters only.
To allow the XSUB for rpcb_gettime() to have a default host
@@ -1314,6 +1314,19 @@ methods will be called as this:
THIS->set_blue( val );
+You could also write a single get/set method using an optional argument:
+
+ int
+ color::blue( val = NO_INIT )
+ int val
+ PROTOTYPE $;$
+ CODE:
+ if (items > 1)
+ THIS->set_blue( val );
+ RETVAL = THIS->blue();
+ OUTPUT:
+ RETVAL
+
If the function's name is B<DESTROY> then the C++ C<delete> function will be
called and C<THIS> will be given as its parameter. The generated C++ code for
diff --git a/pp_ctl.c b/pp_ctl.c
index 7c69e3526b..308c824b17 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2931,15 +2931,17 @@ PP(pp_require)
}
}
else if (!SvPOKp(sv)) { /* require 5.005_03 */
- NV n = SvNV(sv);
- rev = (UV)n;
- ver = (UV)((n-rev)*1000);
- sver = (UV)((((n-rev)*1000 - ver) + 0.0009) * 1000);
-
if ((NV)PERL_REVISION + ((NV)PERL_VERSION/(NV)1000)
+ ((NV)PERL_SUBVERSION/(NV)1000000)
+ 0.00000099 < SvNV(sv))
{
+ NV nrev = SvNV(sv);
+ UV rev = (UV)nrev;
+ NV nver = (nrev - rev) * 1000;
+ UV ver = (UV)(nver + 0.0009);
+ NV nsver = (nver - ver) * 1000;
+ UV sver = (UV)(nsver + 0.0009);
+
DIE(aTHX_ "Perl v%"UVuf".%"UVuf".%"UVuf" required--this is only version "
"v%d.%d.%d, stopped", rev, ver, sver, PERL_REVISION,
PERL_VERSION, PERL_SUBVERSION);
diff --git a/sv.c b/sv.c
index fcabe6b63d..fb33f383b4 100644
--- a/sv.c
+++ b/sv.c
@@ -5729,6 +5729,8 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
for (p = (char*)pat; p < patend; p = q) {
bool alt = FALSE;
bool left = FALSE;
+ bool vectorize = FALSE;
+ bool utf = FALSE;
char fill = ' ';
char plus = 0;
char intsize = 0;
@@ -5750,6 +5752,10 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
char ebuf[IV_DIG * 4 + NV_DIG + 32];
/* large enough for "%#.#f" --chip */
/* what about long double NVs? --jhi */
+
+ SV *vecsv;
+ U8 *vecstr = Null(U8*);
+ STRLEN veclen = 0;
char c;
int i;
unsigned base;
@@ -5759,6 +5765,8 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
STRLEN have;
STRLEN need;
STRLEN gap;
+ char *dotstr = ".";
+ STRLEN dotstrlen = 1;
for (q = p; q < patend && *q != '%'; ++q) ;
if (q > p) {
@@ -5791,6 +5799,30 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
q++;
continue;
+ case '*': /* printf("%*vX",":",$ipv6addr) */
+ if (q[1] != 'v')
+ break;
+ q++;
+ if (args)
+ vecsv = va_arg(*args, SV*);
+ else if (svix < svmax)
+ vecsv = svargs[svix++];
+ dotstr = SvPVx(vecsv,dotstrlen);
+ if (DO_UTF8(vecsv))
+ is_utf = TRUE;
+ /* FALL THROUGH */
+
+ case 'v':
+ vectorize = TRUE;
+ q++;
+ if (args)
+ vecsv = va_arg(*args, SV*);
+ else if (svix < svmax)
+ vecsv = svargs[svix++];
+ vecstr = (U8*)SvPVx(vecsv,veclen);
+ utf = DO_UTF8(vecsv);
+ continue;
+
default:
break;
}
@@ -5926,63 +5958,6 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
}
goto string;
- case 'v':
- if (args)
- argsv = va_arg(*args, SV*);
- else if (svix < svmax)
- argsv = svargs[svix++];
- {
- STRLEN len;
- U8 *str = (U8*)SvPVx(argsv,len);
- I32 vlen = len*3+1;
- SV *vsv = NEWSV(73,vlen);
- I32 ulen;
- I32 vfree = vlen;
- U8 *vptr = (U8*)SvPVX(vsv);
- STRLEN vcur = 0;
- bool utf = DO_UTF8(argsv);
-
- if (utf)
- is_utf = TRUE;
- while (len) {
- UV uv;
-
- if (utf)
- uv = utf8_to_uv(str, &ulen);
- else {
- uv = *str;
- ulen = 1;
- }
- str += ulen;
- len -= ulen;
- eptr = ebuf + sizeof ebuf;
- do {
- *--eptr = '0' + uv % 10;
- } while (uv /= 10);
- elen = (ebuf + sizeof ebuf) - eptr;
- while (elen >= vfree-1) {
- STRLEN off = vptr - (U8*)SvPVX(vsv);
- vfree += vlen;
- vlen *= 2;
- SvGROW(vsv, vlen);
- vptr = (U8*)SvPVX(vsv) + off;
- }
- memcpy(vptr, eptr, elen);
- vptr += elen;
- *vptr++ = '.';
- vfree -= elen + 1;
- vcur += elen + 1;
- }
- if (vcur) {
- vcur--;
- vptr[-1] = '\0';
- }
- SvCUR_set(vsv,vcur);
- eptr = SvPVX(vsv);
- elen = vcur;
- }
- goto string;
-
case '_':
/*
* The "%_" hack might have to be changed someday,
@@ -5997,6 +5972,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
is_utf = TRUE;
string:
+ vectorize = FALSE;
if (has_precis && elen > precis)
elen = precis;
break;
@@ -6020,7 +5996,22 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
/* FALL THROUGH */
case 'd':
case 'i':
- if (args) {
+ if (vectorize) {
+ I32 ulen;
+ if (!veclen) {
+ vectorize = FALSE;
+ break;
+ }
+ if (utf)
+ iv = (IV)utf8_to_uv(vecstr, &ulen);
+ else {
+ iv = *vecstr;
+ ulen = 1;
+ }
+ vecstr += ulen;
+ veclen -= ulen;
+ }
+ else if (args) {
switch (intsize) {
case 'h': iv = (short)va_arg(*args, int); break;
default: iv = va_arg(*args, int); break;
@@ -6086,7 +6077,23 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
base = 16;
uns_integer:
- if (args) {
+ if (vectorize) {
+ I32 ulen;
+ vector:
+ if (!veclen) {
+ vectorize = FALSE;
+ break;
+ }
+ if (utf)
+ uv = utf8_to_uv(vecstr, &ulen);
+ else {
+ uv = *vecstr;
+ ulen = 1;
+ }
+ vecstr += ulen;
+ veclen -= ulen;
+ }
+ else if (args) {
switch (intsize) {
case 'h': uv = (unsigned short)va_arg(*args, unsigned); break;
default: uv = va_arg(*args, unsigned); break;
@@ -6186,6 +6193,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
/* This is evil, but floating point is even more evil */
+ vectorize = FALSE;
if (args)
nv = va_arg(*args, NV);
else
@@ -6253,6 +6261,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
/* SPECIAL */
case 'n':
+ vectorize = FALSE;
i = SvCUR(sv) - origlen;
if (args) {
switch (intsize) {
@@ -6273,6 +6282,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
default:
unknown:
+ vectorize = FALSE;
if (!args && ckWARN(WARN_PRINTF) &&
(PL_op->op_type == OP_PRTF || PL_op->op_type == OP_SPRINTF)) {
SV *msg = sv_newmortal();
@@ -6311,7 +6321,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
need = (have > width ? have : width);
gap = need - have;
- SvGROW(sv, SvCUR(sv) + need + 1);
+ SvGROW(sv, SvCUR(sv) + need + dotstrlen + 1);
p = SvEND(sv);
if (esignlen && fill == '0') {
for (i = 0; i < esignlen; i++)
@@ -6337,10 +6347,22 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
memset(p, ' ', gap);
p += gap;
}
+ if (vectorize) {
+ if (veclen) {
+ memcpy(p, dotstr, dotstrlen);
+ p += dotstrlen;
+ }
+ else
+ vectorize = FALSE; /* done iterating over vecstr */
+ }
if (is_utf)
SvUTF8_on(sv);
*p = '\0';
SvCUR(sv) = p - SvPVX(sv);
+ if (vectorize) {
+ esignlen = 0;
+ goto vector;
+ }
}
}
diff --git a/t/comp/require.t b/t/comp/require.t
index f963a8ce30..cd97c55eda 100755
--- a/t/comp/require.t
+++ b/t/comp/require.t
@@ -7,7 +7,7 @@ BEGIN {
# don't make this lexical
$i = 1;
-print "1..20\n";
+print "1..19\n";
sub do_require {
%INC = ();
@@ -59,23 +59,23 @@ eval q{ use v10.0.2; };
print "# $@\nnot " unless $@ =~ /^Perl v10\.0\.2 required/;
print "ok ",$i++,"\n";
-my $ver = v5.5.630;
+my $ver = 5.005_63;
eval { require $ver; };
print "# $@\nnot " if $@;
print "ok ",$i++,"\n";
-$ver = v10.0.2;
+# check inaccurate fp
+$ver = 10.2;
eval { require $ver; };
-print "# $@\nnot " unless $@ =~ /^Perl v10\.0\.2 required/;
-print "ok ",$i++,"\n";
-
-print "not " unless v5.5.1 gt v5.5;
+print "# $@\nnot " unless $@ =~ /^Perl v10\.200\.0 required/;
print "ok ",$i++,"\n";
-print "not " unless 5.005_01 > v5.5;
+$ver = 10.000_02;
+eval { require $ver; };
+print "# $@\nnot " unless $@ =~ /^Perl v10\.0\.20 required/;
print "ok ",$i++,"\n";
-print "not " unless 5.005_64 - v5.5.640 < 0.0000001;
+print "not " unless v5.5.1 gt v5.5;
print "ok ",$i++,"\n";
{
diff --git a/t/lib/glob-basic.t b/t/lib/glob-basic.t
index dde87730c0..a2479ac8c1 100755
--- a/t/lib/glob-basic.t
+++ b/t/lib/glob-basic.t
@@ -3,7 +3,11 @@
BEGIN {
chdir 't' if -d 't';
unshift @INC, '../lib';
-
+ require Config; import Config;
+ if ($Config{'extensions'} !~ /\bFile\/Glob\b/i) {
+ print "1..0\n";
+ exit 0;
+ }
print "1..9\n";
}
END {
diff --git a/t/lib/glob-case.t b/t/lib/glob-case.t
index 2e65a0fc8b..32719b2d9a 100755
--- a/t/lib/glob-case.t
+++ b/t/lib/glob-case.t
@@ -3,6 +3,11 @@
BEGIN {
chdir 't' if -d 't';
unshift @INC, '../lib';
+ require Config; import Config;
+ if ($Config{'extensions'} !~ /\bFile\/Glob\b/i) {
+ print "1..0\n";
+ exit 0;
+ }
print "1..7\n";
}
END {
diff --git a/t/lib/glob-global.t b/t/lib/glob-global.t
index 44d7e8b5c3..9d273bd1ed 100755
--- a/t/lib/glob-global.t
+++ b/t/lib/glob-global.t
@@ -3,7 +3,11 @@
BEGIN {
chdir 't' if -d 't';
unshift @INC, '../lib';
-
+ require Config; import Config;
+ if ($Config{'extensions'} !~ /\bFile\/Glob\b/i) {
+ print "1..0\n";
+ exit 0;
+ }
print "1..10\n";
}
END {
diff --git a/t/lib/glob-taint.t b/t/lib/glob-taint.t
index 1b9c053bf7..a8dc213853 100755
--- a/t/lib/glob-taint.t
+++ b/t/lib/glob-taint.t
@@ -3,6 +3,11 @@
BEGIN {
chdir 't' if -d 't';
unshift @INC, '../lib';
+ require Config; import Config;
+ if ($Config{'extensions'} !~ /\bFile\/Glob\b/i) {
+ print "1..0\n";
+ exit 0;
+ }
print "1..2\n";
}
END {
diff --git a/t/lib/io_unix.t b/t/lib/io_unix.t
index 0e559e0d90..62569a5844 100644
--- a/t/lib/io_unix.t
+++ b/t/lib/io_unix.t
@@ -8,6 +8,7 @@ BEGIN {
# ``use IO::Socket'' executes too early below in the os2 block
if ($^O eq 'dos') {
print "1..0 # Skip: no fork\n";
+ exit 0;
}
}
diff --git a/t/op/ver.t b/t/op/ver.t
index 66e8378d98..206b1d08f8 100755
--- a/t/op/ver.t
+++ b/t/op/ver.t
@@ -5,7 +5,7 @@ BEGIN {
unshift @INC, "../lib";
}
-print "1..6\n";
+print "1..18\n";
my $test = 1;
@@ -13,21 +13,66 @@ use v5.5.640;
require v5.5.640;
print "ok $test\n"; ++$test;
+# printing characters should work
+print v111;
+print v107.32;
+print "$test\n"; ++$test;
+
+# hash keys too
+$h{v111.107} = "ok";
+print "$h{ok} $test\n"; ++$test;
+
+# poetry optimization should also
+sub v77 { "ok" }
+$x = v77;
+print "$x $test\n"; ++$test;
+
+# but not when dots are involved
+$x = v77.78.79;
+print "not " unless $x eq "MNO";
+print "ok $test\n"; ++$test;
+
print "not " unless v1.20.300.4000 eq "\x{1}\x{14}\x{12c}\x{fa0}";
print "ok $test\n"; ++$test;
-print "not " unless v1.20.300.4000 > 1.0203039 and v1.20.300.4000 < 1.0203041;
+print "not " unless sprintf("%vd", "Perl") eq '80.101.114.108';
+print "ok $test\n"; ++$test;
+
+print "not " unless sprintf("%vd", v1.22.333.4444) eq '1.22.333.4444';
+print "ok $test\n"; ++$test;
+
+print "not " unless sprintf("%vx", "Perl") eq '50.65.72.6c';
+print "ok $test\n"; ++$test;
+
+print "not " unless sprintf("%vX", v1.22.333.4444) eq '1.16.14D.115C';
print "ok $test\n"; ++$test;
-print "not " unless sprintf("%v", "Perl") eq '80.101.114.108';
+print "not " unless sprintf("%*v#o", ":", "Perl") eq '0120:0145:0162:0154';
print "ok $test\n"; ++$test;
-print "not " unless sprintf("%v", v1.22.333.4444) eq '1.22.333.4444';
+print "not " unless sprintf("%*vb", "##", v1.22.333.4444)
+ eq '1##10110##101001101##1000101011100';
print "ok $test\n"; ++$test;
{
use bytes;
+ print "not " unless sprintf("%vd", "Perl") eq '80.101.114.108';
+ print "ok $test\n"; ++$test;
+
print "not " unless
- sprintf("%v", v1.22.333.4444) eq '1.22.197.141.225.133.156';
+ sprintf("%vd", v1.22.333.4444) eq '1.22.197.141.225.133.156';
+ print "ok $test\n"; ++$test;
+
+ print "not " unless sprintf("%vx", "Perl") eq '50.65.72.6c';
+ print "ok $test\n"; ++$test;
+
+ print "not " unless sprintf("%vX", v1.22.333.4444) eq '1.16.C5.8D.E1.85.9C';
+ print "ok $test\n"; ++$test;
+
+ print "not " unless sprintf("%*v#o", ":", "Perl") eq '0120:0145:0162:0154';
+ print "ok $test\n"; ++$test;
+
+ print "not " unless sprintf("%*vb", "##", v1.22.333.4444)
+ eq '1##10110##11000101##10001101##11100001##10000101##10011100';
print "ok $test\n"; ++$test;
}
diff --git a/t/pod/poderrs.t b/t/pod/poderrs.t
index e27130ce39..bec2a198b6 100755
--- a/t/pod/poderrs.t
+++ b/t/pod/poderrs.t
@@ -36,6 +36,11 @@ Camps is very,
entertaining.
And they say we'll have some fun if it stops raining!
+Okay, now use a non-empty blank line to terminate a paragraph and make
+sure we get a warning.
+
+The above blank line contains tabs and spaces only
+
=head1 Additional tests
=head2 item without over
diff --git a/t/pod/poderrs.xr b/t/pod/poderrs.xr
index 157d1306ba..038cf4fb4c 100644
--- a/t/pod/poderrs.xr
+++ b/t/pod/poderrs.xr
@@ -1,32 +1,33 @@
-*** ERROR: Unknown command "unknown1" at line 21 in file pod/poderrs.t
-*** ERROR: Unknown interior-sequence "Q" at line 25 in file pod/poderrs.t
-*** ERROR: Unknown interior-sequence "A" at line 26 in file pod/poderrs.t
-*** ERROR: Unknown interior-sequence "Y" at line 27 in file pod/poderrs.t
-*** ERROR: Unknown interior-sequence "V" at line 27 in file pod/poderrs.t
-** Unterminated B<...> at pod/poderrs.t line 31
-** Unterminated I<...> at pod/poderrs.t line 30
-** Unterminated C<...> at pod/poderrs.t line 33
-*** ERROR: =item without previous =over at line 43 in file pod/poderrs.t
-*** ERROR: =over on line 43 without closing =back (at head2) at line 45 in file pod/poderrs.t
-*** ERROR: =back without previous =over at line 47 in file pod/poderrs.t
-*** ERROR: =over on line 51 without closing =back (at head2) at line 55 in file pod/poderrs.t
-*** ERROR: =end without =begin at line 57 in file pod/poderrs.t
-*** ERROR: Nested =begin's (first at line 61:html) at line 63 in file pod/poderrs.t
-*** ERROR: =end without =begin at line 67 in file pod/poderrs.t
-*** ERROR: nested commands C<...C<...>...> at line 71 in file pod/poderrs.t
-*** ERROR: garbled entity E<alea iacta est> at line 75 in file pod/poderrs.t
-*** ERROR: garbled entity E<C<auml>> at line 76 in file pod/poderrs.t
-*** ERROR: garbled entity E<abcI<bla>> at line 77 in file pod/poderrs.t
-*** WARNING: collapsing newlines to blanks at line 87 in file pod/poderrs.t
-*** ERROR: malformed link L<> : empty link at line 89 in file pod/poderrs.t
-*** WARNING: section in `passwd(5)' deprecated at line 94 in file pod/poderrs.t
-*** WARNING: ignoring leading whitespace in link at line 95 in file pod/poderrs.t
-*** WARNING: ignoring trailing whitespace in link at line 95 in file pod/poderrs.t
-*** WARNING: Spurious character(s) after =back at line 101 in file pod/poderrs.t
-*** WARNING: No items in =over (at line 109) / =back list at line 111 in file pod/poderrs.t
-*** WARNING: 2 unescaped <> in paragraph at line 113 in file pod/poderrs.t
-*** ERROR: unresolved internal link `begin or begin' at line 81 in file pod/poderrs.t
-*** ERROR: unresolved internal link `end with begin' at line 82 in file pod/poderrs.t
-*** ERROR: unresolved internal link `OoPs' at line 83 in file pod/poderrs.t
-*** ERROR: unresolved internal link `abc def' at line 87 in file pod/poderrs.t
-pod/poderrs.t has 24 pod syntax errors.
+*** ERROR: Unknown command 'unknown1' at line 21 in file pod/poderrs.t
+*** ERROR: Unknown interior-sequence 'Q' at line 25 in file pod/poderrs.t
+*** ERROR: Unknown interior-sequence 'A' at line 26 in file pod/poderrs.t
+*** ERROR: Unknown interior-sequence 'Y' at line 27 in file pod/poderrs.t
+*** ERROR: Unknown interior-sequence 'V' at line 27 in file pod/poderrs.t
+*** WARNING: unterminated B<...> at line 31 in file pod/poderrs.t
+*** WARNING: unterminated I<...> at line 30 in file pod/poderrs.t
+*** WARNING: unterminated C<...> at line 33 in file pod/poderrs.t
+*** WARNING: line containing nothing but whitespace in paragraph at line 41 in file pod/poderrs.t
+*** ERROR: =item without previous =over at line 48 in file pod/poderrs.t
+*** ERROR: =back without previous =over at line 52 in file pod/poderrs.t
+*** ERROR: =over on line 56 without closing =back (at head2) at line 60 in file pod/poderrs.t
+*** ERROR: =end without =begin at line 62 in file pod/poderrs.t
+*** ERROR: Nested =begin's (first at line 66:html) at line 68 in file pod/poderrs.t
+*** ERROR: =end without =begin at line 72 in file pod/poderrs.t
+*** ERROR: nested commands C<...C<...>...> at line 76 in file pod/poderrs.t
+*** ERROR: garbled entity E<alea iacta est> at line 80 in file pod/poderrs.t
+*** ERROR: garbled entity E<C<auml>> at line 81 in file pod/poderrs.t
+*** ERROR: garbled entity E<abcI<bla>> at line 82 in file pod/poderrs.t
+*** WARNING: collapsing newlines to blanks at line 92 in file pod/poderrs.t
+*** ERROR: malformed link L<> : empty link at line 94 in file pod/poderrs.t
+*** WARNING: section in 'passwd(5)' deprecated at line 99 in file pod/poderrs.t
+*** WARNING: ignoring leading whitespace in link at line 100 in file pod/poderrs.t
+*** WARNING: ignoring trailing whitespace in link at line 100 in file pod/poderrs.t
+*** ERROR: Spurious character(s) after =back at line 106 in file pod/poderrs.t
+*** WARNING: No items in =over (at line 114) / =back list at line 116 in file pod/poderrs.t
+*** WARNING: 2 unescaped <> in paragraph at line 118 in file pod/poderrs.t
+*** ERROR: unresolved internal link 'begin or begin' at line 86 in file pod/poderrs.t
+*** ERROR: unresolved internal link 'end with begin' at line 87 in file pod/poderrs.t
+*** ERROR: unresolved internal link 'OoPs' at line 88 in file pod/poderrs.t
+*** ERROR: unresolved internal link 'abc def' at line 92 in file pod/poderrs.t
+*** WARNING: multiple occurence of link target 'oops' at line - in file pod/poderrs.t
+pod/poderrs.t has 21 pod syntax errors.
diff --git a/t/pod/special_seqs.t b/t/pod/special_seqs.t
index 572fb8c061..b8af57ee05 100755
--- a/t/pod/special_seqs.t
+++ b/t/pod/special_seqs.t
@@ -17,10 +17,16 @@ __END__
=pod
This is a test to see if I can do not only C<$self> and C<method()>, but
-also C<$self->method()> and C<$self->{FIELDNAME}> and C<{FOO=>BAR}> without
-resorting to escape sequences.
+also C<< $self->method() >> and C<< $self->{FIELDNAME} >> and
+C<< $Foo <=> $Bar >> without resorting to escape sequences. If
+I want to refer to the right-shift operator I can do something
+like C<<< $x >> 3 >>> or even C<<<< $y >> 5 >>>>.
-Now for the grand finale of C<$self->method()->{FIELDNAME} = {FOO=>BAR}>.
+Now for the grand finale of C<< $self->method()->{FIELDNAME} = {FOO=>BAR} >>.
+And I also want to make sure that newlines work like this
+C<<<
+$self->{FOOBAR} >> 3 and [$b => $a]->[$a <=> $b]
+>>>
Of course I should still be able to do all this I<with> escape sequences
too: C<$self-E<gt>method()> and C<$self-E<gt>{FIELDNAME}> and C<{FOO=E<gt>BAR}>.
@@ -29,4 +35,9 @@ Dont forget C<$self-E<gt>method()-E<gt>{FIELDNAME} = {FOO=E<gt>BAR}>.
And make sure that C<0> works too!
+Now, if I use << or >> as my delimiters, then I have to use whitespace.
+So things like C<<$self->method()>> and C<<$self->{FIELDNAME}>> wont end
+up doing what you might expect since the first > will still terminate
+the first < seen.
+
=cut
diff --git a/t/pod/special_seqs.xr b/t/pod/special_seqs.xr
index fc06593d9d..a07f4cf417 100644
--- a/t/pod/special_seqs.xr
+++ b/t/pod/special_seqs.xr
@@ -1,8 +1,12 @@
This is a test to see if I can do not only `$self' and `method()', but
- also `$self->method()' and `$self->{FIELDNAME}' and `{FOO=>BAR}' without
- resorting to escape sequences.
+ also `$self->method()' and `$self->{FIELDNAME}' and `$Foo <=> $Bar'
+ without resorting to escape sequences. If I want to refer to the
+ right-shift operator I can do something like `$x >> 3' or even `$y >>
+ 5'.
Now for the grand finale of `$self->method()->{FIELDNAME} = {FOO=>BAR}'.
+ And I also want to make sure that newlines work like this
+ `$self->{FOOBAR} >> 3 and [$b => $a]->[$a <=> $b]'
Of course I should still be able to do all this *with* escape sequences
too: `$self->method()' and `$self->{FIELDNAME}' and `{FOO=>BAR}'.
@@ -11,3 +15,8 @@
And make sure that `0' works too!
+ Now, if I use << or >> as my delimiters, then I have to use whitespace.
+ So things like `<$self-'method()>> and `<$self-'{FIELDNAME}>> wont end
+ up doing what you might expect since the first > will still terminate
+ the first < seen.
+
diff --git a/t/pragma/warn/doop b/t/pragma/warn/doop
index c16e24f919..5803b44581 100644
--- a/t/pragma/warn/doop
+++ b/t/pragma/warn/doop
@@ -1,29 +1,6 @@
- doop.c AOK
-
- \x%s will produce malformed UTF-8 character; use \x{%s} for that
-
-
-__END__
# doop.c
use utf8 ;
$_ = "\x80 \xff" ;
chop ;
EXPECT
########
-# doop.c
-BEGIN {
- if (ord("\t") == 5) {
- print "SKIPPED\n# Character codes differ on ebcdic machines.";
- exit 0;
- }
-}
-use warnings 'utf8' ;
-use utf8 ;
-$_ = "\x80 \xff" ;
-chop ;
-no warnings 'utf8' ;
-$_ = "\x80 \xff" ;
-chop ;
-EXPECT
-\x80 will produce malformed UTF-8 character; use \x{80} for that at - line 10.
-\xff will produce malformed UTF-8 character; use \x{ff} for that at - line 10.
diff --git a/t/pragma/warn/pp b/t/pragma/warn/pp
index b392029767..8f42ba64ec 100644
--- a/t/pragma/warn/pp
+++ b/t/pragma/warn/pp
@@ -28,11 +28,6 @@
Constant subroutine %s undefined <<<TODO
Constant subroutine (anonymous) undefined <<<TODO
- Mandatory Warnings
- ------------------
- Malformed UTF-8 character (not tested: difficult to produce with
- perl now)
-
__END__
# pp.c
use warnings 'substr' ;
@@ -113,20 +108,3 @@ $_ = "\x80 \xff" ;
reverse ;
EXPECT
########
-# pp.c
-BEGIN {
- if (ord("\t") == 5) {
- print "SKIPPED\n# Character codes differ on ebcdic machines.";
- exit 0;
- }
-}
-use warnings 'utf8' ;
-use utf8 ;
-$_ = "\x80 \xff" ;
-reverse ;
-no warnings 'utf8' ;
-$_ = "\x80 \xff" ;
-reverse ;
-EXPECT
-\x80 will produce malformed UTF-8 character; use \x{80} for that at - line 10.
-\xff will produce malformed UTF-8 character; use \x{ff} for that at - line 10.
diff --git a/t/pragma/warn/sv b/t/pragma/warn/sv
index 9a2428e0cb..758137f2e8 100644
--- a/t/pragma/warn/sv
+++ b/t/pragma/warn/sv
@@ -269,25 +269,6 @@ EXPECT
Undefined value assigned to typeglob at - line 3.
########
# sv.c
-BEGIN {
- if (ord("\t") == 5) {
- print "SKIPPED\n# ebcdic \\x characters differ.";
- exit 0;
- }
-}
-use utf8 ;
-$^W =0 ;
-{
- use warnings 'utf8' ;
- my $a = rindex "a\xff bc ", "bc" ;
- no warnings 'utf8' ;
- $a = rindex "a\xff bc ", "bc" ;
-}
-my $a = rindex "a\xff bc ", "bc" ;
-EXPECT
-\xff will produce malformed UTF-8 character; use \x{ff} for that at - line 12.
-########
-# sv.c
use warnings 'y2k';
use Config;
BEGIN {
diff --git a/t/pragma/warn/toke b/t/pragma/warn/toke
index 271ef6365c..cfdea78d3c 100644
--- a/t/pragma/warn/toke
+++ b/t/pragma/warn/toke
@@ -89,10 +89,6 @@ toke.c AOK
sub time {}
my $a = time()
- \x%.*s will produce malformed UTF-8 character; use \x{%.*s} for that
- use utf8 ;
- $_ = "\xffe"
-
Unrecognized escape \\%c passed through
$a = "\m" ;
@@ -447,21 +443,6 @@ EXPECT
########
# toke.c
-BEGIN {
- if (ord("\t") == 5) {
- print "SKIPPED\n# Ebcdic platforms have different \\x constructs.";
- exit 0;
- }
-}
-use warnings 'utf8' ;
-use utf8 ;
-$_ = " \xffe " ;
-no warnings 'utf8' ;
-$_ = " \xffe " ;
-EXPECT
-\xff will produce malformed UTF-8 character; use \x{ff} for that at - line 10.
-########
-# toke.c
my $a = rand + 4 ;
EXPECT
Warning: Use of "rand" without parens is ambiguous at - line 2.
diff --git a/t/pragma/warn/utf8 b/t/pragma/warn/utf8
index cb1f202b8d..6a2fe5446c 100644
--- a/t/pragma/warn/utf8
+++ b/t/pragma/warn/utf8
@@ -14,48 +14,16 @@
<<<<<< Add a test when somethig actually calls utf16_to_utf8
__END__
-# utf8.c [utf8_to_uv]
+# utf8.c [utf8_to_uv] -W
use utf8 ;
-my $a = ord "\x80" ;
-EXPECT
-########
-# utf8.c [utf8_to_uv]
-BEGIN {
- if (ord("\t") == 5) {
- print "SKIPPED\n# Ebcdic platforms have different \\x constructs.";
- exit 0;
- }
-}
-use utf8 ;
-my $a = ord "\x80" ;
+my $a = "snøstorm" ;
{
- use warnings 'utf8' ;
- my $a = ord "\x80" ;
no warnings 'utf8' ;
- my $a = ord "\x80" ;
-}
-EXPECT
-\x80 will produce malformed UTF-8 character; use \x{80} for that at - line 12.
-########
-# utf8.c [utf8_to_uv]
-use utf8 ;
-my $a = ord "\xf080" ;
-EXPECT
-########
-# utf8.c [utf8_to_uv]
-BEGIN {
- if (ord("\t") == 5) {
- print "SKIPPED\n# Ebcdic platforms have different \\x constructs.";
- exit 0;
- }
-}
-use utf8 ;
-my $a = ord "\xf080" ;
-{
+ my $a = "snøstorm";
use warnings 'utf8' ;
- my $a = ord "\xf080" ;
- no warnings 'utf8' ;
- my $a = ord "\xf080" ;
+ my $a = "snøstorm";
}
EXPECT
-\xf0 will produce malformed UTF-8 character; use \x{f0} for that at - line 12.
+Malformed UTF-8 character at - line 3.
+Malformed UTF-8 character at - line 8.
+########
diff --git a/toke.c b/toke.c
index 398c5f90c9..bdf8e516ce 100644
--- a/toke.c
+++ b/toke.c
@@ -821,18 +821,27 @@ STATIC char *
S_force_version(pTHX_ char *s)
{
OP *version = Nullop;
+ bool is_vstr = FALSE;
+ char *d;
s = skipspace(s);
- if (isDIGIT(*s) || (*s == 'v' && isDIGIT(s[1]))) {
- char *d = s;
- if (*d == 'v')
- d++;
+ d = s;
+ if (*d == 'v') {
+ is_vstr = TRUE;
+ d++;
+ }
+ if (isDIGIT(*d)) {
for (; isDIGIT(*d) || *d == '_' || *d == '.'; d++);
if (*d == ';' || isSPACE(*d) || *d == '}' || !*d) {
s = scan_num(s);
/* real VERSION number -- GBARR */
version = yylval.opval;
+ if (is_vstr) {
+ SV *ver = cSVOPx(version)->op_sv;
+ SvUPGRADE(ver, SVt_PVIV);
+ SvIOKp_on(ver); /* hint that it is a version */
+ }
}
}
@@ -1163,6 +1172,8 @@ S_scan_const(pTHX_ char *start)
bool dorange = FALSE; /* are we in a translit range? */
bool has_utf = FALSE; /* embedded \x{} */
I32 len; /* ? */
+ UV uv;
+
I32 utf = (PL_lex_inwhat == OP_TRANS && PL_sublex_info.sub_op)
? (PL_sublex_info.sub_op->op_private & (OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF))
: UTF;
@@ -1284,18 +1295,20 @@ S_scan_const(pTHX_ char *start)
/* (now in tr/// code again) */
if (*s & 0x80 && thisutf) {
- dTHR; /* only for ckWARN */
- if (ckWARN(WARN_UTF8)) {
- (void)utf8_to_uv((U8*)s, &len); /* could cvt latin-1 to utf8 here... */
- if (len) {
- has_utf = TRUE;
- while (len--)
- *d++ = *s++;
- continue;
- }
- }
- else
- has_utf = TRUE; /* assume valid utf8 */
+ (void)utf8_to_uv((U8*)s, &len);
+ if (len == 1) {
+ /* illegal UTF8, make it valid */
+ /* need to grow with 1 char to be safe */
+ char *old_pvx = SvPVX(sv);
+ d = SvGROW(sv, SvCUR(sv)+2) + (d - old_pvx);
+ d = (char*)uv_to_utf8((U8*)d, (U8)*s++);
+ }
+ else {
+ while (len--)
+ *d++ = *s++;
+ }
+ has_utf = TRUE;
+ continue;
}
/* backslashes */
@@ -1351,51 +1364,75 @@ S_scan_const(pTHX_ char *start)
/* \132 indicates an octal constant */
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
- *d++ = (char)scan_oct(s, 3, &len);
+ uv = (UV)scan_oct(s, 3, &len);
s += len;
- continue;
+ goto NUM_ESCAPE_INSERT;
/* \x24 indicates a hex constant */
case 'x':
++s;
if (*s == '{') {
char* e = strchr(s, '}');
- UV uv;
-
if (!e) {
yyerror("Missing right brace on \\x{}");
e = s;
}
- /* note: utf always shorter than hex */
- uv = (UV)scan_hex(s + 1, e - s - 1, &len);
- if (uv > 127) {
- d = (char*)uv_to_utf8((U8*)d, uv);
- has_utf = TRUE;
- }
- else
- *d++ = (char)uv;
- s = e + 1;
+ uv = (UV)scan_hex(s + 1, e - s - 1, &len);
+ s = e + 1;
}
else {
- /* XXX collapse this branch into the one above */
- UV uv = (UV)scan_hex(s, 2, &len);
- if (utf && PL_lex_inwhat == OP_TRANS &&
- utf != (OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF))
- {
- d = (char*)uv_to_utf8((U8*)d, uv); /* doing a CU or UC */
+ uv = (UV)scan_hex(s, 2, &len);
+ s += len;
+ }
+
+ NUM_ESCAPE_INSERT:
+ /* Insert oct or hex escaped character.
+ * There will always enough room in sv since such escapes will
+ * be longer than any utf8 sequence they can end up as
+ */
+ if (uv > 127) {
+ if (!thisutf && !has_utf && uv > 255) {
+ /* might need to recode whatever we have accumulated so far
+ * if it contains any hibit chars
+ */
+ int hicount = 0;
+ char *c;
+ for (c = SvPVX(sv); c < d; c++) {
+ if (*c & 0x80)
+ hicount++;
+ }
+ if (hicount) {
+ char *old_pvx = SvPVX(sv);
+ char *src, *dst;
+ d = SvGROW(sv, SvCUR(sv) + hicount + 1) + (d - old_pvx);
+
+ src = d - 1;
+ d += hicount;
+ dst = d - 1;
+
+ while (src < dst) {
+ if (*src & 0x80) {
+ dst--;
+ uv_to_utf8((U8*)dst, (U8)*src--);
+ dst--;
+ }
+ else {
+ *dst-- = *src--;
+ }
+ }
+ }
+ }
+
+ if (thisutf || uv > 255) {
+ d = (char*)uv_to_utf8((U8*)d, uv);
has_utf = TRUE;
- }
+ }
else {
- if (uv >= 127 && UTF) {
- dTHR;
- if (ckWARN(WARN_UTF8))
- Perl_warner(aTHX_ WARN_UTF8,
- "\\x%.*s will produce malformed UTF-8 character; use \\x{%.*s} for that",
- (int)len,s,(int)len,s);
- }
- *d++ = (char)uv;
+ *d++ = (char)uv;
}
- s += len;
+ }
+ else {
+ *d++ = (char)uv;
}
continue;
@@ -3458,7 +3495,7 @@ Perl_yylex(pTHX)
OPERATOR(REFGEN);
case 'v':
- if (isDIGIT(s[1]) && PL_expect == XTERM) {
+ if (isDIGIT(s[1]) && PL_expect != XOPERATOR) {
char *start = s;
start++;
start++;
@@ -3468,6 +3505,18 @@ Perl_yylex(pTHX)
s = scan_num(s);
TERM(THING);
}
+ /* avoid v123abc() or $h{v1}, allow C<print v10;> */
+ else if (!isALPHA(*start) && (PL_expect == XTERM || PL_expect == XREF)) {
+ char c = *start;
+ GV *gv;
+ *start = '\0';
+ gv = gv_fetchpv(s, FALSE, SVt_PVCV);
+ *start = c;
+ if (!gv) {
+ s = scan_num(s);
+ TERM(THING);
+ }
+ }
}
goto keylookup;
case 'x':
@@ -6895,52 +6944,34 @@ Perl_scan_num(pTHX_ char *start)
pos++;
while (isDIGIT(*pos))
pos++;
- if (*pos == '.' && isDIGIT(pos[1])) {
+ if (!isALPHA(*pos)) {
UV rev;
U8 tmpbuf[UTF8_MAXLEN];
U8 *tmpend;
- NV nshift = 1.0;
bool utf8 = FALSE;
s++; /* get past 'v' */
sv = NEWSV(92,5);
- SvUPGRADE(sv, SVt_PVNV);
sv_setpvn(sv, "", 0);
- do {
+ for (;;) {
if (*s == '0' && isDIGIT(s[1]))
yyerror("Octal number in vector unsupported");
rev = atoi(s);
- s = ++pos;
- while (isDIGIT(*pos))
- pos++;
-
- if (rev > 127) {
- tmpend = uv_to_utf8(tmpbuf, rev);
- utf8 = TRUE;
- }
+ tmpend = uv_to_utf8(tmpbuf, rev);
+ utf8 = utf8 || rev > 127;
+ sv_catpvn(sv, (const char*)tmpbuf, tmpend - tmpbuf);
+ if (*pos == '.' && isDIGIT(pos[1]))
+ s = ++pos;
else {
- tmpbuf[0] = (U8)rev;
- tmpend = &tmpbuf[1];
+ s = pos;
+ break;
}
- sv_catpvn(sv, (const char*)tmpbuf, tmpend - tmpbuf);
- if (rev > 0)
- SvNVX(sv) += (NV)rev/nshift;
- nshift *= 1000;
- } while (*pos == '.' && isDIGIT(pos[1]));
-
- if (*s == '0' && isDIGIT(s[1]))
- yyerror("Octal number in vector unsupported");
- rev = atoi(s);
- s = pos;
- tmpend = uv_to_utf8(tmpbuf, rev);
- utf8 = utf8 || rev > 127;
- sv_catpvn(sv, (const char*)tmpbuf, tmpend - tmpbuf);
- if (rev > 0)
- SvNVX(sv) += (NV)rev/nshift;
+ while (isDIGIT(*pos))
+ pos++;
+ }
SvPOK_on(sv);
- SvNOK_on(sv);
SvREADONLY_on(sv);
if (utf8) {
SvUTF8_on(sv);
diff --git a/utils/perlbug.PL b/utils/perlbug.PL
index 97f8d867da..f46564ea5f 100644
--- a/utils/perlbug.PL
+++ b/utils/perlbug.PL
@@ -57,7 +57,7 @@ print "Extracting $file (with variable substitutions)\n";
# In this section, perl variables will be expanded during extraction.
# You can use $Config{...} to use Configure variables.
-my $extract_version = sprintf("v%v", $^V);
+my $extract_version = sprintf("v%vd", $^V);
print OUT <<"!GROK!THIS!";
$Config{startperl}
@@ -133,7 +133,7 @@ my( $file, $usefile, $cc, $address, $perlbug, $testaddress, $filename,
$subject, $from, $verbose, $ed, $outfile, $Is_MacOS,
$fh, $me, $Is_MSWin32, $Is_VMS, $msg, $body, $andcc, %REP, $ok);
-my $perl_version = $^V ? sprintf("v%v", $^V) : $];
+my $perl_version = $^V ? sprintf("v%vd", $^V) : $];
my $config_tag2 = "$perl_version - $Config{cf_time}";